Skip to content

Commit ff7a667

Browse files
committed
add more missing examples
1 parent 2fe4b36 commit ff7a667

File tree

5 files changed

+608
-0
lines changed

5 files changed

+608
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
Evolve a population of N stars.
3+
Initial mass function between Mmin and Mmax with stellar evolution
4+
for metallicity z.
5+
"""
6+
import numpy as np
7+
from amuse.io import write_set_to_file, read_set_from_file
8+
from amuse.units import units
9+
from amuse.datamodel import Particles
10+
from amuse.community.seba import Seba
11+
from amuse.community.sse import Sse
12+
from amuse.community.mesa_r2208.interface import Mesa
13+
#from amuse.community.mesa import Mesa
14+
from amuse.community.evtwin import Evtwin
15+
from amuse.ic.salpeter import new_salpeter_mass_distribution
16+
17+
def calculate_stellar_temperature_and_luminosity(
18+
star,
19+
evo_code, metallicity=0.02, time_end=100 | units.Myr):
20+
21+
if evo_code.find("Seba") >= 0:
22+
stellar = Seba()
23+
stellar.parameters.metallicity = metallicity
24+
stellar.particles.add_particle(star)
25+
channel_to_framework = stellar.particles.new_channel_to(star)
26+
stellar.evolve_model(time_end)
27+
channel_to_framework.copy_attributes(
28+
["radius", "temperature", "luminosity"]
29+
)
30+
stellar.stop()
31+
else:
32+
if evo_code.find("Mesa") >= 0:
33+
stellar = Mesa()
34+
elif evo_code.find("Evtwin") >= 0:
35+
stellar = Evtwin()
36+
stellar.parameters.metallicity = metallicity
37+
stellar.particles.add_particle(star)
38+
channel_to_framework = stellar.particles.new_channel_to(star)
39+
try:
40+
if star.mass<=0.8|units.MSun:
41+
t_end = 0.1|units.Myr
42+
else:
43+
t_end = time_end
44+
print("Evolved star: m=", star.mass.in_(units.MSun))
45+
stellar.evolve_model(t_end)
46+
channel_to_framework.copy_attributes(
47+
["radius", "temperature", "luminosity"])
48+
print("Successfully evolved star: m=", star.mass.in_(units.MSun))
49+
except:
50+
print("Failed to evolve star: m=", star.mass.in_(units.MSun))
51+
stellar.stop()
52+
return star
53+
54+
def main(input_file, time_end, metallicity, evo_code="Seba"):
55+
evo_code = evo_code.capitalize()
56+
if evo_code.find("Seba") >= 0:
57+
filename = "../data/Stellar_Isochrone_Seba.amuse"
58+
elif evo_code.find("Mesa") >= 0:
59+
filename = "../data/Stellar_Isochrone_Mesa.amuse"
60+
elif evo_code.find("Evtwin") >= 0:
61+
filename = "../data/Stellar_Isochrone_Evtwin.amuse"
62+
else:
63+
print("No input code, stop")
64+
exit(-1)
65+
66+
stars = read_set_from_file(input_file, "amuse", close_file=True)
67+
from os.path import exists
68+
if exists(filename):
69+
stars_done = read_set_from_file(filename, "amuse", close_file=True)
70+
else:
71+
stars_done = Particles(0)
72+
for si in stars:
73+
if si not in stars_done:
74+
star_evolved = calculate_stellar_temperature_and_luminosity(
75+
si.as_set(),
76+
evo_code=evo_code, metallicity=metallicity,
77+
time_end=time_end)
78+
stars_done.add_particle(star_evolved)
79+
write_set_to_file(stars_done, filename, overwrite_file=True)
80+
81+
82+
def new_option_parser():
83+
from amuse.units.optparse import OptionParser
84+
result = OptionParser()
85+
result.add_option("-C", dest="evo_code", default="Seba",
86+
help="stellar evolution code [SeBa]")
87+
result.add_option("--f", dest="input_file",
88+
default="initial_stellar_mass_function.amuse",
89+
help="input data file")
90+
result.add_option("-t", dest="time_end", unit=units.Myr,
91+
type="float", default=4500.0 | units.Myr,
92+
help="end time of the simulation [4500] Myr")
93+
result.add_option("-z", dest="metallicity", type="float", default=0.02,
94+
help="metalicity [0.02]")
95+
return result
96+
97+
98+
if __name__ in ('__main__'):
99+
o, arguments = new_option_parser().parse_args()
100+
main(**o.__dict__)
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
import numpy
2+
import os
3+
import warnings
4+
5+
from optparse import OptionParser
6+
7+
from amuse.units import units
8+
from amuse.community.sse.interface import SSE
9+
from amuse.community.evtwin.interface import EVtwin
10+
from amuse.community.mesa.interface import MESA
11+
from amuse.community.cachedse.interface import CachedStellarEvolution
12+
13+
from amuse.test.amusetest import get_path_to_results
14+
15+
from amuse import datamodel
16+
from amuse.rfi.core import is_mpd_running
17+
from amuse.ic.salpeter import new_salpeter_mass_distribution
18+
usage = """\
19+
usage: %prog [options]
20+
21+
This script will generate HR diagram for an
22+
evolved cluster of stars with a Salpeter mass
23+
distribution.
24+
"""
25+
26+
27+
def simulate_stellar_evolution(
28+
stellar_evolution=SSE(),
29+
number_of_stars=1000,
30+
end_time=1000.0 | units.Myr,
31+
name_of_the_figure="cluster_HR_diagram.png",
32+
):
33+
"""
34+
A cluster of stars will be created, with masses following a Salpeter IMF.
35+
The stellar evolution will be simulated using any of the legacy codes (SSE,
36+
EVtwin, or MESA).
37+
Finally, a Hertzsprung-Russell diagram will be produced for the final state
38+
of the simulation.
39+
"""
40+
print(
41+
"The evolution of",
42+
str(number_of_stars),
43+
"stars will be ",
44+
"simulated until t =",
45+
str(end_time),
46+
"..."
47+
)
48+
49+
stellar_evolution.commit_parameters()
50+
51+
print(
52+
"Deriving a set of",
53+
str(number_of_stars),
54+
"random masses",
55+
"following a Salpeter IMF between 0.1 and 125 MSun (alpha = -2.35)."
56+
)
57+
58+
salpeter_masses = new_salpeter_mass_distribution(number_of_stars)
59+
60+
print("Initializing the particles")
61+
stars = datamodel.Particles(number_of_stars)
62+
stars.mass = salpeter_masses
63+
print("Stars to evolve:")
64+
print(stars)
65+
stars = stellar_evolution.particles.add_particles(stars)
66+
stellar_evolution.commit_particles()
67+
68+
# print stars.temperature
69+
70+
print("Start evolving...")
71+
stellar_evolution.evolve_model(end_time)
72+
73+
print("Evolved model successfully.")
74+
temperatures = stars.temperature
75+
luminosities = stars.luminosity
76+
77+
stellar_evolution.stop()
78+
79+
plot_HR_diagram(temperatures, luminosities, name_of_the_figure, end_time)
80+
81+
print("All done!")
82+
83+
84+
def plot_HR_diagram(temperatures, luminosities, name_of_the_figure, end_time):
85+
try:
86+
# This removes the need for ssh -X to be able to do plotting
87+
import matplotlib
88+
matplotlib.use("Agg", warn=False)
89+
from matplotlib import pyplot
90+
print("Plotting the data...")
91+
number_of_stars = len(temperatures)
92+
pyplot.figure(figsize=(7, 8))
93+
pyplot.title('Hertzsprung-Russell diagram', fontsize=12)
94+
pyplot.xlabel(r'T$_{\rm eff}$ (K)')
95+
pyplot.ylabel(r'Luminosity (L$_\odot$)')
96+
pyplot.loglog(temperatures.value_in(units.K),
97+
luminosities.value_in(units.LSun), "ro")
98+
99+
xmin, xmax = 20000.0, 2500.0
100+
ymin, ymax = 1.e-4, 1.e4
101+
pyplot.text(xmin*.75, ymax*0.1, str(number_of_stars) +
102+
" stars\nt="+str(end_time))
103+
pyplot.axis([xmin, xmax, ymin, ymax])
104+
pyplot.savefig(name_of_the_figure)
105+
except ImportError:
106+
print("Unable to produce plot: couldn't find matplotlib.")
107+
108+
109+
class InstantiateCode(object):
110+
111+
def sse(self, number_of_stars):
112+
return SSE()
113+
114+
def evtwin(self, number_of_stars):
115+
result = EVtwin()
116+
result.initialize_code()
117+
if number_of_stars > result.parameters.maximum_number_of_stars:
118+
result.parameters.maximum_number_of_stars = number_of_stars
119+
warnings.warn(
120+
"You're simulating a large number of stars with EVtwin. This may not be such a good idea...")
121+
return result
122+
123+
def mesa(self, number_of_stars):
124+
result = MESA()
125+
result.initialize_code()
126+
if number_of_stars > (10):
127+
warnings.warn(
128+
"You're simulating a large number of stars with MESA. This may not be such a good idea...")
129+
if number_of_stars > (1000):
130+
raise Exception(
131+
"You want to simulate with more than 1000 stars using MESA, this is not supported")
132+
return result
133+
134+
def new_code(self, name_of_the_code, number_of_stars):
135+
if hasattr(self, name_of_the_code):
136+
return getattr(self, name_of_the_code)(number_of_stars)
137+
else:
138+
raise Exception(
139+
"Cannot instantiate code with name '{0}'".format(
140+
name_of_the_code)
141+
)
142+
143+
144+
def new_code(name_of_the_code, number_of_stars):
145+
return InstantiateCode().new_code(name_of_the_code, number_of_stars)
146+
147+
148+
def test_simulate_short():
149+
assert is_mpd_running()
150+
code = new_code("sse", 100)
151+
152+
test_results_path = get_path_to_results()
153+
output_file = os.path.join(test_results_path, "cluster_HR_diagram.png")
154+
155+
simulate_stellar_evolution(
156+
code,
157+
number_of_stars=100,
158+
end_time=2.0 | units.Myr,
159+
name_of_the_figure=output_file
160+
)
161+
162+
163+
def new_commandline_option_parser():
164+
result = OptionParser(usage)
165+
result.add_option(
166+
"-c",
167+
"--code",
168+
choices=["sse", "evtwin", "mesa"],
169+
default="sse",
170+
dest="code",
171+
metavar="CODE",
172+
help="CODE to use for stellar evolution"
173+
)
174+
result.add_option(
175+
"-n",
176+
"--number_of_stars",
177+
type="int",
178+
default=10,
179+
dest="number_of_stars",
180+
help="Number of stars in the cluster"
181+
)
182+
result.add_option(
183+
"-t",
184+
"--end_time",
185+
type="float",
186+
default=1000.0,
187+
dest="end_time",
188+
help="Time to evolve to in Myr"
189+
)
190+
result.add_option(
191+
"-C",
192+
"--cache",
193+
type="string",
194+
default=None,
195+
dest="cacheDir",
196+
help="Use/write cache from directory"
197+
)
198+
result.add_option(
199+
"-S",
200+
"--seed",
201+
type="int",
202+
default=None,
203+
dest="salpeterSeed",
204+
help="Random number generator seed"
205+
)
206+
result.add_option(
207+
"-p",
208+
"--plot_file",
209+
type="string",
210+
default="cluster_HR_diagram.png",
211+
dest="plot_filename",
212+
help="Name of the file to plot to"
213+
)
214+
215+
return result
216+
217+
218+
if __name__ == '__main__':
219+
220+
parser = new_commandline_option_parser()
221+
(options, arguments) = parser.parse_args()
222+
if arguments:
223+
parser.error("unknown arguments '{0}'".format(arguments))
224+
225+
code = new_code(options.code, options.number_of_stars)
226+
227+
if not (options.cacheDir is None):
228+
print("Using cache directory: %s" % (options.cacheDir))
229+
code = CachedStellarEvolution(code, options.cacheDir)
230+
231+
if not (options.salpeterSeed is None):
232+
numpy.random.seed(options.salpeterSeed)
233+
234+
simulate_stellar_evolution(
235+
code,
236+
number_of_stars=options.number_of_stars,
237+
end_time=options.end_time | units.Myr,
238+
name_of_the_figure=options.plot_filename
239+
)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from amuse.lab import *
2+
bodies = read_set_from_file("../data/Pl_N16NO_A1000R.amuse", close_file=True)
3+
stars = bodies[bodies.name=="star"]
4+
systems = bodies[bodies.name=="system"]
5+
planets = bodies[bodies.name=="planet"]
6+
debris = bodies[bodies.name=="asteroid"]
7+
8+
print(f"N={len(bodies)}, {len(stars)}, {len(systems)}, {len(planets)}, {len(debris)}")
9+
10+
from matplotlib import pyplot as plt
11+
12+
plt.style.use('../lib/matplotlibrc')
13+
14+
figure = plt.figure(figsize=(6, 6))
15+
ax = plt.gca()
16+
ax.minorticks_on() # switch on the minor ticks
17+
ax.locator_params(nbins=3)
18+
19+
plt.xlabel("x [pc]")
20+
plt.ylabel("y [pc]")
21+
plt.xlim(-0.01, 0.01)
22+
plt.ylim(-0.01, 0.01)
23+
plt.scatter(debris.x.value_in(units.pc), debris.y.value_in(units.pc), c='k', lw=0, s=1, label="debris")
24+
plt.scatter(planets.x.value_in(units.pc), planets.y.value_in(units.pc), c='y', lw=0, s=20, label="planet")
25+
plt.scatter(systems.x.value_in(units.pc), systems.y.value_in(units.pc), c='r', lw=0, s=30, label="planetary system")
26+
plt.scatter(stars.x.value_in(units.pc), stars.y.value_in(units.pc), c='b', lw=0, s=30, label="single star")
27+
plt.savefig("fig_Pl_N16NO_A1000R.pdf")
28+
plt.show()

0 commit comments

Comments
 (0)