Warum erfahren Objekte in einer Gravitationssimulation plötzlich große Beschleunigungen?

Ich versuche, ein einfaches Programm zu erstellen, das die Schwerkraft simuliert. Die Idee ist, dass ich eine zentrale Sonne und mehrere Planeten habe, die ich mit einer Wischgeste auf dem Bildschirm erstellen kann, und ich benutze das anfängliche Wischen, um den Planeten eine Anfangsgeschwindigkeit zu geben.

Nach einiger Zeit beginnt sich der Planet nach dem Newtonschen Gesetz um die Sonne zu bewegen.

Mein derzeitiger Ansatz ist: Ich berechne zu jedem Zeitpunkt den Wert der Gravitationskraft, die die Sonne auf den Planeten ausübt ( M P ist die Masse des Planeten und M S ist die Masse der Sonne):

F = G M P M S R 2

Dann finde ich den Beschleunigungswert für den Planeten mit

A = F M P

Dann finde ich den Winkel, θ , der Linie, die den Mittelpunkt des Planeten mit dem Mittelpunkt der Sonne verbindet.

Als nächstes erstelle ich einen Beschleunigungsvektor entlang dieser Linie, indem ich seine x- und ay-Komponente erzeuge:

A X = A cos θ A j = A Sünde θ

Bei der nächsten Iteration verwende ich diesen Beschleunigungsvektor und die seit der vorherigen Iteration verstrichene Zeit, um die Geschwindigkeit des Planeten und dann seine Position zu berechnen. Dann wiederholt sich das Ganze.

Das Hauptproblem bei diesem Ansatz besteht darin, dass der Planet, sobald er eine Entfernung von der Sonne nahe Null erreicht, eine enorme Beschleunigung erfährt und bei der nächsten Iteration einfach zu weit von der Sonne entfernt ist und sich nur noch auf einer geraden Linie bewegt. direkt aus dem Bildschirm, was ich natürlich nicht von der Schwerkraft erwarte. Beachten Sie, dass ich immer noch keine Kollisionserkennung habe, also würde ich erwarten, dass der Planet irgendwie still im Zentrum der Sonne bleibt.

Meine Intuition schreit, dass ich eine Art Integration für die Beschleunigung verwenden sollte, damit jede Beschleunigung, die ich zwischen einer Iteration und der nächsten verpasse, berücksichtigt würde und mein Planet der Schwerkraft nicht mehr entkommen würde, also habe ich meine Mathematik- und Physikbücher zurückgeholt und es versucht um dies selbst herauszufinden, aber kein Glück.

Wenn ich das richtig verstanden habe, besteht das Problem darin, dass meine Beschleunigung eine Funktion der Entfernung ist, sodass ich sie nicht integrieren kann, um die Position des Planeten zu erhalten, da dies eine Beschleunigung als Funktion der Zeit erfordern würde. Habe ich recht? Was ist die richtige Lösung dafür?

Meine Antwort auf eine andere Frage könnte nützlich sein.
Außerdem hostet NBabel ein Set N -Body-Codes, die in mehreren populären Sprachen geschrieben sind (Fortran, C, C++, Python usw.); Sie könnten daran interessiert sein, sich diese Codes anzusehen.
Ich habe einige Off-Topic-Kommentare gelöscht. Eine Erinnerung an alle, dass Kommentare dazu dienen, um Klärung zu bitten und Verbesserungen des Beitrags vorzuschlagen, und vorübergehend auf verwandte Ressourcen hinzuweisen. Definitiv nicht für die Beantwortung der Frage!
so etwas wie dieses Papier wird Ihr Problem lösen.
Ich habe dieses Phänomen kürzlich auch bei der Gravitationssimulation beobachtet. Die grundlegendste Optimierung besteht vielleicht darin, die Gravitationswirkung zu berechnen, da sie der Anwendungszeit einen halben Zeitschritt voraus wäre. Das bedeutet, dass Quantisierungsfehler Objekte mit gleicher Wahrscheinlichkeit verlangsamen wie beschleunigen. Dies kann mit der "Verlet-Integration" zusammenhängen.
Ich empfehle, vor Verwendung komplexerer Lösungen den Abstand (r) zwischen Sonne und Planet nicht auf Null gehen zu lassen. Der kleinste Abstand sollte der Radius der Sonne (R) + ein "angemessener" Abstand (d) sein, der die Kollision des Planeten mit der Sonne vermeidet. Wenn Sie die Kollision zulassen möchten, testen Sie die Entfernungsberechnung und wenn 0 oder negativ ist, "crashen" Sie den Planeten mit einer Explosion, die proportional zur Größe des Planeten ist.

