def new_colliders(self): colliders = Particles(2) colliders.mass = [5, 2] | units.MSun colliders.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.RSun colliders.velocity = [[0.0, 0.0, 0.0], [0.0, 2000.0, 0.0]] | units.km / units.s colliders.move_to_center() return colliders
def set_up_initial_conditions(orbital_period, kinetic_to_potential_ratio): print("Setting up initial conditions") stars = Particles(2) stars.mass = [10.0, 1.0] | units.MSun stars.radius = 0 | units.RSun stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s print("Binary with masses: " + str(stars.mass) + ", and orbital period: ", orbital_period) semimajor_axis = ((constants.G * stars.total_mass() * (orbital_period / (2 * pi))**2.0)**(1.0 / 3.0)) separation = 2 * semimajor_axis * (1 - kinetic_to_potential_ratio) print("Initial separation:", separation.as_quantity_in(units.AU)) relative_velocity = ( (kinetic_to_potential_ratio / (1.0 - kinetic_to_potential_ratio)) * constants.G * stars.total_mass() / semimajor_axis ).sqrt() print("Initial relative velocity:", relative_velocity.as_quantity_in(units.km / units.s)) stars[0].x = separation stars[0].vy = relative_velocity stars.move_to_center() return stars
def test5(self): print "Testing MI6 evolve_model, 2 particles, no SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print particles converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = MI6(converter, **default_options) instance.initialize_code() instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test4(self): print "Testing Pikachu evolve_model, 2 particles" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.0125 * math.pi * particles[0].x / particles[0].vy instance.parameters.rcut_out_star_star = 10.0 | units.AU instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test4(self): print "Testing Adaptb evolve_model, 2 particles" particles = Particles(2) particles.mass = 0.5 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (1.0 | units.MSun) / (1.0 | units.AU)).sqrt() particles.move_to_center() convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Adaptb, convert_nbody) instance.initialize_code() instance.parameters.dt_print = 0.1 | units.yr instance.parameters.bs_tolerance = 1.0e-8 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 6) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 6) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 6) instance.cleanup_code() instance.stop()
def test9(self): print "Testing FastKick for Bridge: evolving a binary" particles = Particles(2) particles.mass = [3.0, 1.0] | units.MSun particles.position = [0, 0, 0] | units.AU particles.velocity = [0, 0, 0] | units.km / units.s particles[1].x = 2.0 | units.AU particles[1].vy = (constants.G * (4.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() primary_sys = new_gravity_code(particles[:1]) secondary_sys = new_gravity_code(particles[1:]) primary = primary_sys.particles[0] P = 2 * math.pi * primary.x / primary.vy converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) kick_from_primary = CalculateFieldForCodesUsingReinitialize(self.new_fastkick_instance(converter), (primary_sys,)) kick_from_secondary = CalculateFieldForCodesUsingReinitialize(self.new_fastkick_instance(converter), (secondary_sys,)) bridgesys = Bridge(timestep = P / 64.0) bridgesys.add_system(primary_sys, (kick_from_secondary,)) bridgesys.add_system(secondary_sys, (kick_from_primary,)) position_at_start = primary.position.x bridgesys.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 2) bridgesys.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 2) bridgesys.evolve_model(P) kick_from_primary.code.stop() kick_from_secondary.code.stop() self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 2)
def solar_system_in_time(time_JD=2457099.5|units.day): """ Initial conditions of Solar system -- particle set with the sun + eight planets, at the center-of-mass reference frame. Defined attributes: name, mass, radius, x, y, z, vx, vy, vz """ time_0 = 2457099.5 | units.day delta_JD = time_JD-time_0 sun, planets = get_sun_and_planets(delta_JD=delta_JD) solar_system = Particles() solar_system.add_particle(sun) solar_system.add_particles(planets) solar_system.move_to_center() ### to compare with JPL, relative positions and velocities need to be corrected for the # Sun's vectors with respect to the barycenter #r_s = (3.123390770608490E-03, -4.370830943817017E-04, -1.443425433116342E-04) | units.AU #v_s = (3.421633816761503E-06, 5.767414405893875E-06, -8.878039607570240E-08) | (units.AU / units.day) #print sun #print planets.position.in_(units.AU) + r_s #print planets.velocity.in_(units.AU/units.day) + v_s return solar_system
def set_up_initial_conditions(orbital_period, kinetic_to_potential_ratio): print("Setting up initial conditions") stars = Particles(2) stars.mass = [10.0, 1.0] | units.MSun stars.radius = 0 | units.RSun stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s print("Binary with masses: "+str(stars.mass) + ", and orbital period: ", orbital_period) semimajor_axis = ((constants.G * stars.total_mass() * (orbital_period / (2 * pi))**2.0)**(1.0/3.0)) separation = 2 * semimajor_axis * (1 - kinetic_to_potential_ratio) print("Initial separation:", separation.as_quantity_in(units.AU)) relative_velocity = ( (kinetic_to_potential_ratio / (1.0 - kinetic_to_potential_ratio)) * constants.G * stars.total_mass() / semimajor_axis ).sqrt() print("Initial relative velocity:", relative_velocity.as_quantity_in(units.km / units.s)) stars[0].x = separation stars[0].vy = relative_velocity stars.move_to_center() return stars
def new_colliders(self): colliders = Particles(2) colliders.mass = [5, 2] | units.MSun colliders.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.RSun colliders.velocity = [[0.0, 0.0, 0.0], [0.0, 2000.0, 0.0]] | units.km / units.s colliders.move_to_center() return colliders
def sun_and_planets(self): particles = Particles(9) sun = particles[0] mercury = particles[1] venus = particles[2] earth = particles[3] mars = particles[4] jupiter = particles[5] saturn = particles[6] uranus = particles[7] neptune = particles[8] sun.mass = 1047.517| units.MJupiter sun.radius = 1.0 | units.RSun sun.position = ( 0.005717 , -0.00538 , -2.130e-5 ) | units.AU sun.velocity = ( 0.007893 , 0.01189 , 0.0002064 ) | units.kms mercury.mass = 0.000174 | units.MJupiter mercury.radius = 0 | units.RSun mercury.position = ( -0.31419 , 0.14376 , 0.035135 ) | units.AU mercury.velocity = ( -30.729 , -41.93 , -2.659 ) | units.kms venus.mass = 0.002564 | units.MJupiter venus.radius = 0 | units.RSun venus.position = ( -0.3767 , 0.60159 , 0.0393 ) | units.AU venus.velocity = ( -29.7725 , -18.849 , 0.795 ) | units.kms earth.mass = 0.003185 | units.MJupiter earth.radius = 0 | units.RSun earth.position = ( -0.98561 , 0.0762 , -7.847e-5 ) | units.AU earth.velocity = ( -2.927 , -29.803 , -0.000533 ) | units.kms mars.mass = 0.000338 | units.MJupiter mars.radius = 0 | units.RSun mars.position = ( -1.2895 , -0.9199 , -0.048494 ) | units.AU mars.velocity = ( 14.9 , -17.721 , 0.2979 ) | units.kms jupiter.mass = 1 | units.MJupiter jupiter.radius = 0 | units.RSun jupiter.position = ( -4.9829 , 2.062 , -0.10990 ) | units.AU jupiter.velocity = ( -5.158 , -11.454 , -0.13558 ) | units.kms saturn.mass = 0.29947 | units.MJupiter saturn.radius = 0 | units.RSun saturn.position = ( -2.075 , 8.7812 , 0.3273 ) | units.AU saturn.velocity = ( -9.9109 , -2.236 , -0.2398 ) | units.kms uranus.mass = 0.045737 | units.MJupiter uranus.radius = 0 | units.RSun uranus.position = ( -12.0872 , -14.1917 , 0.184214 ) | units.AU uranus.velocity = ( 5.1377 , -4.7387 , -0.06108 ) | units.kms neptune.mass = 0.053962 | units.MJupiter neptune.radius = 0 | units.RSun neptune.position = ( 3.1652 , 29.54882 , 0.476391 ) | units.AU neptune.velocity = ( -5.443317 , 0.61054 , -0.144172 ) | units.kms particles.move_to_center() return particles
def get_galaxies_in_orbit(m_a=10.e11|units.MSun, m_b=10.e11|units.MSun, ecc=0.5, r_min=25.|units.kpc, t_start=None): """ binary galaxy with orbit of given parameters -- if ecc=>1, start at t_start (p625, t_start=-10=-10*100Myr) -- if ecc<1, start at apocenter (p644) """ converter=nbody_system.nbody_to_si(m_a+m_b,1|units.kpc) semi = r_min/(1.-ecc) # relative position and velocity vectors at the pericenter using kepler kepler = Kepler_twobody(converter) kepler.initialize_code() kepler.initialize_from_elements(mass=(m_a+m_b), semi=semi, ecc=ecc, periastron=r_min) # at periastron # evolve back till initial position if ( ecc<1. ): kepler.return_to_apastron() else: kepler.transform_to_time(t_start) # get time of the orbit t_orbit = kepler.get_time() rl = kepler.get_separation_vector() r = [rl[0].value_in(units.AU), rl[1].value_in(units.AU), rl[2].value_in(units.AU)] | units.AU vl = kepler.get_velocity_vector() v = [vl[0].value_in(units.kms), vl[1].value_in(units.kms), vl[2].value_in(units.kms)] | units.kms kepler.stop() # assign particle atributes galaxies = Particles(2) galaxies[0].mass = m_a galaxies[0].position = (0,0,0) | units.AU galaxies[0].velocity = (0,0,0) | units.kms galaxies[1].mass = m_b galaxies[1].position = r galaxies[1].velocity = v # identification galaxies[0].id = 'a0' galaxies[1].id = 'b0' galaxies.move_to_center() return galaxies, t_orbit
def evolve_with_kepler(self, hydro): if self.verbose: print("evolve_with_kepler") indices_two_most_massive = self.stars_after_encounter.mass.argsort()[-2:] groups = [self.groups_after_encounter[i] for i in indices_two_most_massive] old_particles = self.stars_after_encounter[indices_two_most_massive] new_particles = Particles(2) new_particles.mass = old_particles.mass new_particles[0].position, new_particles[0].velocity = self.skip_to_relative_position_velocity new_particles.move_to_center() for group, old_particle, new_particle in zip(groups, old_particles, new_particles): in_hydro = group.get_intersecting_subset_in(hydro.gas_particles) if self.verbose: print(in_hydro.center_of_mass().as_quantity_in(units.RSun), old_particle.position.as_quantity_in(units.RSun), new_particle.position.as_quantity_in(units.RSun)) in_hydro.position += new_particle.position - old_particle.position in_hydro.velocity += new_particle.velocity - old_particle.velocity
def evolve_with_kepler(self, hydro): if self.verbose: print "evolve_with_kepler" indices_two_most_massive = self.stars_after_encounter.mass.argsort()[-2:] groups = [self.groups_after_encounter[i] for i in indices_two_most_massive] old_particles = self.stars_after_encounter[indices_two_most_massive] new_particles = Particles(2) new_particles.mass = old_particles.mass new_particles[0].position, new_particles[0].velocity = self.skip_to_relative_position_velocity new_particles.move_to_center() for group, old_particle, new_particle in zip(groups, old_particles, new_particles): in_hydro = group.get_intersecting_subset_in(hydro.gas_particles) if self.verbose: print in_hydro.center_of_mass().as_quantity_in(units.RSun), old_particle.position.as_quantity_in(units.RSun), new_particle.position.as_quantity_in(units.RSun) in_hydro.position += new_particle.position - old_particle.position in_hydro.velocity += new_particle.velocity - old_particle.velocity
def set_up_inner_binary(inclination): semimajor_axis = triple_parameters["a_in"] masses = triple_parameters["masses_in"] print " Initializing inner binary" stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].y = semimajor_axis stars[0].vx = -math.cos(inclination) * get_relative_velocity_at_apastron( stars.total_mass(), semimajor_axis, 0) stars[0].vz = math.sin(inclination) * get_relative_velocity_at_apastron( stars.total_mass(), semimajor_axis, 0) stars.move_to_center() return stars
def test4(self): print("Testing Brutus evolve_model, 2 particles") particles = Particles(2) particles.mass = 0.5 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = (constants.G * (1.0 | units.MSun) / (1.0 | units.AU)).sqrt() particles.move_to_center() convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Brutus, convert_nbody) instance.initialize_code() instance.parameters.bs_tolerance = 1e-6 instance.parameters.word_length = 56 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 6) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 6) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 6) instance.cleanup_code() instance.stop()
def set_up_inner_binary(): semimajor_axis = 0.133256133158 | units.AU eccentricity = 0 masses = [3.2, 3.1] | units.MSun orbital_period = (4 * numpy.pi**2 * semimajor_axis**3 / (constants.G * masses.sum())).sqrt().as_quantity_in(units.day) print(" Initializing inner binary") print(" Orbital period inner binary:", orbital_period) stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].x = semimajor_axis stars[0].vy = get_relative_velocity(stars.total_mass(), semimajor_axis, eccentricity) stars.move_to_center() return stars
def make_circular_binary(M, m, a): masses = [M.value_in(units.MSun), m.value_in(units.MSun)] | units.MSun orbital_period = ( 4 * numpy.pi**2 * a**3 / (constants.G * masses.sum()) ).sqrt().as_quantity_in(units.day) print(" Initializing inner binary") print(" Orbital period inner binary:", orbital_period) stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].x = a stars[0].vy = get_relative_velocity(stars.total_mass(), a, 0.0) stars.move_to_center() return stars
def set_up_inner_binary(): semimajor_axis = 0.133256133158 | units.AU eccentricity = 0 masses = [3.2, 3.1] | units.MSun orbital_period = (4 * numpy.pi**2 * semimajor_axis**3 / (constants.G * masses.sum())).sqrt().as_quantity_in(units.day) print " Initializing inner binary" print " Orbital period inner binary:", orbital_period stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].x = semimajor_axis stars[0].vy = get_relative_velocity(stars.total_mass(), semimajor_axis, eccentricity) stars.move_to_center() return stars
def make_circular_binary(M, m, a): masses = [M.value_in(units.MSun), m.value_in(units.MSun)] | units.MSun orbital_period = ( 4 * numpy.pi**2 * a**3 / (constants.G * masses.sum()) ).sqrt().as_quantity_in(units.day) print " Initializing inner binary" print " Orbital period inner binary:", orbital_period stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].x = a stars[0].vy = get_relative_velocity(stars.total_mass(), a, 0.0) stars.move_to_center() return stars
def set_up_inner_binary(): orbital_period = 835.0 | units.day masses = [10.0, 1.1] | units.MSun semimajor_axis = (((constants.G * masses.sum() * orbital_period**2) / (4 * numpy.pi**2))**(1.0 / 3.0)).as_quantity_in( units.RSun) print " Initializing inner binary" print " Semimajor axis inner binary:", semimajor_axis stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].y = semimajor_axis stars[0].vx = -get_relative_velocity(stars.total_mass(), semimajor_axis, 0) stars.move_to_center() return stars
def xtest04(self): if MODULES_MISSING: self.skip("Failed to import a module required for Tupan") print("Testing Tupan evolve_model, 2 particles orbiting the SMBH") particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = ((constants.G * (10001.0 | units.MSun) / (1.0 | units.AU)).sqrt() + (constants.G * (10000.0 | units.MSun) / (1.0 | units.AU)).sqrt()) particles.move_to_center() print(particles) instance = self.new_instance_of_an_optional_code( Tupan, self.default_converter) instance.initialize_code() # instance.parameters.include_smbh = True instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy P_corrected = (P) * (2.0 / (1.0 + math.sqrt(1.0001))) position_at_start = primary.position.x instance.evolve_model(P_corrected / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P_corrected / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P_corrected) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test4(self): print "Testing MI6 evolve_model, 2 particles orbiting the SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = ((constants.G * (10001.0 | units.MSun) / (1.0 | units.AU)).sqrt() + (constants.G * (10000.0 | units.MSun) / (1.0 | units.AU)).sqrt()) particles.move_to_center() print particles instance = MI6(self.default_converter, **default_options) instance.initialize_code() instance.parameters.include_smbh = True instance.parameters.lightspeed = constants.c instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy P_corrected = (P) * (2.0 / (1.0 + math.sqrt(1.0001))) position_at_start = primary.position.x instance.evolve_model(P_corrected / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P_corrected / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P_corrected) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test05(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print("Testing Sakura evolve_model, 2 particles, no SMBH") particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print(particles) converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code( Sakura, converter, **default_options) instance.initialize_code() # instance.parameters.integrator_method = "asakura" instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
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 test4(self): print "Testing Pikachu evolve_model, 2 particles" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code( Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.0125 * math.pi * particles[ 0].x / particles[0].vy instance.parameters.rcut_out_star_star = 10.0 | units.AU instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test9(self): print("Testing FastKick for Bridge: evolving a binary") particles = Particles(2) particles.mass = [3.0, 1.0] | units.MSun particles.position = [0, 0, 0] | units.AU particles.velocity = [0, 0, 0] | units.km / units.s particles[1].x = 2.0 | units.AU particles[1].vy = (constants.G * (4.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() primary_sys = new_gravity_code(particles[:1]) secondary_sys = new_gravity_code(particles[1:]) primary = primary_sys.particles[0] P = 2 * math.pi * primary.x / primary.vy converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) kick_from_primary = CalculateFieldForCodesUsingReinitialize( self.new_fastkick_instance(converter), (primary_sys, )) kick_from_secondary = CalculateFieldForCodesUsingReinitialize( self.new_fastkick_instance(converter), (secondary_sys, )) bridgesys = Bridge(timestep=P / 64.0) bridgesys.add_system(primary_sys, (kick_from_secondary, )) bridgesys.add_system(secondary_sys, (kick_from_primary, )) position_at_start = primary.position.x bridgesys.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 2) bridgesys.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 2) bridgesys.evolve_model(P) kick_from_primary.code.stop() kick_from_secondary.code.stop() self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 2)
def test5(self): print "Testing MI6 evolve_model, 2 particles, no SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0] ] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print particles converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = MI6(converter, **default_options) instance.initialize_code() instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def xtest04(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing Sakura evolve_model, 2 particles orbiting the SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (10001.0 | units.MSun) / (1.0 | units.AU)).sqrt() + ( constants.G * (10000.0 | units.MSun) / (1.0 | units.AU) ).sqrt() particles.move_to_center() print particles instance = Sakura(self.default_converter) instance.initialize_code() # instance.parameters.include_smbh = True instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy P_corrected = (P) * (2.0 / (1.0 + math.sqrt(1.0001))) position_at_start = primary.position.x instance.evolve_model(P_corrected / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P_corrected / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P_corrected) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test4(self): print "Testing MI6 evolve_model, 2 particles orbiting the SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (10001.0 | units.MSun) / (1.0 | units.AU)).sqrt() + ( constants.G * (10000.0 | units.MSun) / (1.0 | units.AU) ).sqrt() particles.move_to_center() print particles instance = MI6(self.default_converter, **default_options) instance.initialize_code() instance.parameters.include_smbh = True instance.parameters.lightspeed = constants.c instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy P_corrected = (P) * (2.0 / (1.0 + math.sqrt(1.0001))) position_at_start = primary.position.x instance.evolve_model(P_corrected / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P_corrected / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P_corrected) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test05(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing Sakura evolve_model, 2 particles, no SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print particles converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = Sakura(converter) instance.initialize_code() # instance.parameters.integrator_method = "asakura" instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def randomparticles_w_ss(N=20, L=1000. | units.AU, dv=2.5 | units.kms): from amuse.ic.salpeter import new_salpeter_mass_distribution conv = nbody_system.nbody_to_si(N * 1. | units.MSun, 1000. | units.AU) conv_sub = nbody_system.nbody_to_si(1. | units.MSun, 50. | units.AU) dt = smaller_nbody_power_of_two(1000. | units.day, conv) print(dt.in_(units.day)) dt_param = 0.02 LL = L.value_in(units.AU) def radius(sys, eta=dt_param, _G=constants.G): radius = ((_G * sys.total_mass() * dt**2 / eta**2)**(1. / 3.)) # xcm,ycm,zcm=sys.center_of_mass() # r2max=((sys.x-xcm)**2+(sys.y-ycm)**2+(sys.z-zcm)**2).max() # if radius < 10 | units.AU: # radius=20. | units.AU # return max(radius,r2max**0.5) return radius * ((len(sys) + 1) / 2.)**0.75 def timestep(ipart, jpart, eta=dt_param / 2, _G=constants.G): dx = ipart.x - jpart.x dy = ipart.y - jpart.y dz = ipart.z - jpart.z dr2 = dx**2 + dy**2 + dz**2 # if dr2>0: dr = dr2**0.5 dr3 = dr * dr2 mu = _G * (ipart.mass + jpart.mass) tau = eta / 2. / 2.**0.5 * (dr3 / mu)**0.5 return tau numpy.random.seed(7654304) masses = new_salpeter_mass_distribution(N, mass_min=0.3 | units.MSun, mass_max=10. | units.MSun) #masses=([1.]*10) | units.MSun stars = Particles(N, mass=masses) stars.x = L * numpy.random.uniform(-1., 1., N) stars.y = L * numpy.random.uniform(-1., 1., N) stars.z = L * 0. stars.vx = dv * numpy.random.uniform(-1., 1., N) stars.vy = dv * numpy.random.uniform(-1., 1., N) stars.vz = dv * 0. stars.radius = (1. | units.RSun) * (stars.mass / (1. | units.MSun))**(1. / 3.) stars.move_to_center() parts = HierarchicalParticles(stars) # ss=new_solar_system()[[0,5,6,7,8]] # parts.assign_subsystem(ss,parts[0]) def parent_worker(): code = Hermite(conv) code.parameters.epsilon_squared = 0. | units.AU**2 code.parameters.end_time_accuracy_factor = 0. code.parameters.dt_param = 0.001 print(code.parameters.dt_dia.in_(units.yr)) return code def sub_worker(parts): mode = system_type(parts) if mode == "twobody": code = TwoBody(conv_sub) elif mode == "solarsystem": code = Mercury(conv_sub) elif mode == "nbody": code = Huayno(conv_sub) code.parameters.inttype_parameter = code.inttypes.SHARED4 return code def py_worker(): code = CalculateFieldForParticles(gravity_constant=constants.G) return code nemesis = Nemesis(parent_worker, sub_worker, py_worker) nemesis.timestep = dt nemesis.distfunc = timestep nemesis.threshold = dt nemesis.radius = radius nemesis.commit_parameters() nemesis.particles.add_particles(parts) nemesis.commit_particles() tend = 3200. | units.yr t = 0 | units.yr dtdiag = dt * 2 time = [0.] allparts = nemesis.particles.all() E = allparts.potential_energy() + allparts.kinetic_energy() E1 = nemesis.potential_energy + nemesis.kinetic_energy com = allparts.center_of_mass() mom = allparts.total_momentum() ang = allparts.total_angular_momentum() E0 = E A0 = (ang[0]**2 + ang[1]**2 + ang[2]**2)**0.5 P0 = mom[0].value_in(units.MSun * units.kms) totalE = [0.] totalA = [0.] totalP = [0.] ss = nemesis.particles.all() x = (ss.x).value_in(units.AU) xx = [x] y = (ss.y).value_in(units.AU) yy = [y] nstep = 0 while t < tend - dtdiag / 2: t += dtdiag nemesis.evolve_model(t) print(t.in_(units.yr)) print(len(nemesis.particles)) time.append(t.value_in(units.yr)) allparts = nemesis.particles.all() E = allparts.potential_energy() + allparts.kinetic_energy() E1 = nemesis.potential_energy + nemesis.kinetic_energy ang = allparts.total_angular_momentum() mom = allparts.total_momentum() A = (ang[0]**2 + ang[1]**2 + ang[2]**2)**0.5 P = mom[0].value_in(units.MSun * units.kms) totalE.append(abs((E0 - E) / E0)) totalA.append(abs((A0 - A) / A0)) totalP.append(abs(P0 - P)) print(totalE[-1], (E - E1) / E) # print allparts.potential_energy(),nemesis.potential_energy ss = nemesis.particles.all() x = (ss.x).value_in(units.AU) y = (ss.y).value_in(units.AU) lowm = numpy.where(ss.mass.value_in(units.MSun) < 0.1)[0] highm = numpy.where(ss.mass.value_in(units.MSun) >= 0.1)[0] xcm = nemesis.particles.x.value_in(units.AU) ycm = nemesis.particles.y.value_in(units.AU) r = (nemesis.particles.radius).value_in(units.AU) xx.append(x) yy.append(y) key = ss.key f = pyplot.figure(figsize=(8, 8)) ax = f.gca() circles = [] # for i in range(len(xx[0])): # pyplot.plot(xx[-1][i],yy[-1][i],colors[key[i]%numpy.uint64(len(colors))]+ # markerstyles[key[i]%numpy.uint64(len(markerstyles))],markersize=8,mew=2) pyplot.plot(xx[-1][highm], yy[-1][highm], 'go', markersize=8, mew=2) pyplot.plot(xx[-1][lowm], yy[-1][lowm], 'b+', markersize=6, mew=1.5) for p in nemesis.particles: # if nemesis.particles.collection_attributes.subsystems.has_key(p): c = 'k' ls = 'solid' code_colors = dict(TwoBody='b', Mercury='r', Huayno='g', Hermite='y') code_ls = dict(TwoBody='dotted', Mercury='dashed', Huayno='dashdot', Hermite='solid') if nemesis.subcodes.has_key(p): c = code_colors[nemesis.subcodes[p].__class__.__name__] ls = code_ls[nemesis.subcodes[p].__class__.__name__] x = p.x.value_in(units.AU) y = p.y.value_in(units.AU) r = p.radius.value_in(units.AU) circles.append( pyplot.Circle((x, y), r, color=c, lw=0.8, ls=ls, fill=False)) for c in circles: ax.add_artist(c) # pyplot.plot(xcm,ycm,'k+', markersize=4,mew=1) pyplot.xlim(-1.2 * LL, 1.2 * LL) pyplot.ylim(-1.2 * LL, 1.2 * LL) pyplot.xlabel("AU") pyplot.text(-580, -580, '%8.2f' % t.value_in(units.yr), fontsize=18) # pyplot.text(-400,-400,len(nemesis.particles),fontsize=18) pyplot.savefig('xy%6.6i.png' % nstep, bbox_inches='tight') f.clear() pyplot.close(f) nstep += 1 time = numpy.array(time) totalE = numpy.array(totalE) totalA = numpy.array(totalA) totalP = numpy.array(totalP) xx = numpy.array(xx) yy = numpy.array(yy) f = pyplot.figure(figsize=(8, 8)) pyplot.semilogy(time, totalE, 'r') pyplot.semilogy(time, totalA, 'g') pyplot.semilogy(time, totalP, 'b') pyplot.savefig('dEdA.png') f = pyplot.figure(figsize=(8, 8)) for i in range(len(xx[0])): pyplot.plot(xx[:, i], yy[:, i], colors[i % len(colors)] + linestyles[i % len(linestyles)]) pyplot.xlim(-LL, LL) pyplot.ylim(-LL, LL) pyplot.savefig('all-xy.png')
E_n[i] = M_to_E(M_n[i], e) f_n = E_to_f(E_n, e) ## Generate n sets of binaries # - fixed primary particle primary = Particle(mass=m1, position=[0, 0, 0] | units.AU, velocity=[0, 0, 0] | units.AU / units.s) secondary = Particle(mass=m2) # - generated secondary particle and formed set Pset_n = [] Pcenter_n = [] M_tot = [] redu_m = [] for i in range(n): M_tot.append(primary.mass + secondary.mass) redu_m.append(primary.mass * secondary.mass / (primary.mass + secondary.mass)) Pset = Particles(0) Pset.add_particle(primary) secondary_i = kepl_to_cart(secondary, primary, a, e, i_n[i], omg_n[i], OMG_n[i], f_n[i]) Pset.add_particle(secondary_i) Pset_n.append(Pset) Pcenter = Particles(0) Pcenter.add_particle(primary) Pcenter.add_particle(secondary_i) Pcenter.move_to_center() Pcenter_n.append(Pcenter)
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 get_orbit_ini(m0, m1, peri, ecc, incl, omega, rel_force=0.01, r_disk=50 | units.AU): converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) # semi-major axis if ecc != 1.0: semi = peri / (1.0 - ecc) else: semi = 1.0e10 | units.AU # relative position and velocity vectors at the pericenter using kepler kepler = Kepler_twobody(converter) kepler.initialize_code() kepler.initialize_from_elements(mass=(m0 + m1), semi=semi, ecc=ecc, periastron=peri) # at pericenter # moving particle backwards to radius r where: F_m1(r) = rel_force*F_m0(r_disk) #r_disk = peri r_ini = r_disk * (1.0 + numpy.sqrt(m1 / m0) / rel_force) kepler.return_to_radius(radius=r_ini) rl = kepler.get_separation_vector() r = [ rl[0].value_in(units.AU), rl[1].value_in(units.AU), rl[2].value_in( units.AU) ] | units.AU vl = kepler.get_velocity_vector() v = [ vl[0].value_in(units.kms), vl[1].value_in(units.kms), vl[2].value_in( units.kms) ] | units.kms period_kepler = kepler.get_period() time_peri = kepler.get_time() kepler.stop() # rotation of the orbital plane by inclination and argument of periapsis a1 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a2 = ([numpy.cos(omega), -numpy.sin(omega), 0.0], [numpy.sin(omega), numpy.cos(omega), 0.0], [0.0, 0.0, 1.0]) rot = numpy.dot(a1, a2) r_au = numpy.reshape(r.value_in(units.AU), 3, 1) v_kms = numpy.reshape(v.value_in(units.kms), 3, 1) r_rot = numpy.dot(rot, r_au) | units.AU v_rot = numpy.dot(rot, v_kms) | units.kms bodies = Particles(2) bodies[0].mass = m0 bodies[0].radius = 1.0 | units.RSun bodies[0].position = (0, 0, 0) | units.AU bodies[0].velocity = (0, 0, 0) | units.kms bodies[1].mass = m1 bodies[1].radius = 1.0 | units.RSun bodies[1].x = r_rot[0] bodies[1].y = r_rot[1] bodies[1].z = r_rot[2] bodies[1].vx = v_rot[0] bodies[1].vy = v_rot[1] bodies[1].vz = v_rot[2] bodies.age = 0.0 | units.yr bodies.move_to_center() print "\t r_rel_ini = ", r_rot.in_(units.AU) print "\t v_rel_ini = ", v_rot.in_(units.kms) print "\t time since peri = ", time_peri.in_(units.yr) a_orbit, e_orbit, p_orbit = orbital_parameters(r_rot, v_rot, (m0 + m1)) print "\t a = ", a_orbit.in_( units.AU), "\t e = ", e_orbit, "\t period = ", p_orbit.in_(units.yr) return bodies, time_peri
def new_binary_from_orbital_elements(mass1, mass2, semimajor_axis, eccentricity=0, true_anomaly=0, inclination=0, longitude_of_the_ascending_node=0, argument_of_periapsis=0, G=nbody_system.G): """ Function that returns two-particle Particle set, with the second particle position and velocities computed from the input orbital elements. angles in degrees, inclination between 0 and 180 """ inclination = numpy.radians(inclination) argument_of_periapsis = numpy.radians(argument_of_periapsis) longitude_of_the_ascending_node = numpy.radians( longitude_of_the_ascending_node) true_anomaly = numpy.radians(true_anomaly) cos_true_anomaly = numpy.cos(true_anomaly) sin_true_anomaly = numpy.sin(true_anomaly) cos_inclination = numpy.cos(inclination) sin_inclination = numpy.sin(inclination) cos_arg_per = numpy.cos(argument_of_periapsis) sin_arg_per = numpy.sin(argument_of_periapsis) cos_long_asc_nodes = numpy.cos(longitude_of_the_ascending_node) sin_long_asc_nodes = numpy.sin(longitude_of_the_ascending_node) ### alpha is a unit vector directed along the line of node ### alphax = cos_long_asc_nodes * cos_arg_per - sin_long_asc_nodes * sin_arg_per * cos_inclination alphay = sin_long_asc_nodes * cos_arg_per + cos_long_asc_nodes * sin_arg_per * cos_inclination alphaz = sin_arg_per * sin_inclination alpha = [alphax, alphay, alphaz] ### beta is a unit vector perpendicular to alpha and the orbital angular momentum vector ### betax = -cos_long_asc_nodes * sin_arg_per - sin_long_asc_nodes * cos_arg_per * cos_inclination betay = -sin_long_asc_nodes * sin_arg_per + cos_long_asc_nodes * cos_arg_per * cos_inclination betaz = cos_arg_per * sin_inclination beta = [betax, betay, betaz] # print 'alpha',alphax**2+alphay**2+alphaz**2 # For debugging; should be 1 # print 'beta',betax**2+betay**2+betaz**2 # For debugging; should be 1 ### Relative position and velocity ### separation = semimajor_axis * (1.0 - eccentricity**2) / ( 1.0 + eccentricity * cos_true_anomaly ) # Compute the relative separation position_vector = separation * cos_true_anomaly * alpha + separation * sin_true_anomaly * beta velocity_tilde = (G * (mass1 + mass2) / (semimajor_axis * (1.0 - eccentricity**2))).sqrt() # Common factor velocity_vector = -1.0 * velocity_tilde * sin_true_anomaly * alpha + velocity_tilde * ( eccentricity + cos_true_anomaly) * beta result = Particles(2) result[0].mass = mass1 result[1].mass = mass2 result[1].position = position_vector result[1].velocity = velocity_vector result.move_to_center() return result
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 new_binary_from_orbital_elements( mass1, mass2, semimajor_axis, eccentricity = 0, true_anomaly = 0, inclination = 0, longitude_of_the_ascending_node = 0, argument_of_periapsis = 0, G=nbody_system.G ): """ Function that returns two-particle Particle set, with the second particle position and velocities computed from the input orbital elements. angles in degrees, inclination between 0 and 180 """ inclination = numpy.radians(inclination) argument_of_periapsis = numpy.radians(argument_of_periapsis) longitude_of_the_ascending_node = numpy.radians(longitude_of_the_ascending_node) true_anomaly = numpy.radians(true_anomaly) cos_true_anomaly = numpy.cos(true_anomaly) sin_true_anomaly = numpy.sin(true_anomaly) cos_inclination = numpy.cos(inclination) sin_inclination = numpy.sin(inclination) cos_arg_per = numpy.cos(argument_of_periapsis) sin_arg_per = numpy.sin(argument_of_periapsis) cos_long_asc_nodes = numpy.cos(longitude_of_the_ascending_node) sin_long_asc_nodes = numpy.sin(longitude_of_the_ascending_node) ### alpha is a unit vector directed along the line of node ### alphax = cos_long_asc_nodes*cos_arg_per - sin_long_asc_nodes*sin_arg_per*cos_inclination alphay = sin_long_asc_nodes*cos_arg_per + cos_long_asc_nodes*sin_arg_per*cos_inclination alphaz = sin_arg_per*sin_inclination alpha = [alphax,alphay,alphaz] ### beta is a unit vector perpendicular to alpha and the orbital angular momentum vector ### betax = -cos_long_asc_nodes*sin_arg_per - sin_long_asc_nodes*cos_arg_per*cos_inclination betay = -sin_long_asc_nodes*sin_arg_per + cos_long_asc_nodes*cos_arg_per*cos_inclination betaz = cos_arg_per*sin_inclination beta = [betax,betay,betaz] # print 'alpha',alphax**2+alphay**2+alphaz**2 # For debugging; should be 1 # print 'beta',betax**2+betay**2+betaz**2 # For debugging; should be 1 ### Relative position and velocity ### separation = semimajor_axis*(1.0 - eccentricity**2)/(1.0 + eccentricity*cos_true_anomaly) # Compute the relative separation position_vector = separation*cos_true_anomaly*alpha + separation*sin_true_anomaly*beta velocity_tilde = (G*(mass1 + mass2)/(semimajor_axis*(1.0 - eccentricity**2))).sqrt() # Common factor velocity_vector = -1.0*velocity_tilde*sin_true_anomaly*alpha + velocity_tilde*(eccentricity + cos_true_anomaly)*beta result = Particles(2) result[0].mass = mass1 result[1].mass = mass2 result[1].position = position_vector result[1].velocity = velocity_vector result.move_to_center() return result
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 make_model(self): call=[self._exec]+self.arguments() print(call) mameclot=Popen(call, stdout=PIPE,stderr=PIPE,executable=os.path.join(self._bin_path,self._exec)) (out,err)=mameclot.communicate() print(err) outsplit=out.decode().strip().split("\n") errsplit=err.decode().strip().split("\n") if self.mass_ratio==0: nline=errsplit[6].split() mline=errsplit[7].split() rline=errsplit[8].split() N1=int(nline[2]) N2=0 mscale=(float(mline[4])/float(mline[2])) | units.MSun rscale=(float(rline[4])/float(mline[2])) | units.parsec else: nline=errsplit[8].split() n2line=errsplit[22].split() mline=errsplit[9].split() rline=errsplit[10].split() N1=int(nline[2]) N2=int(n2line[2]) mscale=(float(mline[4])/float(mline[2])) | units.MSun rscale=(float(rline[4])/float(mline[2])) | units.parsec print(N1,N2) N=len( outsplit) parts=Particles(N) masses=numpy.zeros((N,)) energy=numpy.zeros((N,)) position=numpy.zeros((N,3)) velocity=numpy.zeros((N,3)) for i,line in enumerate(outsplit): l=line.split() masses[i]=float(l[0]) position[i,0:3]=[float(l[1]),float(l[2]),float(l[3])] velocity[i,0:3]=[float(l[4]),float(l[5]),float(l[6])] energy[i]=float(l[7]) parts.mass=masses | nbody_system.mass parts.position=position | nbody_system.length parts.velocity=velocity | nbody_system.speed parts.specific_energy=energy| nbody_system.specific_energy parts.move_to_center() if self.convert_to_physical: print("mass scale:", mscale) print("length scale:", rscale) convert_nbody=nbody_system.nbody_to_si(mscale,rscale) parts = ParticlesWithUnitsConverted(parts, convert_nbody.as_converter_from_si_to_generic()) parts = parts.copy() self._all=parts self._cluster1=parts[:N1] self._cluster2=parts[N1:]
def make_model(self): call = [self._exec] + self.arguments() print call mameclot = Popen(call, stdout=PIPE, stderr=PIPE, executable=os.path.join(self._bin_path, self._exec)) (out, err) = mameclot.communicate() print err outsplit = out.strip().split("\n") errsplit = err.strip().split("\n") if self.mass_ratio == 0: nline = errsplit[6].split() mline = errsplit[7].split() rline = errsplit[8].split() N1 = int(nline[2]) N2 = 0 mscale = (float(mline[4]) / float(mline[2])) | units.MSun rscale = (float(rline[4]) / float(mline[2])) | units.parsec else: nline = errsplit[8].split() n2line = errsplit[22].split() mline = errsplit[9].split() rline = errsplit[10].split() N1 = int(nline[2]) N2 = int(n2line[2]) mscale = (float(mline[4]) / float(mline[2])) | units.MSun rscale = (float(rline[4]) / float(mline[2])) | units.parsec print N1, N2 N = len(outsplit) parts = Particles(N) masses = numpy.zeros((N,)) energy = numpy.zeros((N,)) position = numpy.zeros((N, 3)) velocity = numpy.zeros((N, 3)) for i, line in enumerate(outsplit): l = line.split() masses[i] = float(l[0]) position[i, 0:3] = [float(l[1]), float(l[2]), float(l[3])] velocity[i, 0:3] = [float(l[4]), float(l[5]), float(l[6])] energy[i] = float(l[7]) parts.mass = masses | nbody_system.mass parts.position = position | nbody_system.length parts.velocity = velocity | nbody_system.speed parts.specific_energy = energy | nbody_system.specific_energy parts.move_to_center() if self.convert_to_physical: print "mass scale:", mscale print "length scale:", rscale convert_nbody = nbody_system.nbody_to_si(mscale, rscale) parts = ParticlesWithUnitsConverted(parts, convert_nbody.as_converter_from_si_to_generic()) parts = parts.copy() self._all = parts self._cluster1 = parts[:N1] self._cluster2 = parts[N1:]
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_orbit_ini(m0, m1, peri, ecc, incl, omega, rel_force=0.01, r_disk=50|units.AU): converter=nbody_system.nbody_to_si(1|units.MSun,1|units.AU) # semi-major axis if ecc!=1.0: semi = peri/(1.0-ecc) else: semi = 1.0e10 | units.AU # relative position and velocity vectors at the pericenter using kepler kepler = Kepler_twobody(converter) kepler.initialize_code() kepler.initialize_from_elements(mass=(m0+m1), semi=semi, ecc=ecc, periastron=peri) # at pericenter # moving particle backwards to radius r where: F_m1(r) = rel_force*F_m0(r_disk) #r_disk = peri r_ini = r_disk*(1.0 + numpy.sqrt(m1/m0)/rel_force) kepler.return_to_radius(radius=r_ini) rl = kepler.get_separation_vector() r = [rl[0].value_in(units.AU), rl[1].value_in(units.AU), rl[2].value_in(units.AU)] | units.AU vl = kepler.get_velocity_vector() v = [vl[0].value_in(units.kms), vl[1].value_in(units.kms), vl[2].value_in(units.kms)] | units.kms period_kepler = kepler.get_period() time_peri = kepler.get_time() kepler.stop() # rotation of the orbital plane by inclination and argument of periapsis a1 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a2 = ([numpy.cos(omega), -numpy.sin(omega), 0.0], [numpy.sin(omega), numpy.cos(omega), 0.0], [0.0, 0.0, 1.0]) rot = numpy.dot(a1,a2) r_au = numpy.reshape(r.value_in(units.AU), 3, 1) v_kms = numpy.reshape(v.value_in(units.kms), 3, 1) r_rot = numpy.dot(rot, r_au) | units.AU v_rot = numpy.dot(rot, v_kms) | units.kms bodies = Particles(2) bodies[0].mass = m0 bodies[0].radius = 1.0|units.RSun bodies[0].position = (0,0,0) | units.AU bodies[0].velocity = (0,0,0) | units.kms bodies[1].mass = m1 bodies[1].radius = 1.0|units.RSun bodies[1].x = r_rot[0] bodies[1].y = r_rot[1] bodies[1].z = r_rot[2] bodies[1].vx = v_rot[0] bodies[1].vy = v_rot[1] bodies[1].vz = v_rot[2] bodies.age = 0.0 | units.yr bodies.move_to_center() print "\t r_rel_ini = ", r_rot.in_(units.AU) print "\t v_rel_ini = ", v_rot.in_(units.kms) print "\t time since peri = ", time_peri.in_(units.yr) a_orbit, e_orbit, p_orbit = orbital_parameters(r_rot, v_rot, (m0+m1)) print "\t a = ", a_orbit.in_(units.AU), "\t e = ", e_orbit, "\t period = ", p_orbit.in_(units.yr) return bodies, time_peri
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