26.11.2015, 21:48 |
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):
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...
|
|
|
|
26.11.2015, 23:14 |
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. |
27.11.2015, 11:17 |
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??? |
27.11.2015, 11:41 |
Auf diesen Beitrag antworten » |
Karlito |
Koordinaten verdreht? Schau mal in die Schleifenköpfe. x = lines und y = columns?
Gruß,
Karlito |
Anzeige |
|
|
27.11.2015, 14:14 |
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
|
27.11.2015, 17:17 |
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:
Es steht zwar da:
Please download the complete execution protocol to see the exact heat matrix!
Kann man aber nicht
Also ich komm irgendwo out of boundaries, weiß aber nicht wo und wieso. |
27.11.2015, 18:05 |
Auf diesen Beitrag antworten » |
eulerscheZahl |
Weißt du sicher, dass die Eingabe Rechteksform hat? Die Fehlerausgabe sieht mir nicht danach aus. |
27.11.2015, 18:22 |
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[⋅,⋅,0] auf einer rechteckigen Fläche erhält.
Vielleicht schaut das nur so aus, weil es ja abbricht, da es out of boundaries ist. |
27.11.2015, 18:27 |
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. |
27.11.2015, 18:49 |
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
Vielen Dank, hab einfach noch Speziallfaelle hinzugefuegt:
php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
|
//Spezialfaelle
if(x == 0 && y == 0 && x == lines-1){
heatNew[x][y] = heat[x][y];
}
else if(x == 0 && y == 0 && y == cols-1){
heatNew[x][y] = heat[x][y];
}
else if(y == 0 && y == cols-1){
heatNew[x][y] = heat[x][y];
}
else if(x == 0 && x == lines-1){
heatNew[x][y] = heat[x][y];
} |
|
Und es laeuft.
Danke fuer den Tipp!!! |
02.06.2016, 22:25 |
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.
|
03.06.2016, 06:35 |
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());
}
}
} |
|
|