def make_binary_star(mprim, msec, semimajor_axis, eccentricity): double_star = Particle() double_star.is_binary = True double_star.mass = mprim + msec double_star.semimajor_axis = semimajor_axis double_star.eccentricity = eccentricity period = (2 * numpy.pi * (semimajor_axis * semimajor_axis * semimajor_axis / (constants.G * double_star.mass)).sqrt()) print("Period =", period.as_string_in(units.yr)) stars = new_binary_from_orbital_elements(mprim, msec, semimajor_axis, eccentricity, G=constants.G) stars.is_binary = False double_star.child1 = stars[0] double_star.child1.name = "primary" double_star.child2 = stars[1] double_star.child2.name = "secondary" for star in stars: star.radius = (star.mass.value_in(units.MSun)**0.8) | units.RSun return double_star, stars
def comet_positions_and_velocities(N_objects, sun_location): positions = np.zeros((N_objects, 3)) | units.AU velocities = np.zeros((N_objects, 3)) | units.kms m_sun = 1 | units.MSun m_comet = 0 | units.MSun for i in range(N_objects): # Values below correspond with random locations anywhere in the Solar System, based of relevant literature a = np.random.uniform(4, 40) | units.AU # semi-major axis e = np.random.uniform(0, 0.05) # eccentricity inclination = np.random.uniform(-5, 5) | units.deg true_anomaly = np.random.uniform(0, 360) | units.deg arg_of_periapsis = np.random.uniform(0, 360) | units.deg long_of_ascending_node = np.random.uniform(0, 360) | units.deg sun_and_comet = new_binary_from_orbital_elements( m_sun, m_comet, a, e, true_anomaly, inclination, long_of_ascending_node, arg_of_periapsis, G=constants.G) positions[i] = (sun_and_comet[1].x + sun_location[0]), ( sun_and_comet[1].y + sun_location[1]), (sun_and_comet[1].z + sun_location[2]) velocities[i] = sun_and_comet[1].vx, sun_and_comet[ 1].vy, sun_and_comet[1].vz return positions, velocities
def test1(self): mass1 = 1 | nbody_system.mass mass2 = 1 | nbody_system.mass binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length ) self.assertEquals(len(binary), 2) binary.position -= binary[0].position binary.velocity -= binary[0].velocity self.assertAlmostRelativeEquals( binary[0].position, [0, 0, 0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[1].position, [1, 0, 0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[0].velocity, [0, 0, 0] | nbody_system.speed) self.assertAlmostRelativeEquals( binary[1].velocity, [0, numpy.sqrt(2), 0] | nbody_system.speed)
def make_secondary(parent, companion_name, mass, semimajor_axis, eccentricity, inclination, mean_anomaly, LoAn, Aop, ctype="star"): from amuse.ext.orbital_elements import new_binary_from_orbital_elements from add_asteroids_to_solar_system import True_anomaly_from_mean_anomaly Ta = True_anomaly_from_mean_anomaly(numpy.deg2rad(mean_anomaly), eccentricity) bs = new_binary_from_orbital_elements(parent.mass, mass, semimajor_axis, eccentricity, Ta, inclination, LoAn, Aop, G=constants.G) companion = bs[1] companion.position -= bs[0].position companion.velocity -= bs[0].velocity companion.position += parent.position companion.velocity += parent.velocity companion.type = "star" companion.name = companion_name #companion.host = parent.key companion.radius = ZAMS_radius(companion.mass) return companion
def rescale_planetary_orbit(sun, planets, name, sma): planet = planets[planets.name == name] pos = planet.position vel = planet.velocity ang_1, ang_2, ang_3 = numpy.random.uniform(0, 2 * numpy.pi, 3) ecc = 0.01 * numpy.random.random() inc = numpy.random.random() binary = new_binary_from_orbital_elements( sun.mass, planet.mass, sma, ecc, inclination=inc, true_anomaly=ang_1, argument_of_periapsis=ang_2, longitude_of_the_ascending_node=ang_3, G=constants.G) binary.position -= binary[0].position binary.velocity -= binary[0].velocity planet.position = binary[1].position planet.velocity = binary[1].velocity planet.semimajor_axis = sma planet.eccentricity = ecc planet.inclination = inc planet.type = "planet" planet.name = name planet.hostname = sun.name return planet
def construct_particle_set_from_orbital_elements(name, mass, a, ecc, inc, Ma, Aop, LoAn, parent): #print("length:", len(a), len(ecc), len(inc), len(Ma), len(Aop), len(LoAn), len(name)) p = Particles(len(a)) p.name = name p.type = "planet" p.host = parent.name Earth = p[p.name == "EM"] Earth.name = "EarthMoon" from orbital_elements_to_cartesian import orbital_elements_to_pos_and_vel from orbital_elements_to_cartesian import orbital_period from amuse.ext.orbital_elements import new_binary_from_orbital_elements for i in range(len(p)): p[i].mass = mass[i] Ta = True_anomaly_from_mean_anomaly(numpy.deg2rad(Ma[i]), ecc[i]) #print("True Anomaly:", Ta) b = new_binary_from_orbital_elements(parent.mass, p[i].mass, a[i], ecc[i], Ta, inc[i], LoAn[i], Aop[i], G=constants.G) p[i].position = b[1].position - b[0].position p[i].velocity = b[1].velocity - b[0].velocity rho = 1.0 | units.g / units.cm**3 p.radius = (p.mass / rho)**(1. / 3.) return p
def make_planetesimal_disk(Nplanetesimals): amin = 6.4 | units.AU amax = 30 | units.AU emax = 0.1 imax = 1 a = amin + (amax - amin) * numpy.random.random_sample(Nplanetesimals) e = emax * numpy.random.random_sample(Nplanetesimals) i = imax * numpy.random.random_sample(Nplanetesimals) ta = 0 # numpy.acos(np.random.uniform(0,2*numpy.pi,Nplanetesimals)) loan = 0 aof = 0 mp = 0.1 | units.MEarth planetesimals = Particles(Nplanetesimals) for i, pi in enumerate(planetesimals): b = new_binary_from_orbital_elements(Mstar, mp, a[i], e[i], ta, inc[i], loan, aof, G=constant.G) pi.mass = mp pi.position = b[1].position pi.velocity = b[1].velocity return planetesimals
def test8(self): """ testing orbital_elements_for_rel_posvel_arrays for extreme cases """ N = 3 mass1 = (1.2 * numpy.ones(N)) | units.MSun mass2 = (0.1, 0.05, 0.003) | units.MSun semi_major_axis = (1., 2., 3.) | units.AU eccentricity = (0., 0.5, 0.6) true_anomaly = (0., 0., 66.) inclination = (12., 0., 180.) longitude_of_the_ascending_node = ( 0., 0., 0., ) argument_of_periapsis = (0., 23., 90.) mass12 = [] rel_position = [] rel_velocity = [] for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=constants.G) mass12.append(sun_and_comet[0].mass + sun_and_comet[1].mass) rel_position.append(sun_and_comet[1].position - sun_and_comet[0].position) rel_velocity.append(sun_and_comet[1].velocity - sun_and_comet[0].velocity) # to convert lists to vector quantities rel_pos = numpy.array( [vec_i.value_in(units.AU) for vec_i in rel_position]) | units.AU rel_vel = numpy.array( [vec_i.value_in(units.kms) for vec_i in rel_velocity]) | units.kms mass_12 = numpy.array([m_i.value_in(units.MSun) for m_i in mass12]) | units.MSun semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(rel_pos, rel_vel, mass_12, G=constants.G) rad_to_deg = 180. / numpy.pi for i in range(N): self.assertAlmostEqual(semi_major_axis[i].value_in(units.AU), semi_major_axis_ext[i].value_in(units.AU)) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual(inclination[i], rad_to_deg * inclination_ext[i]) self.assertAlmostEqual( longitude_of_the_ascending_node[i], rad_to_deg * longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual(argument_of_periapsis[i], rad_to_deg * argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], rad_to_deg * ta_ext[i])
def kepler_binary_from_orbital_elements(m1, m2, sma, ecc, true_anom, inc, long_asc_node, arg_peri): """ returns two particles (w/ coordinates in 'Center of Mass' frame) from given orbital elements """ return new_binary_from_orbital_elements(m1, m2, sma, ecc, true_anom, inc, long_asc_node, arg_peri, G = constants.G)
def new_binary_from_elements(*args, **kwargs): """ amuse.ext.orbital_elements.new_binary_from_elements places the center of mass at the origin. This function reverts the transformation.""" if 'G' not in kwargs: kwargs['G'] = constants.G binary = orbital_elements_amuse.new_binary_from_orbital_elements(*args, **kwargs) binary.position += binary.center_of_mass() binary.velocity += binary.center_of_mass_velocity() return binary
def new_binary_from_elements(*args, **kwargs): """ amuse.ext.orbital_elements.new_binary_from_elements places the center of mass at the origin. This function reverts the transformation.""" if 'G' not in kwargs: kwargs['G'] = constants.G binary = orbital_elements_amuse.new_binary_from_orbital_elements( *args, **kwargs) binary.position += binary.center_of_mass() binary.velocity += binary.center_of_mass_velocity() return binary
def test_kepler_almost_parabolic(tend=1, method=0): code = Kepler(redirection="none") code.set_method(method) mass1 = 1. | nbody_system.mass mass2 = 0 | nbody_system.mass semimajor_axis = 1. | nbody_system.length eccentricity = 0.9999999 p = 2 * numpy.pi * (semimajor_axis**3 / nbody_system.G / mass1)**0.5 tend = tend * p print(tend) parts = new_binary_from_orbital_elements(mass1, mass2, semimajor_axis, eccentricity=eccentricity, true_anomaly=0.0102121) code.central_particle.add_particle(parts[0]) code.orbiters.add_particle(parts[1]) a0, eps0 = elements(mass1, code.orbiters.x, code.orbiters.y, code.orbiters.z, code.orbiters.vx, code.orbiters.vy, code.orbiters.vz, G=nbody_system.G) print(orbital_elements_from_binary(code.particles[0:2])) t1 = time.time() code.evolve_model(tend) t2 = time.time() print(orbital_elements_from_binary(code.particles[0:2])) print(code.orbiters.position) a, eps = elements(mass1, code.orbiters.x, code.orbiters.y, code.orbiters.z, code.orbiters.vx, code.orbiters.vy, code.orbiters.vz, G=nbody_system.G) da = abs((a - a0) / a0) deps = abs(eps - eps0) / eps0 print(da, deps) print("time:", t2 - t1)
def test15(self): """ testing orbital_elements_for_rel_posvel_arrays for N particles with random orbital elements """ numpy.random.seed(666) N = 100 mass_sun = 1. | units.MSun mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) | units.MSun semi_major_axis = (-numpy.log(random.random(N))) | units.AU eccentricity = random.random(N) true_anomaly = 360.*random.random(N)-180. inclination = 180*random.random(N) longitude_of_the_ascending_node = 360*random.random(N)-180 argument_of_periapsis = 360*random.random(N)-180 comets = datamodel.Particles(N) suns = datamodel.Particles(N) for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements( *arg, G=constants.G) comets[i].mass = sun_and_comet[1].mass comets[i].position = sun_and_comet[1].position comets[i].velocity = sun_and_comet[1].velocity suns.mass = mass1 suns.position = 0*comets.position suns.velocity = 0*comets.velocity mass1_ext, mass2_ext, semi_major_axis_ext, eccentricity_ext, ta_ext,\ inclination_ext, longitude_of_the_ascending_node_ext,\ argument_of_periapsis_ext = orbital_elements( suns, comets, G=constants.G) rad_to_deg = 180./numpy.pi for i in range(N): self.assertAlmostEqual( semi_major_axis[i].value_in(units.AU), semi_major_axis_ext[i].value_in(units.AU)) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual( inclination[i], rad_to_deg*inclination_ext[i]) self.assertAlmostEqual( longitude_of_the_ascending_node[i], rad_to_deg*longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual( argument_of_periapsis[i], rad_to_deg*argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], rad_to_deg*ta_ext[i])
def get_ffp_in_orbit(m0, m, a, e, phi): """ initialize attributes of the star and the ffp. """ star_ffp = new_binary_from_orbital_elements(m0, m, a, e, true_anomaly=phi) star_ffp.position -= star_ffp[0].position star_ffp.velocity -= star_ffp[0].velocity print 'v_inf_orb =',(star_ffp[1].vx**2+star_ffp[1].vy**2+star_ffp[1].vz**2).sqrt() print star_ffp return star_ffp
def create_pre_tack_giants_system(): #Create a pre_tack_giants_system by first recreating the sun. pre_tack_giants_system = Particles(1) pre_tack_giants_system[0].name = "Sun" pre_tack_giants_system[0].mass = 1.0 | units.MSun pre_tack_giants_system[0].radius = 1.0 | units.RSun pre_tack_giants_system[0].position = (0, 0, 0) | units.AU pre_tack_giants_system[0].velocity = (0, 0, 0) | units.kms pre_tack_giants_system[0].density = 3 * pre_tack_giants_system[0].mass / ( 4 * np.pi * pre_tack_giants_system[0].radius**3) #The pre tack orbital elements for the planets as below names = ["Jupiter", "Saturn", "Uranus", "Neptune"] masses = np.array([317.8, 30, 5, 5]) | units.MEarth radii = np.array([0.10049, 0.083703, 0.036455, 0.035392]) | units.RSun a = np.array([3.5, 4.5, 6.013, 8.031]) | units.AU inclinations = np.random.uniform(-5, 5, 4) | units.deg true_anomalies = np.random.uniform(0, 360, 4) | units.deg longs_of_ascending_node = np.random.uniform(0, 360, 4) | units.deg args_of_periapsis = np.random.uniform(0, 360, 4) | units.deg #Create the four planets as binaries with the sun and add them to the pre_tack_giants_system for i in range(4): sun_and_planet = new_binary_from_orbital_elements( pre_tack_giants_system[0].mass, masses[i], a[i], 0, true_anomalies[i], inclinations[i], longs_of_ascending_node[i], args_of_periapsis[i], G=constants.G) planet = Particles(1) planet.name = names[i] planet.mass = masses[i] planet.radius = radii[ i] # This is purely non-zero for collisional purposes planet.position = (sun_and_planet[1].x - (0 | units.AU), sun_and_planet[1].y - (0 | units.AU), sun_and_planet[1].z - (0 | units.AU)) planet.velocity = (sun_and_planet[1].vx - (0 | units.kms), sun_and_planet[1].vy - (0 | units.kms), sun_and_planet[1].vz - (0 | units.kms)) planet.density = 3 * planet.mass / (4 * np.pi * planet.radius**3) pre_tack_giants_system.add_particle(planet) return pre_tack_giants_system
def get_bodies_in_orbit(m0, m_ffp, m_bp, a_bp, e_bp, phi_bp, lan_bp, b_ffp, r_inf): #Bodies bodies = Particles() ##Get BP in orbit #Binary star_planet = new_binary_from_orbital_elements(m0, m_bp, a_bp, e_bp, true_anomaly=phi_bp, inclination = 28, longitude_of_the_ascending_node = lan_bp) #Planet attributes star_planet.eccentricity = e_bp star_planet.semimajoraxis = a_bp #Center on the star star_planet.position -= star_planet[0].position star_planet.velocity -= star_planet[0].velocity cm_p = star_planet.center_of_mass() cm_v = star_planet.center_of_mass_velocity() ##Get FFP in orbit #Particle set m0_ffp = Particles(2) #Zeros and parabolic velocity zero_p = 0.0 | nbody_system.length zero_v = 0.0 | nbody_system.speed parabolic_velocity = get_parabolic_velocity(m0, m_ffp, b_ffp, r_inf, m_bp, a_bp, phi_bp) #Central star m0_ffp[0].mass = m0 m0_ffp[0].position = (zero_p,zero_p,zero_p) m0_ffp[0].velocity = (zero_v,zero_v,zero_v) #Free-floating planet m0_ffp[1].mass = m_ffp m0_ffp[1].position = (-r_inf-cm_p[0],-b_ffp-cm_p[1],zero_p) m0_ffp[1].velocity = (parabolic_velocity,zero_v,zero_v) #Orbital Elements star_planet_as_one = Particles(1) star_planet_as_one.mass = m0 + m_bp star_planet_as_one.position = cm_p star_planet_as_one.velocity = cm_v binary = [star_planet_as_one[0], m0_ffp[1]] m1, m2, sma, e = my_orbital_elements_from_binary(binary) #For the star it sets the initial values of semimajoraxis and eccentricity of the ffp around star+bp m0_ffp.eccentricity = e m0_ffp.semimajoraxis = sma #Order: star, ffp, bp bodies.add_particle(m0_ffp[0]) bodies.add_particle(m0_ffp[1]) bodies.add_particle(star_planet[1]) return bodies
def kepler_binary_from_orbital_elements(m1, m2, sma, ecc, true_anom, inc, long_asc_node, arg_peri): """ returns two particles (w/ coordinates in 'Center of Mass' frame) from given orbital elements """ return new_binary_from_orbital_elements(m1, m2, sma, ecc, true_anom, inc, long_asc_node, arg_peri, G=constants.G)
def xtest3(self): mass1 = 1 | nbody_system.mass mass2 = 1 | nbody_system.mass binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0.5 ) self.assertEquals(len(binary), 2) self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [0,numpy.sqrt(2),0] | nbody_system.speed)
def test3(self): mass1 = 1. | nbody_system.mass mass2 = 1. | nbody_system.mass binary = new_binary_from_orbital_elements( mass1, mass2, 1. | nbody_system.length, eccentricity = 0. ) self.assertEquals(len(binary), 2) self.assertAlmostRelativeEquals(binary[0].position, [-0.5,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0.5,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,-1/numpy.sqrt(2),0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [0,1/numpy.sqrt(2),0] | nbody_system.speed)
def gravity_hydro_bridge(Mprim, Msec, a, ecc, t_end, n_steps, Rgas, Mgas, Ngas): stars = new_binary_from_orbital_elements(Mprim, Msec, a, ecc, G=constants.G) eps = 1 | units.RSun gravity = Gravity(ph4, stars, eps) converter = nbody_system.nbody_to_si(1.0 | units.MSun, Rgas) ism = new_plummer_gas_model(Ngas, convert_nbody=converter) ism.move_to_center() ism = ism.select(lambda r: r.length() < 2 * a, ["position"]) hydro = Hydro(Fi, ism, eps) model_time = 0 | units.Myr filename = "gravhydro.hdf5" write_set_to_file(stars.savepoint(model_time), filename, 'amuse') write_set_to_file(ism, filename, 'amuse') gravhydro = bridge.Bridge(use_threading=False) gravhydro.add_system(gravity, (hydro, )) gravhydro.add_system(hydro, (gravity, )) gravhydro.timestep = 2 * hydro.get_timestep() while model_time < t_end: orbit = orbital_elements_from_binary(stars, G=constants.G) a = orbit[2] ecc = orbit[3] dE_gravity = gravity.initial_total_energy / gravity.total_energy dE_hydro = hydro.initial_total_energy / hydro.total_energy print "Time:", model_time.in_(units.yr), "ae=", a.in_( units.AU), ecc, "dE=", dE_gravity, dE_hydro model_time += 10 * gravhydro.timestep gravhydro.evolve_model(model_time) gravity.copy_to_framework() hydro.copy_to_framework() write_set_to_file(stars.savepoint(model_time), filename, 'amuse') write_set_to_file(ism, filename, 'amuse') gravity.stop() hydro.stop()
def test9(self): """ testing orbital_elements_for_rel_posvel_arrays for N particles with random orbital elements, nbody_system """ numpy.random.seed(666) N = 100 mass_sun = 1. | nbody_system.mass mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) | nbody_system.mass semi_major_axis = (-numpy.log(random.random(N))) | nbody_system.length eccentricity = random.random(N) true_anomaly = 360. * random.random(N) - 180. inclination = 180 * random.random(N) longitude_of_the_ascending_node = 360 * random.random(N) - 180 argument_of_periapsis = 360 * random.random(N) - 180 comets = datamodel.Particles(N) for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=nbody_system.G) comets[i].mass = sun_and_comet[1].mass comets[i].position = sun_and_comet[1].position comets[i].velocity = sun_and_comet[1].velocity semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(comets.position, comets.velocity, comets.mass + mass_sun, G=nbody_system.G) rad_to_deg = 180. / numpy.pi for i in range(N): self.assertAlmostEqual(semi_major_axis[i], semi_major_axis_ext[i]) self.assertAlmostEqual(eccentricity[i], eccentricity_ext[i]) self.assertAlmostEqual(inclination[i], rad_to_deg * inclination_ext[i]) self.assertAlmostEqual( longitude_of_the_ascending_node[i], rad_to_deg * longitude_of_the_ascending_node_ext[i]) self.assertAlmostEqual(argument_of_periapsis[i], rad_to_deg * argument_of_periapsis_ext[i]) self.assertAlmostEqual(true_anomaly[i], rad_to_deg * ta_ext[i])
def test5(self): numpy.random.seed(4567893) N=100 mass1=random.random(N) | units.MSun mass2=random.random(N) | units.MSun semi_major_axis=(-numpy.log(random.random(N))) | units.AU eccentricity = random.random(N) true_anomaly = 360.*random.random(N)-180. inclination = 180*random.random(N) longitude_of_the_ascending_node = 360*random.random(N)-180 argument_of_periapsis = 360*random.random(N)-180 for arg in zip(mass1,mass2,semi_major_axis,eccentricity,true_anomaly,inclination, longitude_of_the_ascending_node,argument_of_periapsis): arg_=orbital_elements_from_binary(new_binary_from_orbital_elements(*arg,G=constants.G),G=constants.G) for i,(copy,org) in enumerate(zip(arg_,arg)): self.assertAlmostEquals(copy,org)
def get_planets(m0, a_planets, m_planets, e_planets, phi=0.): #Particle set with all planets planets = Particles() #Initialize star-planet orbit for i,a_i in enumerate(a_planets): #Binary star_planet = new_binary_from_orbital_elements(m0, m_planets[i], a_planets[i], e_planets[i], true_anomaly=phi) #Planets attributes star_planet.eccentricity = e_planets[i] star_planet.semimajoraxis = a_planets[i] #Center on the star star_planet.position -= star_planet[0].position star_planet.velocity -= star_planet[0].velocity planets.add_particle(star_planet[1]) return planets
def planet_v2(ID, host_star, planet_mass, init_a, init_e, random_orientation=False): ''' Creates a planet as an AMUSE Particle with provided characteristics. ID: Identifying number unique to this planet. host_star: The AMUSE Particle that is the host star for the planet. planet_mass: The mass of the planet (in the nbody units). init_a: Initial semi-major axis (in nbody units). init_e: Initial eccentricity (in nbody units). random_orientation: Boolean to incline the planet in a random fashion. ''' # Define the Host Star's Original Location & Position rCM = host_star.position vCM = host_star.velocity # Sets Planet Values to Provided Conditions p = datamodel.Particle() p.id = ID p.type = "planet" p.host_star = host_star.id p.mass = planet_mass # Sets the Dynamical Radius to the Hill Sphere Approx. p.radius = util.calc_HillRadius(init_a, init_e, p.mass, host_star.mass) # Generate a Random Position on the Orbit (True Anomaly) # This ensures that all the planets don't start out along the same joining line. init_ta = 360 * np.random.random() | units.deg # Get the Host Star & Planets Positions from Kepler Relative to the Origin newPSystem = new_binary_from_orbital_elements(host_star.mass, p.mass, init_a, eccentricity=init_e, true_anomaly=init_ta, G=constants.G) # Rotate the Binary System & Move to the CoM's Position if random_orientation: util.preform_EulerRotation(newPSystem) host_star.position = rCM + newPSystem[0].position host_star.velocity = vCM + newPSystem[0].velocity p.position = rCM + newPSystem[1].position p.velocity = vCM + newPSystem[1].velocity # Returns the Created AMUSE Particle return p
def test6(self): """ testing orbital_elements_for_rel_posvel_arrays for N particles with random orbital elements """ numpy.random.seed(666) N = 100 mass_sun = 1. | units.MSun mass1 = numpy.ones(N) * mass_sun mass2 = numpy.zeros(N) | units.MSun semi_major_axis = (-numpy.log(random.random(N))) | units.AU eccentricity = random.random(N) true_anomaly = 360. * random.random(N) - 180. inclination = 180 * random.random(N) longitude_of_the_ascending_node = 360 * random.random(N) - 180 argument_of_periapsis = 360 * random.random(N) - 180 comets = datamodel.Particles(N) for i, arg in enumerate( zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis)): sun_and_comet = new_binary_from_orbital_elements(*arg, G=constants.G) comets[i].mass = sun_and_comet[1].mass comets[i].position = sun_and_comet[1].position comets[i].velocity = sun_and_comet[1].velocity semi_major_axis_ext, eccentricity_ext, ta_ext, inclination_ext, \ longitude_of_the_ascending_node_ext, argument_of_periapsis_ext = \ orbital_elements_for_rel_posvel_arrays(comets.position, comets.velocity, comets.mass + mass_sun, G=constants.G) self.assertAlmostEqual(semi_major_axis, semi_major_axis_ext) self.assertAlmostEqual(eccentricity, eccentricity_ext) self.assertAlmostEqual(inclination, inclination_ext) self.assertAlmostEqual(longitude_of_the_ascending_node, longitude_of_the_ascending_node_ext) self.assertAlmostEqual(argument_of_periapsis, argument_of_periapsis_ext) self.assertAlmostEqual(true_anomaly, ta_ext)
def test_kepler_almost_parabolic( tend=1,method=0): code=Kepler(redirection="none") code.set_method(method) mass1=1.| nbody_system.mass mass2=0| nbody_system.mass semimajor_axis=1.|nbody_system.length eccentricity=0.9999999 p=2*numpy.pi*(semimajor_axis**3/nbody_system.G/mass1)**0.5 tend=tend*p print tend parts=new_binary_from_orbital_elements( mass1, mass2, semimajor_axis, eccentricity = eccentricity, true_anomaly = 0.0102121 ) code.central_particle.add_particle(parts[0]) code.orbiters.add_particle(parts[1]) a0,eps0=elements(mass1,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) print orbital_elements_from_binary(code.particles[0:2]) t1=time.time() code.evolve_model(tend) t2=time.time() print orbital_elements_from_binary(code.particles[0:2]) print code.orbiters.position a,eps=elements(mass1,code.orbiters.x,code.orbiters.y,code.orbiters.z, code.orbiters.vx,code.orbiters.vy,code.orbiters.vz,G=nbody_system.G) da=abs((a-a0)/a0) deps=abs(eps-eps0)/eps0 print da,deps print "time:",t2-t1
def add_secondaries(parent_stars, companion_name, masses, semimajor_axis, eccentricity, inclination, mean_anomaly, LoAn, Aop, ctype="star"): print("m=", masses) for i in range(len(parent_stars)): bi = parent_stars[i] binary_particle = Particle() binary_particle.position = bi.position binary_particle.velocity = bi.velocity binary_particle.type = ctype binary_particle.name = bi.name binary_particle.host = None binary_particle.type = "center_of_mass" mp = bi.mass ms = masses[i] from amuse.ext.orbital_elements import new_binary_from_orbital_elements Ta = True_anomaly_from_mean_anomaly(numpy.deg2rad(mean_anomaly), eccentricity) nb = new_binary_from_orbital_elements(mp, ms, semimajor_axis, eccentricity, Ta, inclination, LoAn, Aop, G=constants.G) nb.position += binary_particle.position nb.velocity += binary_particle.velocity nb[0].type = bi.type #nb[0].host = binary_particle nb[0].name = bi.name nb[1].type = ctype #nb[1].host = binary_particle nb[1].host = nb[0].name nb[1].name = companion_name nb[1].radius = ZAMS_radius(nb[1].mass) return nb
def test4(self): numpy.random.seed(3456789) N = 100 mass1 = random.random(N) | nbody_system.mass mass2 = random.random(N) | nbody_system.mass semi_major_axis = (-numpy.log(random.random(N))) | nbody_system.length eccentricity = random.random(N) true_anomaly = (360. * random.random(N) - 180.) | units.deg inclination = (180 * random.random(N)) | units.deg longitude_of_the_ascending_node = (360 * random.random(N) - 180) | units.deg argument_of_periapsis = (360 * random.random(N) - 180) | units.deg for arg in zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis): arg_ = orbital_elements(new_binary_from_orbital_elements(*arg)) for i, (copy, org) in enumerate(zip(arg_, arg)): self.assertAlmostEqual(copy, org)
def plummer_w_binaries(N, f_bin=1.,logamin=-4,logamax=-0.5,seed=123454321): random.seed(seed) plummer=new_plummer_model(N) semi=10**random.uniform(logamin,logamax,N) | nbody_system.length inc=numpy.arccos(random.uniform(-1.,1.,N))/numpy.pi*180 longi=random.uniform(0,2*numpy.pi,N)/numpy.pi*180 binaries=Particles() tobin=plummer[:int(f_bin*N)] nobin=plummer-tobin if len(nobin)>0: binaries.add_particles(nobin) for i,p in enumerate( tobin ): mass1=p.mass/2 mass2=p.mass/2 binary=new_binary_from_orbital_elements(mass1,mass2,semi[i], inclination=inc[i],longitude_of_the_ascending_node=longi[i]) binary.position+=p.position binary.velocity+=p.velocity binaries.add_particles(binary) return binaries
def gravity_hydro_bridge(Mprim, Msec, a, ecc, t_end, n_steps, Rgas, Mgas, Ngas): stars = new_binary_from_orbital_elements(Mprim, Msec, a, ecc, G=constants.G) eps = 1 | units.RSun gravity = Gravity(ph4, stars, eps) converter=nbody_system.nbody_to_si(1.0|units.MSun, Rgas) ism = new_plummer_gas_model(Ngas, convert_nbody=converter) ism.move_to_center() ism = ism.select(lambda r: r.length()<2*a,["position"]) hydro = Hydro(Fi, ism, eps) model_time = 0 | units.Myr filename = "gravhydro.hdf5" write_set_to_file(stars.savepoint(model_time), filename, 'amuse') write_set_to_file(ism, filename, 'amuse') gravhydro = bridge.Bridge(use_threading=False) gravhydro.add_system(gravity, (hydro,) ) gravhydro.add_system(hydro, (gravity,) ) gravhydro.timestep = 2*hydro.get_timestep() while model_time < t_end: orbit = orbital_elements_from_binary(stars, G=constants.G) a = orbit[2] ecc = orbit[3] dE_gravity = gravity.initial_total_energy/gravity.total_energy dE_hydro = hydro.initial_total_energy/hydro.total_energy print "Time:", model_time.in_(units.yr), "ae=", a.in_(units.AU), ecc, "dE=", dE_gravity, dE_hydro model_time += 10*gravhydro.timestep gravhydro.evolve_model(model_time) gravity.copy_to_framework() hydro.copy_to_framework() write_set_to_file(stars.savepoint(model_time), filename, 'amuse') write_set_to_file(ism, filename, 'amuse') gravity.stop() hydro.stop()
def construct_particle_set_from_orbital_elements(name, mass, a, ecc, inc, Ma, Aop, LoAn, Mparent=1 | units.MSun): print("length:", len(a), len(ecc), len(inc), len(Ma), len(Aop), len(LoAn), len(name)) p = Particles(len(a)) print(name) p.name = name p.type = "asteroid" p.host = "Sun" p.mass = mass from orbital_elements_to_cartesian import orbital_elements_to_pos_and_vel from orbital_elements_to_cartesian import orbital_period from amuse.ext.orbital_elements import new_binary_from_orbital_elements for i in range(len(p)): Ta = True_anomaly_from_mean_anomaly(numpy.rad2deg(Ma[i]), ecc[i]) b = new_binary_from_orbital_elements(Mparent, p[i].mass, a[i], ecc[i], Ta, inc[i], LoAn[i], Aop[i], G=constants.G) p[i].position = b[1].position - b[0].position p[i].velocity = b[1].velocity - b[0].velocity rho = 2.0 | units.g / units.cm**3 p.radius = (p.mass / rho)**(1. / 3.) return p
def test5(self): numpy.random.seed(4567893) N = 100 mass1 = random.random(N) | units.MSun mass2 = random.random(N) | units.MSun semi_major_axis = (-numpy.log(random.random(N))) | units.AU eccentricity = random.random(N) true_anomaly = 360. * random.random(N) - 180. inclination = 180 * random.random(N) longitude_of_the_ascending_node = 360 * random.random(N) - 180 argument_of_periapsis = 360 * random.random(N) - 180 for arg in zip(mass1, mass2, semi_major_axis, eccentricity, true_anomaly, inclination, longitude_of_the_ascending_node, argument_of_periapsis): arg_ = orbital_elements_from_binary( new_binary_from_orbital_elements(*arg, G=constants.G), G=constants.G) for i, (copy, org) in enumerate(zip(arg_, arg)): self.assertAlmostEquals(copy, org)
def test7(self): """ testing orbital_elements_for_rel_posvel_arrays for the case of one particle """ numpy.random.seed(999) mass1 = 0.5 | units.MSun mass2 = 0.8 | units.MSun sem = 12. | units.AU ecc = 0.05 inc = 20. lon = 10. arg = 0.4 ta = 360. * random.random() - 180. binary = new_binary_from_orbital_elements(mass1, mass2, sem, ecc, ta, inc, lon, arg, G=constants.G) rel_pos = binary[1].position - binary[0].position rel_vel = binary[1].velocity - binary[0].velocity mass_12 = binary[1].mass + binary[0].mass sem_ext, ecc_ext, ta_ext, inc_ext, lon_ext, arg_ext = \ orbital_elements_for_rel_posvel_arrays(rel_pos, rel_vel, mass_12, G=constants.G) rad_to_deg = 180. / numpy.pi self.assertAlmostEqual(sem.value_in(units.AU), sem_ext.value_in(units.AU)) self.assertAlmostEqual(ecc, ecc_ext) self.assertAlmostEqual(inc, rad_to_deg * inc_ext) self.assertAlmostEqual(lon, rad_to_deg * lon_ext) self.assertAlmostEqual(arg, rad_to_deg * arg_ext) self.assertAlmostEqual(ta, rad_to_deg * ta_ext)
def add_planet(star, np_obs, mass, sma, ecc, inc): print(mass, sma, ecc, inc) #converter = nbody_system.nbody_to_si(star.mass, max(sma)) planets = Particles() for i in range(len(mass)): ang_1, ang_2, ang_3 = numpy.random.uniform(0, 2 * numpy.pi, 3) print(i, star[0].mass, mass[i], sma[i], ecc[i], inc[i]) print(star[0].mass) print("<<=", type(mass[i].number)) b = new_binary_from_orbital_elements( mass1=star[0].mass, mass2=mass[i], semimajor_axis=sma[i], eccentricity=ecc[i], true_anomaly=ang_1 | units.rad, inclination=inc[i] | units.rad, longitude_of_the_ascending_node=ang_2 | units.rad, argument_of_periapsis=ang_3 | units.rad, G=constants.G) b[1].position -= b[0].position b[1].velocity -= b[0].velocity b[1].mass = mass[i] b[1].semimajor_axis = sma[i] b[1].eccentricity = ecc[i] b[1].inclination = inc[i] b[1].id = i density = 3 | units.g / units.cm**3 b[1].radius = (b[1].mass / density)**(1. / 3.) if i < np_obs: b[1].name = "planet" else: b[1].name = "virtual_planet" planets.add_particle(b[1]) planets.type = "planet" planets.position += star.position planets.velocity += star.velocity star.add_particles(planets) return star
def create_system(): system = new_solar_system() system = system[system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only system.move_to_center() sun = Particles(1) sun.name = "Sun" sun.mass = 1.0 | units.MSun sun.radius = 1.0 | units.RSun sun.position = (0, 0, 0) | units.AU sun.velocity = (0, 0, 0) | units.kms sun.density = 3*sun.mass/(4*np.pi*sun.radius**3) names = ["Jupiter", "Saturn", "Uranus", "Neptune"] masses = [317.8, 90, 15, 17] | units.MEarth radii = [0.10049, 0.083703, 0.036455, 0.035392] | units.RSun semis = [5.4, 7.1, 10.5, 13] | units.AU #[3.5, 4.9, 6.4, 8.4] trues = [0, 90, 180, 270]| units.deg#np.random.uniform(0, 360, 4) | units.deg longs = np.random.uniform(0, 360, 4) | units.deg args = np.random.uniform(0, 360, 4) | units.deg for i in range(4): orbital_elements = get_orbital_elements_from_binary(system[0]+ system[i+1], G=constants.G) eccentricity, inclination = 0, orbital_elements[5] sun_and_plan = new_binary_from_orbital_elements(sun[0].mass, masses[i], semis[i], 0, trues[i], inclination, longs[i], args[i], G=constants.G) planet = Particles(1) planet.name = system[i+1].name planet.mass = system[i+1].mass planet.radius = system[i+1].radius # This is purely non-zero for collisional purposes planet.position = (sun_and_plan[1].x-sun_and_plan[0].x, sun_and_plan[1].y-sun_and_plan[0].y, sun_and_plan[1].z-sun_and_plan[0].z) planet.velocity = (sun_and_plan[1].vx-sun_and_plan[0].vx, sun_and_plan[1].vy-sun_and_plan[0].vy, sun_and_plan[1].vz-sun_and_plan[0].vz) planet.density = 3*planet.mass/(4*np.pi*planet.radius**3) sun.add_particle(planet) return sun
def make_planetesimal_disk(Nplanetesimals): amin = 6.4|units.AU amax = 30|units.AU emax = 0.1 imax = 1 a = amin + (amax-amin)*numpy.random.random_sample(Nplanetesimals) e = emax*numpy.random.random_sample(Nplanetesimals) i = imax*numpy.random.random_sample(Nplanetesimals) ta = 0 # numpy.acos(np.random.uniform(0,2*numpy.pi,Nplanetesimals)) loan = 0 aof = 0 mp = 0.1 | units.MEarth planetesimals = Particles(Nplanetesimals) for i, pi in enumerate(planetesimals): b = new_binary_from_orbital_elements(Mstar, mp, a[i], e[i], ta, inc[i], loan, aof, G=constant.G) pi.mass = mp pi.position = b[1].position pi.velocity = b[1].velocity return planetesimals
def create_post_tack_giants_system(): #Create the present day solar system and keep only the sun and the giants present_day_solar_system = new_solar_system() present_day_solar_system = present_day_solar_system[present_day_solar_system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only present_day_solar_system.move_to_center() #Create a post_tack_giants_system by first recreating the sun. post_tack_giants_system = Particles(1) post_tack_giants_system[0].name = "Sun" post_tack_giants_system[0].mass = 1.0 | units.MSun post_tack_giants_system[0].radius = 1.0 | units.RSun post_tack_giants_system[0].position = (0, 0, 0) | units.AU post_tack_giants_system[0].velocity = (0, 0, 0) | units.kms #The post tack orbital elements for the planets as below a = np.array([5.4, 7.1, 10.5, 13]) | units.AU true_anomalies = np.random.uniform(0, 360, 4) | units.deg long_of_ascending_node = np.random.uniform(0, 360, 4) | units.deg args_of_periapsis = np.random.uniform(0, 360, 4) | units.deg #Create the four planets as binaries with the sun and add them to the post_tack_giants_system for i in range(4): orbital_elements = get_orbital_elements_from_binary(present_day_solar_system[0]+ present_day_solar_system[i+1], G=constants.G) inclination = orbital_elements[5] #Make sure we have a sensable inclination for the giants sun_and_planet = new_binary_from_orbital_elements(post_tack_giants_system.mass[0], present_day_solar_system[i+1].mass, a[i], 0, true_anomalies[i], inclination, long_of_ascending_node[i], args_of_periapsis[i], G=constants.G) planet = Particles(1) planet.name = present_day_solar_system[i+1].name planet.mass = present_day_solar_system[i+1].mass planet.radius = present_day_solar_system[i+1].radius planet.position = (sun_and_planet[1].x-sun_and_planet[0].x, sun_and_planet[1].y-sun_and_planet[0].y, sun_and_planet[1].z-sun_and_planet[0].z) planet.velocity = (sun_and_planet[1].vx-sun_and_planet[0].vx, sun_and_planet[1].vy-sun_and_planet[0].vy, sun_and_planet[1].vz-sun_and_planet[0].vz) post_tack_giants_system.add_particle(planet) return post_tack_giants_system
def planet_v2(ID, host_star, planet_mass, init_a, init_e, random_orientation=False): ''' Creates a planet as an AMUSE Particle with provided characteristics. ID: Identifying number unique to this planet. host_star: The AMUSE Particle that is the host star for the planet. planet_mass: The mass of the planet (in the nbody units). init_a: Initial semi-major axis (in nbody units). init_e: Initial eccentricity (in nbody units). random_orientation: Boolean to incline the planet in a random fashion. ''' # Define the Host Star's Original Location & Position rCM = host_star.position vCM = host_star.velocity # Sets Planet Values to Provided Conditions p = datamodel.Particle() p.id = ID p.type = "planet" p.host_star = host_star.id p.mass = planet_mass # Sets the Dynamical Radius to the Hill Sphere Approx. p.radius = util.calc_HillRadius(init_a, init_e, p.mass, host_star.mass) # Generate a Random Position on the Orbit (True Anomaly) # This ensures that all the planets don't start out along the same joining line. init_ta = 360*np.random.random() | units.deg # Get the Host Star & Planets Positions from Kepler Relative to the Origin newPSystem = new_binary_from_orbital_elements(host_star.mass, p.mass, init_a, eccentricity = init_e, true_anomaly = init_ta, G = constants.G) # Rotate the Binary System & Move to the CoM's Position if random_orientation: util.preform_EulerRotation(newPSystem) host_star.position = rCM + newPSystem[0].position host_star.velocity = vCM + newPSystem[0].velocity p.position = rCM + newPSystem[1].position p.velocity = vCM + newPSystem[1].velocity # Returns the Created AMUSE Particle return p
def add_scattered_asteroids(star, Ndisk_per_MSun, mdisk, qmin, qmax, emin, emax): Ndisk = int(Ndisk_per_MSun * star.mass.value_in(units.MSun)) print("Run with Ndisk = ", Ndisk) converter = nbody_system.nbody_to_si(star.mass, qmin) e = emin + (emax - emin) * numpy.random.random(Ndisk) lqmin = numpy.log10(qmin.value_in(units.au)) lqmax = numpy.log10(qmax.value_in(units.au)) q = 10**numpy.random.uniform(lqmin, lqmax, Ndisk) | units.au a = q / (1 - e) asteroids = Particles(0) for i in range(Ndisk): ang_1, ang_2, ang_3 = numpy.random.uniform(0, 2 * numpy.pi, 3) b = new_binary_from_orbital_elements( mass1=star.mass, mass2=mdisk, semimajor_axis=a[i], eccentricity=e[i], true_anomaly=ang_1 | units.rad, inclination=0 | units.rad, longitude_of_the_ascending_node=ang_2 | units.rad, argument_of_periapsis=ang_3 | units.rad, G=constants.G) b[1].position -= b[0].position b[1].velocity -= b[0].velocity b[1].semimajor_axis = a[i] b[1].eccentricity = e[i] b[1].inclination = 0 asteroids.add_particle(b[1]) asteroids.mass = mdisk asteroids.name = "comet" asteroids.type = "debris" asteroids.position += star.position asteroids.velocity += star.velocity return asteroids
def new_option_parser(): from amuse.units.optparse import OptionParser result = OptionParser() result.add_option("-t", unit=units.Myr, dest="t_end", type="float", default = 20|units.day, help="end time of the simulation [%default]") return result if __name__ in ('__main__', '__plot__'): o, arguments = new_option_parser().parse_args() a = 0.133 | units.AU e = 0.0 m1 = 3.2|units.MSun m2 = 3.1|units.MSun from amuse.ext.orbital_elements import new_binary_from_orbital_elements inner_binary = new_binary_from_orbital_elements(m1, m2, a, e, G=constants.G) XiTau = read_set_from_file("Hydro_PrimaryStar_XiTau.amuse", "amuse") for ci in XiTau.history: if len(ci) == 1: XiTau_core = ci.copy() else: XiTau_envelope = ci.copy() ao = 1.23 | units.AU eo = 0.15 m12 = inner_binary.mass.sum() m3 = XiTau_core.mass + XiTau_envelope.mass.sum() print("M3=", m3.in_(units.MSun)) outer_binary = new_binary_from_orbital_elements(m12, m3, ao, eo, G=constants.G)
def test2(self): #test going around in a circular orbit mass1 = 1 | nbody_system.mass mass2 = 1 | nbody_system.mass binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 90, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0,1,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [-numpy.sqrt(2),0,0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 180, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [-1,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [0,-numpy.sqrt(2),0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 270, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0,-1,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [numpy.sqrt(2),0,0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 45, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0.5 * numpy.sqrt(2),0.5 * numpy.sqrt(2),0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [-1,1,0] | nbody_system.speed)
def test2(self): # test going around in a circular orbit mass1 = 1 | nbody_system.mass mass2 = 1 | nbody_system.mass binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity=0, true_anomaly=90, ) self.assertEquals(len(binary), 2) binary.position -= binary[0].position binary.velocity -= binary[0].velocity self.assertAlmostRelativeEquals( binary[0].position, [0, 0, 0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[1].position, [0, 1, 0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[0].velocity, [0, 0, 0] | nbody_system.speed) self.assertAlmostRelativeEquals( binary[1].velocity, [-numpy.sqrt(2), 0, 0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity=0, true_anomaly=180, ) self.assertEquals(len(binary), 2) binary.position -= binary[0].position binary.velocity -= binary[0].velocity self.assertAlmostRelativeEquals( binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[1].position, [-1,0,0] | nbody_system.length) self.assertAlmostRelativeEquals( binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals( binary[1].velocity, [0,-numpy.sqrt(2),0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 270, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0,-1,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [numpy.sqrt(2),0,0] | nbody_system.speed) binary = new_binary_from_orbital_elements( mass1, mass2, 1 | nbody_system.length, eccentricity = 0, true_anomaly = 45, ) self.assertEquals(len(binary), 2) binary.position-=binary[0].position binary.velocity-=binary[0].velocity self.assertAlmostRelativeEquals(binary[0].position, [0,0,0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[1].position, [0.5 * numpy.sqrt(2),0.5 * numpy.sqrt(2),0] | nbody_system.length) self.assertAlmostRelativeEquals(binary[0].velocity, [0,0,0] | nbody_system.speed) self.assertAlmostRelativeEquals(binary[1].velocity, [-1,1,0] | nbody_system.speed)
def new_option_parser(): from amuse.units.optparse import OptionParser result = OptionParser() result.add_option("-t", unit=units.Myr, dest="t_end", type="float", default = 20|units.day, help="end time of the simulation [%default]") return result if __name__ in ('__main__', '__plot__'): o, arguments = new_option_parser().parse_args() a = 0.133 | units.AU e = 0.0 m1 = 3.2|units.MSun m2 = 3.1|units.MSun from amuse.ext.orbital_elements import new_binary_from_orbital_elements inner_binary = new_binary_from_orbital_elements(m1, m2, a, e, G=constants.G) XiTau = read_set_from_file("Hydro_PrimaryStar_XiTau.amuse", "amuse") for ci in XiTau.history: if len(ci) == 1: XiTau_core = ci.copy() else: XiTau_envelope = ci.copy() ao = 1.23 | units.AU eo = 0.15 m12 = inner_binary.mass.sum() m3 = XiTau_core.mass + XiTau_envelope.mass.sum() print "M3=", m3.in_(units.MSun) outer_binary = new_binary_from_orbital_elements(m12, m3, ao, eo, G=constants.G)
def get_bodies_in_orbit(m0, m_ffp, m_bp, a_bp, e_bp, phi_bp, inc_bp, lan_bp, b_ffp, r_inf): #Bodies bodies = Particles() ##Get BP in orbit #Binary star_planet = new_binary_from_orbital_elements(m0, m_bp, a_bp, e_bp, true_anomaly=phi_bp, inclination = inc_bp, longitude_of_the_ascending_node = lan_bp) #Planet attributes star_planet.eccentricity = e_bp star_planet.semimajoraxis = a_bp #Center on the star star_planet.position -= star_planet[0].position star_planet.velocity -= star_planet[0].velocity cm_p = star_planet.center_of_mass() cm_v = star_planet.center_of_mass_velocity() ##Get FFP in orbit #Particle set m0_ffp = Particles(2) #Zeros and parabolic velocity zero_p = 0.0 | nbody_system.length zero_v = 0.0 | nbody_system.speed parabolic_velocity = get_parabolic_velocity(m0, m_bp, b_ffp, r_inf) #Central star m0_ffp[0].mass = m0 m0_ffp[0].position = (zero_p,zero_p,zero_p) m0_ffp[0].velocity = (zero_v,zero_v,zero_v) #Free-floating planet m0_ffp[1].mass = m_ffp m0_ffp[1].position = (-r_inf+cm_p[0], b_ffp+cm_p[1], cm_p[2]) m0_ffp[1].velocity = (parabolic_velocity+cm_v[0], cm_v[1], cm_v[2]) #To find the orbital period of the BP G = (1.0 | nbody_system.length**3 * nbody_system.time**-2 * nbody_system.mass**-1) orbital_period_bp = 2*math.pi*((a_bp**3)/(G*m0)).sqrt() #To find the distance and time to periastron kep = Kepler() kep.initialize_code() star_planet_as_one = Particles(1) star_planet_as_one.mass = m0 + m_bp star_planet_as_one.position = cm_p star_planet_as_one.velocity = cm_v kepler_bodies = Particles() kepler_bodies.add_particle(star_planet_as_one[0]) kepler_bodies.add_particle(m0_ffp[1]) kep.initialize_from_particles(kepler_bodies) kep.advance_to_periastron() time_pericenter = kep.get_time() kep.stop() binary = [star_planet_as_one[0], m0_ffp[1]] sma, e, inclination, long_asc_node, arg_per = my_orbital_elements_from_binary(binary) m0_ffp.eccentricity = e m0_ffp.semimajoraxis = sma #Adding bodies. Order: star, ffp, bp bodies.add_particle(m0_ffp[0]) bodies.add_particle(m0_ffp[1]) bodies.add_particle(star_planet[1]) return bodies, time_pericenter, orbital_period_bp
def binary_system_v2(star_to_become_binary, **kwargs): # Check Keyword Arguments doFlatEcc = kwargs.get("FlatEcc",True) # Apply Uniform Eccentricity Distribution doBasic = kwargs.get("Basic", False) # Apply a Basic Binary Distribution doFlatQ = kwargs.get("FlatQ",True) # Apply a Uniform Mass-Ratio Distribution doRag_P = kwargs.get("RagP",True) # Apply Raghavan et al. (2010) Period Distribution doSana_P = kwargs.get("SanaP", False) # Apply Sana et al. (2012) Period Distribution Pcirc = kwargs.get("Pcirc", 6 | units.day ) # Circularization Period Pmin = kwargs.get("Pmin", 10.**-1. | units.day ) # Min Orbital Period Allowed Pmax = kwargs.get("Pmax", 10.**10. | units.day ) # Max Orbital Period Allowed # Define Original Star's Information rCM = star_to_become_binary.position vCM = star_to_become_binary.velocity # Define Initial Binary Particle Set singles_in_binary = Particles(2) star1 = singles_in_binary[0] star2 = singles_in_binary[1] star1.type = 'star' star2.type = 'star' star1.mass = 0. | units.MSun star2.mass = 0. | units.MSun # If Desired, Apply a Basic Binary Distribution if (doBasic): semi_major_axis = 500. | units.AU e = 0. star1.mass = 0.5*star_to_become_binary.mass star2.mass = 0.5*star_to_become_binary.mass # If Desired, Apply the Uniform Mass-Ratio Distribution (Goodwin, 2012) if (doFlatQ): min_stellar_mass = 100. | units.MJupiter # Greater Mass Than "AB Doradus C" while star2.mass <= min_stellar_mass: q = np.random.random_sample() star1.mass = star_to_become_binary.mass / (1. + q) star2.mass = q * star1.mass # If Desired, Apply Raghavan et al. (2010) Period Distribution if (doRag_P): sigma = 2.28 mu = 5.03 period = 2.*Pmax while (period > Pmax or period < Pmin): #logP = sigma * np.random.randn() + mu logP = np.random.normal(loc=mu, scale=sigma) period = 10.**logP | units.day semi_major_axis = ((period**2.)/(4.*np.pi**2.)*constants.G*(star1.mass+star2.mass))**(1./3.) # If Desired & Applicable, Apply Sana et al. (2012) Period Distribution if (doSana_P and star1.mass > 15 | units.MSun): maxLogP = np.log10(Pmax.value_in(units.day)) minLogP = np.log10(Pmin.value_in(units.day)) pMod = -0.55 + 1. x1 = np.random.random() logP = ((maxLogP**pMod-minLogP**pMod)*x1 + minLogP**pMod)**(1./pMod) period = 10.**logP | units.day semi_major_axis = ((period**2.)/(4.*np.pi**2.)*constants.G*(star1.mass+star2.mass))**(1./3.) # If Desired, Apply Uniform Eccentricity Distribution if (doFlatEcc): e = rp.uniform(0.0,1.0) if (period < Pcirc): e = 0.0 # Get the Companion's Positions from Kepler Relative to the Origin newBinary = new_binary_from_orbital_elements(star1.mass, star2.mass, semi_major_axis, eccentricity = e, G = constants.G) # Rotate the Binary System & Move to the CoM's Position util.preform_EulerRotation(newBinary) star1.position = rCM + newBinary[0].position star1.velocity = vCM + newBinary[0].velocity star2.position = rCM + newBinary[1].position star2.velocity = vCM + newBinary[1].velocity # Apply a Fitting Dynamical Radius singles_in_binary.radius = 2*semi_major_axis # Create the Binary System Particle (For Stellar Evolution Code) star_to_become_binary.radius = 5*semi_major_axis binary_particle = star_to_become_binary.copy() binary_particle.child1 = star1 binary_particle.child2 = star2 binary_particle.semi_major_axis = semi_major_axis binary_particle.eccentricity = e binary_particle.id = star_to_become_binary.id # Return the Binary System Particle & the Particle Set of Individual Companions return binary_particle, singles_in_binary
def binary_system(star_to_become_binary, **kwargs): # Check Keyword Arguments doFlatEcc = kwargs.get("FlatEcc",True) # Apply Uniform Eccentricity Distribution doBasic = kwargs.get("Basic", False) # Apply a Basic Binary Distribution doFlatQ = kwargs.get("FlatQ",True) # Apply a Uniform Mass-Ratio Distribution doRag_P = kwargs.get("RagP",True) # Apply Raghavan et al. (2010) Period Distribution doSana_P = kwargs.get("SanaP", False) # Apply Sana et al. (2012) Period Distribution Pcirc = kwargs.get("Pcirc", 6 | units.day ) # Circularization Period Pmin = kwargs.get("Pmin", 3. | units.day ) # Min Orbital Period Allowed Pmax = kwargs.get("Pmax", 10.**5. | units.day ) # Max Orbital Period Allowed # Define Original Star's Information rCM = star_to_become_binary.position vCM = star_to_become_binary.velocity # Define Initial Binary Particle Set binary = Particles(2) star1 = binary[0] star2 = binary[1] star1.type = 'star' star2.type = 'star' # If Desired, Apply a Basic Binary Distribution if (doBasic): semi_major_axis = 500. | units.AU e = 0. star1.mass = 0.5*star_to_become_binary.mass star2.mass = 0.5*star_to_become_binary.mass # If Desired, Apply the Uniform Mass-Ratio Distribution (Goodwin, 2012) if (doFlatQ): min_stellar_mass = 100 | units.MJupiter # Greater Mass Than "AB Doradus C" star1.mass = 0 | units.MSun star2.mass = 0 | units.MSun #while (star1.mass <= min_stellar_mass) or (star2.mass <= min_stellar_mass): q = np.random.random() star1.mass = star_to_become_binary.mass / (1. + q) star2.mass = q * star1.mass #star1.mass = star_to_become_binary.mass #print star1.mass.value_in(units.MSun), star2.mass.value_in(units.MSun) # If Desired, Apply Raghavan et al. (2010) Period Distribution if (doRag_P): sigma = 2.28 mu = 5.03 period = 2.*Pmax while (period > Pmax or period < Pmin): logP = sigma * np.random.randn() + mu period = 10.**logP | units.day semi_major_axis = ((period**2.)/(4.*np.pi**2.)*constants.G*(star1.mass+star2.mass))**(1./3.) # If Desired & Applicable, Apply Sana et al. (2012) Period Distribution if (doSana_P and star1.mass > 15 | units.MSun): maxLogP = np.log10(Pmax.value_in(units.day)) minLogP = np.log10(Pmin.value_in(units.day)) pMod = -0.55 + 1. x1 = np.random.random() logP = ((maxLogP**pMod-minLogP**pMod)*x1 + minLogP**pMod)**(1./pMod) period = 10.**logP | units.day semi_major_axis = ((period**2.)/(4.*np.pi**2.)*constants.G*(star1.mass+star2.mass))**(1./3.) # If Desired, Apply Uniform Eccentricity Distribution if (doFlatEcc): e = rp.uniform(0.0,1.0) #if (period < Pcirc): # e = 0.0 # Create the New Binary newBinary = new_binary_from_orbital_elements(star1.mass, star2.mass, semi_major_axis, eccentricity = e, G = constants.G) # Rotate the System util.preform_EulerRotation(newBinary) star1.position = rCM + newBinary[0].position star1.velocity = vCM + newBinary[0].velocity star2.position = rCM + newBinary[1].position star2.velocity = vCM + newBinary[1].velocity # Apply a Fitting Dynamical Radius binary.radius = 5*semi_major_axis # Return the Particle Set of Stars in the Binary return binary