Antworten (5)

Wenn Sie wirklich einen allgemeinen Gravitationssimulator wollen (dh einen, der mehr als zwei Körper handhaben kann), dann gibt es Methoden zum Reduzieren des Fehlers in der Simulation, aber es gibt keine Methoden zum Beseitigen des Fehlers. Im Folgenden sind einige Ansätze aufgeführt – keiner dieser Ansätze ist perfekt, da ein Gleichgewicht zwischen physikalischer Genauigkeit, Programmier- und Rechengeschwindigkeit und der Reduzierung des Escape-Verhaltens besteht.

  1. Adaptive Zeitschritte - Wenn Ihr Partikel große Beschleunigungsänderungen erfährt (dh wenn es sich schnell in der Nähe eines massiven Körpers bewegt), können Sie den Zeitschritt verringern D T Sie "überspringen" also weniger Zeit. Dies erhöht die physikalische Genauigkeit der Simulation, verlangsamt aber auch die Simulation (und verlangsamt sie ungleichmäßig), sodass dies kein guter Ansatz ist, wenn Sie möchten, dass sie in Echtzeit gut aussieht.

  2. Mache in Hard Spheres aus deinen Massen harte Kugeln, die aneinander abprallen. Dadurch wird die Fehleranhäufung reduziert, da die Massen nicht so nahe aneinander kommen. Dies kann die physikalische Genauigkeit der Simulation erhöhen, es sei denn, Sie haben Einwände gegen Planeten, die wie Gummibälle abprallen (was ein berechtigter Einwand ist, nehme ich an - Sie könnten sie auch zu unelastischen Kugeln machen, was für Planeten wahrscheinlich genauer ist).

  3. Geschwindigkeitsbegrenzung - Sie können einfach eine feste Geschwindigkeitsbegrenzung programmieren, um das Fluchtverhalten einzuschränken. Immer wenn die Geschwindigkeit die Geschwindigkeitsbegrenzung überschreitet, ändern Sie die Geschwindigkeitsgröße zurück auf die Geschwindigkeitsbegrenzung. Dies ist physikalisch nicht sehr genau und könnte zu einem seltsam aussehenden Verhalten führen, aber es ist einfach zu programmieren und wird das Entweichen Ihrer Massen reduzieren.

  4. Energieerhaltung - Berechnen Sie in jedem Zeitschritt die Gesamtmenge an Gravitations- und kinetischer Energie, die alle Massen haben. Wenn sich die Gesamtenergiemenge bei jedem Zeitschritt geändert hat, passen Sie die Geschwindigkeiten der Massen künstlich an, damit die Gesamtenergiemenge gleich bleibt. Dies ist auch nicht ganz genau, aber es hält sich an ein physikalisches Gesetz und reduziert das Fluchtverhalten.

Wenn Sie Hilfe benötigen, um die Implementierung einer dieser Methoden zu verstehen, kann ich dies ausführlicher erklären.

Ja, ich habe über Lösung 2 und 3 nachgedacht, aber der Punkt ist, dass ich diese Art von Tricks vermeiden möchte. Ich verwende diese Simulation, um meine Kenntnisse in Analysis zu verbessern, und ich bin mir ziemlich sicher, dass es einen Weg gibt, das Problem zu lösen es benutzen. Trotzdem danke. Und Lösung 4 ist wirklich interessant.
Unelastische Kugeln sind tatsächlich einfacher zu implementieren: Ersetzen Sie die beiden ursprünglichen Körper durch einen neuen, summieren Sie die Massen und summieren Sie die Impulse, dividieren Sie den Summenimpuls durch die neue Masse, um eine neue Geschwindigkeit zu erhalten.

Brionus hat den Schlüssel berührt - adaptive Zeitschritte. Wenn Sie anfangen, große Beschleunigungen zu bekommen, reduzieren Sie die Größe Ihrer Zeitinkremente. Erhöhen Sie auch die Größe, wenn Sie nicht stark beschleunigen.

