/
crtbpRKN1210.py
200 lines (149 loc) · 6.64 KB
/
crtbpRKN1210.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import inspect
import matlab.engine
from scipy import integrate
from Derivatives import derivatives
from Rotation import rotate
import time
from Animation import OutputFcn2
from LagrangePoints import lpoints
from scipy import *
from rkn1210 import rkn1210
from waitbar import bar
import numpy as np
__author__ = 'Ian'
# Numerically integrate a test particle in the circularly restricted
# three-body problem using the Runge-Kutta-Nystrom 12/10 integrator.
#
# Massive bodies M1 and M2 follow circular orbits around their center of
# mass point, set to be the origin. The third test particle does affect the
# motion of the two massive bodies.
#
# We assume G = 1 and R = 1 (distance between the primary bodies)
#
# This function is designed to be called by another function which sets
# the initial conditions.
#
# This function calls the following functions:
# - rkn1210.m (written by Rody P.S. Oldenhuis, MATLAB File Exchange)
# - LagrangePoints.m
#
# Passed parameters:
# masses - 1x2 matrix containing m1 and m2
# pos0 - 1x2N matrix cointaining pairs of (x,y) coordinates for
# the initial conditions of the test particles. If one test
# particle is used, pos0 will be a 1x2 matrix containing (x0, y0)
# For 2 test particles, posq will contain (x10, y10, x20, y20)...
# vel0 - 1x2N matrix containing pairs of (vx, vy) values for each of
# the initial velocities of the test particles.
# times - 1x2 array containing begin and end times [tBegin, tEnd]
# flag - 1x3 array containing plotting options (flags are optional):
# flag(1) = true to plot and return values in rotating frame
# flag(2) = true to animate the orbit as it integrates. Cool to
# watch, but it slows the calculate way down.
# flag(3) = true to leave a trail behind the test particles when
# animation is turned on.
#
# Returned arrays:
# t - Tx1 array returning times used in integration, where T =
# number of time steps
# pos - Tx2N array returning (x,y) coordinate pairs for each test
# particle
# vel - Tx2N array returning (vx,vy) velocity component pairs for each
# test particle
#
#
# MATLAB-Monkey.com 10/6/2013
# global variables used in other functions listed below
global tEnd, wait, mu1, mu2, R10, R20, omega0, plotLimits, LP, leaveTrail, rotatingFrame, animateDelay
def integrator(masses, pos0, vel0, times, flag):
########## OutputFcn1: Status Bar ####################################
#
# the output function
def OutputFcn1(t, y, dy, flag): # ok
# don't stop
stop = False
# only after sucessfull steps
if not flag:
stop = True
else:
bar(t / tEnd, wait)
return stop
global tEnd, wait, mu1, mu2, R10, R20, omega0, plotLimits, LP, leaveTrail, rotatingFrame
# return returnVals
(nargin, varargs, keywords, defaults) = inspect.getargspec(integrator)
if len(nargin) < 4:
print('crtbpRKN1210 requires at least 4 parameters')
exit()
########## ##########
########## Initialization and Parameters ##########
########## ##########
#################### Flags Controlling Output ###########################
animate = False
rotatingFrame = False
if len(nargin) >= 5:
rotatingFrame = flag[0] # if true, transform to rotating frame
# if false, display inertial frame
animate = flag[1] # if true, animate motion
# if false, just display final trajectory
leaveTrail = flag[2] # if true and animation is on, past positions will
# not be erased. If false and animation is on,
# no 'trail' of past positions will be left
progressBar = False # if true, show progress bar
animateDelay = 0.0 # delay (in seconds) between frames of animation.
# smaller the value, faster the animation will play
leaveTrail = flag[2] # if true and animation is on, past positions will
# not be erased. If false and animation is on,
# no 'trail' of past positions will be left
trailLength = 700 # if leaveTrail is true, this sets the length of
# trail
######################### System Parameters ############################
NP = len(pos0) / 2 # number of test particles. Assumes 2D
M1 = masses[0] # mass 1
M2 = masses[1] # mass 2
M = M1 + M2 # total mass
G = 1 # Gravitational Constant
R = 1 # distance between M1 and M2 set to 1
################ Orbital properties of two massive bodies ##############
mu = G * M
mu1 = G * M1
mu2 = G * M2
R10 = ([-M2 / M], [0]) # initial position of M1
R20 = ([M1 / M], [0]) # initial position of M2
P = 2 * math.pi * math.sqrt(R ** 3 / mu) # period from Kepler's 3rd law
omega0 = 2 * math.pi / P # angular velocity of massive bodies
plotLimits = 1.5 # limit for plotting
tEnd = times[len(times) - 1]
LP = lpoints(M2 / M) # calculate Lagrange points
########################### Trail Properties ###########################
trail = np.ones((trailLength, 2 * NP))
for j in range(0, len(pos0)):
trail[:, j] = pos0[j] * np.ones((trailLength))
########## ##########
########## Integrate ##########
########## ##########
# Use Runge-Kutta 45 integrator to solve the ODE
# initialize wait variable
eng = matlab.engine.start_matlab()
options = eng.odeset('RelTol', 1E-12)
wait = True
if animate:
options = eng.odeset('RelTol', 1e-12, 'AbsTol', 1e-12,'outputfcn','@OutputFcn2')
else: # initialize waitbar
if progressBar:
while (wait):
w = bar(0, 'integrating...')
wait = OutputFcn1(0, 0, 0, w)
options = eng.odeset('RelTol', 1e-12, 'AbsTol', 1e-12,'outputfcn','@OutputFcn1')
else:
options = eng.odeset('RelTol', 1e-12, 'AbsTol', 1e-12)
# Use Runge-Kutta-Nystrom integrator to solve the ODE
tic = time.time()
# [t,pos,vel] = rkn1210(@derivatives, times, pos0, vel0, options)
[t, pos, vel, te, ye] = rkn1210(derivatives, times, pos0, vel0, options)
toc = time.time() - tic
DT = toc
if rotatingFrame:
for j in range(0, len(t) - 1):
pos[j, :] = rotate(pos[j, :].transpose(), t[j], -1)
# returnVals = [t, pos, vel, YE]
return [t, pos, vel]