Skip to content

Commit 7928883

Browse files
committed
small change
1 parent acfb670 commit 7928883

2 files changed

Lines changed: 142 additions & 83 deletions

File tree

Lines changed: 140 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,186 @@
1-
import sys
2-
import numpy
3-
from matplotlib import pyplot
4-
from amuse.lab import *
5-
from amuse.plot import plot
6-
from amuse.ext.sph_to_star import convert_SPH_to_stellar_model
7-
from amuse.examples.prepare_figure import *
8-
from amuse.examples.distinct_colours import get_distinct
1+
"""
2+
Example to merge two stars using SPH
3+
"""
4+
import argparse
5+
import numpy as np
6+
import matplotlib.pyplot as plt
7+
8+
from amuse.units import units, constants, nbody_system
9+
from amuse.datamodel import Particle, ParticlesSuperset
10+
from amuse.community.evtwin import Evtwin
11+
from amuse.community.gadget2 import Gadget2
12+
from amuse.ext.star_to_sph import convert_stellar_model_to_SPH
13+
914

1015
def return_evolved_star_hydro(mass, time, Nsph):
11-
star = Particle(mass=mass)
12-
stellar = EVtwin()
16+
star = Particle(mass=mass)
17+
stellar = Evtwin()
1318
star = stellar.particles.add_particle(star)
1419
stellar.evolve_model(time)
1520
Nsph = Nsph * int(mass.value_in(units.MSun))
1621
star_in_sph = convert_stellar_model_to_SPH(star, Nsph).gas_particles
1722
stellar.stop()
1823
return star_in_sph
1924

20-
def merge_two_stars_sph(Mprim, Msec, t_coll, Nsph, opening_angle):
21-
primary_in_sph = return_evolved_star_hydro(Mprim, t_coll,
22-
int(Nsph*Mprim/(1.|units.MSun)))
23-
# primary_in_sph = relax_sph_realization(primary_in_sph)
24-
secondary_in_sph = return_evolved_star_hydro(Msec, t_coll,
25-
int(Nsph*Msec/(1.|units.MSun)))
26-
# secondary_in_sph = relax_sph_realization(secondary_in_sph)
27-
R = primary_in_sph.x.max() + secondary_in_sph.x.max()
28-
M = primary_in_sph.mass.sum() + secondary_in_sph.mass.sum()
29-
secondary_in_sph.x += 0.8*R
30-
secondary_in_sph.y += 0.6*R
31-
secondary_in_sph.vx -= (constants.G*M/R).sqrt()
32-
33-
converter=nbody_system.nbody_to_si(Mprim, 1.0|units.AU)
25+
26+
def merge_two_stars_sph(
27+
mass_primary,
28+
mass_secondary,
29+
time_collision,
30+
Nsph,
31+
opening_angle,
32+
):
33+
primary_in_sph = return_evolved_star_hydro(
34+
mass_primary, time_collision, int(Nsph*mass_primary/(1. | units.MSun))
35+
)
36+
# primary_in_sph = relax_sph_realization(primary_in_sph)
37+
secondary_in_sph = return_evolved_star_hydro(
38+
mass_secondary,
39+
time_collision,
40+
int(Nsph*mass_secondary/(1. | units.MSun))
41+
)
42+
# secondary_in_sph = relax_sph_realization(secondary_in_sph)
43+
radius = primary_in_sph.x.max() + secondary_in_sph.x.max()
44+
total_mass = primary_in_sph.mass.sum() + secondary_in_sph.mass.sum()
45+
secondary_in_sph.x += 0.8*radius
46+
secondary_in_sph.y += 0.6*radius
47+
secondary_in_sph.vx -= (constants.G*total_mass/radius).sqrt()
48+
49+
converter = nbody_system.nbody_to_si(mass_primary, 1.0 | units.au)
3450
hydro = Gadget2(converter, number_of_workers=4)
35-
# hydro = Fi(converter)
3651
hydro.parameters.opening_angle = opening_angle
3752

