Wärmeleitungsgleichung in Java simulieren

Neue Frage »

Auf diesen Beitrag antworten »
Shizmo Wärmeleitungsgleichung in Java simulieren

Hallo, ich steh hier vor einer für mich unverständlichen Aufgabe und hoffe mir kann das evtl jemand besser erklären.

Simulieren Sie die Wärmeleitungsgleichung.
Es geht vorerst mal nur um Teil1.

Ich hab die Angabe mal als PDF verlinkt: Klick


Das Problem ist die Formel (das Schema):
[latex]h[x,y,t+1] = h[x,z,t] - \alpha (4h[x,y,t]-h[x-1,y,t]-h[x+1,y,t]-h[x,y-1,t]-h[x,y+1,t][/latex]

Ich brauche ein Feld (also ein 2dim-Array[][], die Spalten sind die x-Werte und die Zeilen die y-Werte), z.B. 5x5.
So jetzt ist mein x-Wert 5 und mein y-Wert auch 5. Was macht die Formel jetzt mit den Werten, also mit Alpha wird multipliziert, aber was bedeutet h[x,y,t], wie setz ich das um.

Ich verstehs einfach nicht... traurig
 
Auf diesen Beitrag antworten »
eulerscheZahl

x und y hast du durch die Position der Variablen im Array gegeben:
code:
1:
2:
3:
4:
5:
for (int x = 0; x < 5; x++) {
    for (int y = 0; y < 5; y++) {
        //mache was mit heat[x,y], was die Temperatur an (x, y) ist.
    }
}


t ist implizit gegeben: Zu Beginn ist t=0. Wenn du einmal die Hitzeverschiebung berechnet hast, ist danach t=1. So erhöht sich das t für jeden Aufruf der Hitzeverteilungsfunktion weiter.
Auf diesen Beitrag antworten »
Shizmo

Okay danke super, Teil1 funktioniert, bin gerade bei Teil2, sollte auch funktionieren, tut es aber nicht, also meine Methode fuer Teil2 sieht so aus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
   static double[][] heatSimInsulated (double[][] heat, double alpha){
      int lines = heat.length, cols = heat[0].length;
      double[][] heatNew = new double[lines][cols];
      for(int x = 0; x < lines; x++){
         for(int y = 0; y < cols; y++){
            //Ecken
            if(x == 0 && y == 0){
               heatNew[x][y] = heat[x][y] - alpha*(2*heat[x][y]-heat[x+1][y]-heat[x][y+1]);
            }
            else if(x == 0 && y == cols){
               heatNew[x][y] = heat[x][y] - alpha*(2*heat[x][y]-heat[x+1][y]-heat[x][y-1]);
            }
            else if(x == lines && y == 0){
               heatNew[x][y] = heat[x][y] - alpha*(2*heat[x][y]-heat[x-1][y]-heat[x][y+1]);
            }
            else if(x == lines && y == cols){
               heatNew[x][y] = heat[x][y] - alpha*(2*heat[x][y]-heat[x-1][y]-heat[x][y-1]);
            }
            //Raender
            else if(x == 0){
               heatNew[x][y] = heat[x][y] - alpha*(3*heat[x][y]-heat[x+1][y]-heat[x][y-1]-heat[x][y+1]);
            }
            else if(x == lines){
               heatNew[x][y] = heat[x][y] - alpha*(3*heat[x][y]-heat[x-1][y]-heat[x][y-1]-heat[x][y+1]);
            }
            else if(y == 0){
               heatNew[x][y] = heat[x][y] - alpha*(3*heat[x][y]-heat[x+1][y]-heat[x-1][y]-heat[x][y+1]);
            }
            else if(y == cols){
               heatNew[x][y] = heat[x][y] - alpha*(3*heat[x][y]-heat[x+1][y]-heat[x-1][y]-heat[x][y-1]);
            }
            //Mitte
            else {
               heatNew[x][y] = heat[x][y] - alpha*(4*heat[x][y]-heat[x-1][y]-heat[x+1][y]-heat[x][y-1]-heat[x][y+1]);
            }
            
         }
      }
      return heatNew;
   }


Allerdings kommt ein Laufzeitfehler, in dem Fall bei Zeile 20 mit:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5"

Findet wer den Fehler???
Auf diesen Beitrag antworten »
Karlito

Koordinaten verdreht? Schau mal in die Schleifenköpfe. x = lines und y = columns?

Gruß,

Karlito
 
Auf diesen Beitrag antworten »
Shizmo

Zitat:
Original von Karlito
Koordinaten verdreht? Schau mal in die Schleifenköpfe. x = lines und y = columns?

Gruß,

Karlito


Hmm, ich hab:
int lines = heat.length, cols = heat[0].length;

beispiel bei heat[5][4]

Waere dann ja heat.length=5, was dann die Zeilen waeren und heat[0].length=6 die Spalten, also sollte es stimmen!?

Mein Feld sieht ja so aus:

code:
1:
2:
3:
4:
5:
6:
--y0--y1--y2--y3--y4
x0 0  0   0   0   0
x1 0  0   0   0   0
x2 0  0   0   0   0
x3 0  0   0   0   0
x4 0  0   0   0   0


//edit:

Ach ich habs, z.B. x kann ja nie lines erreichen sondern immer nur lines-1, da x bei 0 anfaengt Zunge raus
Auf diesen Beitrag antworten »
Shizmo

Braeuchte noch einen Tipp:

Mein Code sieht so aus und funktioniert auch wunderbar und alles schaut so aus, wie auf den Angabezettel, allerdings kommt bei der Abgabepruefung dieser Fehler:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
> java -classpath '/tmp/autoc-einfprog-0.5.5-33-g6ad7fba-plus/check-62-8-1448638642' -Duser.language=EN -Duser.region=US -Xmx512M Tester
       0.0       0.0      30.9       0.0       0.0       0.0
       0.0       0.0       0.0       0.0       0.0       0.0
       0.0       0.0      46.4       0.0       0.0       0.0
       0.0       0.0       0.0       0.0       0.0       0.0
       0.0       0.0       0.0       0.0       0.0       0.0
       0.0       0.0      66.6       0.0       0.0       0.0
      71.3       0.0      38.7       0.0       0.0      29.2       0.0
       0.0       0.0      80.6       0.0       0.0      37.4       0.0
       0.0      82.7       0.0      82.6       0.0       0.0      63.3
      75.3      48.7       0.0      83.4      17.9      54.0      46.3
      43.5       0.0      28.1      12.6      31.5      59.4      80.9
      37.1      43.6       0.0       2.7       0.0      58.7       0.0
       0.0       0.0       0.0      35.8       0.0      90.9       0.0
      65.5

[Ausführungsprotokoll gekürzt]

>> Input for heatSim()<<
heat:
      65.5053

alpha: 0.1
steps: 1
insulated: true
Please download the complete execution protocol to see the exact heat matrix!

at test.testMatrix(test.java:112)
at test.run(Unknown Source)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at Bsp07.heatSimInsulated(Bsp07.java:38)
at Bsp07.heatSim(Bsp07.java:25)
at test.testMatrix(test.java:110)
... 1 more


Hier mein Code:
code:
1:
Code entfernt


Es steht zwar da:
Please download the complete execution protocol to see the exact heat matrix!

Kann man aber nicht traurig


Also ich komm irgendwo out of boundaries, weiß aber nicht wo und wieso.
Auf diesen Beitrag antworten »
eulerscheZahl

Weißt du sicher, dass die Eingabe Rechteksform hat? Die Fehlerausgabe sieht mir nicht danach aus.
Auf diesen Beitrag antworten »
Shizmo

Das hab ich mir auch schon gedacht, allerdings steht in der Angabe:

Schreiben Sie eine Methode die in heat das Temperaturfeld h[&#8901;,&#8901;,0] auf einer rechteckigen Fläche erhält.

Vielleicht schaut das nur so aus, weil es ja abbricht, da es out of boundaries ist.
Auf diesen Beitrag antworten »
eulerscheZahl

Hmm.
Ein weiterer möglicher Testfall: setze Breite oder Höhe auf 1. Da stürzt dein Programm auch ab.
Auf diesen Beitrag antworten »
Shizmo

Zitat:
Original von eulerscheZahl
Hmm.
Ein weiterer möglicher Testfall: setze Breite oder Höhe auf 1. Da stürzt dein Programm auch ab.


Jawoll das wars großes Grinsen
Vielen Dank, hab einfach noch Speziallfaelle hinzugefuegt:
php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
//Spezialfaelle
            if(== && == && == lines-1){
               heatNew[x][y] = heat[x][y];
            }
            else if(== && == && == cols-1){
               heatNew[x][y] = heat[x][y];
            }
            else if(== && == cols-1){
               heatNew[x][y] = heat[x][y];
            }
            else if(== && == lines-1){
               heatNew[x][y] = heat[x][y];
            }


Und es laeuft.
Danke fuer den Tipp!!!
Auf diesen Beitrag antworten »
Darkwing Duck

Hallo,

ich habe zur Zeit ein ähnliches Problem/Aufgabe wie hier beschrieben. Der Unterschied ist, dass bei mir ein 3 dimensionaler Raum über eine Heizung erwärmt werden soll.
Ich habe soweit alles Programmiert und auch meines Wissens alle Sonderfälle berücksichtigt. Leider sind die Ausgaben teilweise nicht wirklich schlüssig für mich. Mal ist der wert eines Feldes nach dem 2ten Schritt bei 9 und ein anderes in der Nähe bei 0,... Irgendwo scheint der Bock drin zu sein, nur kann ich den Fehler nicht finden.

Ausserdem habe ich ein großes Problem beim Ausgeben des Arrays. Da es eine 3te Dimension gibt weiss ich nicht, wie ich das ganze einigermaßen leserlich ausgeben soll. Hat da vielleicht jemand einen Tipp?
Hier der Code(leider sehr viel):

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
raumTemp[0][3][0]=100;
             
             while(zeit<5){
                 System.out.println("Temperatur Schritt " + zeit);
                 if(zeit>0){
                     raumTemp=raumTempneu;
                 }
                 
                 if(zeit > 1){
                     
                     
                 }
                 
             for(int posX = 0; posX < x; posX++) {
      
                 for(int posY = 0; posY < y; posY++) {
           
                     for(int posZ = 0; posZ < z; posZ++) {
                         
                         //System.out.print("Heizung: (" + raumTempneu[0][3][0]   + ")");
                 
                          
                         //Ecken unten
                         if(posX ==0 && posY==0 && posZ==0){
                         
                             raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX][posY+1][posZ]-raumTemp[posX][posY][posZ+1]);
                             System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                             
                         }
                             else if(posX ==0 && posY==4 && posZ==0){
                                // System.out.print("HierHierHier(" + raumTempneu[0][3][0]   + ")");
                                 raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX][posY-1][posZ]-raumTemp[posX][posY][posZ+1]);
                                 System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                                 
                             }
                         
                         else if(posX ==4 && posY==0 && posZ==0){
                                 
                                 raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX-1][posY][posZ]-raumTemp[posX][posY+1][posZ]-raumTemp[posX][posY][posZ+1]);
                                 System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                             }
                         
                         else if(posX ==4 && posY==4 && posZ==0){
                                 
                                 raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX-1][posY][posZ]-raumTemp[posX][posY-1][posZ]-raumTemp[posX][posY][posZ+1]);
                                 System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                             }
                         
                         //Ecken oben
                         else if(posX ==0 && posY==0 && posZ==2){
                         
                             raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX][posY+1][posZ]-raumTemp[posX][posY][posZ-1]);
                             System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                             
                         }
                             else if(posX ==0 && posY==4 && posZ==2){
                                 
                                 raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(3*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX][posY-1][posZ]-raumTemp[posX][posY][posZ-1]);
                                 System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                             }

                         
                                                                .
                                                                .
                                                                .

                         
                         //Allgemein Decke
                         else if(posX > 0 && posX<4 && posY > 0 && posY < 4 && posZ==2){
                             
                             raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(5*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX-1][posY][posZ]-raumTemp[posX][posY+1][posZ]-raumTemp[posX][posY-1][posZ]-raumTemp[posX][posY][posZ-1]);
                              System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                         }
                         
                         //Allgemein Innen
                         else if(posX > 0 && posX<4 && posY >0 && posY < 4 && posZ>0 && posZ<2){
                             
                             raumTempneu[posX][posY][posZ] = raumTemp[posX][posY][posZ]-temperaturleitfähigkeit*(6*raumTemp[posX][posY][posZ]-raumTemp[posX+1][posY][posZ]-raumTemp[posX-1][posY][posZ]-raumTemp[posX][posY+1][posZ]-raumTemp[posX][posY-1][posZ]-raumTemp[posX][posY][posZ+1]-raumTemp[posX][posY][posZ-1]);
                              System.out.print("(" + raumTempneu[posX][posY][posZ]   + ")");
                              
                             
                         }
                         
                         
                         
                         
                         //System.out.print("(" + raumTemp[posX][posY][posZ]   + ")");
                     }
                      System.out.println(" ");
                 }
                
            
             
         }
             zeit++;
             
    }
             
    }
}


