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 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.assertEqual(len(instance.particles), 0) # before creation instance.particles.add_particles(particles[:-1]) instance.commit_particles() instance.evolve_model(1.0 | units.Myr) self.assertEqual(len(instance.particles), 2) # before remove self.assertAlmostEqual(instance.particles.age, 1.0 | units.Myr) instance.particles.remove_particle(particles[0]) self.assertEqual(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.assertEqual(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 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 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 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 test13(self): print("Testing SSE states") stars = Particles(1) stars.mass = 1.0 | units.MSun print("First do everything manually:", end=' ') instance = SSE() self.assertEqual(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.initialize_code() self.assertEqual(instance.get_name_of_current_state(), 'INITIALIZED') instance.commit_parameters() self.assertEqual(instance.get_name_of_current_state(), 'RUN') instance.cleanup_code() self.assertEqual(instance.get_name_of_current_state(), 'END') instance.stop() print("ok") print("initialize_code(), commit_parameters(), " \ "and cleanup_code() should be called automatically:", end=' ') instance = SSE() self.assertEqual(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.parameters.reimers_mass_loss_coefficient = 0.5 self.assertEqual(instance.get_name_of_current_state(), 'INITIALIZED') instance.particles.add_particles(stars) self.assertEqual(instance.get_name_of_current_state(), 'RUN') instance.stop() self.assertEqual(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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 main_function(number_of_stars=1000, end_time=4.0e4 | units.yr, steps=100, number_of_workers=6, animate=True, save_animation=False, escape=False, Q=0.5, D=2.6, filename="default.mp4", use_huayno=False, use_tree=False): """ Simulates a cluster of stars with varying masses. Input: :param number_of_stars: Number of stars to simulate, default: 1000 :param end_time: Total time at which to stop in nbody_system.time units (I think), default 10 | nbody_system.time :param steps: Total number of steps to save, default: 1000 :param number_of_workers: Number of cores/threads to use, does nothing when using Huayno, default: 5 :param animate: Makes an animation of the stars at each step (size depends on star mass), default: True :param save_animation: Saves the animation as mp4 file, default: True :param Q: Kinectic to potential energy fraction (I think) default: 0.5 :param D: Measure of fragmentedness, must be between 1.5 and 3, default 2.6 :param filename: Determines the name of the mp4 file, default: "default.mp4" :param use_huayno: Use alternative Huayno gravity evolver, default: False :return: (array of position arrays at each time step, array of time at each time step) """ start_time = clock_time() particles = new_cluster(number_of_stars=number_of_stars, Q=Q, D=D) total_mass = particles.mass.sum() convert_nbody = nbody_system.nbody_to_si(total_mass, 1.0 | units.parsec) # Initialize gravity can use others for tests, but hermite is used if use_huayno: gravity = Huayno(convert_nbody, number_of_workers=number_of_workers / 2) elif use_tree: gravity = BHTree(convert_nbody, number_of_workers=1, epsilon_squared=0.05 | nbody_system.length**2) else: gravity = Hermite(convert_nbody, number_of_workers=number_of_workers / 2) gravity.parameters.epsilon_squared = 0.05 | nbody_system.length**2 # gravity.parameters.epsilon_squared = 0.15 | nbody_system.length ** 2 # Used to be this gravity.particles.add_particles(particles) from_gravity_to_model = gravity.particles.new_channel_to(particles) # particles.scale_to_standard() Cannot scale to standard if not using nbody_system units # Initialize the Evolution if not use_tree: stellar_evolution = SSE(number_of_workers=number_of_workers / 2) else: stellar_evolution = SSE(number_of_workers=number_of_workers - 1) 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", "luminosity", "temperature"]) # Initial time (note * end_time for correct units) time = 0.0 * end_time # Save initial conditions and make arrays (lists) for each step total_energy_at_t0 = gravity.kinetic_energy + gravity.potential_energy save_positions = [particles.position] save_velocities = [particles.velocity] save_masses = [particles.mass] save_luminosities = [particles.luminosity] save_temperatures = [particles.temperature] times = [time] while time < end_time: time += end_time / steps # Evolve gravity gravity.evolve_model(time) from_gravity_to_model.copy() # Evolve stars stellar_evolution.evolve_model(time) from_gravity_to_model.copy() from_stellar_evolution_to_model.copy_attributes( ["mass", "luminosity", "temperature"]) # Save data save_positions.append(particles.position) save_velocities.append(particles.velocity) save_masses.append(particles.mass) save_luminosities.append(particles.luminosity) save_temperatures.append(particles.temperature) times.append(time) total_energy = gravity.kinetic_energy + gravity.potential_energy if np.abs( (total_energy - total_energy_at_t0) / total_energy_at_t0) > 0.001: print( "Warning! Total energy of the system is changing too significantly!" ) print "Time: %.4g" % time.number total_mass = particles.mass.sum() print total_mass if escape: escaped_stars_3d, escaped_stars_2d = find_escapees(particles) gravity.stop() stellar_evolution.stop() print "It took %.3g seconds clock time" % (clock_time() - start_time) if animate: make_animation(save_positions, save_luminosities, save_temperatures, times, save_animation=save_animation, filename=filename) if escape: return save_positions[-1], save_velocities[-1], save_masses[ -1], escaped_stars_3d, escaped_stars_2d else: return save_positions, save_velocities
filetype, close_file=True, ) if stellar_evolution: print( "Calculating luminosity/temperature for %s old stars..." % (age) ) from amuse.community.sse.interface import SSE se = SSE() se.particles.add_particles(stars) if age > 0 | units.Myr: se.evolve_model(age) stars.luminosity = se.particles.luminosity stars.radius = se.particles.radius se.stop() com = stars.center_of_mass() stars.position -= com if fieldstars: for age in np.array([400, 600, 800, 1600, 3200, 6400]) | units.Myr: fieldstars = new_field_stars( int(len(stars)/3), width=image_width, height=image_width, ) evolve_to_age(fieldstars, age) # TODO: add distance modulus stars.add_particles(fieldstars) if gasfilename:
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)
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_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) # 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() 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) 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_model(time) print "gravity evolve step done" print "stellar evolution step starting" stellar_evolution.evolve_model(time) print "stellar evolution 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)