Euler Methode in Runge Kutta 2 < DGL < Numerik < Hochschule < Mathe < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 23:47 Sa 16.01.2010 | Autor: | kushkush |
Hi,
ich habe ein Programm erstellt, welches die Koordinaten 2er Planeten um die Sonne berechnet und ausgibt. Es handelt sich dabei um zwei Differentialgleichungen, welche ich durch die Euler Methode numerisch annähre. Zum Vergleich möchte ich jedoch gerne die Euler Methode mit der Runge Kutta Methode 2. Ordnung ersetzen, habe leider keinen Schimmer wie ich das anstellen soll. Was muss ich ändern, dass aus meinen Euler-Methodischen Berechnungen Runge-Kuttaische werden?
1: |
| 2: | int m = 200000;
| 3: | int m1 = 6000;
| 4: | int m2 = 8000;
| 5: | int b = 900;
| 6: | int h = 900;
| 7: |
| 8: | double gamma = 6.67;
| 9: | double r = 15;
| 10: | double r2 = 20;
| 11: | double vx = 0;
| 12: | double vx2 = 0;
| 13: | double alpha = 0;
| 14: | double alpha2 = 0;
| 15: | double alpha3 = 0;
| 16: | double alpha4 = 0;
| 17: | double x = r;
| 18: | double x2 = r2;
| 19: | double y = 0;
| 20: | double y2 = 0;
| 21: | double mittelpunktx = b/2;
| 22: | double mittelpunkty = h/2;
| 23: | double vy = 0.0001 * Math.sqrt(1000 * gamma * m / r);
| 24: | double vy2 = 0.0001 * Math.sqrt(1000* gamma * m / r2);
| 25: | double tend = 500;
| 26: | double t = 0;
| 27: | double pi = 4*Math.atan(1);
| 28: | double deltat = 0.2;
| 29: | double result = 0;
| 30: |
| 31: | while (t <= tend) {
| 32: |
| 33: | t = t + deltat;
| 34: | r = Math.sqrt(x * x + y * y);
| 35: | r2 = Math.sqrt(x2 * x2 + y2 * y2);
| 36: |
| 37: | double posx = mittelpunktx + x;
| 38: | double posy = mittelpunkty + y;
| 39: | double posx2 = mittelpunktx + x2;
| 40: | double posy2 = mittelpunkty + y2;
| 41: | double poswechselx = posx2 - posx;
| 42: | double poswechsely = posy2 - posy;
| 43: | double rwechselq = poswechselx * poswechselx + poswechsely * poswechsely;
| 44: |
| 45: | double a = 0.00001 * gamma * ((m / r) / r);
| 46: | double a2 = 0.00001 * gamma * ((m / r2) / r2);
| 47: | double avon1auf2 = 0.00001 * gamma * (m2 / rwechselq);
| 48: | double avon2auf1 = 0.00001 * gamma * (m1 / rwechselq);
| 49: |
| 50: | alpha = winkel(x,y,alpha);
| 51: | alpha2 = winkel(x2, y2, alpha2);
| 52: | alpha3 = winkel(poswechselx, poswechsely, alpha3);
| 53: | alpha4 = alpha3 + pi;
| 54: |
| 55: | double ax = a * Math.cos(alpha);
| 56: | double ay = a * Math.sin(alpha);
| 57: | double ax2 = a2 * Math.cos(alpha2);
| 58: | double ay2 = a2 * Math.sin(alpha2);
| 59: | double ax3 = avon1auf2 * Math.cos(alpha4);
| 60: | double ay3 = avon1auf2 * Math.sin(alpha4);
| 61: | double ax4 = avon2auf1 * Math.cos(alpha3);
| 62: | double ay4 = avon2auf1 * Math.sin(alpha3);
| 63: |
| 64: | ax = ax + ax3;
| 65: | ay = ay + ay3;
| 66: | ax2 = ax2 + ax4;
| 67: | ay2 = ay2 + ay4;
| 68: | vx = vx - ax * deltat;
| 69: | vy = vy - ay * deltat;
| 70: | x = x + vx * deltat;
| 71: | y = y + vy * deltat;
| 72: | vx2 = vx2 - ax2 * deltat;
| 73: | vy2 = vy2 - ay2 * deltat;
| 74: | x2 = x2 + vx2 * deltat;
| 75: | y2 = y2 + vy2 * deltat;
| 76: |
|
ich habe diese Frage in keinem anderen Forum gestellt und bin für jede Antwort dankbar.
|
|
|
|
Hallo,
hast du schon mal mit Feldern programmiert? Das wäre meine erste Empfehlung. Zweitens ist nicht gerade leicht zu sehen, wo du die Euler-Methode einsetzt - könntest du vielleicht mal die Programmzeile angeben?
Soweit ich mich erinnere hat man doch bei dem Planetenproblem eine Differentialgleichung zweiter Ordnung, oder? Die muss man umwandeln in zwei Differentialgleichungen erster Ordnung. Das wirst du sicher gemacht haben, aber ich weiß nicht wo.
So, jetzt erstmal genug Kritik... Wenn du eine Runge-Kutta-Methode schreiben willst, brauchst du noch mehr Variablen. Nämlich die, mit denen du die Zwischenwerte abspeicherst. Damit wird dein Programm noch unübersichtlicher. Ich weiß halt nicht, ob das viel Sinn macht.
Aber sei es drum... Die Euler-Methode funktioniert formal nach dem Schema:
[mm] x_{n+1}=x_n+h*f(t_n,x_n)
[/mm]
Eine einfache Runge-Kutta-Methode hat folgendes Schema:
[mm] x_{n+1}=x_n+h*f(t_n+h/2,x_n+h/2*f(t_n,x_n))
[/mm]
Wie du siehst, kann man die Euler-Methode zum Teil benutzen (nämlich am Ende, nur mit der halben Schrittweite), doch nutzt man deren berechneten Wert noch einmal.
Vielleicht konnte ich dir schon helfen...
Viel Erfolg noch,
Roland.
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 01:53 So 17.01.2010 | Autor: | kushkush |
Eingabefehler: "{" und "}" müssen immer paarweise auftreten, es wurde aber ein Teil ohne Entsprechung gefunden (siehe rote Markierung)
Hallo pi-roland,
danke erstmal für deine Zusatzinformationen.
Aus der Differentialgleichung habe ich die 8 Variablen $a_{x_{1}}$, $a_{y_{1}}$, $a_{x_{2}}$, $a_{y_{2}}$, $x_{1}}$,$ x_{2}$, $y_{1}$ und $y_{2}$ . Der Euler ist dort wo deltat angewendet wird. (ausser beim t+ deltat Teil natürlich...)
Ich blicke immer noch nicht durch wo ich ansetzen soll mit dem Runge-Kutta (2.O) Schema.
Weitere Inputs sind deshalb immer noch herzlichst willkommen.
|
|
|
|
|
Hallo,
was bei mir h ist ist bei dir deltat.
Kommt eigentlich eine gescheite Bewegung heraus bei dir? Ich kapiere nämlich noch nicht ganz, was du rechnest. Nach meinem Verständnis für die Planetenbewegung ist gar keine Winkelberechnung nötig.
Ein erster Schritt für eine genauere Berechnung wäre ja deltat kleiner zumachen.
Mit Runge-Kutta zu rechnen bedeutet, dass du als erstes die Berechnung wie zur Zeit machst, aber mit halben deltat.
Nun musst du mit den errechneten Werten nochmals die Änderungen (also das was jeweils vor deinem deltat steht) berechnen. Diesmal hast du aber die "richtigen" Änderungswerte erhalten und kannst mit deiner ursprünglichen Methode die nächsten Positionen und Geschwindigkeiten berechnen.
Es ist leider nach wie vor recht schwierig dir zu helfen, da dein Programm nicht schnell anpassbar ist. Eine Implementierung einer Runge-Kutta-Methode noch höherer Ordnung ist praktisch unmöglich. Daher nochmals die Empfehlung das Problem mit Feldern und vor allem Funktionen zu lösen.
Viel Erfolg noch,
Roland.
|
|
|
|
|
Ja, es ergeben sich vernünftige Planetenbahnen. Die Winkel sind nötig da die Planeten ja nicht immer nur im recht-oberen Quadranten sind. (Also komplexe Unterscheidung)
Das Problem ist halt, dass sobald sich die Planeten nahekommen, es den einen wegspickt; und in Wirklichkeit sollte er aber um den anderen Planeten herum oszillieren. Das naheliegendste ist, dass es sich bei der Fehlerquelle beim Verfahren handelt...
Das mit den kleineren Schrittweite habe ich schon versucht, hilft nicht wirklich...
> Mit Runge-Kutta zu rechnen bedeutet, dass du als erstes
> die Berechnung wie zur Zeit machst, aber mit halben
> deltat.
> Nun musst du mit den errechneten Werten nochmals die
> Änderungen (also das was jeweils vor deinem deltat steht)
> berechnen. Diesmal hast du aber die "richtigen"
> Änderungswerte erhalten und kannst mit deiner
> ursprünglichen Methode die nächsten Positionen und
> Geschwindigkeiten berechnen.
Kannst du mir diesen Teil eventuell mit Pseudo-Code an meinem Code zeigen? Ich verstehe nicht wie ich deine Erklärung konkret ausführen soll.
Danke
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 06:20 Mo 18.01.2010 | Autor: | matux |
$MATUXTEXT(ueberfaellige_frage)
|
|
|
|