Eine ziemlich übliche Methode, dies zu tun, besteht darin, Ihre Positionsänderung über einen Schritt zu berechnen. Dann den Schritt halbieren und ausgehend vom gleichen Startpunkt 2 aufeinanderfolgende Positionsschritte berechnen. Vergleichen Sie die beiden endgültigen Positionsänderungen, und wenn sie sich um einen vorbestimmten Faktor unterscheiden (sagen wir 10 ^ -6), ersetzen Sie den ursprünglichen Zeitschritt durch den kleineren Schritt und führen Sie die Berechnung erneut durch. Wenn die beiden Schritte genau übereinstimmen, versuchen Sie eine Berechnung mit einem Zeitschritt, der doppelt so hoch ist wie der ursprüngliche.

Dies erfordert eine Menge zusätzlicher Berechnungen, erzeugt jedoch eine Simulation, die weder zu genau noch zu genau genug ist. Bei Orbitalsimulationen werden die großen Zeitschritte, die während Flugbahnen mit geringer Schwerkraft verwendet werden, die zusätzliche Rechenzeit mehr als kompensieren.

BEARBEITEN - Als Antwort auf die Anfrage nach "dem Kalkülansatz":

Der von Ihnen verwendete Berechnungsansatz funktioniert für einen wirklich einfachen Simulator, ignoriert jedoch die Wechselwirkungen zwischen den Nicht-Sonnenkörpern und geht davon aus, dass sich die Zentralsonne nicht bewegt. Um dies zu handhaben, verwenden Sie einen allgemeineren Ansatz. Speichern Sie die Werte (x,y,z) (Vx,Vy,Vz) und (Mx,My,Mz) für Ihre Körper in Arrays, die auf die gleiche Weise indiziert sind. Dann werden die Gravitationsanziehungen zwischen zwei beliebigen Körpern einfach als (Fx, Fy, Fz) berechnet, wobei

F N = Δ N Δ X 2 + Δ j 2 + Δ z 2 G M A M B Δ X 2 + Δ j 2 + Δ z 2
Berechnen Sie jede Komponente separat und integrieren Sie separat, um neue Geschwindigkeiten und Positionen zu erhalten. Beachten Sie auch, dass Sie rechnen müssen N ( N 1 ) Werte für N Körper (einschließlich der Sonne), aber dieser Körper A zieht genau so stark an Körper B wie Körper B an Körper A, also müssen Sie nur die Hälfte der scheinbaren Summe numerisch berechnen, obwohl Sie es sein müssen Achten Sie darauf, das Vorzeichen umzukehren, um die andere Hälfte der Werte richtig zu machen. (Der Grund dafür N ( N 1 ) statt N 2 ist, dass Sie die Anziehungskraft eines Körpers nicht auf sich selbst berechnen.)

Für einen einfachen Simulator können Sie die Euler-Integration verwenden. Angesichts der Kraft auf einen Körper und seiner Masse, für einen sehr kleinen Δ T Sie können sagen

Δ v = F Δ T M
und wenn Sie sowohl die ursprüngliche Geschwindigkeit V als auch die Geschwindigkeitsänderung kennen, die Positionsänderung Δ P Ist
Δ P = ( v + Δ v ) Δ T

Für kurze Zeitskalen und sehr klein Δ T Dies wird funktionieren, aber Sie versuchen im Grunde, eine unregelmäßige Kurve mit geraden Segmenten anzunähern, und auf lange Sicht werden Sie große und wachsende Fehler sehen. Für längere Zeiträume sollten Sie sich also mit ausgefeilteren Algorithmen befassen. Wie zeldridge kommentierte, ist Runge-Kutta eine bekannte Alternative.

ZWEITE BEARBEITUNG - Führen Sie beim Aktualisieren Ihrer Werte auch jeden Satz von Berechnungen auf der Grundlage derselben ursprünglichen Bedingungen für alle Körper durch. Das heißt, wenn Sie Vneu und Pneu für Körper A berechnen, berechnen Sie die Ergebnisse für Körper B nicht mit dem aktualisierten Pneu für Körper A. Berechnen Sie ein völlig neues Array von V- und P-Werten und ersetzen Sie dann die alten Werte als Block .

