Help designing an n-body gravity simulator in Python

Click For Summary

Discussion Overview

The discussion revolves around designing a 2-dimensional gravity simulator in Python, focusing on numerical methods for simulating gravitational interactions among multiple bodies. Participants explore various integration techniques and address issues related to numerical stability and energy conservation in simulations.

Discussion Character

  • Exploratory
  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes using Euler's method for their simulator but notes its numerical instability over long timescales, leading to bodies being propelled away from their original positions.
  • Another suggests the Leapfrog method as an improvement over explicit Euler, claiming it does not add false energy to the system for small enough time steps.
  • A participant questions the assumption that bodies being propelled away in straight lines is incorrect, suggesting that close two-body interactions can lead to energy gain and ejection, which is observed in real clusters.
  • One participant shares their experience with Runge-Kutta integration, explaining how to implement it for a system of differential equations and mentioning the energy conservation issues they encountered.
  • Another participant acknowledges the "false energy" problem and suggests vectorizing the Leapfrog algorithm while considering higher-order versions if necessary.

Areas of Agreement / Disagreement

Participants express differing views on the behavior of bodies in the simulation, particularly regarding whether the observed ejections are incorrect. There is no consensus on the best numerical method to use, as multiple approaches are proposed and discussed.

Contextual Notes

Participants mention limitations related to numerical methods, such as energy conservation and stability over long timescales. There are unresolved mathematical steps in implementing the suggested algorithms.

Who May Find This Useful

Individuals interested in computational physics, numerical methods for simulations, or those working on similar gravity simulation projects may find this discussion beneficial.

Wer900
Messages
2
Reaction score
0
Hi everyone:

I wanted to design a 2-dimensional gravity simulator as part of a larger research project. I wrote it in Python using numpy to store positions, velocities, and accelerations, and matplotlib to display the trajectories; code is available upon request.

In order to solve the problem I've used Euler's method, which I know is numerically unstable over long timescales. In particular, I've been observing that over time many bodies are propelled away, in straight lines, from their original positions. By imposing an artificial minimum limit of 0.3 meters on effective gravitational radius (the masses and gravitational constant I'm using for testing purposes are very different from what I'll actually use) I'm able to reduce this mostly, although this reduces the accuracy of predictions at small radii.

I've read up on Runge-Kutta integration and other, more exotic methods of calculating orbits, but I have no idea of how to implement them in an orbital simulator. Would anyone here be able to help? Thanks in advance to everyone.
 
Technology news on Phys.org
If you want a fairly easy improvement over explicit Euler, you may want to try the Leapfrog method [1], which for small enough time steps do not add false energy to the system you are simulating.

[1] https://en.wikipedia.org/wiki/Leapfrog_integration
 
How do you know that the bodies that are "propelled away in straight lines" are incorrect? Close two body interactions should result in some bodies gaining energy and being ejected. This happens in real clusters and results in the clusters losing energy and becoming more tightly bound over time.
 
Wer900 said:
I've read up on Runge-Kutta integration and other, more exotic methods of calculating orbits, but I have no idea of how to implement them

The magic phrase to Google for is "runge kutta for system of differential equations". You'll find pages like this one:

http://www.physics.buffalo.edu/phy410-505-2009/topic3/lec-3-2.pdf

Start with Newton's Second Law for each pair of objects. Convert the second-order differential equations into pairs of first-order differential equations. Put the components of all positions and velocities into a single array or vector. The intermediate values k1, k2, etc. in the Runge-Kutta algorithm are now also vectors of the same dimension. You basically re-interpret the scalar R-K equations as vector equations. Write functions that carry out the steps of the calculation, taking vectors as input and returning vectors as output.

I did something like this about 25 years ago, for a solar-system simulator, but it was in Fortran, not Python, so I can't help with the actual code. Instead of standard 4th-order Runge-Kutta, I used a variation called Runge-Kutta-Fehlberg which varies the step-size dynamically.

I had the problem that orbits tended to drift outwards because the R-K algorithm tends to not conserve energy over long time spans. Loosely speaking, the errors introduced by the discrete steps tend to reinforce each other instead of cancelling. I understand there are algorithms in which the errors do tend to cancel and energy is at least approximately conserved, but I didn't go any further with my simulator.

[added] Ah, now I see that Filip also mentioned this "false energy" problem. Maybe a good start would be to vectorize the leapfrog algorithm that he mentioned, and look for higher-order versions if necessary.
 
Filip Larsen said:
If you want a fairly easy improvement over explicit Euler, you may want to try the Leapfrog method [1], which for small enough time steps do not add false energy to the system you are simulating.

[1] https://en.wikipedia.org/wiki/Leapfrog_integration

Thanks for the link. I think I tried this before, but maybe reversed the order in which I set velocity and acceleration (causing eventual drifting outward of the system).

phyzguy said:
How do you know that the bodies that are "propelled away in straight lines" are incorrect? Close two body interactions should result in some bodies gaining energy and being ejected. This happens in real clusters and results in the clusters losing energy and becoming more tightly bound over time.

Yes, I understand, but I sometimes saw bodies (representing the majority of the mass of the overall system) propelled outward even in 2 or 3 body systems. This doesn't make a whole lot of sense.

Also: Thanks jtbell for the info. I'm reading up on it right now, hopefully I can get something working soon.
 
Last edited:

Similar threads

  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 19 ·
Replies
19
Views
5K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 3 ·
Replies
3
Views
6K
Replies
3
Views
2K
  • · Replies 15 ·
Replies
15
Views
3K
  • · Replies 6 ·
Replies
6
Views
6K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K