Exemplo n.º 1
0
 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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
 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()
Exemplo n.º 4
0
 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()
Exemplo n.º 5
0
 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()
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
 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
Exemplo n.º 10
0
 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
Exemplo n.º 11
0
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
Exemplo n.º 12
0
 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
Exemplo n.º 13
0
 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
Exemplo n.º 14
0
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
Exemplo n.º 15
0
    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()
Exemplo n.º 16
0
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
Exemplo n.º 17
0
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
Exemplo n.º 18
0
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
Exemplo n.º 19
0
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
Exemplo n.º 20
0
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
Exemplo n.º 21
0
    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()
Exemplo n.º 22
0
    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()
Exemplo n.º 23
0
    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()
Exemplo n.º 24
0
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
Exemplo n.º 25
0
    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()
Exemplo n.º 26
0
    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)
Exemplo n.º 27
0
    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()
Exemplo n.º 28
0
    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()
Exemplo n.º 29
0
    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()
Exemplo n.º 30
0
    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')
Exemplo n.º 32
0
    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)
Exemplo n.º 33
0
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
Exemplo n.º 34
0
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
Exemplo n.º 35
0
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
Exemplo n.º 36
0
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
Exemplo n.º 37
0
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
Exemplo n.º 38
0
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
Exemplo n.º 39
0
    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:]
Exemplo n.º 40
0
    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:]
Exemplo n.º 41
0
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
Exemplo n.º 42
0
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
Exemplo n.º 43
0
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