Kommentare sind nicht für längere Diskussionen gedacht; diese Konversation wurde in den Chat verschoben .

Wenn Sie nicht an einer vollständigen n-Körper-Simulation interessiert sind und eine akzeptieren, bei der die Sonne viel massiver ist als alle Planeten, können Sie die Dinge stark vereinfachen. Wir haben eine analytische Lösung für das Zwei-Körper-Problem, also können Sie die Schwerkraft der Sonne auf diese Weise anwenden. Für jeden Planeten können Sie anhand seiner Position und Geschwindigkeit seinen Drehimpuls und seine Energie berechnen und dann die Umlaufbahn erhalten. Auf diese Weise können Sie die Position des Planeten am Ende des Zeitschritts berechnen und dabei die Anziehungskraft aller Planeten ignorieren. Bis zur nullten Ordnung sind Sie fertig, weil Sie die Planet-Planet-Wechselwirkungen ignorieren. Wenn Sie die Planet-Planet-Wechselwirkungen anwenden möchten, können Sie die Kraft auf den Planeten berechnen ich von allen anderen Planeten und wenden Sie die Beschleunigung für den gesamten Zeitschritt an. Da die Kraft viel kleiner als die Schwerkraft der Sonne ist, wird die Positionsänderung gering sein. Dies wird Ihre Fehler viel kleiner halten, ungefähr wie das Verhältnis der Kräfte auf den Planeten von den anderen Planeten zur Kraft der Sonne. Sie können dann die adaptiven Zeitschritte und die Energieeinsparung anwenden, die die anderen Responder vorschlagen.

Dieser Physics.SE-Beitrag behandelt parametrisierte Positionen von umlaufenden Körpern.

Ein anderer Programmieransatz in einer Schritt-für-Schritt-Animation besteht darin, jedem der Objekte Positions- und Impulsvariablen zuzuweisen. Programmiertechnisch haben wir Objektname, Masse, Ort x/y/z und Impuls px/py/pz. Berechnen Sie zwischen jedem Frame für jedes Objekt zuerst seinen Abstand zu jedem anderen Objekt und berechnen Sie die Gravitationskraft auf dieses Objekt basierend auf Newtons inversem Kraftgesetz; zweitens füge die Kraft zum Impuls hinzu; Fügen Sie schließlich den Impuls zur Position hinzu (px=px+forcex, x=x+px).

Mit dieser Methode können Sie sehr gute Animationen erhalten, wobei die Genauigkeit nur durch die Genauigkeit der Berechnungen, die Häufigkeit der Berechnungen und die Startposition / den Impuls jedes der Objekte begrenzt ist. Ein Beispiel für diese Methode finden Sie unter http://www.animatedphysics.com/planets/Moon_Orbit.htm

WRT Ihr Problem "Das Hauptproblem bei diesem Ansatz ist, dass der Planet, sobald er eine Entfernung von der Sonne nahe Null erreicht, eine enorme Beschleunigung erhält und bei der nächsten Iteration einfach zu weit von der Sonne entfernt ist und sich einfach weiterbewegt eine gerade Linie direkt aus dem Bildschirm". Dies ist ein sehr bedeutendes Problem. Wenn Sie zulassen, dass ein Objekt einem zweiten Objekt beliebig nahe kommt, wird die Kraft zwischen den Objekten beliebig groß (daher springt das Objekt plötzlich aus dem Sichtfeld, wie Sie es erlebt haben), egal wie klein die Zeitschritte sind, die Sie verwenden.

Ich denke, es wäre sehr aufschlussreich, wenn @Brionius seine Option 4 erweitern könnte.

Basierend auf dem physikalischen Modell, das Sie übernehmen (dass nur die „Sonne“ Gravitationskraft auf die „Planeten“ ausübt und dass wir die Gravitationseffekte der Planeten auf die Sonne oder aufeinander ignorieren), ist dies sicherlich ein anständiger Anfang Punkt (ganz zu schweigen von gut genug für Kepler in Bezug auf unser eigenes Sonnensystem), gibt es zwei Hauptpunkte zu erkennen:

