Skip to content

Commit 12f6927

Browse files
committed
add missing examples (incomplete)
1 parent de86dc4 commit 12f6927

28 files changed

Lines changed: 5230 additions & 0 deletions
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
import numpy
2+
import math
3+
from amuse.lab import *
4+
from amuse import datamodel
5+
from amuse.units import quantities
6+
from amuse.ext.rotating_bridge import Rotating_Bridge
7+
from amuse_galaxia.interface import BarAndSpirals3D
8+
from amuse.ext.composition_methods import *
9+
from matplotlib import pyplot as plt
10+
11+
12+
class drift_without_gravity(object):
13+
"""
14+
This class is to make the ev of non interactig particles by using bridge.
15+
"""
16+
17+
def __init__(self, particles, time=0 | units.Myr):
18+
self.particles = particles
19+
self.model_time = time
20+
21+
def evolve_model(self, t_end):
22+
dt = t_end - self.model_time
23+
self.particles.position += self.particles.velocity * dt
24+
self.model_time = t_end
25+
26+
@property
27+
def potential_energy(self):
28+
return quantities.zero
29+
30+
@property
31+
def kinetic_energy(self):
32+
return (
33+
0.5 * self.particles.mass * self.particles.velocity.lengths() ** 2
34+
).sum()
35+
36+
37+
I = 0
38+
39+
40+
class IntegrateOrbit(object):
41+
"""
42+
This class makes the integration of the Sun in the Milky Way
43+
by using BarAndSpirals3D.
44+
galaxy(): Function that sets the desired Galactic model. Any question on the parameters, contact me
45+
creation_particles_noinertial(): creates a parti le set in a rotating frame
46+
noinertial_to_inertial(): converts data from rotating to inertial frame
47+
get_pos_vel_and_orbit(): Makes the evolution of the particle set
48+
"""
49+
50+
def __init__(
51+
self,
52+
t_end=10 | units.Myr,
53+
dt_bridge=0.5 | units.Myr,
54+
method=SPLIT_6TH_SS_M13,
55+
phase_bar=0,
56+
phase_spiral=0,
57+
omega_spiral=-20 | (units.kms / units.kpc),
58+
amplitude=650 | (units.kms**2 / units.kpc),
59+
m=4,
60+
omega_bar=-50 | (units.kms / units.kpc),
61+
mass_bar=1.1e10 | units.MSun,
62+
):
63+
# Simulation parameters
64+
self.t_end = t_end
65+
self.dt_bridge = dt_bridge
66+
self.method = method
67+
self.time = 0 | units.Myr
68+
# galaxy parameters
69+
self.omega = 0 | (units.kms / units.kpc)
70+
self.initial_phase = 0
71+
self.bar_phase = phase_bar
72+
self.spiral_phase = phase_spiral
73+
self.omega_spiral = omega_spiral
74+
self.amplitude = amplitude
75+
self.rsp = 3.12 | units.kpc
76+
self.m = m
77+
self.tan_pitch_angle = 0.227194425
78+
self.omega_bar = omega_bar
79+
self.mass_bar = mass_bar
80+
self.aaxis_bar = 3.12 | units.kpc
81+
self.axis_ratio_bar = 0.37
82+
return
83+
84+
def galaxy(self):
85+
global I
86+
galaxy = BarAndSpirals3D(
87+
redirection="file", redirect_stdout_file="GAL{0}.log".format(I)
88+
)
89+
I = I + 1
90+
galaxy.kinetic_energy = quantities.zero
91+
galaxy.potential_energy = quantities.zero
92+
galaxy.parameters.bar_contribution = True
93+
galaxy.parameters.bar_phase = self.bar_phase
94+
galaxy.parameters.omega_bar = self.omega_bar
95+
galaxy.parameters.mass_bar = self.mass_bar
96+
galaxy.parameters.aaxis_bar = self.aaxis_bar
97+
galaxy.parameters.axis_ratio_bar = self.axis_ratio_bar
98+
galaxy.parameters.spiral_contribution = False
99+
galaxy.parameters.spiral_phase = self.spiral_phase
100+
galaxy.parameters.omega_spiral = self.omega_spiral
101+
galaxy.parameters.amplitude = self.amplitude
102+
galaxy.parameters.rsp = self.rsp
103+
galaxy.parameters.m = self.m
104+
galaxy.parameters.tan_pitch_angle = self.tan_pitch_angle
105+
galaxy.commit_parameters()
106+
self.omega = galaxy.parameters.omega_system
107+
self.initial_phase = galaxy.parameters.initial_phase
108+
print("INITIAL_PHASE:", self.initial_phase)
109+
110+
galaxy.kinetic_energy = quantities.zero
111+
galaxy.potential_energy = quantities.zero
112+
return galaxy
113+
114+
def creation_particles_noinertial(self, particles):
115+
"""
116+
makes trans in a counterclockwise frame.
117+
If the Galaxy only has bar or only spiral arms, the frame corotates with
118+
the bar or with the spiral arms. If the Galaxy has bar and spiral arms, the frame corotates with the bar
119+
"""
120+
no_inertial_system = particles.copy()
121+
angle = self.initial_phase + self.omega * self.time
122+
C1 = particles.vx + self.omega * particles.y
123+
C2 = particles.vy - self.omega * particles.x
124+
no_inertial_system.x = particles.x * numpy.cos(angle) + particles.y * numpy.sin(
125+
angle
126+
)
127+
no_inertial_system.y = -particles.x * numpy.sin(
128+
angle
129+
) + particles.y * numpy.cos(angle)
130+
no_inertial_system.z = particles.z
131+
no_inertial_system.vx = C1 * numpy.cos(angle) + C2 * numpy.sin(angle)
132+
no_inertial_system.vy = C2 * numpy.cos(angle) - C1 * numpy.sin(angle)
133+
no_inertial_system.vz = particles.vz
134+
return no_inertial_system
135+
136+
def noinertial_to_inertial(self, part_noin, part_in):
137+
# makes trans in a counterclockwise frame
138+
angle = self.initial_phase + self.omega * self.time
139+
C1 = part_noin.vx - part_noin.y * self.omega
140+
C2 = part_noin.vy + part_noin.x * self.omega
141+
part_in.x = part_noin.x * numpy.cos(angle) - part_noin.y * numpy.sin(angle)
142+
part_in.y = part_noin.x * numpy.sin(angle) + part_noin.y * numpy.cos(angle)
143+
part_in.z = part_noin.z
144+
part_in.vx = C1 * numpy.cos(angle) - C2 * numpy.sin(angle)
145+
part_in.vy = C1 * numpy.sin(angle) + C2 * numpy.cos(angle)
146+
part_in.vz = part_noin.vz
147+
return
148+
149+
def testing_potential_and_force(self, galaxy, x, y, z):
150+
dx, dy, dz = 0.001 | units.kpc, 0.001 | units.kpc, 0.001 | units.kpc
151+
phi1x = galaxy.get_potential_at_point(0 | units.kpc, (x + dx), y, z)
152+
phi2x = galaxy.get_potential_at_point(0 | units.kpc, (x - dx), y, z)
153+
f1x = -(phi1x - phi2x) / (2 * dx)
154+
phi1y = galaxy.get_potential_at_point(0 | units.kpc, x, (y + dy), z)
155+
phi2y = galaxy.get_potential_at_point(0 | units.kpc, x, (y - dy), z)
156+
f1y = -(phi1y - phi2y) / (2 * dy)
157+
phi1z = galaxy.get_potential_at_point(0 | units.kpc, x, y, (z + dz))
158+
phi2z = galaxy.get_potential_at_point(0 | units.kpc, x, y, (z - dz))
159+
f1z = -(phi1z - phi2z) / (2 * dz)
160+
fx, fy, fz = galaxy.get_gravity_at_point(0 | units.kpc, x, y, z)
161+
print("analytic", "numerical")
162+
print(
163+
fx.value_in(100 * units.kms**2 / units.kpc),
164+
f1x.value_in(100 * units.kms**2 / units.kpc),
165+
)
166+
print(
167+
fy.value_in(100 * units.kms**2 / units.kpc),
168+
f1y.value_in(100 * units.kms**2 / units.kpc),
169+
)
170+
print(
171+
fz.value_in(100 * units.kms**2 / units.kpc),
172+
f1z.value_in(100 * units.kms**2 / units.kpc),
173+
)
174+
return
175+
176+
def get_pos_vel_and_orbit(self, particle_set):
177+
# particle_set.velocity= (-1)*particle_set.velocity
178+
179+
filename = "sunandM67.hdf5"
180+
write_set_to_file(
181+
particle_set.savepoint(self.time),
182+
filename,
183+
"hdf5",
184+
append_to_file=False,
185+
overwrite_file=True,
186+
)
187+
188+
MW = self.galaxy()
189+
print("OMEGA:", self.omega.as_quantity_in(1 / units.Gyr))
190+
particle_rot = self.creation_particles_noinertial(particle_set)
191+
gravless = drift_without_gravity(particle_rot)
192+
193+
system = Rotating_Bridge(
194+
self.omega, timestep=self.dt_bridge, verbose=False, method=self.method
195+
)
196+
system.add_system(gravless, (MW,), False)
197+
system.add_system(MW, (), False) # This is to update time inside the interface
198+
199+
Ei = (
200+
system.potential_energy
201+
+ system.kinetic_energy
202+
+ system.jacobi_potential_energy
203+
)
204+
energy = []
205+
206+
dmin = (particle_set[0].position - particle_set[1].position).length()
207+
tmin = 0 | units.Myr
208+
d = [] | units.kpc
209+
t = [] | units.Myr
210+
d.append(dmin)
211+
t.append(self.time)
212+
while self.time < self.t_end - self.dt_bridge / 2:
213+
self.time += self.dt_bridge
214+
system.evolve_model(self.time)
215+
self.noinertial_to_inertial(particle_rot, particle_set)
216+
217+
Ef = (
218+
system.potential_energy
219+
+ system.kinetic_energy
220+
+ system.jacobi_potential_energy
221+
)
222+
dje = (Ef - Ei) / Ei
223+
energy.append(dje)
224+
225+
d.append((particle_set[0].position - particle_set[1].position).length())
226+
t.append(self.time)
227+
if d[-1] < dmin:
228+
dmin = d[-1]
229+
tmin = self.time
230+
231+
x = particle_set.x
232+
y = particle_set.y
233+
write_set_to_file(
234+
particle_set.savepoint(self.time), filename, "hdf5", overwrite_file=True
235+
)
236+
237+
print("minimum", tmin.in_(units.Myr), dmin.in_(units.parsec))
238+
bar_angle = self.bar_phase + (self.omega_bar * self.time)
239+
spiral_angle = self.spiral_phase + (self.omega_spiral * self.time)
240+
241+
return (
242+
self.time,
243+
particle_set[0].x.value_in(units.kpc),
244+
particle_set[0].y.value_in(units.kpc),
245+
particle_set[0].z.value_in(units.kpc),
246+
particle_set[0].vx.value_in(units.kms),
247+
particle_set[0].vy.value_in(units.kms),
248+
particle_set[0].vz.value_in(units.kms),
249+
bar_angle,
250+
spiral_angle,
251+
t,
252+
d,
253+
)
254+
255+
256+
def Sun_and_M67_in_the_Galaxy():
257+
258+
bodies = Particles(2)
259+
Sun = bodies[0]
260+
v_LSR = (-10, 5.2, 7.2) | units.kms
261+
Sun.mass = 1 | units.MSun
262+
Sun.radius = 1 | units.RSun
263+
Sun.position = (8.4, 0.0, 0.017) | units.kpc
264+
Sun.velocity = (-11.4, 232, 7.41) | units.kms # SPZ2009
265+
266+
M67 = bodies[1]
267+
M67.mass = 50000 | units.MSun
268+
M67.radius = 3 | units.parsec
269+
M67.position = Sun.position + ((0.766, 0.0, 0.49) | units.kpc)
270+
M67.velocity = Sun.velocity + ((31.92, -21.66, -8.87) | units.kms)
271+
272+
bodies.velocity *= -1
273+
274+
simulation_time = 4600.0 | units.Myr
275+
dt_bridge = 5 | units.Myr
276+
OS = 20 | (units.kms / units.kpc)
277+
OB = 40 | (units.kms / units.kpc)
278+
A = 1300 | (units.kms**2 / units.kpc)
279+
M = 1.4e10 | units.MSun
280+
m = 2
281+
phi_bar, phi_sp = -0.34906, -0.34906
282+
inte = IntegrateOrbit(
283+
t_end=simulation_time,
284+
dt_bridge=dt_bridge,
285+
phase_bar=phi_bar,
286+
phase_spiral=phi_sp,
287+
omega_spiral=OS,
288+
omega_bar=OB,
289+
amplitude=A,
290+
m=m,
291+
mass_bar=M,
292+
)
293+
294+
MW = inte.galaxy()
295+
print(MW.parameters)
296+
print(MW.get_phi21())
297+
298+
print("Backwards integration")
299+
time, xf, yf, zf, vxf, vyf, vzf, bar_angle, spiral_angle, t1, d1 = (
300+
inte.get_pos_vel_and_orbit(bodies)
301+
)
302+
print("Birth position of the Sun:", xf, yf, zf, vxf, vyf, vzf)
303+
print("---")
304+
print("time after backward integration:", time)
305+
306+
plt.style.use("../lib/matplotlibrc")
307+
figure = plt.figure()# figsize=(16, 12))
308+
ax = plt.gca()
309+
ax.minorticks_on() # switch on the minor ticks
310+
ax.locator_params(nbins=3)
311+
312+
x_label = "t [Gyr]"
313+
y_label = "d [kpc]"
314+
plt.xlabel(x_label)
315+
plt.ylabel(y_label)
316+
plt.plot(-t1.value_in(units.Gyr), d1.value_in(units.kpc), lw=3)
317+
plt.ylim(0, 6)
318+
plt.xlim(-5, 0)
319+
plt.savefig("sun_and_M67")
320+
plt.show()
321+
322+
"""
323+
from matplotlib import pyplot
324+
from amuse.plot import scatter, plot
325+
plot(-1*t1, d1, c = "k")
326+
pyplot.semilogy()
327+
pyplot.show()
328+
"""
329+
330+
331+
if __name__ in ("__main__", "__plot__"):
332+
set_printing_strategy(
333+
"custom", # nbody_converter = converter,
334+
preferred_units=[units.MSun, units.kpc, units.Myr],
335+
precision=4,
336+
prefix="",
337+
separator=" [",
338+
suffix="]",
339+
)
340+
Sun_and_M67_in_the_Galaxy()

0 commit comments

Comments
 (0)