def continue_evolution(sph_code, dynamics_code, t_end, n_steps, relaxed_giant_output_base_name, do_energy_evolution_plot): print("Loading snapshots...", end=' ') files = os.listdir("snapshots") files.sort() files = files[-4:] print(files) binary = read_set_from_file(os.path.join("snapshots", files[0]), format='amuse') gd_particles = read_set_from_file(os.path.join("snapshots", files[1]), format='amuse') sph_particles = read_set_from_file(os.path.join("snapshots", files[2]), format='amuse') snapshotfile = os.path.join("..", "giant_models", relaxed_giant_output_base_name + "_core.amuse") core_particle = read_set_from_file(snapshotfile, format='amuse') giant_model = StellarModelInSPH( gas_particles = sph_particles, core_particle = gd_particles[0], core_radius = core_particle.radius) view_on_giant = Particle() view_on_giant.position = [0]*3 | units.m view_on_giant.velocity = [0]*3 | units.m / units.s print("\nSetting up {0} to simulate inner binary system".format(dynamics_code.__name__)) binary_system = prepare_binary_system(dynamics_code, binary) print("\nSetting up {0} to simulate giant in SPH".format(sph_code.__name__)) giant_system = prepare_giant_system(sph_code, giant_model, view_on_giant, t_end, n_steps) print("\nEvolving with bridge between", sph_code.__name__, "and", dynamics_code.__name__) evolve_coupled_system(binary_system, giant_system, t_end, n_steps, do_energy_evolution_plot, previous_data = os.path.join("snapshots", files[3])) print("Done")
def test_kepler(N=10000, tend=1.| units.yr,method=0): numpy.random.seed(12345) conv=nbody_system.nbody_to_si(2.| units.MSun, 5.|units.AU) comets=new_plummer_model(N,conv) sun=Particle(mass=1.|units.MSun) sun.position=[0,0,0]|units.AU sun.velocity=[0,0,0]|units.kms comets.mass*=0. code=Kepler(conv,redirection="none") code.set_method(method) code.central_particle.add_particle(sun) code.orbiters.add_particles(comets) a0,eps0=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz) # print code.orbiters.x[0] print orbital_elements_from_binary(code.particles[0:2],constants.G) t1=time.time() code.evolve_model(tend) t2=time.time() print orbital_elements_from_binary(code.particles[0:2],constants.G) # print code.orbiters.x[0] a,eps=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz) da=abs((a-a0)/a0) deps=abs(eps-eps0)/eps0 dev=numpy.where(da > 0.00001)[0] print len(dev) print a0[dev].value_in(units.AU) print eps0[dev] # pyplot.plot(a0[dev].value_in(units.AU),eps0[dev],"ro") # pyplot.plot(a[dev].value_in(units.AU),eps[dev],"g+") print "max da,deps:",da.max(), deps.max() print "time:",t2-t1 # pyplot.show() return t2-t1,da.max(),deps.max()
def test4(self): instance=SPHRay() instance.gas_particles.add_particle( Particle( mass = 1 | (10**10*units.MSun), x = 2 | units.kpc, y = 3 | units.kpc, z = 4 | units.kpc, h_smooth = 0.1 | (units.kpc), rho = 0.5 | ((10**10*units.MSun) /(units.kpc)**3), xion = 0.01, u = 0.2 | (10**5 * units.cm/units.s)**2 ) ) instance.src_particles.add_particle( Particle( luminosity = 1 | 1e48 * units.s**-1, x = 2 | units.m, y = 3 | units.m, z = 4 | units.m, SpcType = 12.3 ) ) instance.commit_particles() self.assertAlmostRelativeEquals(instance.src_particles.luminosity, 1 | 1e48 * units.s**-1, 6) self.assertAlmostRelativeEquals(instance.src_particles.x, 2 | units.m,7) self.assertAlmostRelativeEquals(instance.src_particles.y, 3 | units.m,7) self.assertAlmostRelativeEquals(instance.src_particles.z, 4 | units.m,7) self.assertAlmostRelativeEquals(instance.src_particles.SpcType, 12.3,7) print instance.src_particles instance.stop()
def new_single_star(mass, pos, vel): single_star = Particle() single_star.mass = mass single_star.position = pos single_star.velocity = vel single_star.radius = 1.0 | units.RSun return single_star
def result(self): if self.pickle_file is None: self.retrieve_stellar_structure() else: self.unpickle_stellar_structure() if self.with_core_particle: self.setup_core_parameters() sph_particles = self.convert_to_SPH() if self.do_relax: for result_string in self.relax(sph_particles): print result_string specific_internal_energy, composition, mu = self.interpolate_internal_energy( sph_particles.position.lengths(), do_composition_too = self.do_store_composition ) sph_particles.u = specific_internal_energy if self.do_store_composition: sph_particles.add_vector_attribute("composition", self.species_names) sph_particles.composition = composition sph_particles.mu = mu if self.with_core_particle and self.core_radius: core_particle = Particle() core_particle.mass = self.core_mass core_particle.position = [0.0, 0.0, 0.0] | units.m core_particle.velocity = [0.0, 0.0, 0.0] | units.m / units.s core_particle.radius = self.core_radius return StellarModelInSPH(gas_particles=sph_particles, core_particle=core_particle, core_radius=self.core_radius) return StellarModelInSPH(gas_particles=sph_particles, core_particle=None, core_radius=None)
def test11(self): print "Test that a source is not included when calculating gravity on itself." number_of_sources = 100 mass, length, G = nbody_system.mass, nbody_system.length, nbody_system.G sources = Particles(mass=numpy.ones(number_of_sources)|mass, x=0|length, y=0|length, z=0|length) point = Particle(x=0|length, y=0|length, z=1.0|length) instance = self.new_fastkick_instance() instance.particles.add_particles(sources) potential = instance.get_potential_at_point(0|length, point.x, point.y, point.z) ax, ay, az = instance.get_gravity_at_point(0|length, point.x, point.y, point.z) self.assertAlmostEqual(ax, G * (0 | mass/length**2), 5) self.assertAlmostEqual(ay, G * (0 | mass/length**2), 5) self.assertAlmostRelativeEqual(az, -G*sources.total_mass()/point.z**2, 3) self.assertAlmostRelativeEqual(potential, -G*sources.total_mass()/point.z, 3) point.mass = 1e6 | mass instance.particles.add_particle(point) potential = instance.get_potential_at_point(0|length, point.x, point.y, point.z) ax, ay, az = instance.get_gravity_at_point(0|length, point.x, point.y, point.z) self.assertAlmostEqual(ax, G * (0 | mass/length**2), 5) self.assertAlmostEqual(ay, G * (0 | mass/length**2), 5) self.assertAlmostRelativeEqual(az, -G*sources.total_mass()/point.z**2, 3) self.assertAlmostRelativeEqual(potential, -G*sources.total_mass()/point.z, 3) instance.stop()
def continue_evolution(sph_code, dynamics_code, t_end, n_steps, relaxed_giant_output_base_name, do_energy_evolution_plot): print "Loading snapshots...", files = os.listdir("snapshots") files.sort() files = files[-4:] print files binary = read_set_from_file(os.path.join("snapshots", files[0]), format='amuse') gd_particles = read_set_from_file(os.path.join("snapshots", files[1]), format='amuse') sph_particles = read_set_from_file(os.path.join("snapshots", files[2]), format='amuse') snapshotfile = os.path.join("..", "giant_models", relaxed_giant_output_base_name + "_core.amuse") core_particle = read_set_from_file(snapshotfile, format='amuse') giant_model = StellarModelInSPH( gas_particles = sph_particles, core_particle = gd_particles[0], core_radius = core_particle.radius) view_on_giant = Particle() view_on_giant.position = [0]*3 | units.m view_on_giant.velocity = [0]*3 | units.m / units.s print "\nSetting up {0} to simulate inner binary system".format(dynamics_code.__name__) binary_system = prepare_binary_system(dynamics_code, binary) print "\nSetting up {0} to simulate giant in SPH".format(sph_code.__name__) giant_system = prepare_giant_system(sph_code, giant_model, view_on_giant, t_end, n_steps) print "\nEvolving with bridge between", sph_code.__name__, "and", dynamics_code.__name__ evolve_coupled_system(binary_system, giant_system, t_end, n_steps, do_energy_evolution_plot, previous_data = os.path.join("snapshots", files[3])) print "Done"
def handle_collision(self, primary, secondary, stellar_evolution_code=None, gravity_code=None): primary = self.add_particle_with_internal_structure(primary, stellar_evolution_code=stellar_evolution_code) secondary = self.add_particle_with_internal_structure(secondary, stellar_evolution_code=stellar_evolution_code) merge_product = Particle( key = self.key_for_merge_product(primary, secondary), primary = primary, secondary = secondary ) return self.merge_products.add_particles(merge_product.as_set())
def new_particle_from_model(self, internal_structure, current_age, key=None): tmp_star = Particle(key=key) tmp_star.mass = internal_structure["mass"] tmp_star.radius = internal_structure["radius"] tmp_star.type = "new particle from model" return self.particles.add_particle(tmp_star)
def main(): temperatures_original = [] | units.K luminosities_original = [] | units.LSun temperatures_helium = [] | units.K luminosities_helium = [] | units.LSun star = Particle() star.mass = 12.0 | units.MSun stop_radius = 100 | units.RSun stellar_evolution = MESA() se_star = stellar_evolution.particles.add_particle(star) print("Evolving a", star.mass, "star with", stellar_evolution.__class__.__name__, end=' ') print("until its radius exceeds", stop_radius) while (se_star.radius < stop_radius): se_star.evolve_one_step() temperatures_original.append(se_star.temperature) luminosities_original.append(se_star.luminosity) ###BOOKLISTSTART1### number_of_zones = se_star.get_number_of_zones() composition = se_star.get_chemical_abundance_profiles() index = (composition[0] > 1.0e-9).nonzero()[0][0] # first zone with X > 1.0e-9 print("Creating helium star, from the inner", index, "(out of", str(number_of_zones)+") shells.") helium_star = stellar_evolution.new_particle_from_model(dict( mass = (se_star.get_cumulative_mass_profile() * se_star.mass)[:index], radius = se_star.get_radius_profile()[:index], rho = se_star.get_density_profile()[:index], temperature = se_star.get_temperature_profile()[:index], luminosity = se_star.get_luminosity_profile()[:index], X_H = composition[0][:index], X_He = composition[1][:index] + composition[2][:index], X_C = composition[3][:index], X_N = composition[4][:index], X_O = composition[5][:index], X_Ne = composition[6][:index], X_Mg = composition[7][:index], X_Si = composition[7][:index]*0.0, X_Fe = composition[7][:index]*0.0), 0.0 | units.Myr) ###BOOKLISTSTOP1### print("\nStar properties before helium star evolution:\n", stellar_evolution.particles) for i in range(1000): helium_star.evolve_one_step() temperatures_helium.append(helium_star.temperature) luminosities_helium.append(helium_star.luminosity) print("\nStar properties after helium star evolution:\n", stellar_evolution.particles) stellar_evolution.stop() return temperatures_original, luminosities_original, \ temperatures_helium, luminosities_helium
def test7(self): print "Testing Pikachu states" stars = new_plummer_model(100) black_hole = Particle() black_hole.mass = 1.0 | nbody_system.mass black_hole.radius = 0.0 | nbody_system.length black_hole.position = [0.0, 0.0, 0.0] | nbody_system.length black_hole.velocity = [0.0, 0.0, 0.0] | nbody_system.speed print "First do everything manually:" instance = self.new_instance_of_an_optional_code(Pikachu, **default_options) self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.initialize_code() self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') #~ instance.parameters.rcut_out_star_star = 1.0 | nbody_system.length instance.parameters.timestep = 0.001 | nbody_system.time instance.commit_parameters() self.assertEquals(instance.get_name_of_current_state(), 'EDIT') instance.particles.add_particles(stars) instance.commit_particles() self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.particles.remove_particle(stars[0]) instance.particles.add_particle(black_hole) self.assertEquals(instance.get_name_of_current_state(), 'UPDATE') instance.recommit_particles() self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.evolve_model(0.001 | nbody_system.time) self.assertEquals(instance.get_name_of_current_state(), 'EVOLVED') instance.synchronize_model() self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.cleanup_code() self.assertEquals(instance.get_name_of_current_state(), 'END') instance.stop() print "initialize_code(), commit_parameters(), (re)commit_particles(), " \ "synchronize_model(), and cleanup_code() should be called " \ "automatically before editing parameters, new_particle(), get_xx(), and stop():" instance = self.new_instance_of_an_optional_code(Pikachu, **default_options) self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.parameters.timestep = 0.001 | nbody_system.time self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') instance.particles.add_particles(stars) self.assertEquals(instance.get_name_of_current_state(), 'EDIT') mass = instance.particles[0].mass self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.particles.remove_particle(stars[0]) instance.particles.add_particle(black_hole) self.assertEquals(instance.get_name_of_current_state(), 'UPDATE') mass = instance.particles[0].mass self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.evolve_model(0.001 | nbody_system.time) self.assertEquals(instance.get_name_of_current_state(), 'EVOLVED') mass = instance.particles[0].mass self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.stop() self.assertEquals(instance.get_name_of_current_state(), 'STOPPED')
def __init__(self, potential, particle=None): self.potential = potential if particle is None: particle = Particle() particle.position = [0., 0., 0.] | units.parsec particle.velocity = [0., 0., 0.] | units.kms self.particles = Particles() self.particles.add_particle(particle)
def xtest7(self): instance = self.new_instance_of_an_optional_code(SeBa) instance.parameters.metallicity = 0.03 p = Particle() p.mass = 99.1605930967 | units.MSun p = instance.particles.add_particle(p) instance.evolve_model(614 | units.Myr) print p.stellar_type self.assertEquals(str(p.stellar_type),'Black Hole') self.assertAlmostRelativeEqual(p.mass, 0.9906 | units.MSun, 4)
def xtest7(self): instance = self.new_instance_of_an_optional_code(SeBa) instance.parameters.metallicity = 0.03 p = Particle() p.mass = 99.1605930967 | units.MSun p = instance.particles.add_particle(p) instance.evolve_model(614 | units.Myr) print(p.stellar_type) self.assertEqual(str(p.stellar_type), 'Black Hole') self.assertAlmostRelativeEqual(p.mass, 0.9906 | units.MSun, 4)
def merge_two_stars(primary, secondary): "Merge two colliding stars into one new one" colliders = Particles() colliders.add_particle(primary) colliders.add_particle(secondary) new_particle = Particle() new_particle.mass = colliders.mass.sum() new_particle.position = colliders.center_of_mass() new_particle.velocity = colliders.center_of_mass_velocity() return new_particle
def test2(self): instance = self.new_instance_of_an_optional_code(SeBa) p = Particle() p.mass = 5 | units.MSun p.metallicity = 0.02 p = instance.particles.add_particle(p) instance.evolve_model(130 | units.Myr) print(p) self.assertAlmostRelativeEqual(p.mass, 0.9906 | units.MSun, 4)
def set_up_outer_star(inner_binary_mass): semimajor_axis = triple_parameters["a_out"] eccentricity = triple_parameters["eccentricity_out"] print " Initializing outer star" giant = Particle() giant.mass = triple_parameters["mass_out"] giant.position = semimajor_axis * (1 + eccentricity) * ([1, 0, 0] | units.none) giant.velocity = get_relative_velocity_at_apastron( giant.mass + inner_binary_mass, semimajor_axis, eccentricity) * ([0, 1, 0] | units.none) return giant
def set_up_outer_star(inner_binary_mass): semimajor_axis = 1.22726535008 | units.AU eccentricity = 0.15 inclination = math.radians(9.0) print " Initializing outer star" giant = Particle() giant.mass = 5.5 | units.MSun giant.position = semimajor_axis * ([math.cos(inclination), 0, math.sin(inclination)] | units.none) giant.velocity = get_relative_velocity(giant.mass + inner_binary_mass, semimajor_axis, eccentricity) * ([0, 1, 0] | units.none) return giant
def set_up_outer_star(inner_binary_mass): semimajor_axis = 1.22726535008 | units.AU eccentricity = 0.15 inclination = math.radians(9.0) print(" Initializing outer star") giant = Particle() giant.mass = 5.5 | units.MSun giant.position = semimajor_axis * ([math.cos(inclination), 0, math.sin(inclination)] | units.none) giant.velocity = get_relative_velocity(giant.mass + inner_binary_mass, semimajor_axis, eccentricity) * ([0, 1, 0] | units.none) return giant
def test2(self): instance = self.new_instance_of_an_optional_code(SeBa) p = Particle() p.mass = 5 | units.MSun p.metallicity = 0.02 p = instance.particles.add_particle(p) instance.evolve_model(130 | units.Myr) print p self.assertAlmostRelativeEqual(p.mass, 0.9906 | units.MSun, 4)
def test1(self): print "Testing FastKick (SI)" sun = Particle() sun.mass = 1.0|units.MSun sun.position = [0, 0, 0] | units.m convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) fastkick = self.new_fastkick_instance(convert_nbody) fastkick.particles.add_particle(sun) ax, ay, az = fastkick.get_gravity_at_point(0|units.AU, 1|units.AU, 0|units.AU, 0|units.AU) fastkick.stop() self.assertAlmostRelativeEqual(ax, -4*math.pi**2 | units.AU / units.yr**2, 3) self.assertAlmostRelativeEqual(ay, 0 | units.m * units.s**-2, 6) self.assertAlmostRelativeEqual(az, 0 | units.m * units.s**-2, 6)
def setup_system(): """ Galacitic center potential and Arches cluster position from Kruijssen 2014 """ potential = static_potentials.Galactic_Center_Potential_Kruijssen() cluster = Particle() # At time 2.05 in KDL15 cluster.position = [-17.55767, -53.26560, -9.39921] | units.parsec cluster.velocity = [-187.68008, 80.45276, 33.96556] | units.kms cluster.position += coordinate_correction return potential, cluster
def make_binary_star(mprim, msec, semimajor_axis, eccentricity): double_star = Particle() double_star.is_binary = True double_star.mass = mprim + msec double_star.semimajor_axis = semimajor_axis double_star.eccentricity = eccentricity period = (2 * numpy.pi * (semimajor_axis * semimajor_axis * semimajor_axis / (constants.G * double_star.mass)).sqrt()) print("Period =", period.as_string_in(units.yr)) stars = new_binary_from_orbital_elements(mprim, msec, semimajor_axis, eccentricity, G=constants.G) stars.is_binary = False double_star.child1 = stars[0] double_star.child1.name = "primary" double_star.child2 = stars[1] double_star.child2.name = "secondary" for star in stars: star.radius = (star.mass.value_in(units.MSun)**0.8) | units.RSun return double_star, stars
def new_system(star_mass=1 | units.MSun, star_radius=1 | units.RSun, disk_minimum_radius=0.05 | units.AU, disk_maximum_radius=10 | units.AU, disk_mass=20 | MEarth, accurancy=0.0001, planet_density=3 | units.g / units.cm**3, rng=None, kepler=None): central_particle = Particle() central_particle.mass = star_mass central_particle.position = (0, 0, 0) | units.AU central_particle.velocity = (0, 0, 0) | units.kms central_particle.radius = star_radius central_particle.name = "star" central_particle.type = "star" central_particle.id = 0 if rng is None: rng = numpy.random converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) if kepler is None: kepler = Kepler(converter) kepler.initialize_code() m, r, f = new_planet_distribution(disk_minimum_radius, disk_maximum_radius, disk_mass, accurancy) planets = make_planets(central_particle, m, r, density=planet_density, phi=0, theta=None, kepler=kepler, rng=rng) planets.name = "planet" planets.type = "planet" for i in range(len(planets)): planets[i].id = i central_particle.planets = planets kepler.stop() p = Particles() p.add_particle(central_particle) return p
def create_particles(): star = Particle() star.mass = 3.0 | units.MSun stellar_evolution = EVtwin() se_star = stellar_evolution.particles.add_particle(star) print("Evolving", star.mass, "star with", stellar_evolution.__class__.__name__, "up to", 100 | units.Myr) stellar_evolution.evolve_model(100 | units.Myr) print("Creating SPH particles from the (1D) stellar evolution model") sph_particles = convert_stellar_model_to_SPH(se_star, 1000).gas_particles stellar_evolution.stop() return sph_particles
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 slowtest5(self): print "Test convert_SPH_to_stellar_model result in EVtwin" stellar_evolution = EVtwin() stellar_evolution.parameters.verbosity = True stellar_evolution.particles.add_particle( Particle(mass=1.0 | units.MSun)) # reference particle stellar_evolution.evolve_model(100.0 | units.Myr) model = convert_SPH_to_stellar_model( self.new_particles()) # model is from center to surface stellar_evolution.new_particle_from_model(model, 0.0 | units.Myr) print stellar_evolution.particles self.assertAlmostEqual(stellar_evolution.particles.age, [100.0, 0.0] | units.Myr, 1) stellar_evolution.evolve_model(200.0 | units.Myr) print stellar_evolution.particles self.assertAlmostEqual(stellar_evolution.particles.age, [200.0, 100.0] | units.Myr, 1) self.assertAlmostRelativeEqual( stellar_evolution.particles[0].temperature, stellar_evolution.particles[1].temperature, 2) self.assertAlmostRelativeEqual( stellar_evolution.particles[0].luminosity, stellar_evolution.particles[1].luminosity, 2) stellar_evolution.stop()
def test18(self): print("MOSSE validation") mosse_src_path = os.path.join(os.path.dirname(sys.modules[MOSSE.__module__].__file__), 'src') if not os.path.exists(os.path.join(mosse_src_path, "evolve.in")): self.skip("Not in a source release") instance = MOSSE() 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, "mosse")], 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 structure_from_star(mass, age): stellar_evolution = EVtwin() star = stellar_evolution.particles.add_particle(Particle(mass=mass)) star.evolve_for(age) radius_profile = star.get_radius_profile() density_profile = star.get_density_profile() if hasattr(star, "get_mass_profile"): mass_profile = star.get_mass_profile() * star.mass else: radii_cubed = radius_profile**3 radii_cubed.prepend(0 | units.m**3) mass_profile = ( (4.0 / 3.0 * numpy.pi) * density_profile * (radii_cubed[1:] - radii_cubed[:-1]) ) print("Derived mass profile from density and radius.") return dict( radius=radius_profile.as_quantity_in(units.RSun), density=density_profile, mass=mass_profile, temperature=star.get_temperature_profile(), pressure=star.get_pressure_profile(), composition=star.get_chemical_abundance_profiles(), species_names=star.get_names_of_species() )
def xtest18(self): print "Testing EVtwin calculate_core_mass" instance = EVtwin()#redirection="none") star = instance.particles.add_particle(Particle(mass=1|units.MSun)) instance.evolve_model(0.4|units.Gyr) # VERY short, for test speed up central_hydrogen_abundance = star.get_chemical_abundance_profiles()[0][0] self.assertTrue(central_hydrogen_abundance < 0.68) # some hydrogen is burned self.assertTrue(central_hydrogen_abundance > 0.67) # ... but not that much yet self.assertEqual(star.calculate_core_mass(core_H_abundance_limit=0.67), 0 | units.MSun) self.assertAlmostEqual(star.calculate_core_mass(core_H_abundance_limit=0.71), 1 | units.MSun, 1) # For test speed up, we use a weird core_H_abundance_limit to define the "hydrogen exhausted core" limit = 0.68 expected_core_mass = 0.0123182798542 | units.MSun self.assertAlmostEqual(star.calculate_core_mass(core_H_abundance_limit=limit), expected_core_mass, 3) species_names = star.get_names_of_species() self.assertEquals(species_names, ['h1', 'he4', 'c12', 'n14', 'o16', 'ne20', 'mg24', 'si28', 'fe56']) h1_core_mass = star.calculate_core_mass(species=["h1"], core_H_abundance_limit=limit) he4_core_mass = star.calculate_core_mass(species=["he4"], core_H_abundance_limit=limit) c12_core_mass = star.calculate_core_mass(species=["c12"], core_H_abundance_limit=limit) n14_core_mass = star.calculate_core_mass(species=["n14"], core_H_abundance_limit=limit) o16_core_mass = star.calculate_core_mass(species=["o16"], core_H_abundance_limit=limit) ne20_core_mass = star.calculate_core_mass(species=["ne20"], core_H_abundance_limit=limit) mg24_core_mass = star.calculate_core_mass(species=["mg24"], core_H_abundance_limit=limit) si28_core_mass = star.calculate_core_mass(species=["si28"], core_H_abundance_limit=limit) fe56_core_mass = star.calculate_core_mass(species=["fe56"], core_H_abundance_limit=limit) metal_core_mass = star.calculate_core_mass(species=["c12", "n14", "o16", "ne20", "mg24", "si28", "fe56"], core_H_abundance_limit=limit) instance.stop() self.assertAlmostRelativeEqual(h1_core_mass, expected_core_mass*0.68, 2) self.assertAlmostRelativeEqual(he4_core_mass, expected_core_mass*0.30, 2) self.assertAlmostRelativeEqual(metal_core_mass, expected_core_mass*0.02, 1) self.assertAlmostRelativeEqual(expected_core_mass, he4_core_mass + metal_core_mass + h1_core_mass, 7) self.assertAlmostRelativeEqual(metal_core_mass, c12_core_mass + n14_core_mass + o16_core_mass + ne20_core_mass + mg24_core_mass + si28_core_mass + fe56_core_mass, 7)
def get_orbital_elements_from_binary(binary, G=nbody_system.G): """ Function that computes orbital elements from given two-particle set. Elements are computed for the second particle in this set and the return values are: mass1, mass2, semimajor axis, eccentricity, cosine of true anomaly, cosine of inclination, cosine of the longitude of the ascending node and the cosine of the argument of pericenter. In case of a perfectly circular orbit the true anomaly and argument of pericenter cannot be determined; in this case the return values are 1.0 for both cosines. """ primaries = Particles() secondaries = Particles() if len(binary) > 2: raise Exception("expects binary or single part") elif len(binary) == 2: primaries.add_particle(binary[0]) secondaries.add_particle(binary[1]) else: # FIXME: in case of one particle, what do we calculate the orbit of? # The method below is what was default before. primaries.add_particle(binary[0]) primaries[0].position *= 0 primaries[0].velocity *= 0 secondaries.add_particle(Particle()) secondaries[0].mass = 0 * primaries[0].mass secondaries[0].position = binary.position secondaries[0].velocity = binary.velocity (mass1, mass2, semimajor_axis, eccentricity, true_anomaly, inclination, long_asc_node, arg_per) = get_orbital_elements_from_binaries(primaries, secondaries, G=G) return (mass1[0], mass2[0], semimajor_axis[0], eccentricity[0], true_anomaly[0], inclination[0], long_asc_node[0], arg_per[0])
def test1(self): print("Testing FastKick (SI)") sun = Particle() sun.mass = 1.0 | units.MSun sun.position = [0, 0, 0] | units.m convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) fastkick = self.new_fastkick_instance(convert_nbody) fastkick.particles.add_particle(sun) ax, ay, az = fastkick.get_gravity_at_point(0 | units.AU, 1 | units.AU, 0 | units.AU, 0 | units.AU) fastkick.stop() self.assertAlmostRelativeEqual( ax, -4 * math.pi**2 | units.AU / units.yr**2, 3) self.assertAlmostRelativeEqual(ay, 0 | units.m * units.s**-2, 6) self.assertAlmostRelativeEqual(az, 0 | units.m * units.s**-2, 6)
def convert_star_to_hydro_model(M, t_end): stellar_evolution = EVtwin() star = stellar_evolution.particles.add_particle(Particle(mass=M)) stellar_evolution.evolve_model(t_end) Ngas = 10000 sph_particles = convert_stellar_model_to_SPH(star, Ngas).gas_particles stellar_evolution.stop() return sph_particles
def set_up_outer_star(inner_binary_mass): orbital_period = 4020.0 | units.day mass = 1.3 | units.MSun semimajor_axis = (((constants.G * (inner_binary_mass + mass) * orbital_period**2) / (4 * numpy.pi**2))**(1.0 / 3.0)).as_quantity_in( units.RSun) print " Initializing outer star" print " Semimajor axis outer binary:", semimajor_axis giant = Particle() giant.mass = mass giant.position = semimajor_axis * ([1, 0, 0] | units.none) giant.velocity = get_relative_velocity(giant.mass + inner_binary_mass, semimajor_axis, 0) * ([0, 1, 0] | units.none) return giant
def create_particles(): star = Particle() star.mass = 3.0 | units.MSun stellar_evolution = EVtwin() se_star = stellar_evolution.particles.add_particle(star) print("Evolving", star.mass, "star with", stellar_evolution.__class__.__name__, "up to", 100 | units.Myr) stellar_evolution.evolve_model(100 | units.Myr) print("Creating SPH particles from the (1D) stellar evolution model") sph_particles = convert_stellar_model_to_SPH( se_star, 1000 ).gas_particles stellar_evolution.stop() return sph_particles
def brunt_vaisala_frequency_squared_profile(mass, age): stellar_evolution = MESA() star = stellar_evolution.particles.add_particle(Particle(mass=mass)) star.evolve_for(age) radius_profile = star.get_radius_profile() brunt_profile = star.get_brunt_vaisala_frequency_squared_profile() stellar_evolution.stop() return radius_profile.as_quantity_in(units.RSun), brunt_profile
def test12(self): N = 1000 Lstar = 100 | units.LSun boxsize = 10 | units.parsec rho = 1.0 | (units.amu / units.cm**3) t_end = 0.01 | units.Myr internal_energy = (9. | units.kms)**2 source = Particle() source.position = (0, 0, 0) | units.parsec source.flux = Lstar / (20. | units.eV) source.rho = rho source.xion = 0.0 source.u = internal_energy ism = ism_cube(N, boxsize / 2., rho, internal_energy).result ism.rho = rho ism.flux = 0. | units.s**-1 ism.xion = source.xion radiative = SimpleX() radiative.parameters.box_size = 1.001 * boxsize radiative.parameters.timestep = 0.001 | units.Myr radiative.particles.add_particle(source) radiative.particles.add_particles(ism) radiative.evolve_model(t_end) self.assertAlmostRelativeEquals(0.0750819123073, radiative.particles.xion.mean(), 1) radiative.stop()
def test3(self): particles = Particles(2) particles.add_attribute_domain('a') particles.add_attribute_domain('b') particles.a.foo = 1 | units.m particles.b.foo = 2 | units.kg particles.foo = 3 | units.s particles.a.add_particle(Particle(foo=2 | units.m)) self.assertAlmostRelativeEqual(particles.a.foo, [1, 1, 2] | units.m) self.assertAlmostRelativeEqual(particles.b.foo, [2, 2, 0] | units.kg) self.assertAlmostRelativeEqual(particles.foo, [3, 3, 0] | units.s) particles.add_particle(Particle(foo=2 | units.s)) self.assertAlmostRelativeEqual(particles.a.foo, [1, 1, 2, 0] | units.m) self.assertAlmostRelativeEqual(particles.b.foo, [2, 2, 0, 0] | units.kg) self.assertAlmostRelativeEqual(particles.foo, [3, 3, 0, 2] | units.s)
def get_moons_for_planet(planet, delta_JD=0. | units.day): """ The Earth's moon as for JD = 2457099.500000000 = A.D. 2015-Mar-18 00:00:00.0000 (CT) https://ssd.jpl.nasa.gov/?sat_elem """ data = numpy.array([tuple(entry) for entry in _lunar_data], dtype=[('planet_name', 'S10'), ('name', 'S10'), ('mass', '<f8'), ('radius', '<f8'), ('semimajor_axis', '<f8'), ('eccentricity', '<f8'), ('argument_of_peri', '<f8'), ('mean_anomaly', '<f8'), ('inclination', '<f8'), ('longitude_oan', '<f8')]) moon_data = data[data['planet_name'] == planet.name.encode('UTF-8')] print("Planet=", planet.name, "moon=", moon_data["name"]) moons = Particles() if len(moon_data["name"]): print(len(moon_data["name"])) for moon in moon_data: #Ignore the moon for now, because it's complicated if planet.name == "EarthMoon": planet.mass -= moon["mass"] * 1.e+16 | units.kg planet.name = "Earth" #print moon r, v = get_position(planet.mass, moon["mass"] * 1.e+16 | units.kg, moon["eccentricity"], moon["semimajor_axis"] | units.km, numpy.deg2rad(moon["mean_anomaly"]), numpy.deg2rad(moon["inclination"]), numpy.deg2rad(moon["longitude_oan"]), numpy.deg2rad(moon["argument_of_peri"]), delta_t=delta_JD) single_moon = Particle() single_moon.type = "moon" single_moon.name = moon["name"] single_moon.mass = moon["mass"] * 1.e+16 | units.kg single_moon.hostname = moon["planet_name"] single_moon.radius = moon["radius"] | units.km single_moon.position = r single_moon.position += planet.position single_moon.velocity = v single_moon.velocity += planet.velocity moons.add_particle(single_moon) return moons
def nbody_integrator(Ncl, mcl, rcl, t_end, n_steps, escape_velocity_fraction, R): converter = nbody_system.nbody_to_si(mcl, rcl) bodies = new_plummer_model(Ncl, convert_nbody=converter) #estimate of milky way mass by "Mass models of the Milky Way", McMillan blackhole_mass = 1.26e12 | units.MSun blackhole = Particle(mass=blackhole_mass) blackhole.position = [0, 0, 0] | units.m cluster_velocity = [0, 0, 0] | units.m / units.s cluster_position = [0, 0, 0] | units.parsec cluster_position[0] = R G_si = converter.to_si(nbody_system.G) escape_v = (2 * G_si * blackhole_mass / R).sqrt().as_quantity_in(units.m / units.s) V = escape_v * escape_velocity_fraction cluster_velocity[1] = V bodies.move_to_center() bodies.velocity += cluster_velocity bodies.position += cluster_position bodies.add_particle(blackhole) gravity = BHTree(converter) gravity.particles.add_particles(bodies) channel_from_gravity_to_framework = gravity.particles.\ new_channel_to(bodies) time = zero dt = t_end / float(n_steps) x = 0 base_path = "encounter_plots/"+str(R.value_in(units.parsec))+"_"+\ str(escape_velocity_fraction)+"_" while time < t_end: plot_cluster(bodies, base_path + str(x), time, rcl, V) time += dt gravity.evolve_model(time) channel_from_gravity_to_framework.copy() x += 1 plot_cluster(bodies, base_path + str(x), time, rcl, V) gravity.stop() return V, bodies
def test10(self): """ Test supernova stopping condition """ instance = self.new_instance_of_an_optional_code(SeBa) instance.stopping_conditions.supernova_detection.enable() p = Particle() p.mass = 10 | units.MSun p.metallicity = 0.02 p = instance.particles.add_particle(p) instance.set_supernova_kick_velocity(0.0|units.kms) instance.evolve_model(30 | units.Myr) self.assertEquals(instance.stopping_conditions.supernova_detection.is_set(), True) self.assertEquals(instance.stopping_conditions.supernova_detection.particles(0)[0].key, p.key) self.assertAlmostRelativeEqual(p.age, 27.35866 | units.Myr, 4) self.assertAlmostRelativeEqual(p.mass, 1.22632 | units.MSun, 4) self.assertAlmostRelativeEqual(p.natal_kick_velocity, [0,0,0] | units.kms, 4)
def nbody_integrator(Ncl, mcl, rcl, t_end, n_steps, escape_velocity_fraction, R): converter = nbody_system.nbody_to_si(mcl, rcl) bodies = new_plummer_model(Ncl, convert_nbody=converter) #estimate of milky way mass by "Mass models of the Milky Way", McMillan blackhole_mass = 1.26e12 | units.MSun blackhole = Particle(mass=blackhole_mass) blackhole.position = [0,0,0] | units.m cluster_velocity = [0,0,0] | units.m / units.s cluster_position = [0,0,0] | units.parsec cluster_position[0] = R G_si = converter.to_si(nbody_system.G) escape_v = (2*G_si*blackhole_mass/R).sqrt().as_quantity_in(units.m/units.s) V = escape_v * escape_velocity_fraction cluster_velocity[1] = V bodies.move_to_center() bodies.velocity += cluster_velocity bodies.position += cluster_position bodies.add_particle(blackhole) gravity = BHTree(converter) gravity.particles.add_particles(bodies) channel_from_gravity_to_framework = gravity.particles.\ new_channel_to(bodies) time = zero dt = t_end / float(n_steps) x = 0 base_path = "encounter_plots/"+str(R.value_in(units.parsec))+"_"+\ str(escape_velocity_fraction)+"_" while time < t_end: plot_cluster(bodies, base_path+str(x),time, rcl, V) time += dt gravity.evolve_model(time) channel_from_gravity_to_framework.copy() x+=1 plot_cluster(bodies, base_path+str(x),time, rcl, V) gravity.stop() return V, bodies
def old_new_solar_system(): """ Create initial conditions describing the solar system. Returns a single particle set containing the sun, planets and Pluto. The model is centered at the origin (center-of-mass(-velocity) coordinates). Defined attributes: name, mass, radius, x, y, z, vx, vy, vz """ sun = Particle() sun.name = 'SUN' sun.mass = 1.0 | units.MSun sun.radius = 1.0 | units.RSun planets = _planets_only() particles = Particles() particles.add_particle(sun) particles.add_particles(planets) particles.move_to_center() return particles
def test12(self): N = 1000 Lstar=100|units.LSun boxsize=10|units.parsec rho=1.0 | (units.amu/units.cm**3) t_end=0.01 |units.Myr internal_energy = (9. |units.kms)**2 source=Particle() source.position = (0, 0, 0) |units.parsec source.flux = Lstar/(20. | units.eV) source.rho = rho source.xion = 0.0 source.u = internal_energy ism = ism_cube(N, boxsize/2., rho, internal_energy).result ism.rho = rho ism.flux = 0. | units.s**-1 ism.xion = source.xion radiative = SimpleX() radiative.parameters.box_size=1.001*boxsize radiative.parameters.timestep=0.001 | units.Myr radiative.particles.add_particle(source) radiative.particles.add_particles(ism) radiative.evolve_model(t_end) self.assertAlmostRelativeEquals( 0.0750819123073, radiative.particles.xion.mean(), 1) radiative.stop()
def get_moons_for_planet(planet, delta_JD=0.|units.day): """ The Earth's moon as for JD = 2457099.500000000 = A.D. 2015-Mar-18 00:00:00.0000 (CT) https://ssd.jpl.nasa.gov/?sat_elem """ data = numpy.array([tuple(entry) for entry in _lunar_data], dtype=[('planet_name','S10'), ('name','S10'), ('mass','<f8'), ('radius','<f8'), ('semimajor_axis','<f8'), ('eccentricity','<f8'), ('argument_of_peri','<f8'), ('mean_anomaly','<f8'), ('inclination','<f8'), ('longitude_oan','<f8')]) moon_data = data[data['planet_name']==planet.name] print "Planet=", planet.name, "moon=", moon_data["name"] moons = Particles() if len(moon_data["name"]): print len(moon_data["name"]) for moon in moon_data: #print moon r, v = get_position(planet.mass, moon["mass"] * 1.e+16 | units.kg, moon["eccentricity"], moon["semimajor_axis"]|units.km, numpy.deg2rad(moon["mean_anomaly"]), numpy.deg2rad(moon["inclination"]), numpy.deg2rad(moon["longitude_oan"]), numpy.deg2rad(moon["argument_of_peri"]), delta_t=delta_JD) single_moon = Particle() single_moon.type = "moon" single_moon.name = moon["name"] single_moon.mass = moon["mass"] * 1.e+16 | units.kg single_moon.hostname = moon["planet_name"] single_moon.radius = moon["radius"] | units.km single_moon.position = r single_moon.position += planet.position single_moon.velocity = v single_moon.velocity += planet.velocity moons.add_particle(single_moon) return moons
def new_system( star_mass = 1|units.MSun, star_radius = 1|units.RSun, disk_minumum_radius = 0.05 | units.AU, disk_maximum_radius = 10 | units.AU, disk_mass = 20 | MEarth, accurancy = 0.0001, planet_density = 3 | units.g/units.cm**3, rng = None, kepler = None): central_particle = Particle() central_particle.mass = star_mass central_particle.position = (0,0,0) | units.AU central_particle.velocity = (0,0,0) | units.kms central_particle.radius = star_radius if rng is None: rng = numpy.random converter = nbody_system.nbody_to_si(1|units.MSun, 1 | units.AU) if kepler is None: kepler = Kepler(converter) kepler.initialize_code() m, r, f = new_planet_distribution( disk_minumum_radius, disk_maximum_radius, disk_mass, accurancy ) planets = make_planets( central_particle, m, r, density = planet_density, phi = 0, theta = None, kepler = kepler, rng = rng ) central_particle.planets = planets kepler.stop() p = Particles() p.add_particle(central_particle) return p
def new_particle_from_cluster_core( particles, unit_converter=None, density_weighting_power=2, cm=None, reuse_hop=False, hop=HopContainer() ): """ Uses Hop to find the density centre (core) of a particle distribution and stores the properties of this core on a particle: position, velocity, (core) radius and (core) density. Particles are assigned weights that depend on the density (as determined by Hop) to a certain power. The default weighting power is 2, which is most commonly used. Set density_weighting_power to 1 in order to get the original weighting of Casertano & Hut (1985, ApJ, 298, 80). :argument unit_converter: Required if the particles are in SI units :argument density_weighting_power: Particle properties are weighted by density to this power """ if isinstance(hop, HopContainer): hop.initialize(unit_converter) hop = hop.code in_hop = hop.particles.add_particles(particles) hop.parameters.density_method = 2 hop.parameters.number_of_neighbors_for_local_density = 7 hop.calculate_densities() density = in_hop.density.copy() if not reuse_hop: hop.stop() weights = (density ** density_weighting_power).reshape((-1, 1)) # Reshape makes sure that density can be multiplied with vectors, e.g. position result = Particle() result.density = density.amax() total_weight = weights.sum() if cm is None: result.position = (weights * particles.position).sum(axis=0) / total_weight else: result.position = cm result.velocity = (weights * particles.velocity).sum(axis=0) / total_weight result.radius = (weights.flatten() * (particles.position - result.position).lengths()).sum() / total_weight return result
def new_particle_from_model(self, internal_structure, current_age, key=None): tmp_star = Particle(key=key) tmp_star.mass = internal_structure["mass"] tmp_star.radius = internal_structure["radius"] tmp_star.type = "new particle from model" | units.string return self.particles.add_particle(tmp_star)
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, dtse_fac): import random from amuse.ext.solarsystem import get_position print "Initial masses:", M1, M2, M3 t_stellar = 4.0|units.Myr triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Masses at time T:", M1, M2, M3 # Inner binary tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print 'ain_0 =', ain_0 print 'M1+M2 =', M1+M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt = 0.1*Pin_0 ma = 180 inc = 30 aop = 180 lon = 0 r, v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary r, v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) gravity = Hermite(converter) gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() time = 0.0 | t_end.unit ts = t_stellar + time ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout dt_diag = t_end/float(nsteps) t_diag = dt_diag t = [time.value_in(units.Myr)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] ain = ain_0 def advance_stellar(ts, dt): E0 = gravity.kinetic_energy + gravity.potential_energy ts += dt stellar.evolve_model(ts) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return ts, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: Pin = orbital_period(ain, triple[0].mass+triple[1].mass) dt = dtse_fac*Pin dt *= random.random() if scheme == 1: ts, dE_se = advance_stellar(ts, dt) time = advance_gravity(time, dt) elif scheme == 2: time = advance_gravity(time, dt) ts, dE_se = advance_stellar(ts, dt) else: dE_se = zero #ts, dE_se = advance_stellar(ts, dt/2) time = advance_gravity(time, dt) #ts, dE = advance_stellar(ts, dt/2) #dE_se += dE if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time, print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", print "E= ", Etot, "Q= ", Ekin/Epot, print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", (4|units.Myr) + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.Myr)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break gravity.stop() stellar.stop() return t, smai, ecci, smao, ecco
def get_sun_and_planets(delta_JD=0.|units.day): """ eight planets of the Solar System as for JD = 2457099.500000000 = A.D. 2015-Mar-18 00:00:00.0000 (CT) http://ssd.jpl.nasa.gov/horizons.cgi """ planets = Particles(8) # mass planets.mass = [3.302e23, 48.685e23, 5.97219e24, 6.4185e23, 1898.13e24, 5.68319e26, 86.8103e24, 102.41e24] | units.kg # eccentricity planets_ecc = [2.056263501026885E-01, 6.756759719005901E-03, 1.715483324953308E-02, 9.347121362500883E-02, 4.877287772914470E-02, 5.429934603664216E-02, 4.911406962716518E-02, 8.494660388602767E-03] # semi-major axis planets_semi = [3.870989725156447E-01, 7.233252880006816E-01, 1.000816989613834E+00, 1.523624142457679E+00, 5.203543088590996E+00, 9.547316304899041E+00, 1.915982879739036E+01, 2.997013749028780E+01] | units.AU # mean anomaly [degrees] planets_mean_anomaly = [2.256667460183225E+02, 3.096834722926926E+02, 6.970055236286768E+01, 5.013506750245609E+01, 1.213203242081277E+02, 1.423311616732398E+02, 2.079860620353052E+02, 2.712246916734600E+02] planets_mean_anomaly = numpy.array(planets_mean_anomaly) * pi_over_180 # inclination [IN degrees] planets_inclination = [7.004026765179669E+00, 3.394480103844425E+00, 3.563477431351056E-03, 1.848403408106458E+00, 1.303457729562742E+00, 2.488017444885577E+00, 7.728000142736371E-01, 1.767720502209091E+00] planets_inclination = numpy.array(planets_inclination) * pi_over_180 # Longitude of Ascending Node [OM degrees] planets_longitude = [4.831163083479358E+01, 7.663982595051040E+01, 1.775515437672556E+02, 4.951282677064384E+01, 1.005036717671826E+02, 1.135683875842263E+02, 7.388411509910506E+01, 1.317497218434830E+02] planets_longitude = numpy.array(planets_longitude) * pi_over_180 # Argument of Perihelion [W degrees] planets_argument = [2.916964171964058E+01, 5.469102797401222E+01, 2.877495001117996E+02, 2.865420083537150E+02, 2.740725976811202E+02, 3.398666856578898E+02, 9.666856264946740E+01, 2.951871807292030E+02] planets_argument = numpy.array(planets_argument) * pi_over_180 planets.name = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Satrun', 'Uranus', 'Neptune'] ### to compare with JPL, mass of the Sun needs to be rescaled #mg_nasa = 1.32712440018e20 | (units.m**3 / units.s**2) #g_nasa = 6.67259e-11 | (units.m**3 / units.kg / units.s**2) #ms = mg_nasa / g_nasa sun = Particle() sun.name = 'Sun' #sun.mass = ms sun.mass = 1.0 | units.MSun sun.position = [0.,0.,0.] | units.AU sun.velocity = [0.,0.,0.] | units.kms # get the position and velocity vectors relative to sun # by evolving in Kepler for i,ecc_i in enumerate(planets_ecc): r, v = get_position(sun.mass, planets[i].mass, planets_ecc[i], planets_semi[i], planets_mean_anomaly[i], planets_inclination[i], planets_longitude[i], planets_argument[i], delta_t=delta_JD) planets[i].position = r planets[i].velocity = v return sun, planets
def xtest2(self): print "Testing FallbackStellarEvolution: evolve tests" # results of original code (not really check the numbers, tests have been relaxed because # different timestepping of evolve_model and evolve_one_step) results=dict() results["10.0 MSun"]=dict(sse_age=3644655.52487 | units.yr, sse_mass=9.99289747724 | units.MSun, sse_rad=4.24764389443 | units.RSun, sse_L=5993.72678228 | units.LSun, evtwin_age=2999999.99732 | units.yr, evtwin_mass=9.99832250931 | units.MSun, evtwin_rad=4.1727904434 | units.RSun, evtwin_L=6175.5214329 | units.LSun) results["20.0 MSun"]=dict(sse_age= 2609167.84395| units.yr, sse_mass= 19.8895071502| units.MSun, sse_rad=7.07713598137| units.RSun, sse_L=51232.436257| units.LSun, evtwin_age= 2999999.99792| units.yr, evtwin_mass=19.877338008| units.MSun, evtwin_rad=6.77369109826| units.RSun, evtwin_L= 54123.7589452| units.LSun) results["40.0 MSun"]=dict(sse_age= 2627093.59096| units.yr, sse_mass=38.3702723816| units.MSun, sse_rad=13.6137662257 | units.RSun, sse_L=303498.877464 | units.LSun, evtwin_age= 2999999.99923| units.yr, evtwin_mass=37.0862227121 | units.MSun, evtwin_rad= 13.5982316053| units.RSun, evtwin_L=320099.608846| units.LSun) for m in [40.]| units.MSun:#,20.,10.] | units.MSun: instance = FallbackStellarEvolution() instance._main_se.parameters.max_age_stop_condition=3.| units.Myr star = Particle(1) star.mass = m star = instance.particles.add_particle(star) instance.commit_particles() while instance.ActiveModel[star].__class__.__name__=="EVtwin": instance.evolve_model() print "%s\t%s\t%s\t%s\t%s\t%s" % (star.age, star.mass, star.radius, star.luminosity, star.stellar_type, instance.ActiveModel[star].__class__.__name__) self.assertAlmostRelativeEqual(results[str(m)]["sse_age"],instance._FBTimeseries[star].particles[0].SSEAgeAtSwitch,7) self.assertAlmostRelativeEqual(results[str(m)]["sse_mass"],star.mass,7) self.assertAlmostRelativeEqual(results[str(m)]["sse_rad"],star.radius,7) self.assertAlmostRelativeEqual(results[str(m)]["sse_L"],star.luminosity,7) star=instance._main_se.particles[0] self.assertAlmostRelativeEqual(results[str(m)]["evtwin_age"],star.age,7) self.assertAlmostRelativeEqual(results[str(m)]["evtwin_mass"],star.mass,2) self.assertAlmostRelativeEqual(results[str(m)]["evtwin_rad"],star.radius,2) self.assertAlmostRelativeEqual(results[str(m)]["evtwin_L"],star.luminosity,2) print "%s\t%s\t%s\t%s\t%s" % (star.age, star.mass, star.radius, star.luminosity, star.stellar_type) instance.stop()
def test_softening(method=1): code=Kepler(redirection="none") code.set_method(method) dt=float.fromhex("0x1.67b39e372f04dp+4") mu=float.fromhex("0x1.fffffffffffdfp-3") e2=float.fromhex("0x1.0000000000003p+0") pos1=float.fromhex("0x1.1b76542265052p-1") pos2=float.fromhex("0x1.0c4dbda42097cp-6") pos3=float.fromhex("0x1.54fd66cd1e212p-3") vel1=float.fromhex("0x1.d6ef43d58ca7ep-2") vel2=float.fromhex("0x1.7a85379e59794p-2") vel3=float.fromhex("-0x1.5421044d1acffp-1") sun=Particle() sun.mass=mu | nbody_system.mass sun.x=0. | nbody_system.length sun.y=0. | nbody_system.length sun.z=0. | nbody_system.length sun.vx=0. | nbody_system.speed sun.vy=0. | nbody_system.speed sun.vz=0. | nbody_system.speed comet=Particle() comet.mass= 0 | nbody_system.mass comet.x=pos1 | nbody_system.length comet.y=pos2 | nbody_system.length comet.z=pos3 | nbody_system.length comet.vx=vel1 | nbody_system.speed comet.vy=vel2 | nbody_system.speed comet.vz=vel3 | nbody_system.speed tend=dt | nbody_system.time print tend,mu code.central_particle.add_particle(sun) code.orbiters.add_particle(comet) code.parameters.epsilon_squared = e2 | nbody_system.length**2 a0,eps0=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) print orbital_elements_from_binary(code.particles[0:2]) t1=time.time() code.evolve_model(tend) t2=time.time() print orbital_elements_from_binary(code.particles[0:2]) print code.orbiters.position a,eps=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) da=abs((a-a0)/a0) deps=abs(eps-eps0)/eps0 print da,deps print "time:",t2-t1
def t_linear(tend=1,N=100,method=0): code=Kepler(redirection="none") code.set_method(method) mass=1. | nbody_system.mass x=1. | nbody_system.length vx=0 | nbody_system.speed e=0.5*vx**2-nbody_system.G*mass/x semimajor_axis=-nbody_system.G*mass/2/e p=2*numpy.pi*(semimajor_axis**3/nbody_system.G/mass)**0.5 print semimajor_axis print p tend=tend*p dt=p/N sun=Particle() sun.mass=mass sun.x=0. | nbody_system.length sun.y=0. | nbody_system.length sun.z=0. | nbody_system.length sun.vx=0. | nbody_system.speed sun.vy=0. | nbody_system.speed sun.vz=0. | nbody_system.speed comet=Particle() comet.mass= 0 | nbody_system.mass comet.x=x comet.y=0. | nbody_system.length comet.z=0. | nbody_system.length comet.vx=vx comet.vy=0. | nbody_system.speed comet.vz=0. | nbody_system.speed code.central_particle.add_particle(sun) code.orbiters.add_particle(comet) a0,eps0=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) print orbital_elements_from_binary(code.particles[0:2]) #pyplot.ion() #f=pyplot.figure(figsize=(8,6)) #pyplot.show() tnow=0*tend time=[] xs=[] while tnow<tend: tnow+=dt print tnow,int(tnow/dt) code.evolve_model(tnow) #f.clf() time.append(tnow/tend) xs.append(code.orbiters.x[0].number) #pyplot.plot(time,xs,"r+") #pyplot.xlim(-0.1,1.1) #pyplot.ylim(-1.1,3.1) #pyplot.draw() print orbital_elements_from_binary(code.particles[0:2]) print code.orbiters.position a,eps=elements(sun.mass,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) da=abs((a-a0)/a0) deps=abs(eps-eps0)/eps0 print da,deps raw_input()
def evolve_triple_with_wind(M1, M2, M3, Pora, Pin_0, ain_0, aout_0, ein_0, eout_0, t_end, nsteps, scheme, integrator, t_stellar, dt_se, dtse_fac, interp): import random from amuse.ext.solarsystem import get_position numpy.random.seed(42) print "Initial masses:", M1, M2, M3 triple = Particles(3) triple[0].mass = M1 triple[1].mass = M2 triple[2].mass = M3 stellar = SeBa() stellar.particles.add_particles(triple) channel_from_stellar = stellar.particles.new_channel_to(triple) # Evolve to t_stellar. stellar.evolve_model(t_stellar) channel_from_stellar.copy_attributes(["mass"]) M1 = triple[0].mass M2 = triple[1].mass M3 = triple[2].mass print "t=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "R=", stellar.particles.radius.in_(units.RSun) print "L=", stellar.particles.luminosity.in_(units.LSun) print "T=", stellar.particles.temperature.in_(units.K) print "Mdot=", \ -stellar.particles.wind_mass_loss_rate.in_(units.MSun/units.yr) # Start the dynamics. # Inner binary: tmp_stars = Particles(2) tmp_stars[0].mass = M1 tmp_stars[1].mass = M2 if Pora == 1: ain_0 = semimajor_axis(Pin_0, M1+M2) else: Pin_0 = orbital_period(ain_0, M1+M2) print 'Pin =', Pin_0 print 'ain_0 =', ain_0 print 'M1+M2 =', M1+M2 print 'Pin_0 =', Pin_0.value_in(units.day), '[day]' #print 'semi:', semimajor_axis(Pin_0, M1+M2).value_in(units.AU), 'AU' #print 'period:', orbital_period(ain_0, M1+M2).value_in(units.day), '[day]' dt_init = 0.01*Pin_0 ma = 180 inc = 60 aop = 180 lon = 0 r,v = get_position(M1, M2, ein_0, ain_0, ma, inc, aop, lon, dt_init) tmp_stars[1].position = r tmp_stars[1].velocity = v tmp_stars.move_to_center() # Outer binary: r,v = get_position(M1+M2, M3, eout_0, aout_0, 0, 0, 0, 0, dt_init) tertiary = Particle() tertiary.mass = M3 tertiary.position = r tertiary.velocity = v tmp_stars.add_particle(tertiary) tmp_stars.move_to_center() triple.position = tmp_stars.position triple.velocity = tmp_stars.velocity Mtriple = triple.mass.sum() Pout = orbital_period(aout_0, Mtriple) print "T=", stellar.model_time.in_(units.Myr) print "M=", stellar.particles.mass.in_(units.MSun) print "Pout=", Pout.in_(units.Myr) print 'tK =', ((M1+M2)/M3)*Pout**2*(1-eout_0**2)**1.5/Pin_0 converter = nbody_system.nbody_to_si(triple.mass.sum(), aout_0) if integrator == 0: gravity = Hermite(converter) gravity.parameters.timestep_parameter = 0.01 elif integrator == 1: gravity = SmallN(converter) gravity.parameters.timestep_parameter = 0.01 gravity.parameters.full_unperturbed = 0 elif integrator == 2: gravity = Huayno(converter) gravity.parameters.inttype_parameter = 20 gravity.parameters.timestep = (1./256)*Pin_0 else: gravity = symple(converter) gravity.parameters.integrator = 10 #gravity.parameters.timestep_parameter = 0. gravity.parameters.timestep = (1./128)*Pin_0 print gravity.parameters gravity.particles.add_particles(triple) channel_from_framework_to_gd = triple.new_channel_to(gravity.particles) channel_from_gd_to_framework = gravity.particles.new_channel_to(triple) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot_prev = Etot_init gravity.particles.move_to_center() # Note: time = t_diag = 0 at the start of the dynamical integration. dt_diag = t_end/float(nsteps) t_diag = dt_diag time = 0.0 | t_end.unit t_se = t_stellar + time print 't_end =', t_end print 'dt_diag =', dt_diag ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t = [time.value_in(units.Myr)] Mtot = triple.mass.sum() mtot = [Mtot.value_in(units.MSun)] smai = [ain/ain_0] ecci = [ein/ein_0] smao = [aout/aout_0] ecco = [eout/eout_0] if interp: # Create arrays of stellar times and masses for interpolation. times = [time] masses = [triple.mass.copy()] while time < t_end: time += dt_se stellar.evolve_model(t_stellar+time) channel_from_stellar.copy_attributes(["mass"]) times.append(time) masses.append(triple.mass.copy()) time = 0.0 | t_end.unit print '\ntimes:', times, '\n' # Evolve the system. def advance_stellar(t_se, dt): E0 = gravity.kinetic_energy + gravity.potential_energy t_se += dt if interp: t = t_se-t_stellar i = int(t/dt_se) mass = masses[i] + (t-times[i])*(masses[i+1]-masses[i])/dt_se triple.mass = mass #print 't_se =', t_se, 'masses =', mass else: stellar.evolve_model(t_se) channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) return t_se, gravity.kinetic_energy + gravity.potential_energy - E0 def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg while time < t_end: if scheme == 1: # Advance to the next diagnostic time. dE_se = zero dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) elif scheme == 2: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, dt) time = advance_gravity(time, dt) elif scheme == 3: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: time = advance_gravity(time, dt) t_se, dE_se = advance_stellar(t_se, dt) elif scheme == 4: # Derive dt from Pin using dtse_fac. dt = dtse_fac*Pin_0 if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: t_se, dE_se = advance_stellar(t_se, 0.5*dt) time = advance_gravity(time, dt) t_se, dE_se2 = advance_stellar(t_se, 0.5*dt) dE_se += dE_se2 elif scheme == 5: # Use the specified dt_se. dE_se = zero dt = dt_se if time + dt > t_diag: dt = t_diag - time if dt > 0|dt.unit: # For use with symple only: set up average mass loss. channel_from_stellar.copy_attributes(["mass"]) m0 = triple.mass.copy() stellar.evolve_model(t_se+dt) channel_from_stellar.copy_attributes(["mass"]) t_se = stellar.model_time m1 = triple.mass dmdt = (m1-m0)/dt for i in range(len(dmdt)): gravity.set_dmdt(i, dmdt[i]) time = advance_gravity(time, dt) else: print 'unknown option' sys.exit(0) if time >= t_diag: t_diag = time + dt_diag Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_prev - Etot Mtot = triple.mass.sum() print "T=", time, print "M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", print "E= ", Etot, "Q= ", Ekin/Epot, print "dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, print "(dE[SE]=", dE_se/Etot, ")" Etot_init -= dE Etot_prev = Etot ain, ein, aout, eout = get_orbital_elements_of_triple(triple) print "Triple elements t=", t_stellar + time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, \ "outer:", triple[2].mass, aout, eout t.append(time.value_in(units.yr)) mtot.append(Mtot.value_in(units.MSun)) smai.append(ain/ain_0) ecci.append(ein/ein_0) smao.append(aout/aout_0) ecco.append(eout/eout_0) if eout > 1 or aout <= zero: print "Binary ionized or merged" break gravity.stop() stellar.stop() return t, mtot, smai, ecci, smao, ecco
def main(number_of_grid_cells=15, min_convergence=20): inner_radius = 30.0e17 | units.cm outer_radius = 95.0e17 | units.cm hydrogen_density = 100 | units.cm ** -3 star = Particle() star.position = [0.0, 0.0, 0.0] | units.AU star.temperature = 20000 | units.K star.luminosity = 600.5 | 1e37 * units.erg * (units.s**-1) grid = make_grid( number_of_grid_cells=number_of_grid_cells, length=outer_radius, constant_hydrogen_density=hydrogen_density, inner_radius=inner_radius, outer_radius=outer_radius ) radiative_transfer = Mocassin(number_of_workers=2) # , debugger = "xterm") radiative_transfer.set_input_directory( radiative_transfer.get_default_input_directory()) radiative_transfer.set_mocassin_output_directory( radiative_transfer.output_directory + os.sep) radiative_transfer.initialize_code() radiative_transfer.set_symmetricXYZ(True) radiative_transfer.parameters.length_x = outer_radius radiative_transfer.parameters.length_y = outer_radius radiative_transfer.parameters.length_z = outer_radius radiative_transfer.parameters.mesh_size = [ number_of_grid_cells, number_of_grid_cells, number_of_grid_cells] setup_abundancies(radiative_transfer) radiative_transfer.parameters.initial_nebular_temperature = 6000.0 | units.K radiative_transfer.parameters.high_limit_of_the_frequency_mesh = 15 | mocassin_rydberg_unit radiative_transfer.parameters.low_limit_of_the_frequency_mesh = 1.001e-5 | mocassin_rydberg_unit radiative_transfer.parameters.total_number_of_photons = 10000000 radiative_transfer.parameters.total_number_of_points_in_frequency_mesh = 600 radiative_transfer.parameters.convergence_limit = 0.09 radiative_transfer.parameters.number_of_ionisation_stages = 6 radiative_transfer.commit_parameters() radiative_transfer.grid.hydrogen_density = grid.hydrogen_density radiative_transfer.commit_grid() radiative_transfer.particles.add_particle(star) radiative_transfer.commit_particles() max_number_of_photons = radiative_transfer.parameters.total_number_of_photons * 100 previous_percentage_converged = 0.0 for i in range(20): radiative_transfer.step() percentage_converged = radiative_transfer.get_percentage_converged() print( "percentage converged :", percentage_converged, ", step :", i, ", photons:", radiative_transfer.parameters.total_number_of_photons) if percentage_converged >= min_convergence: break if previous_percentage_converged > 5 and percentage_converged < 95: convergence_increase = ( percentage_converged - previous_percentage_converged ) / previous_percentage_converged if ( convergence_increase < 0.2 and radiative_transfer.parameters.total_number_of_photons < max_number_of_photons ): radiative_transfer.parameters.total_number_of_photons *= 2 previous_percentage_converged = percentage_converged grid.electron_temperature = radiative_transfer.grid.electron_temperature radius = grid.radius.flatten() electron_temperature = grid.electron_temperature.flatten() selection = electron_temperature > 0 | units.K plot_temperature_line(radius[selection], electron_temperature[selection]) write_set_to_file(grid, 'h2region.h5', 'amuse')