1) Es GIBT legitime Umlaufbahnen (oder besser sagen wir sie Trajektorien), in denen der Planet nicht an die Sonne gebunden ist! Das heißt, der Planet bewegt sich nicht auf einer Bahn, die in der Nähe der Sonne bleibt und sie periodisch umkreist, sondern kann in vollständiger Übereinstimmung mit Newtons Gesetzen auf einen Kurs gebracht werden, der ihn aus dem Sonnensystem herausführt und niemals zurückkehrt ( und dies kann sogar passieren, nachdem der Planet einen ersten nahen Vorbeiflug an der Sonne gemacht hat, was zu der Annahme führen könnte, dass er in eine Umlaufbahn gehen würde). Angesichts der willkürlichen Anfangsgeschwindigkeiten der Planeten sollten wir auch nicht erwarten, dass diese Bahnen selten oder ungewöhnlich sind, obwohl sie vielleicht nicht die sind, an denen Sie interessiert sind. Die Lösung von Newtons Bewegungsgesetzen zusammen mit seinem Gravitationsgesetz sagt uns, dass die Bahn des Planeten wird einer von drei Typen sein: elliptisch, parabolisch oder hyperbolisch. Nur die erste dieser elliptischen Trajektorien ist geschlossen oder begrenzt. Nun ist es durchaus möglich, ja sogar wahrscheinlich, dass die von Ihnen beobachteten "außer Kontrolle geratenen" Trajektorien wirklich auf die numerischen Artefakte eines nicht ausreichend genauen Simulationsalgorithmus zurückzuführen sind, aber es wäre wahrscheinlich Ihre Pflicht, dies als ersten Schritt durch Überprüfung zu bestätigen dass die Anfangsgeschwindigkeiten, die Sie den Planeten zuweisen, klein genug sind, um den Planeten nicht auf eine parabolische oder hyperbolische Flugbahn zu bringen. Wenn Sie solche Trajektorien vollständig ausschließen möchten, wie es scheint, wäre es klug, Ihren Code so zu schreiben, dass der Benutzer daran gehindert wird, Anfangsgeschwindigkeiten zu wählen, die zu ihnen führen würden. Der Test ist einfach; verlange das einfach dass die von Ihnen beobachteten "außer Kontrolle geratenen" Bahnen wirklich auf die numerischen Artefakte eines nicht ausreichend genauen Simulationsalgorithmus zurückzuführen sind, aber es wäre wahrscheinlich an Ihnen, dies als ersten Schritt zu bestätigen, indem Sie überprüfen, ob Sie die Anfangsgeschwindigkeiten den Planeten zuweisen sind klein genug, dass sie den Planeten nicht auf eine parabolische oder hyperbolische Flugbahn bringen. Wenn Sie solche Trajektorien vollständig ausschließen möchten, wie es scheint, wäre es klug, Ihren Code so zu schreiben, dass der Benutzer daran gehindert wird, Anfangsgeschwindigkeiten zu wählen, die zu ihnen führen würden. Der Test ist einfach; verlange das einfach dass die von Ihnen beobachteten "außer Kontrolle geratenen" Bahnen wirklich auf die numerischen Artefakte eines nicht ausreichend genauen Simulationsalgorithmus zurückzuführen sind, aber es wäre wahrscheinlich an Ihnen, dies als ersten Schritt zu bestätigen, indem Sie überprüfen, ob Sie die Anfangsgeschwindigkeiten den Planeten zuweisen sind klein genug, dass sie den Planeten nicht auf eine parabolische oder hyperbolische Flugbahn bringen. Wenn Sie solche Trajektorien vollständig ausschließen möchten, wie es scheint, wäre es klug, Ihren Code so zu schreiben, dass der Benutzer daran gehindert wird, Anfangsgeschwindigkeiten zu wählen, die zu ihnen führen würden. Der Test ist einfach; verlange das einfach aber es wäre wahrscheinlich Ihre Pflicht, dies als ersten Schritt zu bestätigen, indem Sie überprüfen, ob die Anfangsgeschwindigkeiten, die Sie den Planeten zuweisen, klein genug sind, dass sie den Planeten nicht auf eine parabolische oder hyperbolische Flugbahn bringen. Wenn Sie solche Trajektorien vollständig ausschließen möchten, wie es scheint, wäre es klug, Ihren Code so zu schreiben, dass der Benutzer daran gehindert wird, Anfangsgeschwindigkeiten zu wählen, die zu ihnen führen würden. Der Test ist einfach; verlange das einfach aber es obliegt Ihnen wahrscheinlich, dies als ersten Schritt zu bestätigen, indem Sie überprüfen, ob die Anfangsgeschwindigkeiten, die Sie den Planeten zuweisen, klein genug sind, dass sie den Planeten nicht auf eine parabolische oder hyperbolische Flugbahn bringen. Wenn Sie solche Trajektorien vollständig ausschließen möchten, wie es scheint, wäre es klug, Ihren Code so zu schreiben, dass der Benutzer daran gehindert wird, Anfangsgeschwindigkeiten zu wählen, die zu ihnen führen würden. Der Test ist einfach; verlange das einfach Der Test ist einfach; verlange das einfach Der Test ist einfach; verlange das einfach v 2 < G M / R , Wo v ist die anfängliche Gesamtgeschwindigkeit des Planeten und R ist der Sonne-Planet-Abstand in dem Moment, in dem diese Anfangsgeschwindigkeit gemessen wird. Vielleicht möchten Sie noch einen Schritt weiter gehen und fordern, dass die Exzentrizität aller elliptischen Bahnen klein genug ist, dass der Planet den Bildschirm nicht verlässt (wie es zum Beispiel für ein Halleysches Kometen-ähnliches Objekt sein könnte, das, obwohl es an unsere Sonne gebunden ist, verändert seinen Abstand zur Sonne während seiner 76-jährigen Umlaufzeit um den Faktor 70). Indem man das verlangt A 1 2 R v 2 G M , die sogenannte "große Halbachse" der Umlaufbahn, kleiner ist als der Abstand von der Sonne zum Rand des Bildschirms, können Sie sicher sein, dass alle Planeten, die den Bildschirm verlassen, niemals zurückkommen und beide parabolisch darstellen /hyperbolische Trajektorien oder, wenn diese ausgeschlossen wurden, numerische Artefakte.

