def test6(self): print("Test whether a set of stars evolves synchronously...") # Create an array of stars with a range in stellar mass masses = [.5, 1., 2., 5., 10., 30.] | units.MSun number_of_stars = len(masses) stars = Particles(number_of_stars) stars.mass = masses # Initialize stellar evolution code instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() from_code_to_model = instance.particles.new_channel_to(stars) from_code_to_model.copy() instance.evolve_model(end_time=125 | units.Myr) from_code_to_model.copy() end_types = ( "deeply or fully convective low mass MS star", "Main Sequence star", "Main Sequence star", "Carbon/Oxygen White Dwarf", "Neutron Star", "Black Hole", ) for i in range(number_of_stars): self.assertAlmostEqual(stars[i].age, 125.0 | units.Myr) self.assertTrue(stars[i].mass <= masses[i]) self.assertEqual(str(stars[i].stellar_type), end_types[i]) instance.stop()
def test18(self): print "SSE validation" sse_src_path = os.path.join(os.path.dirname(sys.modules[SSE.__module__].__file__), 'src') if not os.path.exists(os.path.join(sse_src_path, "evolve.in")): self.skip("Not in a source release") instance = SSE() instance.particles.add_particle(Particle(mass = 1.416 | units.MSun)) instance.particles[0].evolve_for(7000.0 | units.Myr) evolved_star = instance.particles.copy()[0] evolved_star.temperature = instance.particles[0].temperature instance.stop() testpath = get_path_to_results() shutil.copy(os.path.join(sse_src_path, "evolve.in"), os.path.join(testpath, "evolve.in")) call([os.path.join(sse_src_path, "sse")], cwd=testpath) with open(os.path.join(testpath, "evolve.dat"), "r") as sse_output: lines = sse_output.readlines() sse_final_result = lines[-2].split() self.assertAlmostEqual(evolved_star.age, float(sse_final_result[0]) | units.Myr, 3) self.assertAlmostEqual(evolved_star.stellar_type, float(sse_final_result[1]) | units.stellar_type, 3) self.assertAlmostEqual(evolved_star.initial_mass, float(sse_final_result[2]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.mass, float(sse_final_result[3]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.luminosity, 10**float(sse_final_result[4]) | units.LSun, 3) self.assertAlmostEqual(evolved_star.radius, 10**float(sse_final_result[5]) | units.RSun, 3) self.assertAlmostRelativeEqual(evolved_star.temperature, 10**float(sse_final_result[6]) | units.K, 2) self.assertAlmostEqual(evolved_star.core_mass, float(sse_final_result[7]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.convective_envelope_mass, float(sse_final_result[8]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.epoch, float(sse_final_result[9]) | units.Myr, 3) self.assertAlmostEqual(evolved_star.spin, float(sse_final_result[10]) | units.yr**-1, 3)
def test17(self): print "evolve_one_step and evolve_for after particle removal and addition" particles = Particles(10) particles.mass = range(1, 11) | units.MSun instance = SSE() instance.particles.add_particles(particles) self.assertAlmostEqual(instance.particles.age, 0.0 | units.yr) time_steps = numpy.linspace(0.1, 1.0, num=10) | units.Myr for i in range(10): instance.particles[i].evolve_for(time_steps[i]) self.assertAlmostEqual(instance.particles.age, time_steps) instance.particles.remove_particles(particles[[1, 4, 8]]) revived = instance.particles.add_particle(particles[4]) revived.evolve_for(numpy.pi | units.Myr) for star in instance.particles: star.evolve_for(star.age) self.assertAlmostEqual(instance.particles.age[:-1], 2*time_steps[[0, 2,3, 5,6,7, 9]]) self.assertAlmostEqual(instance.particles.age[-1], 2*numpy.pi | units.Myr) instance.particles.remove_particles(particles[[2, 5, 6]]) instance.particles.add_particles(particles[[8, 1]]) self.assertEqual(len(instance.particles), 7) expected_ages = instance.particles.age + instance.particles.time_step for star in instance.particles: star.evolve_one_step() self.assertAlmostEqual(instance.particles.age, expected_ages) instance.stop()
def test16(self): print "test evolution of 1000 star sampled over flattish IMF" number_of_stars=1000 class notsorandom(object): def random(self,N): return numpy.array(range(N))/(N-1.) def random_sample(self,N): return numpy.array(range(N))/(N-1.) masses = new_salpeter_mass_distribution( number_of_stars, mass_min = 0.1 | units.MSun, mass_max = 100.0 | units.MSun, alpha = -1.01,random=notsorandom() ) stars=Particles(mass=masses) instance=SSE() instance.particles.add_particles(stars) i=0 for p in instance.particles: print i,p.mass, p.evolve_for(13.2 | units.Gyr) print p.mass i+=1 instance.stop()
def test18(self): print("SSE validation") sse_src_path = os.path.join(os.path.dirname(sys.modules[SSE.__module__].__file__), 'src') if not os.path.exists(os.path.join(sse_src_path, "evolve.in")): self.skip("Not in a source release") instance = SSE() instance.particles.add_particle(Particle(mass = 1.416 | units.MSun)) instance.particles[0].evolve_for(7000.0 | units.Myr) evolved_star = instance.particles.copy()[0] evolved_star.temperature = instance.particles[0].temperature instance.stop() testpath = get_path_to_results() shutil.copy(os.path.join(sse_src_path, "evolve.in"), os.path.join(testpath, "evolve.in")) call([os.path.join(sse_src_path, "sse")], cwd=testpath) with open(os.path.join(testpath, "evolve.dat"), "r") as sse_output: lines = sse_output.readlines() sse_final_result = lines[-2].split() self.assertAlmostEqual(evolved_star.age, float(sse_final_result[0]) | units.Myr, 3) self.assertAlmostEqual(evolved_star.stellar_type, float(sse_final_result[1]) | units.stellar_type, 3) self.assertAlmostEqual(evolved_star.initial_mass, float(sse_final_result[2]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.mass, float(sse_final_result[3]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.luminosity, 10**float(sse_final_result[4]) | units.LSun, 3) self.assertAlmostEqual(evolved_star.radius, 10**float(sse_final_result[5]) | units.RSun, 3) self.assertAlmostRelativeEqual(evolved_star.temperature, 10**float(sse_final_result[6]) | units.K, 2) self.assertAlmostEqual(evolved_star.core_mass, float(sse_final_result[7]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.convective_envelope_mass, float(sse_final_result[8]) | units.MSun, 3) self.assertAlmostEqual(evolved_star.epoch, float(sse_final_result[9]) | units.Myr, 3) self.assertAlmostEqual(evolved_star.spin, float(sse_final_result[10]) | units.yr**-1, 3)
def test14b(self): print( "Testing basic operations: evolve_one_step and evolve_for (on subset)" ) stars = Particles(2) stars.mass = 1.0 | units.MSun instance = SSE() se_stars = instance.particles.add_particles(stars) self.assertAlmostEqual(se_stars.age, [0.0, 0.0] | units.yr) for i in range(3): se_stars[:1].evolve_one_step() self.assertAlmostEqual(se_stars.age, [1650.46953688, 0.0] | units.Myr, 3) number_of_steps = 10 step_size = se_stars[0].age / number_of_steps for i in range(1, number_of_steps + 1): se_stars[1:].evolve_for(step_size) self.assertAlmostEqual(se_stars.age, [number_of_steps, i] * step_size) self.assertAlmostRelativeEqual(se_stars[0].age, se_stars[1].age) self.assertAlmostRelativeEqual(se_stars[0].luminosity, se_stars[1].luminosity, 3) self.assertAlmostRelativeEqual(se_stars[0].radius, se_stars[1].radius, 3) self.assertAlmostRelativeEqual(se_stars[0].temperature, se_stars[1].temperature, 3) instance.stop()
def test16(self): print("test evolution of 1000 star sampled over flattish IMF") number_of_stars = 1000 class notsorandom(object): def random(self, N): return numpy.array(range(N)) / (N - 1.) def random_sample(self, N): return numpy.array(range(N)) / (N - 1.) masses = new_salpeter_mass_distribution(number_of_stars, mass_min=0.1 | units.MSun, mass_max=100.0 | units.MSun, alpha=-1.01, random=notsorandom()) stars = Particles(mass=masses) instance = SSE() instance.particles.add_particles(stars) i = 0 for p in instance.particles: p.evolve_for(13.2 | units.Gyr) i += 1 instance.stop()
def test17(self): print( "evolve_one_step and evolve_for after particle removal and addition" ) particles = Particles(10) particles.mass = list(range(1, 11)) | units.MSun instance = SSE() instance.particles.add_particles(particles) self.assertAlmostEqual(instance.particles.age, 0.0 | units.yr) time_steps = numpy.linspace(0.1, 1.0, num=10) | units.Myr for i in range(10): instance.particles[i].evolve_for(time_steps[i]) self.assertAlmostEqual(instance.particles.age, time_steps) instance.particles.remove_particles(particles[[1, 4, 8]]) revived = instance.particles.add_particle(particles[4]) revived.evolve_for(numpy.pi | units.Myr) for star in instance.particles: star.evolve_for(star.age) self.assertAlmostEqual(instance.particles.age[:-1], 2 * time_steps[[0, 2, 3, 5, 6, 7, 9]]) self.assertAlmostEqual(instance.particles.age[-1], 2 * numpy.pi | units.Myr) instance.particles.remove_particles(particles[[2, 5, 6]]) instance.particles.add_particles(particles[[8, 1]]) self.assertEqual(len(instance.particles), 7) expected_ages = instance.particles.age + instance.particles.time_step for star in instance.particles: star.evolve_one_step() self.assertAlmostEqual(instance.particles.age, expected_ages) instance.stop()
def simulate_evolution_tracks(): stellar_evolution = SSE() star = datamodel.Particle() star.mass = stellar_mass star = stellar_evolution.particles.add_particle(star) luminosity_at_time = [] | units.LSun temperature_at_time = [] | units.K print("Evolving a star with mass:", stellar_mass) is_evolving = True while is_evolving and star.age < end_time: luminosity_at_time.append(star.luminosity) temperature_at_time.append(star.temperature) previous_age = star.age # if we do not specify an end_time in the evolve_model function # a stellar evolution code will evolve to the next # 'natural' timestep, this will ensure all interesting physics # is seen in the hr diagram stellar_evolution.evolve_model() is_evolving = (star.age != previous_age) stellar_evolution.stop() return temperature_at_time, luminosity_at_time
def plottillagb(): sun = datamodel.Particle( mass=1 | units.MSun, radius=1 | units.RSun ) sse = SSE() sse.particles.add_particle(sun) channel_from_se_to_memory = sse.particles.new_channel_to(sun.as_set()) channel_from_se_to_memory.copy() masses = [] | units.MSun timerange = numpy.arange(11500, 13500, 10) | units.Myr for time in timerange: sse.evolve_model(time) channel_from_se_to_memory.copy() masses.append(sun.mass) print(time.as_quantity_in(units.Myr), sun.mass.as_quantity_in(units.MSun)) sse.stop() figure = pyplot.figure(figsize=(6, 6)) subplot = figure.add_subplot(1, 1, 1) subplot.plot(timerange.value_in(units.Gyr), masses.value_in(units.MSun), '.') subplot.set_xlabel('t (Gyr)') subplot.set_ylabel('mass (MSun)') pyplot.show()
def test23(self): instance = SSE() p=Particles(mass = [1.0, 10.0] | units.MSun, temperature=[10,10] | units.K) stars = instance.particles.add_particles(p) channel=stars.new_channel_to(p) channel.copy_attributes(["mass","temperature"]) self.assertEqual(stars.temperature, p.temperature) instance.stop()
def test1(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 5 | units.MSun star.radius = 0.0 | units.RSun sse.particles.add_particles(stars) from_sse_to_model = sse.particles.new_channel_to(stars) from_sse_to_model.copy() previous_type = star.stellar_type results = [] t0 = 0 | units.Myr current_time = t0 while current_time < (125 | units.Myr): sse.update_time_steps() current_time = current_time + sse.particles[0].time_step sse.evolve_model(current_time) from_sse_to_model.copy() if not star.stellar_type == previous_type: results.append((star.age, star.mass, star.stellar_type)) previous_type = star.stellar_type self.assertEqual(len(results), 6) times = (104.0 | units.Myr, 104.4 | units.Myr, 104.7 | units.Myr, 120.1 | units.Myr, 120.9 | units.Myr, 121.5 | units.Myr) for result, expected in zip(results, times): self.assertAlmostEqual(result[0].value_in(units.Myr), expected.value_in(units.Myr), 1) masses = (5.000 | units.MSun, 5.000 | units.MSun, 4.998 | units.MSun, 4.932 | units.MSun, 4.895 | units.MSun, 0.997 | units.MSun) for result, expected in zip(results, masses): self.assertAlmostEqual(result[1].value_in(units.MSun), expected.value_in(units.MSun), 3) types = ( "Hertzsprung Gap", "First Giant Branch", "Core Helium Burning", "First Asymptotic Giant Branch", "Second Asymptotic Giant Branch", "Carbon/Oxygen White Dwarf", ) for result, expected in zip(results, types): self.assertEqual(str(result[2]), expected) sse.stop()
def test6(self): print "Test whether a set of stars evolves synchronously..." # Create an array of stars with a range in stellar mass masses = [.5, 1., 2., 5., 10., 30.] | units.MSun number_of_stars = len(masses) stars = Particles(number_of_stars) stars.mass = masses # Initialize stellar evolution code instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() from_code_to_model = instance.particles.new_channel_to(stars) from_code_to_model.copy() instance.evolve_model(end_time = 125 | units.Myr) from_code_to_model.copy() end_types = ( "deeply or fully convective low mass MS star", "Main Sequence star", "Main Sequence star", "Carbon/Oxygen White Dwarf", "Neutron Star", "Black Hole", ) for i in range(number_of_stars): self.assertAlmostEquals(stars[i].age, 125.0 | units.Myr) self.assertTrue(stars[i].mass <= masses[i]) self.assertEquals(str(stars[i].stellar_type), end_types[i]) instance.stop()
def test21(self): instance = SSE() stars = instance.particles.add_particles(Particles(mass = 30 | units.MSun)) mass_loss_wind = stars[0].mass_loss_wind self.assertAlmostRelativeEquals(mass_loss_wind, 1.703e-07 | units.MSun / units.yr, 3) instance.evolve_model(1 | units.Myr) dm = (1 | units.Myr)* mass_loss_wind self.assertAlmostRelativeEquals(stars[0].mass, (30 | units.MSun) - dm , 3) self.assertAlmostRelativeEquals(stars[0].mass_loss_wind, 2.053e-07 | units.MSun / units.yr, 3) instance.stop()
def stellar_lifetime(mZAMS, z=0.02): global se if se is None: se = SSE() se.parameters.metallicity = z se.particles.add_particle(Particle(mass=mZAMS)) while not stellar_remnant_state(se.particles[0]): se.evolve_model() t_end = se.particles[0].age # tpe = se.particles[0].stellar_type se.particles.remove_particle(se.particles[0]) return t_end
def test9(self): print "Test: large number of particles" stellar_evolution = SSE(max_message_length=500) stellar_evolution.commit_parameters() number_of_particles = 10000 print "Has been tested with up to a million particles!" print "Now using ", number_of_particles, "particles only, for speed." stars = Particles(number_of_particles) stars.mass = 1.0 | units.MSun stellar_evolution.particles.add_particles(stars) self.assertEqual(len(stellar_evolution.particles), number_of_particles) stellar_evolution.stop()
def test5(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 35 | units.MSun star.radius = 0.0 | units.RSun stars.synchronize_to(sse.particles) channel = sse.particles.new_channel_to(stars) channel.copy_attributes( sse.particles.get_attribute_names_defined_in_store()) previous_type = star.stellar_type results = [] dt = 1 | units.Myr t = 0 | units.Myr while t < 30 | units.Myr: t += dt sse.evolve_model(t) self.assertTrue(sse.particles[0].mass.value_in(units.MSun) < 10.6) sse.stop()
def test3(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 5 | units.MSun star.radius = 0.0 | units.RSun stars.synchronize_to(sse.particles) channel = sse.particles.new_channel_to(stars) channel.copy_attributes( sse.particles.get_attribute_names_defined_in_store()) previous_type = sse.particles.stellar_type results = [] sse.evolve_model(121.5 | units.Myr) channel.copy_attributes( sse.particles.get_attribute_names_defined_in_store()) self.assertAlmostEqual(star.mass.value_in(units.MSun), 0.997, 3) sse.stop()
def test20(self): print "SSE core_mass and CO_core_mass (low mass stars)" instance = SSE() stars = instance.particles.add_particles(Particles(mass = [0.6, 1.0] | units.MSun)) instance.evolve_model(100 | units.Gyr) self.assertEqual(str(stars[0].stellar_type), "Helium White Dwarf") self.assertAlmostEqual(stars[0].mass, 0.405 | units.MSun, 2) self.assertEqual(stars[0].core_mass, stars[0].mass) self.assertEqual(stars[0].CO_core_mass, 0 | units.MSun) self.assertEqual(str(stars[1].stellar_type), "Carbon/Oxygen White Dwarf") self.assertAlmostEqual(stars[1].mass, 0.520 | units.MSun, 2) self.assertEqual(stars[1].core_mass, stars[1].mass) self.assertEqual(stars[1].CO_core_mass, stars[1].mass) instance.stop()
def evolve_to_age(stars, age, stellar_evolution="SeBa"): "Evolve stars to specified age with specified code" if stellar_evolution == "SeBa": from amuse.community.seba.interface import SeBa stellar_evolution = SeBa() elif stellar_evolution == "SSE": from amuse.community.sse.interface import SSE stellar_evolution = SSE() # SSE can result in nan values for luminosity/radius else: raise "No such stellar evolution code %s or no code specified" % ( stellar_evolution ) stellar_evolution.particles.add_particles(stars) if age > 0 | units.yr: stellar_evolution.evolve_model(age) stars.luminosity = np.nan_to_num( stellar_evolution.particles.luminosity.value_in(units.LSun) ) | units.LSun stars.radius = stellar_evolution.particles.radius # prevent zero/nan radius. x = np.where( np.nan_to_num( stars.radius.value_in(units.RSun) ) == 0. ) stars[x].radius = 0.01 | units.RSun stellar_evolution.stop() return
def test10(self): stellar_evolution = SSE() stellar_evolution.commit_parameters() stars = Particles(10) stars.mass = 1.0 | units.MSun stellar_evolution.particles.add_particles(stars) self.assertEqual(stellar_evolution.particles._factory_for_new_collection(), Particles) filename = os.path.join(get_path_to_results(), "test.h5") if os.path.exists(filename): os.remove(filename) io.write_set_to_file(stellar_evolution.particles, filename, 'hdf5') stored_stars = io.read_set_from_file(filename, 'hdf5') self.assertEqual(len(stars), len(stored_stars)) self.assertAlmostRelativeEquals(stars.mass, stored_stars.mass)
def test10(self): stellar_evolution = SSE() stellar_evolution.commit_parameters() stars = Particles(10) stars.mass = 1.0 | units.MSun stellar_evolution.particles.add_particles(stars) self.assertEquals(stellar_evolution.particles._factory_for_new_collection(), Particles) filename = os.path.join(get_path_to_results(), "test.h5") if os.path.exists(filename): os.remove(filename) io.write_set_to_file(stellar_evolution.particles, filename, 'hdf5') stored_stars = io.read_set_from_file(filename, 'hdf5') self.assertEquals(len(stars), len(stored_stars)) self.assertAlmostRelativeEquals(stars.mass, stored_stars.mass)
def test5(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 35 | units.MSun star.radius = 0.0 | units.RSun stars.synchronize_to(sse.particles) channel = sse.particles.new_channel_to(stars) channel.copy_attributes(sse.particles.get_attribute_names_defined_in_store()) previous_type = star.stellar_type results = [] dt = 1 | units.Myr t = 0 | units.Myr while t < 30 | units.Myr: t += dt sse.evolve_model(t) self.assertTrue(sse.particles[0].mass.value_in(units.MSun) < 10.6) sse.stop()
def test8(self): instance = SSE() self.assertEqual(instance.parameters.reimers_mass_loss_coefficient, 0.5) myvalue = 0.7 instance.parameters.reimers_mass_loss_coefficient = myvalue self.assertEqual(instance.parameters.reimers_mass_loss_coefficient, myvalue) instance.commit_parameters() self.assertEqual(instance.parameters.reimers_mass_loss_coefficient, myvalue) instance.stop() instance = SSE() self.assertEqual(instance.parameters.reimers_mass_loss_coefficient, 0.5) myvalue = 0.7 instance.parameters.reimers_mass_loss_coefficient = myvalue instance.parameters.set_defaults() instance.commit_parameters() self.assertEqual(instance.parameters.reimers_mass_loss_coefficient, 0.5) instance.stop()
def test22(self): instance = SSE() stars = instance.particles.add_particles(Particles(mass = [1.0, 10.0] | units.MSun)) gyration_radius = stars.gyration_radius self.assertTrue(numpy.all(0.0 < gyration_radius)) self.assertTrue(numpy.all(gyration_radius < 1.0)) instance.evolve_model(12.4 | units.Gyr) self.assertTrue(stars[0].gyration_radius < gyration_radius[0]) self.assertTrue(stars[1].gyration_radius > gyration_radius[1]) instance.evolve_model(14 | units.Gyr) self.assertTrue(numpy.all(stars.gyration_radius > gyration_radius)) instance.stop()
def test7(self): print("Test: evolve particles one at a time.") print("Used to be problematic, since initial_mass of idle particle is set to zero.") stars = Particles(2) stars.mass = 1.0 | units.MSun for star in stars: print(star) stellar_evolution = SSE() stellar_evolution.commit_parameters() stellar_evolution.particles.add_particles(star.as_set()) stellar_evolution.commit_particles() from_stellar_evolution_to_model = stellar_evolution.particles.new_channel_to(star.as_set()) stellar_evolution.evolve_model() from_stellar_evolution_to_model.copy() stellar_evolution.stop() self.assertEqual(stars[0].initial_mass, stars[1].initial_mass) self.assertEqual(stars[0].luminosity, stars[1].luminosity) self.assertEqual(stars[0].age, stars[1].age) print("Solved: SSE_muse_interface.f sets initial_mass to mass when necessary.")
def plottillagb(): sun = datamodel.Particle( mass = 1 | units.MSun, radius = 1 | units.RSun ) sse = SSE() sse.particles.add_particle(sun) channel_from_se_to_memory = sse.particles.new_channel_to(sun.as_set()) channel_from_se_to_memory.copy() masses = []|units.MSun timerange = numpy.arange(11500, 13500,10) | units.Myr for time in timerange: sse.evolve_model(time) channel_from_se_to_memory.copy() masses.append(sun.mass) print(time.as_quantity_in(units.Myr), sun.mass.as_quantity_in(units.MSun)) sse.stop() figure = pyplot.figure(figsize= (6,6)) subplot = figure.add_subplot(1, 1, 1) subplot.plot(timerange.value_in(units.Gyr), masses.value_in(units.MSun),'.') subplot.set_xlabel('t (Gyr)') subplot.set_ylabel('mass (MSun)') pyplot.show()
def planetplot(): sun, planets = new_solar_system_for_mercury() initial = 12.2138 | units.Gyr final = 12.3300 | units.Gyr step = 10000.0 | units.yr timerange = VectorQuantity.arange(initial, final, step) gd = MercuryWayWard() gd.initialize_code() # gd.stopping_conditions.timeout_detection.disable() gd.central_particle.add_particles(sun) gd.orbiters.add_particles(planets) gd.commit_particles() se = SSE() # se.initialize_code() se.commit_parameters() se.particles.add_particles(sun) se.commit_particles() channelp = gd.orbiters.new_channel_to(planets) channels = se.particles.new_channel_to(sun) for time in timerange: err = gd.evolve_model(time - initial) channelp.copy() # planets.savepoint(time) err = se.evolve_model(time) channels.copy() gd.central_particle.mass = sun.mass print( (sun[0].mass.value_in(units.MSun), time.value_in(units.Myr), planets[4].x.value_in(units.AU), planets[4].y.value_in(units.AU), planets[4].z.value_in(units.AU))) gd.stop() se.stop() for planet in planets: t, x = planet.get_timeline_of_attribute_as_vector("x") t, y = planet.get_timeline_of_attribute_as_vector("y") plot(x, y, '.') native_plot.gca().set_aspect('equal') native_plot.show()
def test14b(self): print "Testing basic operations: evolve_one_step and evolve_for (on subset)" stars = Particles(2) stars.mass = 1.0 | units.MSun instance = SSE() se_stars = instance.particles.add_particles(stars) self.assertAlmostEqual(se_stars.age, [0.0, 0.0] | units.yr) for i in range(3): se_stars[:1].evolve_one_step() self.assertAlmostEqual(se_stars.age, [1650.46953688, 0.0] | units.Myr, 3) number_of_steps = 10 step_size = se_stars[0].age / number_of_steps for i in range(1, number_of_steps + 1): se_stars[1:].evolve_for(step_size) self.assertAlmostEqual(se_stars.age, [number_of_steps, i] * step_size) print se_stars self.assertAlmostRelativeEqual(se_stars[0].age, se_stars[1].age) self.assertAlmostRelativeEqual(se_stars[0].luminosity, se_stars[1].luminosity, 3) self.assertAlmostRelativeEqual(se_stars[0].radius, se_stars[1].radius, 3) self.assertAlmostRelativeEqual(se_stars[0].temperature, se_stars[1].temperature, 3) instance.stop()
def planetplot(): sun, planets = new_solar_system_for_mercury() initial = 12.2138 | units.Gyr final = 12.3300 | units.Gyr step = 10000.0 | units.yr timerange = VectorQuantity.arange(initial, final, step) gd = MercuryWayWard() gd.initialize_code() # gd.stopping_conditions.timeout_detection.disable() gd.central_particle.add_particles(sun) gd.orbiters.add_particles(planets) gd.commit_particles() se = SSE() # se.initialize_code() se.commit_parameters() se.particles.add_particles(sun) se.commit_particles() channelp = gd.orbiters.new_channel_to(planets) channels = se.particles.new_channel_to(sun) for time in timerange: err = gd.evolve_model(time-initial) channelp.copy() # planets.savepoint(time) err = se.evolve_model(time) channels.copy() gd.central_particle.mass = sun.mass print( sun[0].mass.value_in(units.MSun), time.value_in(units.Myr), planets[4].x.value_in(units.AU), planets[4].y.value_in(units.AU), planets[4].z.value_in(units.AU) ) gd.stop() se.stop() for planet in planets: t, x = planet.get_timeline_of_attribute_as_vector("x") t, y = planet.get_timeline_of_attribute_as_vector("y") plot(x, y, '.') native_plot.gca().set_aspect('equal') native_plot.show()
def test7(self): print "Test: evolve particles one at a time." print "Used to be problematic, since initial_mass of idle particle is set to zero." stars = Particles(2) stars.mass = 1.0 | units.MSun for star in stars: print star stellar_evolution = SSE() stellar_evolution.commit_parameters() stellar_evolution.particles.add_particles(star.as_set()) stellar_evolution.commit_particles() from_stellar_evolution_to_model = stellar_evolution.particles.new_channel_to(star.as_set()) stellar_evolution.evolve_model() from_stellar_evolution_to_model.copy() stellar_evolution.stop() self.assertEquals(stars[0].initial_mass, stars[1].initial_mass) self.assertEquals(stars[0].luminosity, stars[1].luminosity) self.assertEquals(stars[0].age, stars[1].age) print "Solved: SSE_muse_interface.f sets initial_mass to mass when necessary."
def test2(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 5 | units.MSun star.radius = 0.0 | units.RSun sse.particles.add_particles(stars) sse.evolve_model(120.1 | units.Myr) self.assertAlmostEqual(sse.particles[0].mass.value_in(units.MSun), 4.932, 3) self.assertAlmostEqual(sse.particles[0].temperature.value_in(units.K), 4221., 0) sse.stop()
def evolve_to_age(stars, age, se="SSE"): if se == "SSE": se = SSE() se.particles.add_particles(stars) se.evolve_model(age) stars.luminosity = se.particles.luminosity stars.radius = se.particles.radius se.stop() return
def simulate_stellar_evolution( stellar_evolution=SSE(), number_of_stars=1000, end_time=1000.0 | units.Myr, name_of_the_figure="cluster_HR_diagram.png", ): """ A cluster of stars will be created, with masses following a Salpeter IMF. The stellar evolution will be simulated using any of the legacy codes (SSE, EVtwin, or MESA). Finally, a Hertzsprung-Russell diagram will be produced for the final state of the simulation. """ print("The evolution of", str(number_of_stars), "stars will be ", "simulated until t =", str(end_time), "...") stellar_evolution.commit_parameters() print( "Deriving a set of", str(number_of_stars), "random masses", "following a Salpeter IMF between 0.1 and 125 MSun (alpha = -2.35).") salpeter_masses = new_salpeter_mass_distribution(number_of_stars) print("Initializing the particles") stars = datamodel.Particles(number_of_stars) stars.mass = salpeter_masses print("Stars to evolve:") print(stars) stars = stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() # print stars.temperature print("Start evolving...") stellar_evolution.evolve_model(end_time) print("Evolved model successfully.") temperatures = stars.temperature luminosities = stars.luminosity stellar_evolution.stop() plot_HR_diagram(temperatures, luminosities, name_of_the_figure, end_time) print("All done!")
def test9(self): print("Test: large number of particles") stellar_evolution = SSE(max_message_length=500) stellar_evolution.commit_parameters() number_of_particles = 10000 print("Has been tested with up to a million particles!") print("Now using ", number_of_particles, "particles only, for speed.") stars = Particles(number_of_particles) stars.mass = 1.0 | units.MSun stellar_evolution.particles.add_particles(stars) self.assertEqual(len(stellar_evolution.particles), number_of_particles) stellar_evolution.stop()
def evolve_model(self, tend): if not hasattr(self.particles, 'Emech'): self.particles.Lmech = lmech(self.particles) self.particles.Emech = (0. | units.Myr) * self.particles.Lmech stellar_type = self.particles.stellar_type.copy() prev_lm = self.particles.Lmech.copy() ret = SSE.evolve_model(self, tend) tend = self.model_time if tend > self.mech_time: dt = tend - self.mech_time self.mech_time = tend lm = lmech(self.particles) self.particles.Lmech = lm.copy() self.particles.Emech=self.particles.Emech+dt*(prev_lm+lm)/2. + \ e_supernova(self.particles.stellar_type,stellar_type) return ret
def test20(self): print("SSE core_mass and CO_core_mass (low mass stars)") instance = SSE() stars = instance.particles.add_particles(Particles(mass = [0.6, 1.0] | units.MSun)) instance.evolve_model(100 | units.Gyr) self.assertEqual(str(stars[0].stellar_type), "Helium White Dwarf") self.assertAlmostEqual(stars[0].mass, 0.405 | units.MSun, 2) self.assertEqual(stars[0].core_mass, stars[0].mass) self.assertEqual(stars[0].CO_core_mass, 0 | units.MSun) self.assertEqual(str(stars[1].stellar_type), "Carbon/Oxygen White Dwarf") self.assertAlmostEqual(stars[1].mass, 0.520 | units.MSun, 2) self.assertEqual(stars[1].core_mass, stars[1].mass) self.assertEqual(stars[1].CO_core_mass, stars[1].mass) instance.stop()
def get_stellar_radius(star, SEVCode = None): if SEVCode == None: sev_code = SSE() else: sev_code = SEVCode temp_star = Particle() temp_star.mass = star.mass temp_star.age = star.time sev_code.particles.add_particle(temp_star) sev_code.model_time = star.time sev_code.evolve_model(star.time) radius = sev_code.particles[0].radius print(radius, sev_code.particles[0].age) if SEVCode == None: sev_code.stop() else: sev_code.particles.remove_particle(temp_star) return radius
def __init__(self, pEVtwin = None, pSSE = None): # specifying the stellar evolution objects as parameters in the constructor # allows setting up caching in a convenient way if pEVtwin is None: self._EVtwin = EVtwin() else: self._EVtwin = pEVtwin if pSSE is None: self._SSE = SSE() else: self._SSE = pSSE # initialize member variables self.particles = datamodel.Particles() self.EVtwinAgeAtSwitch = float("nan") | units.Myr self.EVtwinException = None self.ActiveModel = self._EVtwin # self.ActiveModel.__class__.__name__ contains name of active model self._EVtwin_particlesh = None self._SSE_particlesh = None
def __init__(self, evo_code=SeBa, logger=None, time_offset=0 | units.Myr, settings=None, **keyword_arguments): self.typestr = "Evolution" self.namestr = evo_code.__name__ self.logger = logger or logging.getLogger(__name__) self.__evo_code = evo_code self.settings = settings if evo_code is SSE: self.code = SSE( # channel_type="sockets", **keyword_arguments) elif evo_code is SeBa: self.code = SeBa(**keyword_arguments) else: self.code = evo_code(**keyword_arguments) self.parameters = self.code.parameters if time_offset is None: time_offset = 0 | units.Myr self.__time_offset = time_offset
def test3(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 5 | units.MSun star.radius = 0.0 | units.RSun stars.synchronize_to(sse.particles) channel = sse.particles.new_channel_to(stars) channel.copy_attributes(sse.particles.get_attribute_names_defined_in_store()) previous_type = sse.particles.stellar_type results = [] sse.evolve_model(121.5 | units.Myr) channel.copy_attributes(sse.particles.get_attribute_names_defined_in_store()) self.assertAlmostEqual(star.mass.value_in(units.MSun), 0.997, 3) sse.stop()
def test11(self): print "Test evolve_model optional arguments: end_time and keep_synchronous" stars = Particles(3) stars.mass = [1.0, 2.0, 3.0] | units.MSun instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) self.assertEqual(instance.particles.age, [0.0, 0.0, 0.0] | units.yr) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.particles.radius, [0.8882494502, 1.610210385, 1.979134445] | units.RSun) print "evolve_model without arguments: use shared timestep = min(particles.time_step)" instance.evolve_model() self.assertAlmostEqual(instance.particles.age, [18.8768, 18.8768, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 18.8768 | units.Myr, 3) print "evolve_model with end_time: take timesteps, until end_time is reached exactly" instance.evolve_model(100 | units.Myr) self.assertAlmostEqual(instance.particles.age, [100.0, 100.0, 100.0] | units.Myr, 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3) print "evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge" instance.evolve_model(keep_synchronous = False) self.assertAlmostEqual(instance.particles.age, (100 | units.Myr) + ([550.1565, 58.2081, 18.8768] | units.Myr), 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3) # Unchanged! instance.stop()
def test12(self): print "Testing adding and removing particles from stellar evolution code..." particles = Particles(3) particles.mass = 1.0 | units.MSun instance = SSE() instance.initialize_code() instance.commit_parameters() self.assertEquals(len(instance.particles), 0) # before creation instance.particles.add_particles(particles[:-1]) instance.commit_particles() instance.evolve_model(1.0 | units.Myr) self.assertEquals(len(instance.particles), 2) # before remove self.assertAlmostEqual(instance.particles.age, 1.0 | units.Myr) instance.particles.remove_particle(particles[0]) self.assertEquals(len(instance.particles), 1) instance.evolve_model(2.0 | units.Myr) self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) instance.particles.add_particles(particles[::2]) self.assertEquals(len(instance.particles), 3) # it's back... self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) self.assertAlmostEqual(instance.particles[1].age, 0.0 | units.Myr) self.assertAlmostEqual(instance.particles[2].age, 0.0 | units.Myr) # ... and rejuvenated. instance.evolve_model(3.0 | units.Myr) # The young stars keep their age offset from the old star self.assertAlmostEqual(instance.particles.age, [3.0, 1.0, 1.0] | units.Myr) instance.evolve_model(4.0 | units.Myr) self.assertAlmostEqual(instance.particles.age, [4.0, 2.0, 2.0] | units.Myr) instance.stop()
def __init__(self, **options): SSE.__init__(self, convert_nbody=None, **options)
def test13(self): print "Testing SSE states" stars = Particles(1) stars.mass = 1.0 | units.MSun print "First do everything manually:", instance = SSE() self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.initialize_code() self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') instance.commit_parameters() self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.cleanup_code() self.assertEquals(instance.get_name_of_current_state(), 'END') instance.stop() print "ok" print "initialize_code(), commit_parameters(), " \ "and cleanup_code() should be called automatically:", instance = SSE() self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.parameters.reimers_mass_loss_coefficient = 0.5 self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') instance.particles.add_particles(stars) self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.stop() self.assertEquals(instance.get_name_of_current_state(), 'STOPPED') print "ok"
def test19(self): print "SSE core_mass and CO_core_mass (high mass star)" instance = SSE() star = instance.particles.add_particle(Particle(mass = 30 | units.MSun)) instance.evolve_model(5.8 | units.Myr) print star.mass, star.core_mass, star.CO_core_mass, star.stellar_type self.assertEqual(str(star.stellar_type), "Main Sequence star") self.assertIsOfOrder(star.mass, 30 | units.MSun) self.assertEqual(star.core_mass, 0 | units.MSun) self.assertEqual(star.CO_core_mass, 0 | units.MSun) instance.evolve_model(6.0 | units.Myr) print star.mass, star.core_mass, star.CO_core_mass, star.stellar_type self.assertEqual(str(star.stellar_type), "Core Helium Burning") self.assertIsOfOrder(star.mass, 30 | units.MSun) self.assertIsOfOrder(star.core_mass, 10 | units.MSun) self.assertEqual(star.CO_core_mass, 0 | units.MSun) instance.evolve_model(6.5 | units.Myr) print star.mass, star.core_mass, star.CO_core_mass, star.stellar_type self.assertEqual(str(star.stellar_type), "Main Sequence Naked Helium star") self.assertIsOfOrder(star.mass, 10 | units.MSun) self.assertEqual(star.core_mass, star.mass) self.assertEqual(star.CO_core_mass, 0 | units.MSun) instance.evolve_model(6.65 | units.Myr) print star.mass, star.core_mass, star.CO_core_mass, star.stellar_type self.assertEqual(str(star.stellar_type), "Hertzsprung Gap Naked Helium star") self.assertIsOfOrder(star.mass, 10 | units.MSun) self.assertEqual(star.core_mass, star.mass) self.assertAlmostEqual(star.CO_core_mass, 7.12 | units.MSun, 2) instance.evolve_model(7.0 | units.Myr) print star.mass, star.core_mass, star.CO_core_mass, star.stellar_type self.assertEqual(str(star.stellar_type), "Black Hole") self.assertIsOfOrder(star.mass, 10 | units.MSun) self.assertEqual(star.core_mass, star.mass) self.assertEqual(star.CO_core_mass, star.mass) instance.stop()
def test1(self): sse = SSE() sse.commit_parameters() stars = Particles(1) star = stars[0] star.mass = 5 | units.MSun star.radius = 0.0 | units.RSun sse.particles.add_particles(stars) from_sse_to_model = sse.particles.new_channel_to(stars) from_sse_to_model.copy() previous_type = star.stellar_type results = [] t0 = 0 | units.Myr current_time = t0 while current_time < (125 | units.Myr): sse.update_time_steps() current_time = current_time + sse.particles[0].time_step sse.evolve_model(current_time) from_sse_to_model.copy() if not star.stellar_type == previous_type: results.append((star.age, star.mass, star.stellar_type)) previous_type = star.stellar_type self.assertEqual(len(results), 6) times = ( 104.0 | units.Myr, 104.4 | units.Myr, 104.7 | units.Myr, 120.1 | units.Myr, 120.9 | units.Myr, 121.5 | units.Myr ) for result, expected in zip(results, times): self.assertAlmostEqual(result[0].value_in(units.Myr), expected.value_in(units.Myr), 1) masses = ( 5.000 | units.MSun, 5.000 | units.MSun, 4.998 | units.MSun, 4.932 | units.MSun, 4.895 | units.MSun, 0.997 | units.MSun ) for result, expected in zip(results, masses): self.assertAlmostEqual(result[1].value_in(units.MSun), expected.value_in(units.MSun), 3) types = ( "Hertzsprung Gap", "First Giant Branch", "Core Helium Burning", "First Asymptotic Giant Branch", "Second Asymptotic Giant Branch", "Carbon/Oxygen White Dwarf", ) for result, expected in zip(results, types): self.assertEquals(str(result[2]), expected) sse.stop()
def simulate_evolution_tracks( stellar_evolution=SSE(), masses=[0.5, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0] | units.MSun, name_of_the_figure="HR_evolution_tracks.png" ): """ For every mass in the `masses' array, a stellar evolution track across the Hertzsprung-Russell diagram will be calculated and plotted. Each star will be created, evolved and removed one by one. This is only necessary because the time span of each track is different (a solar mass star evolution track takes billions of years, but we don't want to also evolve high mass stars for billions of years) In most applications the stars have to be evolved up to a common end time, which can be more easily accomplished by creating an array (stars = datamodel.Stars(number_of_stars)) and using evolve_model(end_time = ...). """ number_of_stars = len(masses) all_tracks_luminosity = [] all_tracks_temperature = [] all_tracks_stellar_type = [] stellar_evolution.commit_parameters() print( "The evolution across the Hertzsprung-Russell diagram of ", str(number_of_stars), " stars with\nvarying masses will be simulated..." ) for j in range(number_of_stars): star = datamodel.Particle() star.mass = masses[j] print("Created new star with mass: ", star.mass) star = stellar_evolution.particles.add_particle(star) stellar_evolution.commit_particles() luminosity_at_time = [] | units.LSun temperature_at_time = [] | units.K stellar_type_at_time = [] | units.stellar_type stopped_evolving = False # Evolve this star until it changes into a compact stellar remnant # (white dwarf, neutron star, or black hole) while not stellar_remnant_state(star) and not stopped_evolving: luminosity_at_time.append(star.luminosity) temperature_at_time.append(star.temperature) stellar_type_at_time.append(star.stellar_type) previous_age = star.age try: stellar_evolution.evolve_model() # Check whether the age has stopped increasing stopped_evolving = (star.age == previous_age) except Exception as ex: print(str(ex)) stopped_evolving = True if stopped_evolving: print("Age did not increase during timestep. Aborted evolving...") else: stellar_type_at_time.append(star.stellar_type) # Fudged: final stellar type annotation at previous (Teff, L); # BHs and neutron stars would otherwise fall off the chart. luminosity_at_time.append(luminosity_at_time[-1]) temperature_at_time.append(temperature_at_time[-1]) print(" ... evolved model to t = " + \ str(star.age.as_quantity_in(units.Myr))) print( "Star has now become a: ", star.stellar_type, "(stellar_type: " + str( star.stellar_type.value_in(units.stellar_type) ) + ")" ) print() all_tracks_luminosity.append(luminosity_at_time) all_tracks_temperature.append(temperature_at_time) all_tracks_stellar_type.append(stellar_type_at_time) # Remove the star before creating the next one. See comments at the top. stellar_evolution.particles.remove_particle(star) stellar_evolution.stop() plot_HR_diagram( masses, all_tracks_luminosity, all_tracks_temperature, all_tracks_stellar_type, name_of_the_figure ) print("All done!")
def sse(self, number_of_stars): return SSE()
result.add_option("-N", dest="N", type="int", default=10, help="number of stars to calculate <m>. [10]") result.add_option("-m", dest="Mmin", type="float", default=0.15, help="Minimal mass of the IMF in MSun. [0.15MSun]") result.add_option("-M", dest="Mmax", type="float", default=100, help="Maximal mass of the IMF in MSun. [100MSun]") result.add_option("-x", dest="x_imf", type="float", default=-2.35, help="Slope of the IMF. [-2.35]") result.add_option("-v", dest="verbose", action="store_true", default=False, help="verbose output [True]") o, arguments = result.parse_args() t_end = o.t_end | units.Myr dt = o.dt | units.Myr stellar_evolution = SSE() stellar_evolution.commit_parameters() stars = Particles(o.N) Mmin = o.Mmin | units.MSun Mmax = o.Mmax | units.MSun if o.verbose: print("#Selected parameters: ") print("#\tN=", o.N) print("#\tIMF=", o.Mmin, "MSun", o.Mmax, "MSun", o.x_imf) print("#\t t [Myr] \t <m> [MSun] \t\t d<m>/dt [MSun/Myr]") stars.mass = new_salpeter_mass_distribution( o.N, mass_min=Mmin, mass_max=Mmax, alpha=o.x_imf) stars = stellar_evolution.particles.add_particles(stars)
def simulate_small_cluster(number_of_stars, end_time=40 | units.Myr, name_of_the_figure="test-2.svg"): random.seed() salpeter_masses = new_salpeter_mass_distribution(number_of_stars) total_mass = salpeter_masses.sum() convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec) convert_nbody.set_as_default() particles = new_plummer_model(number_of_stars, convert_nbody) gravity = PhiGRAPE(convert_nbody, mode="gpu") gravity.initialize_code() gravity.parameters.timestep_parameter = 0.01 gravity.parameters.initial_timestep_parameter = 0.01 gravity.parameters.epsilon_squared = 0.000001 | units.parsec**2 stellar_evolution = SSE() stellar_evolution.initialize_module_with_default_parameters() #print "setting masses of the stars" particles.radius = 0.0 | units.RSun #comment out to get plummer masses particles.mass = salpeter_masses gravity.particles.add_particles(particles) gravity.initialize_particles(0.0) from_model_to_gravity = particles.new_channel_to(gravity.particles) from_gravity_to_model = gravity.particles.new_channel_to(particles) time = 0.0 | units.Myr particles.savepoint(time) move_particles_to_center_of_mass(particles) kineticEnergy = gravity.kinetic_energy.value_in(units.J) potentialEnergy = gravity.potential_energy.value_in(units.J) ToverV = kineticEnergy / potentialEnergy file.write(str(time.value_in(units.Myr))) file.write(' ') file.write(str(ToverV)) file.write('\n') while time < end_time: time += 0.25 | units.Myr gravity.evolve_model(time) from_gravity_to_model.copy() print "Evolved model to t =", str(time) print "Evolved model to t =", str( convert_nbody.to_nbody(time.value_in(units.Myr) | units.Myr)) kineticEnergy = gravity.kinetic_energy.value_in(units.J) potentialEnergy = gravity.potential_energy.value_in(units.J) ToverV = kineticEnergy / potentialEnergy print "Kin / Pot =", ToverV #print "Particle Mass =", particles[1].mass file.write(str(time.value_in(units.Myr))) file.write(' ') file.write(str(ToverV)) file.write('\n') file.close() if os.path.exists('small.hdf5'): os.remove('small.hdf5') storage = store.StoreHDF("small.hdf5") storage.store(particles) del gravity del stellar_evolution
def simulate_small_cluster(number_of_stars, end_time=40 | units.Myr, name_of_the_figure="test-2.svg"): # numpy.random.seed(1) salpeter_masses = new_salpeter_mass_distribution(number_of_stars) total_mass = salpeter_masses.sum() convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec) particles = new_plummer_model(number_of_stars, convert_nbody) gravity = BHTree(convert_nbody) gravity.initialize_code() # gravity.parameters.set_defaults() # print gravity.parameters.timestep.as_quantity_in(units.Myr) gravity.parameters.timestep = 0.0001 | units.Myr # tiny! gravity.parameters.epsilon_squared \ = (float(number_of_stars)**(-0.333333) | units.parsec) ** 2 stellar_evolution = SSE() stellar_evolution.initialize_module_with_default_parameters() print "setting masses of the stars" particles.radius = 0.0 | units.RSun particles.mass = salpeter_masses print "initializing the particles" stellar_evolution.particles.add_particles(particles) from_stellar_evolution_to_model \ = stellar_evolution.particles.new_channel_to(particles) from_stellar_evolution_to_model.copy_attributes(["mass"]) print "centering the particles" particles.move_to_center() print "scaling particles to viridial equilibrium" particles.scale_to_standard(convert_nbody) gravity.particles.add_particles(particles) from_model_to_gravity = particles.new_channel_to(gravity.particles) from_gravity_to_model = gravity.particles.new_channel_to(particles) gravity.commit_particles() time = 0.0 | units.Myr particles.savepoint(time) total_energy_at_t0 = gravity.kinetic_energy + gravity.potential_energy print "evolving the model until t = " + str(end_time) while time < end_time: time += 0.25 | units.Myr print "Gravity evolve step starting" gravity_evolve = gravity.evolve_model.async(time) print "Stellar evolution step starting" stellar_evolution_evolve = stellar_evolution.evolve_model(time) print "Stellar evolution step done." gravity_evolve.result() print "Gravity evolve step done." from_gravity_to_model.copy() from_stellar_evolution_to_model.copy_attributes(["mass", "radius"]) particles.savepoint(time) from_model_to_gravity.copy_attributes(["mass"]) total_energy_at_this_time \ = gravity.kinetic_energy + gravity.potential_energy print_log(time, gravity, particles, total_energy_at_t0, total_energy_at_this_time) test_results_path = get_path_to_results() output_file = os.path.join(test_results_path, "small.hdf5") if os.path.exists(output_file): os.remove(output_file) storage = store.StoreHDF(output_file) storage.store(particles) gravity.stop() stellar_evolution.stop() plot_particles(particles, name_of_the_figure)