Ein weiteres Problem ist, dass der Startwert von 100 in allen durchgängen konstant bleiben sollte. Bisher verringert sich dieser mit jedem Durchlauf.

Ich hoffe jemand kann helfen. Daumen hoch
Auf diesen Beitrag antworten »
eulerscheZahl

Als Ausgabe habe ich Programmcode für sage (sagemath.org). Damit werden 3D Plots erstellt, die die Temperaturverteilung farblich darstellen.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
public class Main {

	public static void main(String[] args) {
		int xMax = 5;
		int yMax = 5;
		int zMax = 5;
		double alpha = 0.5;
		double tempInit = 100;
		double[][][] temp = new double[xMax + 1][yMax + 1][zMax + 1];
		int[][] offset = { { 0, 0, 1 }, { 0, 0, -1 }, { 0, 1, 0 }, { 0, -1, 0 }, { 1, 0, 0 }, { -1, 0, 0 } }; //definieren, welche Felder benachbart sind
		temp[0][3][0] = tempInit; //Heizung
		for (int t = 0; t <= 500; t++) {
			double[][][] tempNew = new double[xMax + 1][yMax + 1][zMax + 1];
			for (int x = 0; x <= xMax; x++) {
				for (int y = 0; y <= yMax; y++) {
					for (int z = 0; z <= zMax; z++) {
						double neighborCount = 0;
						double neighborTemp = 0;
						for (int i = 0; i < 6; i++) {
							int x_ = x + offset[i][0];
							int y_ = y + offset[i][1];
							int z_ = z + offset[i][2];
							//prüfen, ob Nachbarn innerhalb des Raums sind
							if (x_ >= 0 && x_ <= xMax && y_ >= 0 && y_ <= yMax && z_ >= 0 && z_ <= zMax) {
								neighborCount++;
								neighborTemp += temp[x_][y_][z_];
							}
						}
						tempNew[x][y][z] = temp[x][y][z] - alpha / neighborCount * (neighborCount * temp[x][y][z] - neighborTemp);
					}
				}
			}
			tempNew[0][3][0] = tempInit; //Heizung verliert nicht an Temperatur
			temp = tempNew;
			// Ausgabe
			StringBuilder sb = new StringBuilder();
			sb.append("p = point3d([])\n");
			for (int x = 0; x <= xMax; x++) {
				for (int y = 0; y <= yMax; y++) {
					for (int z = 0; z <= zMax; z++) {
						sb.append("p += point3d([" + x + "," + y + "," + z + "], color=(" + temp[x][y][z] / tempInit + ",0," + (1 - temp[x][y][z] / tempInit) + "))\n");
					}
				}
			}
			sb.append("p.show()");
			if (t % 100 == 0) //alle 100 Schritte die Temperaturverteilung ausgeben
				System.out.println(sb.toString());
		}
	}
}
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »