Simulation des Sonnensystems mit Newtons Gesetz

Ich habe eine Simulation in C++ mit dem Newtonschen Gesetz gemacht und sie getestet, indem ich die Planetenpositionen mit der Position aus dem Sonnensystemrechner Don Cross (den ich von JavaScript in C++ konvertiert habe) http://cosinekitty.com/solar_system.html
vergleicht

Was ich mache, ist jeder Zeitschritt (normalerweise 1 Sekunde, aber Schritt 0,2 Sekunden ist dem 10-Sekunden-Schritt sehr ähnlich):

  1. Beschleunigung berechnen ( = Newton forzes × Deltazeit)
  2. Aktualisieren Sie Geschwindigkeit und Positionen
  3. Vergleichen Sie Positionen mit Ergebnissen von Don Cross-Solarrechneralgorithmen.
    Aber nach 10 Tagen Simulation erhalte ich diese Entfernungsabweichung (zum Rechner von Don Cross):

M e R C u R j   4498.7   k M

v e N u S   X   1939,8   k M

E A R T H   X   10614.6   k M

M Ö Ö N   X   7800.2   k M

M A R S   X   445.2   k M

C e R e S   X   129.5   k M

P A l l A S   X   432.4   k M

J u N Ö   X   151.4   k M

v e S T A   X   157.6   k M

ICH D A   X   73.6   k M

G A S P R A   455.3   k M

9 P / T 1   241.5   k M

19 P / B   402.7   k M

67 P / C G   533.2   k M

81 P / W 2   110.7   k M

J u P ich T e R   172.3   k M

S A T u R N   261.2   k M

U R A N u S   71.4   k M

N e P T u N e   31.3   k M

P l u T Ö   X     45.7   k M

Wie Sie sehen, haben einige Planeten kleine Abweichungen und einige größere, also ist meine Frage: Kann Newtons genau sein? oder Don Cross Sonnensystem-Rechner nicht? Oder gibt es in dieser Region schwarze Materie? Oder was sonst?