38-
"""
39-
print "Opening criterion:", hydro.parameters.opening_angle
40-
print "Opening criterion:", hydro.get_gdgop()
41-
print "Opening criterion:", hydro.parameters.opening_angle
42-
print "Opening criterion:", hydro.get_gdgop()
43-
"""
44-
53+
# print("Opening criterion:", hydro.parameters.opening_angle)
54+
# print("Opening criterion:", hydro.get_gdgop())
55+
# print("Opening criterion:", hydro.parameters.opening_angle)
56+
# print("Opening criterion:", hydro.get_gdgop())
57+
4558
hydro.gas_particles.add_particles(primary_in_sph)
4659
hydro.gas_particles.add_particles(secondary_in_sph)
47-
hydro.evolve_model(2.0|units.hour)
60+
hydro.evolve_model(2.0 | units.hour)
4861
hydro.gas_particles.new_channel_to(primary_in_sph).copy()
4962
hydro.gas_particles.new_channel_to(secondary_in_sph).copy()
5063
hydro.stop()
5164
return primary_in_sph, secondary_in_sph
5265

53-
def relax_sph_realization(sph_star):
5466

67+
def relax_sph_realization(sph_star):
5568
dynamical_timescale = sph_star.dynamical_timescale()
56-
converter = nbody_system.nbody_to_si(dynamical_timescale, 1|units.RSun)
69+
converter = nbody_system.nbody_to_si(dynamical_timescale, 1 | units.RSun)
5770
hydro = Gadget2(converter, number_of_workers=2)
5871
hydro.gas_particles.add_particles(sph_star)
5972

60-
to_hydro = sph_star.new_channel_to(hydro.gas_particles)
73+
# to_hydro = sph_star.new_channel_to(hydro.gas_particles)
6174
to_framework = hydro.gas_particles.new_channel_to(sph_star)
6275

6376
ts_factor = 2.5
6477
t_end = ts_factor * sph_star.dynamical_timescale(mass_fraction=0.9)
6578
n_steps = ts_factor * 100
66-
velocity_damp_factor = 1.0 - (ts_factor*2*numpy.pi)/n_steps
79+
velocity_damp_factor = 1.0 - (ts_factor*2*np.pi)/n_steps
6780
dt = t_end/float(n_steps)
68-
time = 0|units.day
81+
time = 0 | units.day
6982
while time < t_end:
7083
time += dt
7184
hydro.evolve_model(time)
72-
hydro.gas_particles.velocity = velocity_damp_factor * hydro.gas_particles.velocity
85+
hydro.gas_particles.velocity = (
86+
velocity_damp_factor
87+
* hydro.gas_particles.velocity
88+
)
7389
to_framework.copy()
7490
hydro.stop()
7591
return sph_star
7692