2) Vielleicht noch wichtiger, weil es das Potenzial hat, die Einfachheit, Genauigkeit und Effizienz Ihres Codes erheblich zu verbessern, ist, dass die Newtonschen Gesetze unter Ihren physikalischen Annahmen vollständig lösbar sind , was bedeutet, dass es nicht erforderlich ist, die Physik zu simulieren ( !). Es wird das Zwei-Körper-Problem genannt (obwohl es mehrere Planeten gibt, gehen wir davon aus, dass sie nicht miteinander interagieren, sodass der Weg jedes Planeten vollständig durch seine Wechselwirkungen mit genau einem anderen Objekt, der Sonne, bestimmt wird), und es ist im Wesentlichen die Berechnung, die Kepler anstellte, um zu zeigen, dass sich die Planeten auf elliptischen Bahnen bewegen. Es ist etwas kompliziert, das aufzuschreiben X Und j Positionen als Funktion der Zeit bei einer beliebigen Anfangsposition und Geschwindigkeit für den Planeten, also werde ich es hier nicht tun, aber der Wikipedia-Artikel über "Kepler-Umlaufbahnen" und die darin enthaltenen Links liefern alle Gleichungen, die man massieren müsste, um zu kommen das gewünschte Ergebnis (beachten Sie, dass dort angenommen wird, dass wir die Perihel/Aphel-Richtung des Orbits so nehmen, dass sie mit einer der Koordinatenachsen ausgerichtet ist, und man eine Änderung der Basis durchführen müsste, um das allgemeinere Ergebnis zu erhalten). Ich bin eigentlich ein Angestellter bei Wolfram Alpha und ich bin überrascht, dass wir die parametrischen Ergebnisse für nicht haben X Und j als Funktion der Zeit für das auf unserer Website verfügbare Kepler-Problem. Aber ich werde daran arbeiten, dies in Zukunft zu korrigieren und meine Antwort hier zu aktualisieren, falls/wenn ich dies tue! Es genügt jedoch zu sagen, dass, wenn Sie sich nicht für interplanetare Wechselwirkungen interessieren, die Simulation der Newtonschen Gesetze definitiv nicht der richtige Weg ist, um dieses Problem anzugehen, und Dinge wie adaptive Zeitschritte, obwohl sie funktionieren würden, wären es massive Überforderung.