Exemplo n.º 1
0
def make_planets(central_particle,
                 masses,
                 radii,
                 density=3 | units.g / units.cm**3,
                 phi=None,
                 theta=None,
                 eccentricity=0.0,
                 kepler=None,
                 rng=None):
    volumes = masses / density
    planet_radii = (3.0 * volumes / (4.0 * numpy.pi))**(1.0 / 3.0)
    n = len(masses)
    planet_particles = Particles(n)
    planet_particles.semimajor_axis = radii
    if eccentricity is None:
        eccentricity = numpy.abs(rng.normal(-0.00001, 0.00001, n))
    planet_particles.eccentricity = eccentricity
    planet_particles.mass = masses
    planet_particles.radius = planet_radii

    if phi is None:
        phi = numpy.radians(rng.uniform(0.0, 90.0, 1)[0])  #rotate under x
    if theta is None:
        theta0 = numpy.radians((rng.normal(-90.0, 90.0,
                                           1)[0]))  #rotate under y
        theta0 = 0
        theta_inclination = numpy.radians(rng.normal(0, 1.0, n))
        theta_inclination[0] = 0
        theta = theta0 + theta_inclination

    #psi = numpy.radians(rng.uniform(0, 180, 1))[0] #0 # numpy.radians(90) # numpy.radians(rng.uniform(0, 180, 1))[0]
    psi = numpy.radians(rng.uniform(0.0, 180.0, 1))[
        0]  #0 # numpy.radians(90) # numpy.radians(rng.uniform(0, 180, 1))[0]
    com_particle = central_particle.copy()
    for x, t in zip(iter(planet_particles), theta):
        pos, vel = posvel_from_orbital_elements(com_particle.mass + x.mass,
                                                x.semimajor_axis,
                                                x.eccentricity, kepler, rng)
        pos, vel = rotate(pos, vel, 0, 0, psi)  # theta and phi in radians
        pos, vel = rotate(pos, vel, 0, t, 0)  # theta and phi in radians
        pos, vel = rotate(pos, vel, phi, 0, 0)  # theta and phi in radians
        x.position = pos + com_particle.position
        x.velocity = vel + com_particle.velocity
        if False:
            two_body = Particles(particles=[com_particle, x])
            print "dp:", (com_particle.position -
                          two_body.center_of_mass()).as_quantity_in(units.AU)
            com_particle.mass = two_body.mass.sum()
            com_particle.position = two_body.center_of_mass()
            com_particle.velocity = two_body.center_of_mass_velocity()

    #planet_particles.position += central_particle.position
    #planet_particles.velocity += central_particle.velocity

    return planet_particles
Exemplo n.º 2
0
    def test8(self):
        print(
            "Testing adding and removing particles from stellar evolution code..."
        )

        instance = BSE()
        instance.initialize_code()

        stars = Particles(6)
        stars.mass = [1.0, 1.0, 1.0, 0.2, 0.2, 0.2] | units.MSun

        binaries = Particles(3)
        binaries.eccentricity = 0.0
        for i in range(3):
            binaries[i].child1 = stars[i]
            binaries[i].child2 = stars[i + 3]
        orbital_period = 200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(
            orbital_period,
            binaries.child1.as_set().mass,
            binaries.child2.as_set().mass)
        binaries.semi_major_axis = semi_major_axis

        instance.commit_parameters()
        self.assertEqual(len(instance.particles), 0)
        self.assertEqual(len(instance.binaries), 0)  # before creation
        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries[:-1])
        instance.commit_particles()
        instance.evolve_model(1.0 | units.Myr)
        self.assertEqual(len(instance.binaries), 2)  # before remove
        self.assertAlmostEqual(instance.binaries.age, 1.0 | units.Myr)

        instance.binaries.remove_particle(binaries[0])
        self.assertEqual(len(instance.binaries), 1)
        instance.evolve_model(2.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[0].age, 2.0 | units.Myr)

        instance.binaries.add_particles(binaries[::2])
        self.assertEqual(len(instance.binaries), 3)  # it's back...
        self.assertAlmostEqual(instance.binaries[0].age, 2.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[1].age, 0.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[2].age,
                               0.0 | units.Myr)  # ... and rejuvenated.

        instance.evolve_model(
            3.0 | units.Myr
        )  # The young stars keep their age offset from the old star
        self.assertAlmostEqual(instance.binaries.age,
                               [3.0, 1.0, 1.0] | units.Myr)
        instance.evolve_model(4.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries.age,
                               [4.0, 2.0, 2.0] | units.Myr)
        instance.stop()
