Stimmt diese Planetenlaufbahn-Approximation?


15.03.2025, 18:46

Hier ist noch die deriv-Funktion:

def deriv(t, state):
    x, y, vx, vy = state
    x, y, vx, vy = Decimal(x), Decimal(y), Decimal(vx), Decimal(vy) 


    r = (x**2 + y**2).sqrt()  
    if r == 0:
        return [vx, vy, Decimal("0"), Decimal("0")]  
    
    r_modified = r**exp_r 
    F = -G * M_SUN / r_modified
    ax = F * x / r
    ay = F * y / r
    return [vx, vy, ax, ay]

3 Antworten

Ich habe mir Deine Runge-Kutta-Funktion nicht näher angeschaut (und schon garnicht nachgerechnet).

Mir ist jedoch aufgefallen, das diese mit Floats nahe den Min/Max-Values operiert.

1.175494351E-38 und 3.402823466E+38

Float benutzt 32 Bit und "rundetc um so "aggressiver", je näher Resultate von Operationen an den Limits liegen. Dies kann zu massiven Rechenfehler führen, da jeweils nur eine stark begrenzte Anzahl an Bits für Exponent und Mantisse zur Verfügung stehen.

Versuche es statt dessen mal mit Double oder Decimal oder sogar BigInt (sollte auch Python haben).

Double rechnet mit 64Bit , Decimal mit 128 und Bigint sogar mit ca. max. 20Mrd Bit (extrem langsam auf Konsumerrechnern).

Für BigInt-Berechnungen musst Du gegebenenfalls kommazahlen manuell in (big)Integer scalieren.

Ich habe zu dieser frühen Stunde leider keine Zeit auf Deine Berechnungen näher einzugehen. Versuche es erstmal mit den übrigen (genaueren) Datentypen zu arbeiten. Sollte dies nicht klappen werde ich mich mal über Deine Funktion beugen.


gabriel3544  14.03.2025, 12:24

Python kennt nur einen eingebauten Gleitkommatyp, und der wird auf allen modernen Plattformen in 64 Bit untergebracht, entspricht also "double".

Leonie4863 
Beitragsersteller
 14.03.2025, 12:53

Vielen Dank für deine Hilfe! 😊 Ich nun die Dezimal-Funktion in meinem Programm eingefügt, welche deutlich mehr Nachkommastellen ermöglicht. Nun werden die Ellipsen zwar etwas schöner gezeichnet, aber deren Form und Grösse oder besser gesagt deren Exzentrizität bleibt gleich...

Aber ist es normal, dass die Umlaufbahn der Erde bei einer kleinen Exponenten-Änderung von 2 auf 2.02 so viel grösser wird? Falls ja, warum ist das so?

Ja, das sollte so schon richtig sein. Der Exponent bestimmt, wie stark die Anziehungskraft mit der Entfernung abnimmt. Bei Werten über 2 (Normalwert) nimmt diese Kraft stärker ab, also wird die Erde weniger zurückgezogen und eine größere, ovale Umlaufbahn entsteht. Das macht sich schon bei kleineren Zuwächsen deutlich bemerkbar. Deshalb wird diese Kraft auch mit einer Potenzfunktion abgebildet. Der Wert steigt (oder sinkt) exponentiell.

Probiere für deine Simulation doch noch weitere Werte. Womöglich geht es bei einem Exponent wie 2.5 bereits in eine Hyperbelbahn.

Hier ist mein Programm:

1) Deine deriv-Funktion hast du gar nicht geteilt, dabei sollte die doch erst aufzeigen, ob du exp_r richtig verwendest.

2) Hier fehlt die Klammer vor dem ersten Anführungszeichen:

exp_r = float(input"Exponent:"))

3) Auch wenn du deine mathematischen Formeln als Vorlage hast, würde ich dir empfehlen, Bezeichner wie AU, dt, k1, t, u.ä. gegen aussagekräftigere Namen zu tauschen.

4) Für mehr (wissenschaftliche) Genauigkeit würde ich nicht PyGame für die Visualisierung nutzen, sondern eher Matplotlib oder vielleicht Manim.


Leonie4863 
Beitragsersteller
 15.03.2025, 19:11

Danke für deine Hilfe! Ich habe nun die deriv-Funktion bei meiner Fragestellung hinzugefügt und werde auch nach deinem Tipp ein Matplotlib-Diagramm erstellen. 😊 Mich wundert es immer noch, wie schnell sich die Laufbahn ändert. Ab einem Exponent-Wert r von 2.03 wird gar keine Ellipse mehr gezeichnet: Sie wird nur angefangen und anschliessend wird die Erde aus dem Sonnensystem geschleudert. Bei 2.5 wird sogar nur noch eine gerade, senkrechte Linie nach unten gezeichnet. 😆

regex9  16.03.2025, 21:09
@Leonie4863

Die Konversion der Werte in decimal kommt zu spät, wenn du sie in der deriv-Funktion behältst. Die Werte für x, y, usw. werden ja viel früher, in runge_kutta4 berechnet, wo Python noch seinen float-Typ benutzen wird. Bei den Berechnungen müsstest du darauf achten, dass alle Fließkommazahlterme explizit in decimal angelegt/konvertiert werden, denn sonst kann es zu einem Typfehler kommen (decimal und float können nicht direkt miteinander verrechnet werden).

Meiner Meinung reicht es aber aus, für diese Simulation nur mit float zu arbeiten. Wenn es bei deiner Rechnung zu (physikalischen) Ungenauigkeiten kommt, dann sind da andere Quellen bedeutender (z.B. das Annäherungsverfahren via Runge-Kutta oder die Präzision der Konstanten), wobei ich auch da nicht andeuten möchte, dass du dir eine andere Lösung suchen solltest - dein Lösungsweg ist vollkommen legitim.

Du könntest zur Prüfung noch die jeweilige Geschwindigkeit der Erde berechnen und mit ihrer Fluchtgeschwindigkeit vergleichen.

escape_velocity ​= ((2 * G * M_SUN) / r).sqrt()

Sobald diese Geschwindigkeit erreicht wird, fällt die Erde aus ihrer Bahn.

Leonie4863 
Beitragsersteller
 19.03.2025, 08:15
@regex9

Danke für deinen Tipp! 😃 Ich habe jetzt zu Beginn der Funktion Runge Kutta folgende Zeile hinzugefügt: state = [Decimal(s) for s in state] . Bei einer Geschwindigkeit von 43 km/s bei einem Exponenten r von 2, fliegt die Erde tatsächlich aus dem Sonnensystem heraus. 👍

Mich überrascht das nicht: Beim Exponenten 2.02 hast Du nur noch 60% Anziehungskraft, bei 2.03 nur noch 46%. Kein Wunder, dass sich die Erde da aus dem Staub macht.

Gib ihr wenigstens eine Chance auf eine stabile Umlaufbahn, indem Du sie langsamer machst, näher an die Sonne rückst oder G erhöhst.


Leonie4863 
Beitragsersteller
 19.03.2025, 08:19

Vielen Dank für deinen Kommentar! 👍 Es ist erstaunlich wie schnell die Anziehungskraft abnimmt, das hätte ich zu Beginn des Programmierens nicht gedacht. 😅

ralphdieter  19.03.2025, 09:14
@Leonie4863

So schnell wird das nicht weniger. Zu Hause dürftest Du keinen Unterschied merken. Aber auf 150 Milliarden Metern läppert sich doch etwas zusammen.