Common boilerplate code The simplest implementation of N-body simulations where n\geq 3 is a naive propagation of orbiting bodies; naive implying that the only forces acting on the orbiting bodies is the gravitational force which they exert on each other. In
object-oriented programming languages, such as
C++, some
boilerplate code is useful for establishing the fundamental mathematical structures as well as data containers required for propagation; namely
state vectors, and thus
vectors, and some fundamental object containing this data, as well as the mass of an orbiting body. This method is applicable to other types of N-body simulations as well; a simulation of point masses with charges would use a similar method, however the force would be due to attraction or repulsion by interaction of electric fields. Regardless, acceleration of particle is a result of summed force vectors, divided by the mass of the particle: \vec{a} = \frac{1}{m} \sum\vec{F} An example of a programmatically stable and
scalable method for containing kinematic data for a particle is the use of fixed length arrays, which in optimised code allows for easy memory allocation and prediction of consumed resources; as seen in the following C++ code: struct Vector3 { double e[3] = { 0 }; Vector3() {} ~Vector3() {} inline Vector3(double e0, double e1, double e2) { this->e[0] = e0; this->e[1] = e1; this->e[2] = e2; } }; struct OrbitalEntity { double e[7] = { 0 }; OrbitalEntity() {} ~OrbitalEntity() {} inline OrbitalEntity(double e0, double e1, double e2, double e3, double e4, double e5, double e6) { this->e[0] = e0; this->e[1] = e1; this->e[2] = e2; this->e[3] = e3; this->e[4] = e4; this->e[5] = e5; this->e[6] = e6; } }; Note that contains enough room for a state vector, where: • e_{0} = x, the projection of the objects position vector in Cartesian space along \left[1\;0\;0\right] • e_{1} = y, the projection of the objects position vector in Cartesian space along \left[0\;1\;0\right] • e_{2} = z, the projection of the objects position vector in Cartesian space along \left[0\;0\;1\right] • e_{3} = \dot{x}, the projection of the objects velocity vector in Cartesian space along \left[1\;0\;0\right] • e_{4} = \dot{y}, the projection of the objects velocity vector in Cartesian space along \left[0\;1\;0\right] • e_{5} = \dot{z}, the projection of the objects velocity vector in Cartesian space along \left[0\;0\;1\right] Additionally, contains enough room for a mass value.
Initialisation of simulation parameters Commonly, N-body simulations will be systems based on some type of
equations of motion; of these, most will be dependent on some initial configuration to "seed" the simulation. In systems such as those dependent on some gravitational or electric potential, the force on a simulation entity is independent on its velocity. Hence, to seed the
forces of the simulation, merely initial positions are needed, but this will not allow propagation- initial velocities are required. Consider a planet orbiting a star- it has no motion, but is subject to gravitational attraction to its host star. As a time progresses, and time
steps are added, it will gather velocity according to its acceleration. For a given instant in time, t_{n}, the resultant acceleration of a body due to its neighbouring masses is independent of its velocity, however, for the time step t_{n+1}, the resulting change in position is significantly different due the propagation's inherent dependency on velocity. In basic propagation mechanisms, such as the symplectic euler method to be used below, the position of an object at t_{n+1} is only dependent on its velocity at t_{n}, as the shift in position is calculated via \vec{r}_{t_{n+1}}=\vec{r}_{t_{n}}+\vec{v}_{t_{n}} \cdot \Delta t Without acceleration, \vec{v}_{t_{n}} is static, however, from the perspective of an observer seeing only position, it will take two time steps to see a change in velocity. A solar-system-like simulation can be accomplished by taking average distances of planet equivalent point masses from a central star. To keep code simple, a non-rigorous approach based on
semi-major axes and mean velocities will be used.
Memory space for these bodies must be reserved before the bodies are configured; to allow for scalability, a
malloc command may be used: OrbitalEntity* orbital_entities = malloc(sizeof(OrbitalEntity) * (9 + N_ASTEROIDS)); orbital_entities[0] = { 0.0,0.0,0.0, 0.0,0.0,0.0, 1.989e30 }; // a star similar to the sun orbital_entities[1] = { 57.909e9,0.0,0.0, 0.0,47.36e3,0.0, 0.33011e24 }; // a planet similar to mercury orbital_entities[2] = { 108.209e9,0.0,0.0, 0.0,35.02e3,0.0, 4.8675e24 }; // a planet similar to venus orbital_entities[3] = { 149.596e9,0.0,0.0, 0.0,29.78e3,0.0, 5.9724e24 }; // a planet similar to earth orbital_entities[4] = { 227.923e9,0.0,0.0, 0.0,24.07e3,0.0, 0.64171e24 }; // a planet similar to mars orbital_entities[5] = { 778.570e9,0.0,0.0, 0.0,13e3,0.0, 1898.19e24 }; // a planet similar to jupiter orbital_entities[6] = { 1433.529e9,0.0,0.0, 0.0,9.68e3,0.0, 568.34e24 }; // a planet similar to saturn orbital_entities[7] = { 2872.463e9,0.0,0.0, 0.0,6.80e3,0.0, 86.813e24 }; // a planet similar to uranus orbital_entities[8] = { 4495.060e9,0.0,0.0, 0.0,5.43e3,0.0, 102.413e24 }; // a planet similar to neptune where is a variable which will remain at 0 temporarily, but allows for future inclusion of significant numbers of asteroids, at the users discretion. A critical step for the configuration of simulations is to establish the time ranges of the simulation, t_{0} to t_\text{end}, as well as the incremental time step dt which will progress the simulation forward: double t_0 = 0; double t = t_0; double dt = 86400; double t_end = 86400 * 365 * 10; // approximately a decade in seconds double BIG_G = 6.67e-11; // gravitational constant The positions and velocities established above are interpreted to be correct for t = t_{0}. The extent of a simulation would logically be for the period where t_{0}\leq t .
Propagation An entire simulation may consist of countless time steps. At the elementary level, each time step involves calculating, for each body: • the forces on the body; • acceleration (\vec{a}); • velocity (\vec{v}_{n} = \vec{v}_{n-1} + \vec{a}_{n} \cdot \Delta t); • and position (\vec{r}_{n+1} = \vec{r}_{n} + \vec{v}_{n} \cdot \Delta t). The above can be implemented quite simply with a
while loop which continues while t exists in the aforementioned range: while (t Focusing on the inner four
rocky planets in the simulation, the trajectories resulting from the above propagation is shown below: ==See also==