My fallowing code (was supposed to) solve the equation of motion for two bodies but the result is the particles running way and I wasn't able to find where is the error
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
DIM = 2
N = 2
ITER = 1000
def acc(r, v, a):
for i in range(N - 1):
for j in range(i+1, N):
r2 = 0.0
rij = [0.0, 0.0]
for k in range(DIM):
rij[k] = r[i][k] - r[j][k]
r2 += rij[k] * rij[k]
fg = -1.0 /np.power(np.sqrt(r2), 3)
for k in range(DIM):
a[i][k] += fg * rij[k]
a[j][k] -= fg * rij[k]
return a
def verlet(r, v, a, dt):
for i in range(N):
for k in range(DIM):
v[i][k] += 0.5 * a[i][k] * dt
r[i][k] += v[i][k] * dt
a = acc(r, v, a)
for i in range(N):
for k in range(DIM):
v[i][k] += 0.5 * a[i][k] * dt
return [r,v]
r = np.zeros((N, DIM))
v = np.zeros((N ,DIM))
a = np.zeros((N, DIM))
r[0] = [0.5,0.0]
v[0] = [0.0,1.0]
r[1] = [-0.5,0.0]
v[1] = [0.0,-1.0]
dt = 0.01
plt.ion()
for i in range(ITER):
r,v = verlet(r, v, a, dt)
plt.scatter(r[0][0], r[0][1])
plt.scatter(r[1][0], r[1][1],color='yellow')
plt.pause(0.00005)
And I used the algorithm described in velocity Verlet
Acceleration doesn't accumulate over time, the way velocity and position do: it should be computed from scratch at each step of the process. So,
a
from the argument list of both acc
and verlet
a
by zeros at the beginning of acc
.a = acc(r, v)
to the beginning of verlet
. You will see the articles rotating around each other, as expected.
Unrelated to your issue but important for effective use of NumPy: get rid of loops over vector coordinates, leave it for NumPy to add and subtract vectors. I rewrote acc
method in this way:
def acc(r, v):
a = np.zeros((N, DIM))
for i in range(N - 1):
for j in range(i+1, N):
rij = r[i, :] - r[j, :]
r2 = np.dot(rij, rij)
fg = -1.0 /np.power(np.sqrt(r2), 3)
a[i, :] += fg * rij
a[j, :] -= fg * rij
return a