Lekcja 8: Siły i całkowanie
Zbuduj w Pythonie wzór „Orbity trzech ciał” i po drodze naucz się:
- grawitacja Newtona jako wektory
- pętle zagnieżdżone po parach ciał
- metoda żabiego skoku (leapfrog)
- tablica trójwymiarowa: krok × ciało × współrzędna
- sprawdzanie symulacji tym, co nie może się zmieniać
Najpierw obejrzyj
Film gra z YouTube po kliknięciu.
"""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
Nie masz Pythona na tym komputerze? Notatnik uruchamia ten sam skrypt, zadania i odpowiedzi w przeglądarce, w Google Colab. Notatnik jest po angielsku.
Linijka po linijce
def pull(p):Przyspieszenie każdego ciała od grawitacji dwóch pozostałych.
acc[i] += d / np.linalg.norm(d) ** 3Grawitacja G·m / r² wzdłuż kierunku d / r razem dają d / r³; tutaj G i masy są równe 1.
vel += acc * dt / 2Żabi skok: pół kroku prędkości, cały krok położenia, potem druga połowa kroku z nowymi siłami.
pos += vel * dtPołożenia przesuwają się z prędkościami zmienionymi w połowie.
track = np.array(track)Wszystkie kroki jako jedna tablica: track[krok, ciało, x albo y].
plt.scatter(track[-1, :, 0], track[-1, :, 1], c=colours, s=80, zorder=3)Trzy ciała tam, gdzie skończyły, na jednym wspólnym torze, w odstępach jednej trzeciej okresu.
Twoja kolej
Gdzie jest środek masy na końcu?
Podpowiedź
track[-1].mean(axis=0).
Odpowiedź
W (0, 0) z dokładnością do około 10⁻¹³: pęd całkowity jest zerowy, więc środek masy się nie porusza.
Ustaw turn = 15, jak w filmie. Co się dzieje i gdzie jest teraz środek masy?
Podpowiedź
Porównaj start z położeniami po jednym okresie.
Odpowiedź
Tory przestają się zamykać: po jednym okresie trzy ciała są razem około 2 jednostki od miejsca startu. Obrót jednej prędkości daje też układowi pęd, więc środek masy dryfuje, na końcu do około (−0.81, 0.67).
Zwiększ dt dziesięć razy, do 0.005. Czy ósemka nadal się zamyka?
Podpowiedź
Zmierz, jak daleko od startu są ciała po jednym okresie.
Odpowiedź
Tak, ale mniej dokładnie: po jednym okresie trzy ciała są razem około 0,006 od startu, wobec około 0,0001 przy dt = 0.0005.
Quiz
Fiszki
Przeczytaj przód, powiedz sobie, co jest z tyłu, potem otwórz kartę.
Grawitacja na ciało i
Σ G·mⱼ·(rⱼ − rᵢ) / |rⱼ − rᵢ|³ po pozostałych ciałach j.
Żabi skok
Pół kroku prędkości, cały krok położenia, znów pół kroku prędkości.
Orbita okresowa
Start, który po jednym okresie wraca dokładnie do siebie.
Środek masy
Średnie położenie ważone masą; porusza się tylko wtedy, gdy pęd całkowity nie jest zerowy.
Chaos
Najmniejsza zmiana na starcie rośnie, aż ruch staje się zupełnie inny.