In [ ]:
from IPython.display import display
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from pyodesys.symbolic import SymbolicSys
%matplotlib inline
3 body system in 3 dimensional space => 9 spatial + 9 momentum degrees of freedom (i.e. when not exploiting translational / rotational symmetry of the system)
In [ ]:
def dydt(t, y, params=(), be=None):
x0, y0, z0, x1, y1, z1, x2, y2, z2, px0, py0, pz0, px1, py1, pz1, px2, py2, pz2 = y
m0, m1, m2 = params
coord = [[x0, y0, z0], [x1, y1, z1], [x2, y2, z2]]
mmntm = [[px0, py0, pz0], [px1, py1, pz1], [px2, py2, pz2]]
def r(a, b):
return be.sqrt(sum((c0 - c1)**2 for c0, c1 in zip(a, b)))
r01 = r(coord[0], coord[1])
r02 = r(coord[0], coord[2])
r12 = r(coord[1], coord[2])
f01 = m0*m1/r01
f02 = m0*m2/r02
f12 = m1*m2/r12
def e(a, b, denom):
return [(c1 - c0)/denom for c0, c1 in zip(a, b)]
e01 = e(coord[0], coord[1], r01)
e02 = e(coord[0], coord[2], r02)
e12 = e(coord[1], coord[2], r12)
f0 = [f01*c01 + f02*c02 for c01, c02 in zip(e01, e02)]
f1 = [-f01*c01 + f12*c12 for c01, c12 in zip(e01, e12)]
f2 = [-f02*c02 - f12*c12 for c02, c12 in zip(e02, e12)]
return [mmntm[i][j]/params[i] for i in range(3) for j in range(3)] + f0 + f1 + f2
In [ ]:
odesys = SymbolicSys.from_callback(dydt, 18, 3)
In [ ]:
y0 = [0, 0, 0, 0, 0, 1, 0, 1, 0] + [0]*9
res = odesys.integrate(15, y0, [2, 3, 4], integrator='cvode', method='adams', nsteps=15000)
print(res.info['time_cpu'], res.info['time_wall'])
In [ ]:
_ = res.plot(title_info=1)
In [ ]:
fig1 = plt.figure()
ax = fig1.gca(projection='3d')
ax.plot(*res.yout[:, 0:3].T, alpha=1.0, color='r')
ax.plot(*res.yout[:, 3:6].T, alpha=1.0, color='g')
ax.plot(*res.yout[:, 6:9].T, alpha=1.0, color='b')
In [ ]:
import numpy as np
import time
from pyodesys.native import native_sys
nativesys = native_sys['cvode'].from_other(odesys)
In [ ]:
nlvls = 300
params_varied = np.tile([2,3,4], (nlvls, 1))
params_varied[:, 0] = np.linspace(2, 5, nlvls)
t0 = time.time()
results = nativesys.integrate(15, y0, params_varied, integrator='native', method='adams', nsteps=15000)
print(sum([r.info['time_cpu'] for r in results]), time.time() - t0)
Native multi-threaded integration was approximately two orders of magnitude faster (wall clock) than single threaded python implementation.