void CGravitator::CalcAceleration(double timeseconds){
unsigned int i,j,iend;
if (sunStatic)iend=m_np-1;
else iend=m_np;
for (i = 0; i < iend; i++) {
        m_planetas[i].aceleration.set(0,0,0);
        CVector3 totalGravitationalForce;                                       
        // Loop through all bodies in the universe to calculate their gravitational pull on the object (TODO: Ignore very far away objects for better performance)


     for (j = 0; j < m_np; j++) {
            if (i == j) continue; // No need to calculate the gravitational pull of a body on itself as it will always be 0.                                
            double distancia =CVector3::Distancia(m_planetas[i].pos,m_planetas[j].pos);
            double force = KGNEWTON * m_planetas[i].masa * m_planetas[j].masa / pow(distancia, 2);
            CVector3 forceDirection = CVector3::Normalize(m_planetas[j].pos - m_planetas[i].pos);
            
            totalGravitationalForce += forceDirection * force;
        }
            CVector3 incspeed = totalGravitationalForce / m_planetas[i].masa ;          
        m_planetas[i].aceleration += incspeed * timeseconds;
        
    
}
Berechnen Sie alle Kräfte zwischen den Körpern oder nur die Kraft zwischen jedem Körper und der Sonne?
Übrigens ist es ziemlich einfach, Ihren Code von der Euler-Integration zu einem symplektischen Integrator wie Verlet oder Leapfrog zu ändern, und Sie können einen viel größeren Zeitschritt verwenden.
"Kann Newtons genau sein? Oder Don Cross Sonnensystem-Rechner nicht?" Beim Schreiben von neuem Simulationscode ist es immer gut, sich mit etwas etablierterem zu vergleichen. Wenn sich die Ergebnisse jedoch unterscheiden, sollte die Standardannahme lauten, dass der Fehler bei Ihrem Code liegt.
Wenn Sie Code portieren, der dieselbe Methode verwendet, sollten Sie überprüfen, ob dieselben Eingaben (Planetenpositionen, Zeitschritte usw.) dieselbe Ausgabe liefern, wie jkej vorschlägt. Das ist eher eine Programmierübung. Das Erlernen der Probleme mit bestimmten numerischen Methoden ist eher mathematisch, und warum bestimmte Methoden für bestimmte Systeme besser sind, ist eher physikalisch.
Hallo, ich summiere alle Kräfte zwischen allen Körpern. Die Sonne beginnt bei (0,0,0) und kann sich bewegen oder nicht (Kontrollkästchen), aber diese Sonne, die sich bewegt oder nicht, ergab sehr ähnliche Ergebnisse es liegt kein Codefehler vor.
Und nach dem Beschleunigungscode summieren Sie Beschleunigung auf Geschwindigkeit und addieren Geschwindigkeit *Deltatime zur Position für jeden Planeten. Ich weiß nicht, ob das Elulers Methode ist
@LuisALberto Ja. Momentane Geschwindigkeit und Beschleunigung berechnen und diese dann zusammen mit verwenden Δ T Position und Geschwindigkeit in einem einzigen Schritt zu aktualisieren, ist am einfachsten und sinnvollsten das Vorwärts-Euler-Verfahren. Einige ausgefeiltere allgemeine Methoden verwenden die neuen Positionen und Geschwindigkeiten, um Korrekturen vorzunehmen, bevor sie zum nächsten Zeitschritt übergehen. Damit kommt man ins Runge-Kutta-Land.
Dies ist keine Codeüberprüfung , daher werde ich dies nicht zu einer Antwort machen, sondern zu ein paar Tipps für numerische Stabilität und Leistung. #1 Du multiplizierst zuerst und dividierst dann durch m_planetas[i].masa. Heben Sie diese auf. (Und ändern Sie "Kraft" in Ihren Variablennamen in "Beschleunigung".) #2 Sie ziehen zuerst (vermutlich) eine Quadratwurzel nach innen CVector3::Distanciaund quadrieren dann den Abstand. Stornieren Sie diese auch. Und Nr. 3 ja, vermeide die Euler-Integration. Und Nr. 4, bitte fügen Sie Ihren tatsächlichen Geschwindigkeits- und Positionsaktualisierungscode in Ihre Frage ein – es könnte Fehler oder numerische Ungenauigkeiten geben, die Ihre Ergebnisse beeinflussen.
@LuisALberto, verwenden Sie für Ihre Gleitkommaberechnungen doppelte Genauigkeit (oder höhere Genauigkeit)?
Numerische Integration, insbesondere von Planetenbewegungen, ist schwierig, wirklich schwierig. Einige Methoden funktionieren kaum, einige sind völlig instabil und einige erfordern eine sehr gute Feinabstimmung, um genaue Ergebnisse zu erhalten. Das Problem ist nicht Newton, sondern die Schwierigkeit der numerischen Integration.
Eine Möglichkeit, Ihr Programm zu überprüfen, besteht darin, den Gesamtimpuls aller Objekte in Ihrem System zu berechnen. Dies sollte sich nicht ändern, daher stellt jede Abweichung eine Art Fehler dar. Sie werden immer etwas haben, aber es sollte sehr klein sein.
Ja, die Euler-Integration ist der "offensichtliche" Algorithmus: Δ v = A Δ T , Δ X = v Δ T . Anstatt die Masse zu verwenden, ist es genauer, den Standard-Gravitationsparameter zu verwenden ; Horizons verwendet Werte, die sich geringfügig von denen auf Wikipedia unterscheiden.
Was verwenden Sie für Ihre anfänglichen Planetenpositionen und -geschwindigkeiten? Verwenden Sie dafür das Don Cross-Programm oder Horizons? Übrigens beträgt die mittlere Entfernung zwischen dem Zentrum der Sonne und dem Baryzentrum des Sonnensystems ~830.000 km, mit einem Maximum von etwa 1,5 Millionen km. Ich habe ein Diagramm (erstellt mit Horizons) in dieser Antwort .
Es gibt viele Dinge, die im geposteten Code falsch sind. Das bei weitem Größte ist, dass die Technik keine Geschwindigkeit verwendet. A Δ T (Beschleunigung mal Zeitschritt) ist die Geschwindigkeitsänderung. Es ist nicht die Geschwindigkeit des Planeten. Sie müssen Position und Geschwindigkeit integrieren, was bedeutet, dass Sie eine Anfangsposition und eine Anfangsgeschwindigkeit benötigen.
@DavidHammen: Das ist ein sehr guter Punkt. Wir wissen nicht, was der Code von OP mit macht m_planetas[i].aceleration, da sie den Rest nicht gepostet haben, aber der Wert, den sie in diesem Vektor speichern, ist keine Beschleunigung. ( incspeed ist eine Beschleunigung, zumindest unter der Annahme, dass es totalGravitationalForcesich tatsächlich um eine Kraft handelt, die dann aber mit einem Zeitintervall multipliziert wird.)
Wäre Computational Science ein besseres Zuhause für diese Frage?
Der Code, den ich jetzt verwende, stammt von Wikipedia Verlet Newton (aber die Ergebnisse unterscheiden sich geringfügig von oben). Die Geschwindigkeiten und Positionen stammen jetzt aus Horizon-Dateien. Ich habe auch die Präzisionsbibliothek GMP verwendet, ist aber dieselbe. Ich habe auch versucht, die Sonnenmasse (per Code) zu suchen, aber der Fehler verringert sich nur auf die Hälfte. Möglicherweise ist die Geschwindigkeit der Dateien von Horizon (Deltazeit 1 Minute) im Moment nicht perfekt (Newton-Deltazeit beträgt 0,1 Sekunden). Oder gibt es vielleicht eine uneinheitliche schwarze Materie?
Ich habe festgestellt, dass die Geschwindigkeit von Horizon für jede Zeit nicht die genaue Geschwindigkeit zu diesem Zeitpunkt ist, sondern die Durchschnittsgeschwindigkeit zum nächsten Zeitschritt, da das Hinzufügen von Position + Geschwindigkeit die nächste Position ergibt (und nicht exakt, da x und y perfekt sind, während z nicht ¿ ¿¿¿WTF???? Wenn also die Datei von Horizon verwendet werden muss, um die Anfangsgeschwindigkeit zu finden, um Newton für die Berechnung von Zeitschritten kleiner als Horizon in Ordnung zu bringen, wird ein kleiner Fehler am Anfang größer und größer.

Antworten (3)

Sie müssen eine bessere numerische Methode verwenden. Eulers Methode ist notorisch schlecht für die Orbitalmechanik, da sich die numerischen Fehler immer kumulieren. Insbesondere spart Eulers Methode keine Energie, sodass Sie Umlaufbahnen erhalten, die auf magische Weise Energie gewinnen und außer Kontrolle geraten.

Sie müssen so etwas wie die Verlet-Methode oder einen anderen symplektischen Integrator verwenden.

https://en.wikipedia.org/wiki/Verlet_integration

https://en.wikipedia.org/wiki/Symplectic_integrator

Danke, aber ich habe den Verlet-Code von Wikipedia verwendet und die gleichen Ergebnisse erhalten
Ich würde empfehlen, die JPL-Ephemeriden zu verwenden, um Ihre Berechnungen zu überprüfen: ssd.jpl.nasa.gov/horizons
Danke, ich habe versucht, Horizon-Dateien zu analysieren, habe aber größere Fehler bekommen!. Auch sein minimaler Zeitschritt beträgt 0,5 Sekunden. Da einige Planeten denselben Code verwenden (in Don Cross Source) und diejenigen mit größeren Fehlern kleinere Konstanten haben, werde ich es mit einer Präzisionsbibliothek wie gmp versuchen, aber es ist langweilig.
Ich bezweifle, dass gmp helfen wird. Sie haben nur die ungenauen Positionen mit hoher Präzision.
Sie müssen keinen symplektischen Integrator verwenden. JPL verwendet beispielsweise keine. Sie verwenden einen Integrator der Adams-Familie mit variabler Schrittgröße und variabler Reihenfolge. Vielleicht Cowell oder Gauss-Jackson? Dies sind in der Adams-Familie numerische Integratoren, und sowohl die Position als auch die Geschwindigkeit sind unterschiedlich.
Dake, du hast Recht, der Hauptfehler kommt vom Gehen in die falsche Richtung. Ich nehme wieder die Daten aus Horizon-Dateien und der Fehler hängt mit der Entfernung von der Sonne zusammen (Merkur am größten). Also ich denke, es ist die Masse, weil es nicht genau ist. Ich werde zuerst einige Massensonnen simulieren und die besten mit minimalem Fehler zu Horizon bringen. Gehen Sie dann von Planet zu Planet und tun Sie dasselbe.
@LuisALberto Aber Merkur ist nicht der größte Fehler, Erde und Mond sind es, was mich an Ihrer Frage wirklich verwirrt. Normalerweise hat Merkur immer den größten Fehler (aus mehreren Gründen), wenn also etwas anderes der größte ist (Erde-Mond), das die meisten der normalen Einzelursachen eliminiert (nicht-symplektische Integration, schlechtes G, schlechte Masse der Sonne usw .) Was das Erde-Mond-System auszeichnet, ist die starke Winkelneigung der Mondumlaufbahn und die hohe Masse des Mondes im Vergleich zu seiner primären (Erde). Mein Bauchgefühl ist, dass mit den Quelldaten oder den Z-Berechnungen etwas nicht stimmt.

Neben den in der anderen Antwort aufgezeigten Mängeln in der numerischen Methode müssen bei der Simulation der Merkurbahn die Gravitation des Jupiter sowie relativistische Effekte berücksichtigt werden. Dies erklärt nur einen winzigen Bruchteil der Abweichung, sollte aber berücksichtigt werden, wenn die numerische Methode besser wird.

Anscheinend beträgt die Perihelpräzession von Merkur aufgrund von Jupiters Anziehungskraft und relativistischen Effekten etwa 574 Bogensekunden in einem Jahrhundert oder 1,57E-2 Bogensekunden/Tag. Bei einem Umlaufumfang von etwa 3,6E8 km und einer Bogensekunde von 1,296E-6 Umdrehungen sind das etwa 4,3 km oder 43 km in 10 Tagen.

Während der Unterschied in der Position des Perihels nicht direkt in einen Ortsunterschied übersetzt wird, sollte er eine Vorstellung von dem Effekt vermitteln.

danke, das gibt mir eine Vorstellung von der Fehlergröße

Der Fehler kam von den Datenquellen. Jetzt habe ich zu NAIF cspice.lib gewechselt und eine allgemeine SPK-Datei nur für die Planeten heruntergeladen, und der Fehler ist ohne andere Schwerkraftkörper wie Asteoriden und Kometen wirklich gering. Es ist wirklich einfach, nur 2 Funktionen (furnsh_c und spkezr_c), ein Include und eine Lib zu verwenden.
Codiert mit vc6 ++ pure win 32. Ich habe makeall.bat von Spice entpackt ausgeführt (konnte es nicht in MFC zum Laufen bringen).
Außerdem kann der Zeitschritt ein beliebiger Sekundenbruchteil sein, sodass Spice und Newton synchronisiert sind. Also sagte mir Newton, dass es keine schwarze Materie gibt.
Hier sind die Ergebnisse ohne Asteroiden- und Kometengravitation für 10 Tage und ohne Korrekturen in cpsice spkezr_c

Entfernungsfehler in KM Newton (Verlet) von der Gewürzzeit
= 864000,250
MERCURY BARYCENTER = 5,511496277969209e+002
SATURN BARYCENTER = 8.535731413118873e+001
VENUS BARYCENTER = 2.701394194074592e+002
URANUS BARYCENTER = 8.651056255887706e+001
EARTH = 9.664941717935676e+001
NEPTUNE BARYCENTER = 8.654038466254323e+001
MOON = 1.208560265740111e+002
MARS BARYCENTER = 5.954829440293592e+001
PLUTO BARYCENTER = 8.661640570487361e+001
JUPITER BARYCENTER = 8.256645190275238e+001
TOTAL ERROR DISTANCE = 1.525933904320919e+003
Time Ini GREGORIAN = 2000 JAN 01 12:00:00.000
Time End GREGORIAN = 20.01.05 02:00