77-
def merge_and_plot_distribution(Mprim, Msec, t_coll, Nsph, opening_angle, c, label):
78-
p, s = merge_two_stars_sph(Mprim, Msec, t_coll, Nsph, opening_angle)
93+
94+
def merge_and_plot_distribution(
95+
mass_primary,
96+
mass_secondary,
97+
time_collision,
98+
Nsph,
99+
opening_angle,
100+
c=None,
101+
label=None
102+
):
103+
p, s = merge_two_stars_sph(
104+
mass_primary,
105+
mass_secondary,
106+
time_collision,
107+
Nsph,
108+
opening_angle,
109+
)
79110
merger = ParticlesSuperset([p, s])
80111
com = merger.center_of_mass()
81-
merger.r = ((merger.x-com[0])**2 + (merger.y-com[1])**2 + (merger.z-com[2])**2).sqrt()
112+
merger.r = (
113+
(merger.x-com[0])**2
114+
+ (merger.y-com[1])**2
115+
+ (merger.z-com[2])**2
116+
).sqrt()
82117
merger = merger.sorted_by_attributes("r")
83118
n = []
84119
m = 0
85-
mi = 1.0*(Mprim+Msec).value_in(units.MSun)/len(merger)
120+
mi = 1.0*(mass_primary+mass_secondary).value_in(units.MSun)/len(merger)
86121
for i in range(len(merger.r)):
87122
m += mi
88123
n.append(m)
89-
pyplot.plot(merger.r.value_in(units.RSun), n, c=c, label=label)
90-
91-
def new_option_parser():
92-
from amuse.units.optparse import OptionParser
93-
result = OptionParser()
94-
result.add_option("-M", unit=units.MSun,
95-
dest="Mprim", type="float",default = 10|units.MSun,
96-
help="Mass of the primary star [%default] MSun")
97-
result.add_option("-m", unit=units.MSun,
98-
dest="Msec", type="float",default = 1|units.MSun,
99-
help="Mass of the secondary star [%default] MSun")
100-
result.add_option("-N",
101-
dest="Nsph", type="int",default = 100,
102-
help="Number of sph particles per MSun [%default]")
103-
result.add_option("-t", unit=units.Myr,
104-
dest="t_coll", type="float", default = 0.01|units.Myr,
105-
help="end time of the simulation [%default] Myr")
106-
return result
107-
108-
if __name__ in ('__main__', '__plot__'):
109-
o, arguments = new_option_parser().parse_args()
110-
111-
colors = get_distinct(4)
112-
figure = pyplot.figure(figsize=(16, 12))
113-
pyplot.xlabel("R [R$_\odot$]")
114-
pyplot.ylabel("$M_{<r}$")
115-
ax = pyplot.gca()
116-
ax.minorticks_on() # switch on the minor ticks
124+
plt.plot(merger.r.value_in(units.RSun), n, c=c, label=label)
125+
126+
127+
def new_argument_parser():
128+
parser = argparse.ArgumentParser(
129+
formatter_class=argparse.ArgumentDefaultsHelpFormatter
130+
)
131+
parser.add_argument(
132+
"-M", "--mass_primary", type=units.MSun, default=10 | units.MSun,
133+
help="Mass of the primary star"
134+
)
135+
parser.add_argument(
136+
"-m", "--mass_secondary", type=units.MSun, default=1 | units.MSun,
137+
help="Mass of the secondary star"
138+
)
139+
# specifying more numbers will result in more simulations
140+
parser.add_argument(
141+
"-N", "--number_of_sph_particles", type=int, nargs="+",
142+
default=[10, 100, 1000, 10000],
143+
help="number of sph particles"
144+
)
145+
parser.add_argument(
146+
"-t",
147+
"--time_collision",
148+
type=units.Myr,
149+
default=0.01 | units.Myr,
150+
help="end time of the simulation"
151+
)
152+
return parser
153+
154+
155+
def merge_two_stars_sph_convergence(
156+
mass_primary=10 | units.MSun,
157+
mass_secondary=1 | units.MSun,
158+
time_collision=0.01 | units.Myr,
159+
number_of_sph_particles=None,
160+
):
161+
if number_of_sph_particles is None:
162+
number_of_sph_particles = [10, 100, 1000, 10000]
163+
plt.figure(figsize=(8, 6))
164+
plt.xlabel(r"R [R$_\odot$]")
165+
plt.ylabel("$M_{<r}$")
166+
ax = plt.gca()
167+
ax.minorticks_on() # switch on the minor ticks
117168
ax.locator_params(nbins=3)
118-
merge_and_plot_distribution(o.Mprim, o.Msec, o.t_coll, 10, 0.5, colors[0], "$N_{sph} = 10/M_\odot$")
119-
merge_and_plot_distribution(o.Mprim, o.Msec, o.t_coll, 100, 0.5, colors[1], "$N_{sph} = 100/M_\odot$")
120-
merge_and_plot_distribution(o.Mprim, o.Msec, o.t_coll, 1000, 0.5, colors[2], "$N_{sph} = 10^3/M_\odot$")
121-
merge_and_plot_distribution(o.Mprim, o.Msec, o.t_coll, 10000, 0.5, colors[3], "$N_{sph} = 10^4/M_\odot$")
122-
# pyplot.show()
123-
# pyplot.semilogx()
124-
pyplot.xlim(0, 20)
125-
pyplot.ylim(0, 12)
126-
pyplot.legend(loc=4, fontsize=24)
127-
pyplot.savefig("stellar_merger_convergence")
169+
for n in number_of_sph_particles:
170+
merge_and_plot_distribution(
171+
mass_primary, mass_secondary, time_collision, n, 0.5,
172+
label=r"$N_{sph} = " + f"{n}" + r"/M_\odot$"
173+
)
174+
plt.xlim(0, 20)
175+
plt.ylim(0, 12)
176+
plt.legend(loc=4, fontsize=24)
177+
plt.savefig("stellar_merger_convergence.pdf")
178+
179+
180+
def main():
181+
args = new_argument_parser().parse_args()
182+
merge_two_stars_sph_convergence(**args.__dict__)
183+
184+
185+
if __name__ == "__main__":
186+
main()

src/amuse/examples/run_examples_benchmark.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
import sys
55
import time
66
import os
7+
import argparse
8+
import platform
79
import contextlib
810
if sys.version_info < (3, 9):
911
from importlib_resources import files
1012
else:
1113
from importlib.resources import files
1214
from datetime import datetime, timezone
13-
import argparse
14-
import platform
1515
import matplotlib.pyplot as plt
1616
from amuse.units import units
1717
import amuse.examples as ae

0 commit comments

Comments
 (0)