Lesson 8: Forces and integration
Build the three-body orbits in Python, and learn on the way:
- Newton’s gravity as vectors
- nested loops over pairs of bodies
- the leapfrog method of integration
- a 3-D array: step × body × coordinate
- checking a simulation by what must not change
Watch it first
Plays from YouTube after a click.
The script
Open in Colab: this lesson as a notebook"""Three bodies: the figure-eight orbit, from the starting values computed by Carles Simo
(in Chenciner and Montgomery, 2000). G = 1, three masses of 1.
Run: python three-body-orbits.py (needs: pip install numpy matplotlib)
"""
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")
x1 = np.array([0.97000436, -0.24308753])
V = np.array([-0.93240737, -0.86473146]) # the velocity of body 3
pos = np.array([x1, -x1, [0.0, 0.0]])
vel = np.array([-V / 2, -V / 2, V])
period, dt = 6.32591398, 0.0005
turn = 0 # degrees to turn the first velocity by (the film breaks the eight with 15)
a = np.radians(turn)
vel[0] = [vel[0, 0] * np.cos(a) - vel[0, 1] * np.sin(a), vel[0, 0] * np.sin(a) + vel[0, 1] * np.cos(a)]
def pull(p):
"""Each body's acceleration: the sum of the other two's gravity, G*m / r**2 towards each"""
acc = np.zeros_like(p)
for i in range(3):
for j in range(3):
if i != j:
d = p[j] - p[i]
acc[i] += d / np.linalg.norm(d) ** 3
return acc
track = []
acc = pull(pos)
for _ in range(int(3 * period / dt)): # three periods, leapfrog steps (they keep the energy well)
vel += acc * dt / 2
pos += vel * dt
acc = pull(pos)
vel += acc * dt / 2
track.append(pos.copy())
track = np.array(track)
colours = ["#5eead4", "#f0abfc", "#f5c76b"]
plt.figure(figsize=(7, 4))
for body in range(3): # all three run along the same track, a third of a period apart
plt.plot(track[:, body, 0], track[:, body, 1], color=colours[body], linewidth=1)
plt.scatter(track[-1, :, 0], track[-1, :, 1], c=colours, s=80, zorder=3)
plt.axis("equal")
plt.axis("off")
plt.show()
# Try: turn = 15 -> the three tracks no longer close; the eight falls apart
No Python on this computer? The notebook runs the same script, the exercises and the answers in your browser, on Google Colab.
Line by line
def pull(p):The acceleration of each body, from the gravity of the other two.
acc[i] += d / np.linalg.norm(d) ** 3Gravity G·m / r² along the direction d / r together make d / r³; here G and the masses are 1.
vel += acc * dt / 2Leapfrog: half a step of velocity, a whole step of position, then the other half step with the new forces.
pos += vel * dtThe positions move with the half-updated velocities.
track = np.array(track)All the steps as one array: track[step, body, x or y].
plt.scatter(track[-1, :, 0], track[-1, :, 1], c=colours, s=80, zorder=3)The three bodies where they ended, on one shared track, a third of a period apart.
Try it yourself
Where is the centre of mass at the end?
Hint
track[-1].mean(axis=0).
Answer
At (0, 0) to within about 10⁻¹³: the total momentum is zero, so it never moves.
Set turn = 15, as in the film. What happens, and where does the centre of mass go now?
Hint
Compare the start with the positions after one period.
Answer
The tracks no longer close: after one period the three bodies are, together, about 2 units away from where they began. Turning one velocity also gives the system some momentum, so the centre of mass drifts, to about (−0.81, 0.67) at the end.
Make dt ten times bigger, 0.005. Does the eight still close?
Hint
Measure how far the bodies are from the start after one period.
Answer
Yes, but less exactly: after one period the three are, together, about 0.006 away from the start, against about 0.0001 with dt = 0.0005.
Quiz
Flashcards
Read the front, say the back to yourself, then open the card.
Gravity on body i
Σ G·mⱼ·(rⱼ − rᵢ) / |rⱼ − rᵢ|³ over the other bodies j.
Leapfrog
Half a velocity step, a whole position step, another half velocity step.
Periodic orbit
A start that comes back exactly to itself after one period.
Centre of mass
The average position weighted by mass; it moves only if the total momentum is not zero.
Chaos
The tiniest change at the start grows until the motion is completely different.