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 form_new_star( densest_gas_particle, gas_particles, # density_threshold= ): """ Forms a new star by merging all gas particles within a Jeans radius of the densest particle. Returns the new star and all particles used to make it. """ new_star = Particle() gas_copy = gas_particles.copy() # densest_gas_particle = gas_copy.sorted_by_attribute("density")[0] jeans_radius = 0.025 | units.parsec # 100 | units.AU gas_copy.position -= densest_gas_particle.position gas_copy.distance_to_core = gas_copy.position.lengths() dense_gas = gas_copy.select(lambda x: x < jeans_radius, ["distance_to_core"]) new_star.mass = dense_gas.mass.sum() new_star.position = (dense_gas.center_of_mass() + densest_gas_particle.position) new_star.velocity = dense_gas.center_of_mass_velocity() new_star.radius = jeans_radius absorbed_gas = dense_gas return new_star, absorbed_gas
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 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 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 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 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 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 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 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 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 = 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 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 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 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 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_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 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 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 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 giant_to_sph(giant, stellar_structure_file, number_of_sph_particles): model = convert_stellar_model_to_SPH(None, number_of_sph_particles, pickle_file=stellar_structure_file, with_core_particle=True, target_core_mass=2.0 | units.MSun, do_store_composition=False, base_grid_options=dict(type="fcc")) sph_giant = model.gas_particles if model.core_particle is None: core = Particle(mass=0 | units.MSun, radius=1 | units.RSun) core_radius = core.radius else: core = model.core_particle core_radius = model.core_radius sph_giant.position += giant.position sph_giant.velocity += giant.velocity core.position = giant.position core.velocity = giant.velocity print "Core radius:", core_radius.as_string_in(units.RSun) return sph_giant, core, core_radius
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 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, end=' ') print("M=", Mtot, "(dM[SE]=", Mtot/Mtriple, ")", end=' ') print("E= ", Etot, "Q= ", Ekin/Epot, end=' ') print("dE=", (Etot_init-Etot)/Etot, "ddE=", (Etot_prev-Etot)/Etot, end=' ') 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 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 time_framework = 0 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) t0 = ctime.time() stellar.evolve_model(t_stellar) delta_t = ctime.time() - t0 time_framework += delta_t 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 = Huayno(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 # begin when stars have formed after 4.0 Myr years ain, ein, aout, eout, iin, iout = get_orbital_elements_of_triple(triple) print "Triple elements t=", time, \ "inner:", triple[0].mass, triple[1].mass, ain, ein, iin, \ "outer:", triple[2].mass, aout, eout, iout dt_diag = t_end / float( nsteps) # how often we want to save the generated data 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] inci = [iin] inco = [iout] 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_stellar_with_massloss( ts, time_framework, dt_massloss=15e-9 | units.Myr, max_massloss=3e-4 | units.MSun): # Scheme 3: dt 8*10^-7, dm = 2*10^-5 ( max_massloss = 0.0 | units.MSun # massloss over full gravtiational time step massloss0 #max_massloss= 3e-6 | units.MSun # massloss over full gravtiational time step massloss1 #max_massloss= 1e-6 | units.MSun # massloss over full gravtiational time step massloss2 E0 = gravity.kinetic_energy + gravity.potential_energy massloss = -1 | units.MSun mass_0 = numpy.sum(stellar.particles.mass) dt_stellar = 0 | units.Myr niter = 0 while massloss < max_massloss: ts += dt_massloss dt_stellar += dt_massloss # counter for full time niter += 1 t0 = ctime.time() stellar.evolve_model(ts) delta_t = ctime.time() - t0 time_framework += delta_t massloss = 2. * ( mass_0 - numpy.sum(stellar.particles.mass) ) # massloss over full gravtiational time step is x2 channel_from_stellar.copy_attributes(["mass"]) channel_from_framework_to_gd.copy_attributes(["mass"]) print 'Tstellar:', dt_stellar, ', Total Mloss:', massloss, ' Niter:', niter return ts, time_framework, gravity.kinetic_energy + gravity.potential_energy - E0, dt_stellar def advance_gravity(tg, dt): tg += dt gravity.evolve_model(tg) channel_from_gd_to_framework.copy() return tg global_time = [] global_massloss = [] global_dmdt = [] while time < t_end: Pin = orbital_period(ain, triple[0].mass + triple[1].mass) dt = dtse_fac * Pin dt *= random.random( ) # time step is chosen random between 0 and 50*Pin 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) elif scheme == 3: # inital mass mass_init = stellar.particles.mass.sum() # perform step ts, dE_se = advance_stellar(ts, dt / 2) time = advance_gravity(time, dt) ts, dE = advance_stellar(ts, dt / 2) dE_se += dE # add right vlaues global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) else: # our scheme is 4 # inital mass mass_init = stellar.particles.mass.sum() time_init = time.value_in(units.Myr) | units.Myr # get optimal dt to perform a time step without losing too much mass ts, time_framework, dE_se, dt_stellar = advance_stellar_with_massloss( ts, time_framework) # perform time step dt t0 = ctime.time() time = advance_gravity(time, dt_stellar * 2) ts, dE = advance_stellar(ts, dt_stellar) delta_t = ctime.time() - t0 time_framework += delta_t dE_se += dE # save everything global_time = numpy.append(global_time, time.value_in(units.Myr)) global_massloss = numpy.append( global_massloss, mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) global_dmdt = numpy.append( global_dmdt, (mass_init.value_in(units.MSun) - numpy.sum(stellar.particles.mass).value_in(units.MSun)) / (time.value_in(units.Myr) - time_init.value_in(units.Myr))) 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, iin, iout = 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) inci.append(iin) inco.append(iout) if eout > 1.0 or aout <= zero: print "Binary ionized or merged" break pyplot.close() data = numpy.array(zip(global_time, global_massloss, global_dmdt)) numpy.save('massloss0', data) return t, smai, ecci, smao, ecco, inci, inco, time_framework
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 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