Exemplo n.º 3
0
    def test7(self):
        print "Test evolve_model optional arguments: end_time and keep_synchronous"

        instance = BSE()
        instance.commit_parameters()

        stars = Particles(6)
        stars.mass = [1.0, 2.0, 3.0, 0.1, 0.2, 0.3] | units.MSun

        binaries = Particles(3)
        binaries.eccentricity = 0.0
        for i in range(3):
            binaries[i].child1 = stars[i]
            binaries[i].child2 = stars[i + 3]
        orbital_period = 200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(
            orbital_period,
            binaries.child1.as_set().mass,
            binaries.child2.as_set().mass)
        binaries.semi_major_axis = semi_major_axis

        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries)

        self.assertAlmostEqual(instance.binaries.age,
                               [0.0, 0.0, 0.0] | units.yr)
        self.assertAlmostEqual(instance.binaries.time_step,
                               [550.1565, 58.2081, 18.8768] | units.Myr, 3)

        print "evolve_model without arguments: use shared timestep = min(particles.time_step)"
        instance.evolve_model()
        self.assertAlmostEqual(instance.binaries.age,
                               [18.8768, 18.8768, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.binaries.time_step,
                               [550.1565, 58.2081, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 18.8768 | units.Myr, 3)

        print "evolve_model with end_time: take timesteps, until end_time is reached exactly"
        instance.evolve_model(100 | units.Myr)
        self.assertAlmostEqual(instance.binaries.age,
                               [100.0, 100.0, 100.0] | units.Myr, 3)
        self.assertAlmostEqual(instance.binaries.time_step,
                               [550.1565, 58.2081, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3)

        print "evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge"
        instance.evolve_model(keep_synchronous=False)
        self.assertAlmostEqual(instance.binaries.age, (100 | units.Myr) +
                               ([550.1565, 58.2081, 18.8768] | units.Myr), 3)
        self.assertAlmostEqual(instance.binaries.time_step,
                               [550.1565, 58.2081, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr,
                               3)  # Unchanged!
        instance.stop()
Exemplo n.º 4
0
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
Exemplo n.º 5
0
    def test8(self):
        print "Testing adding and removing particles from stellar evolution code..."
        
        instance = MOBSE()
        instance.initialize_code()
        
        stars =  Particles(6)
        stars.mass = [1.0,1.0, 1.0, 0.2, 0.2, 0.2]  | units.MSun
        
        binaries =  Particles(3)
        binaries.eccentricity = 0.0
        for i in range(3):
            binaries[i].child1 = stars[i]
            binaries[i].child2 = stars[i+3]
        orbital_period =   200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(
            orbital_period,  
            binaries.child1.as_set().mass , 
            binaries.child2.as_set().mass
        )
        binaries.semi_major_axis = semi_major_axis

        instance.commit_parameters()
        self.assertEquals(len(instance.particles), 0)
        self.assertEquals(len(instance.binaries), 0) # before creation
        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries[:-1])
        instance.commit_particles()
        instance.evolve_model(1.0 | units.Myr)
        self.assertEquals(len(instance.binaries), 2) # before remove
        self.assertAlmostEqual(instance.binaries.age, 1.0 | units.Myr)
        
        instance.binaries.remove_particle(binaries[0])
        self.assertEquals(len(instance.binaries), 1)
        instance.evolve_model(2.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[0].age, 2.0 | units.Myr)
        
        instance.binaries.add_particles(binaries[::2])
        self.assertEquals(len(instance.binaries), 3) # it's back...
        self.assertAlmostEqual(instance.binaries[0].age, 2.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[1].age, 0.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries[2].age, 0.0 | units.Myr) # ... and rejuvenated.
        
        instance.evolve_model(3.0 | units.Myr) # The young stars keep their age offset from the old star
        self.assertAlmostEqual(instance.binaries.age, [3.0, 1.0, 1.0] | units.Myr)
        instance.evolve_model(4.0 | units.Myr)
        self.assertAlmostEqual(instance.binaries.age, [4.0, 2.0, 2.0] | units.Myr)
        instance.stop()
Exemplo n.º 6
0
    def test7(self):
        print "Test evolve_model optional arguments: end_time and keep_synchronous"

        instance = MOBSE()
        instance.commit_parameters()
        
        stars =  Particles(6)
        stars.mass = [1.0,2.0,3.0, 0.1, 0.2, 0.3]  | units.MSun
        
        binaries =  Particles(3)
        binaries.eccentricity = 0.0
        for i in range(3):
            binaries[i].child1 = stars[i]
            binaries[i].child2 = stars[i+3]
        orbital_period =   200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(
            orbital_period,  
            binaries.child1.as_set().mass , 
            binaries.child2.as_set().mass
        )
        binaries.semi_major_axis = semi_major_axis
        
        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries)
        
        self.assertAlmostEqual(instance.binaries.age, [0.0, 0.0, 0.0] | units.yr)
        self.assertAlmostEqual(instance.binaries.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3)
        
        print "evolve_model without arguments: use shared timestep = min(particles.time_step)"
        instance.evolve_model()
        self.assertAlmostEqual(instance.binaries.age, [18.8768, 18.8768, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.binaries.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 18.8768 | units.Myr, 3)
        
        print "evolve_model with end_time: take timesteps, until end_time is reached exactly"
        instance.evolve_model(100 | units.Myr)
        self.assertAlmostEqual(instance.binaries.age, [100.0, 100.0, 100.0] | units.Myr, 3)
        self.assertAlmostEqual(instance.binaries.time_step, [550.1565, 58.2081, 18.8785] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3)
        
        print "evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge"
        instance.evolve_model(keep_synchronous = False)
        self.assertAlmostEqual(instance.binaries.age, (100 | units.Myr) + ([550.1565, 58.2081, 18.8785] | units.Myr), 3)
        self.assertAlmostEqual(instance.binaries.time_step, [550.1565, 58.2081, 18.8785] | units.Myr, 3)
        self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3) # Unchanged!
        instance.stop()
Exemplo n.º 7
0
def make_planets(central_particle, masses, radii, density = 3 | units.g/units.cm**3, phi=None, theta=None, eccentricity = 0.0, kepler = None, rng = None):
    volumes = masses / density
    planet_radii = (3.0 * volumes /  (4.0 * numpy.pi))**(1.0/3.0)
    n = len(masses)
    planet_particles = Particles(n)
    planet_particles.semimajor_axis = radii
    if eccentricity is None:
        eccentricity = numpy.abs(rng.normal(-0.00001,0.00001,n))
    planet_particles.eccentricity = eccentricity
    planet_particles.mass = masses
    planet_particles.radius = planet_radii


    if phi is None:
        phi = numpy.radians(rng.uniform(0.0, 90.0, 1)[0])#rotate under x
    if theta is None:
        theta0 = numpy.radians((rng.normal(-90.0,90.0,1)[0]))#rotate under y
        theta0 = 0
        theta_inclination = numpy.radians(rng.normal(0, 1.0, n )) 
        theta_inclination[0] = 0
        theta = theta0 + theta_inclination

    #psi = numpy.radians(rng.uniform(0, 180, 1))[0] #0 # numpy.radians(90) # numpy.radians(rng.uniform(0, 180, 1))[0]
    psi = numpy.radians(rng.uniform(0.0, 180.0, 1))[0] #0 # numpy.radians(90) # numpy.radians(rng.uniform(0, 180, 1))[0]
    com_particle = central_particle.copy()
    for x, t in zip(iter(planet_particles), theta):
        pos,vel = posvel_from_orbital_elements(com_particle.mass + x.mass, x.semimajor_axis, x.eccentricity, kepler, rng)
        pos,vel = rotate(pos, vel, 0, 0, psi) # theta and phi in radians            
        pos,vel = rotate(pos, vel, 0, t, 0) # theta and phi in radians            
        pos,vel = rotate(pos, vel, phi, 0, 0) # theta and phi in radians            
        x.position = pos + com_particle.position
        x.velocity = vel + com_particle.velocity
        if False:
            two_body = Particles(particles=[com_particle, x])
            print "dp:", (com_particle.position - two_body.center_of_mass()).as_quantity_in(units.AU)
            com_particle.mass = two_body.mass.sum()
            com_particle.position = two_body.center_of_mass()
            com_particle.velocity = two_body.center_of_mass_velocity()

    #planet_particles.position += central_particle.position
    #planet_particles.velocity += central_particle.velocity

    return planet_particles
Exemplo n.º 8
0
    def test9(self):
        print "Testing BSE states"
        instance = BSE()

        stars = Particles(2)
        stars.mass = [1.0, 0.2] | units.MSun

        binaries = Particles(1)
        orbital_period = 200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(
            orbital_period, stars[0].mass, stars[1].mass)
        binaries.semi_major_axis = semi_major_axis
        binaries.eccentricity = 0.0
        binaries[0].child1 = stars[0]
        binaries[0].child2 = stars[1]

        print "First do everything manually:",
        self.assertEquals(instance.get_name_of_current_state(),
                          'UNINITIALIZED')
        instance.initialize_code()
        self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED')
        instance.commit_parameters()
        self.assertEquals(instance.get_name_of_current_state(), 'RUN')
        instance.cleanup_code()
        self.assertEquals(instance.get_name_of_current_state(), 'END')
        instance.stop()
        print "ok"

        print "initialize_code(), commit_parameters(), " \
            "and cleanup_code() should be called automatically:",
        instance = BSE()
        self.assertEquals(instance.get_name_of_current_state(),
                          'UNINITIALIZED')
        instance.parameters.reimers_mass_loss_coefficient = 0.5
        self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED')
        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries)
        self.assertEquals(instance.get_name_of_current_state(), 'RUN')
        instance.stop()
        self.assertEquals(instance.get_name_of_current_state(), 'STOPPED')
        print "ok"
Exemplo n.º 9
0
    def test9(self):
        print "Testing MOBSE states"
        instance = MOBSE()
        
        stars =  Particles(2)
        stars.mass = [1.0, 0.2]  | units.MSun
        
        binaries =  Particles(1)
        orbital_period =   200.0 | units.day
        semi_major_axis = instance.orbital_period_to_semi_major_axis(orbital_period,  stars[0].mass , stars[1].mass)
        binaries.semi_major_axis = semi_major_axis
        binaries.eccentricity = 0.0
        binaries[0].child1 = stars[0]
        binaries[0].child2 = stars[1]
        
        print "First do everything manually:",
        self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED')
        instance.initialize_code()
        self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED')
        instance.commit_parameters()
        self.assertEquals(instance.get_name_of_current_state(), 'RUN')
        instance.cleanup_code()
        self.assertEquals(instance.get_name_of_current_state(), 'END')
        instance.stop()
        print "ok"

        print "initialize_code(), commit_parameters(), " \
            "and cleanup_code() should be called automatically:",
        instance = MOBSE()
        self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED')
        instance.parameters.reimers_mass_loss_coefficient = 0.5
        self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED')
        instance.particles.add_particles(stars)
        instance.binaries.add_particles(binaries)
        self.assertEquals(instance.get_name_of_current_state(), 'RUN')
        instance.stop()
        self.assertEquals(instance.get_name_of_current_state(), 'STOPPED')
        print "ok"
Exemplo n.º 10
0
def get_ffp_in_orbit(m0, m_ffp, b, r_inf, parabolic_velocity):

    m0_and_ffp_in_orbit = Particles(2)

    zero_p = 0.0 | nbody_system.length
    zero_v = 0.0 | nbody_system.speed

    #Central star
    m0_and_ffp_in_orbit[0].mass = m0
    m0_and_ffp_in_orbit[0].position = (zero_p,zero_p,zero_p)
    m0_and_ffp_in_orbit[0].velocity = (zero_v,zero_v,zero_v)

    #Free-floating planet
    m0_and_ffp_in_orbit[1].mass = m_ffp
    m0_and_ffp_in_orbit[1].position = (-r_inf,-b,zero_p)
    m0_and_ffp_in_orbit[1].velocity = (parabolic_velocity,zero_v,zero_v)

    m1, m2, sma, e, ta, i, lan, ap = orbital_elements_from_binary(m0_and_ffp_in_orbit)

    #For the star it sets the initial values of semimajoraxis and eccentricity of the ffp
    m0_and_ffp_in_orbit.eccentricity = e
    m0_and_ffp_in_orbit.semimajoraxis = sma

    return m0_and_ffp_in_orbit
Exemplo n.º 11
0
def new_binary_distribution(
        primary_mass,
        secondary_mass=None,
        binaries=None,
        min_mass=0.08 | units.MSun,
        ):
    """
    Takes primary masses, and returns a set of stars and a set of binaries
    formed by these stars.
    Secondary masses are given by a uniform random mass ratio with the primary
    masses. If optional secondary masses are given, these are used instead.
    binaries is an optional particleset used for the binary pairs, with given
    positions and velocities. Other parameters are ignored.
    """
    N = len(primary_mass)
    if binaries is None:
        binaries = Particles(N)
        # Should give some position/velocity as well?
    elif len(binaries) != N:
        print("binaries must be None or have the same lenght as primary_mass")
        return -1
    if secondary_mass is None:
        # Now, we need to specify the mass ratio in the binaries.
        # A flat distribution seems to be OK.
        mass_ratio = uniform(N)
        # This gives us the secondaries' masses
        secondary_mass = mass_ratio * primary_mass
        # secondaries are min_mass at least
        secondary_mass = numpy.maximum(secondary_mass, min_mass)
    elif len(secondary_mass) != N:
        print("Number of secondaries is unequal to number of primaries!")
        return -1
    else:
        # Make sure primary_mass is the larger of the two, and secondary_mass
        # the smaller.
        pm = primary_mass.maximum(secondary_mass)
        sm = primary_mass.minimum(secondary_mass)
        primary_mass = pm
        secondary_mass = sm
        del(pm, sm)
    # Now, we need to calculate the semi-major axes for the binaries. Since the
    # observed quantity is orbital periods, we start from there.
    mean_log_orbital_period = 5  # 10log of the period in days, (Duchene&Kraus)
    sigma_log_orbital_period = 2.3
    orbital_period = numpy.random.lognormal(
            size=N,
            mean=numpy.log(10) * mean_log_orbital_period,
            sigma=numpy.log(10) * sigma_log_orbital_period,
            ) | units.day
    # We need the masses to calculate the corresponding semi-major axes.
    semi_major_axis = orbital_period_to_semi_major_axis(
            orbital_period,
            primary_mass,
            secondary_mass,
            )
    # Eccentricity: square root of random value
    eccentricity = numpy.sqrt(random(N))
    # Other orbital elements at random
    inclination = pi * random(N) | units.rad
    true_anomaly = 2 * pi * random(N) | units.rad
    longitude_of_the_ascending_node = 2 * pi * random(N) | units.rad
    argument_of_periapsis = 2 * pi * random(N) | units.rad
    primaries, secondaries = generate_binaries(
            primary_mass,
            secondary_mass,
            semi_major_axis,
            eccentricity=eccentricity,
            inclination=inclination,
            true_anomaly=true_anomaly,
            longitude_of_the_ascending_node=longitude_of_the_ascending_node,
            argument_of_periapsis=argument_of_periapsis,
            G=constants.G,
            )
    stars = Particles()

    primaries.position += binaries.position
    secondaries.position += binaries.position
    primaries.velocity += binaries.velocity
    secondaries.velocity += binaries.velocity
    primaries = stars.add_particles(primaries)
    secondaries = stars.add_particles(secondaries)

    binaries.eccentricity = eccentricity
    binaries.semi_major_axis = semi_major_axis
    for i in range(len(primaries)):
        binaries[i].child1 = primaries[i]
        binaries[i].child2 = secondaries[i]
        # Probably needed
        binaries[i].mass = primaries[i].mass + secondaries[i].mass
    return stars, binaries
Exemplo n.º 12
0
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