예제 #1
0
def sma_determinator(primary, secondary):
    binary = Particles(0)
    binary.add_particle(primary)
    binary.add_particle(secondary)

    orbital_params = get_orbital_elements_from_binary(binary, G=constants.G)
    return orbital_params[2]
예제 #2
0
def create_pre_tack_giants_system():
    #Create a pre_tack_giants_system by first recreating the sun.
    pre_tack_giants_system = Particles(1)
    pre_tack_giants_system[0].name = "Sun"
    pre_tack_giants_system[0].mass = 1.0 | units.MSun
    pre_tack_giants_system[0].radius = 1.0 | units.RSun
    pre_tack_giants_system[0].position = (0, 0, 0) | units.AU
    pre_tack_giants_system[0].velocity = (0, 0, 0) | units.kms
    pre_tack_giants_system[0].density = 3 * pre_tack_giants_system[0].mass / (
        4 * np.pi * pre_tack_giants_system[0].radius**3)

    #The pre tack orbital elements for the planets as below
    names = ["Jupiter", "Saturn", "Uranus", "Neptune"]
    masses = np.array([317.8, 30, 5, 5]) | units.MEarth
    radii = np.array([0.10049, 0.083703, 0.036455, 0.035392]) | units.RSun
    a = np.array([3.5, 4.5, 6.013, 8.031]) | units.AU
    inclinations = np.random.uniform(-5, 5, 4) | units.deg
    true_anomalies = np.random.uniform(0, 360, 4) | units.deg
    longs_of_ascending_node = np.random.uniform(0, 360, 4) | units.deg
    args_of_periapsis = np.random.uniform(0, 360, 4) | units.deg

    #Create the four planets as binaries with the sun and add them to the pre_tack_giants_system
    for i in range(4):
        sun_and_planet = new_binary_from_orbital_elements(
            pre_tack_giants_system[0].mass,
            masses[i],
            a[i],
            0,
            true_anomalies[i],
            inclinations[i],
            longs_of_ascending_node[i],
            args_of_periapsis[i],
            G=constants.G)

        planet = Particles(1)
        planet.name = names[i]
        planet.mass = masses[i]
        planet.radius = radii[
            i]  # This is purely non-zero for collisional purposes
        planet.position = (sun_and_planet[1].x - (0 | units.AU),
                           sun_and_planet[1].y - (0 | units.AU),
                           sun_and_planet[1].z - (0 | units.AU))
        planet.velocity = (sun_and_planet[1].vx - (0 | units.kms),
                           sun_and_planet[1].vy - (0 | units.kms),
                           sun_and_planet[1].vz - (0 | units.kms))
        planet.density = 3 * planet.mass / (4 * np.pi * planet.radius**3)
        pre_tack_giants_system.add_particle(planet)

    return pre_tack_giants_system
예제 #3
0
def create_system():
    system = new_solar_system()
    system = system[system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only
    system.move_to_center()
    
    sun = Particles(1)
    sun.name = "Sun"
    sun.mass = 1.0 | units.MSun
    sun.radius = 1.0 | units.RSun  
    sun.position = (0, 0, 0) | units.AU
    sun.velocity = (0, 0, 0) | units.kms
    sun.density = 3*sun.mass/(4*np.pi*sun.radius**3)
    
    names = ["Jupiter", "Saturn", "Uranus", "Neptune"]
    masses = [317.8, 90, 15, 17] | units.MEarth
    radii = [0.10049, 0.083703, 0.036455, 0.035392] | units.RSun
    semis = [5.4, 7.1, 10.5, 13] | units.AU #[3.5, 4.9, 6.4, 8.4]
    trues = [0, 90, 180, 270]| units.deg#np.random.uniform(0, 360, 4) | units.deg
    longs = np.random.uniform(0, 360, 4) | units.deg
    args = np.random.uniform(0, 360, 4) | units.deg
    
    for i in range(4):
        orbital_elements = get_orbital_elements_from_binary(system[0]+ system[i+1], G=constants.G)
        eccentricity, inclination = 0, orbital_elements[5]
        
        
        sun_and_plan = new_binary_from_orbital_elements(sun[0].mass, masses[i], 
                                          semis[i], 0, trues[i], inclination, longs[i], args[i], G=constants.G)
        
        planet = Particles(1)
        planet.name = system[i+1].name
        planet.mass = system[i+1].mass
        planet.radius = system[i+1].radius # This is purely non-zero for collisional purposes
        planet.position = (sun_and_plan[1].x-sun_and_plan[0].x, sun_and_plan[1].y-sun_and_plan[0].y, sun_and_plan[1].z-sun_and_plan[0].z)
        planet.velocity = (sun_and_plan[1].vx-sun_and_plan[0].vx, sun_and_plan[1].vy-sun_and_plan[0].vy, sun_and_plan[1].vz-sun_and_plan[0].vz)
        planet.density = 3*planet.mass/(4*np.pi*planet.radius**3)
        sun.add_particle(planet)
        
    return sun
def evolve_sun_jupiter(particles, tend, dt):

    SunJupiter = Particles()
    SunJupiter.add_particle(particles[0])
    SunJupiter.add_particle(particles[1])

    converter = nbody_system.nbody_to_si(particles.mass.sum(),
                                         particles[1].position.length())
    gravity = ph4(converter)
    gravity.particles.add_particles(particles)

    channel_from_to_SunJupiter = gravity.particles.new_channel_to(SunJupiter)

    semi_major_axis = []
    eccentricity = []
    times = quantities.arange(0 | units.yr, tend, dt)
    for i, t in enumerate(times):
        print "Time=", t.in_(units.yr)
        channel_from_to_SunJupiter.copy()
        orbital_elements = orbital_elements_from_binary(SunJupiter,
                                                        G=constants.G)
        a = orbital_elements[2]
        e = orbital_elements[3]
        semi_major_axis.append(a.value_in(units.AU))
        eccentricity.append(e)
        gravity.evolve_model(t, timestep=dt)

    # Plot

    fig = plt.figure(figsize=(8, 6))
    ax1 = fig.add_subplot(211,
                          xlabel='time(yr)',
                          ylabel='semi major axis (AU)')
    ax1.plot(times.value_in(units.yr), semi_major_axis)
    ax2 = fig.add_subplot(212, xlabel='time(yr)', ylabel='eccentriity')
    ax2.plot(times.value_in(units.yr), eccentricity)
    plt.show()

    gravity.stop()
예제 #5
0
def evolve_sun_jupiter(particles, tend, dt):
    
    SunJupiter = Particles()
    SunJupiter.add_particle(particles[0])
    SunJupiter.add_particle(particles[1])

    converter=nbody_system.nbody_to_si(particles.mass.sum(), particles[1].position.length())
    gravity = ph4(converter)
    gravity.particles.add_particles(particles)

    channel_from_to_SunJupiter = gravity.particles.new_channel_to(SunJupiter)

    semi_major_axis = list()
    eccentricity = list()
    times = quantities.arange(0|units.yr, tend+dt, dt)

    for i,t in enumerate(times):
        #print "Time =", t.in_(units.yr)
        channel_from_to_SunJupiter.copy()
        orbital_elements = orbital_elements_from_binary(SunJupiter, G=constants.G)
        a = orbital_elements[2]
        e = orbital_elements[3]
        semi_major_axis.append(a.value_in(units.AU))
        eccentricity.append(e)
        gravity.evolve_model(t, timestep=dt)

    gravity.stop()

    # save the data: times, semi_major_axis and eccentricity of Jupiter's orbit
    t_a_e = np.column_stack((times.value_in(units.yr), semi_major_axis, eccentricity))
    np.savetxt('t_a_e.txt', t_a_e, delimiter=',')

    # make plots
    fig = plt.figure(figsize = (8, 6))
    ax1 = fig.add_subplot(211, xlabel = 'time(yr)', ylabel = 'semi major axis (AU)')
    ax1.plot(times.value_in(units.yr), semi_major_axis)
    ax2 = fig.add_subplot(212, xlabel = 'time(yr)', ylabel = 'eccentriity')
    ax2.plot(times.value_in(units.yr), eccentricity)
    plt.show()
예제 #6
0
def create_post_tack_giants_system():
    #Create the present day solar system and keep only the sun and the giants
    present_day_solar_system = new_solar_system()
    present_day_solar_system = present_day_solar_system[present_day_solar_system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only
    present_day_solar_system.move_to_center()
    
    #Create a post_tack_giants_system by first recreating the sun.
    post_tack_giants_system = Particles(1) 
    post_tack_giants_system[0].name = "Sun"
    post_tack_giants_system[0].mass = 1.0 | units.MSun
    post_tack_giants_system[0].radius = 1.0 | units.RSun  
    post_tack_giants_system[0].position = (0, 0, 0) | units.AU
    post_tack_giants_system[0].velocity = (0, 0, 0) | units.kms
    
    #The post tack orbital elements for the planets as below
    a =  np.array([5.4, 7.1, 10.5, 13]) | units.AU 
    true_anomalies = np.random.uniform(0, 360, 4) | units.deg
    long_of_ascending_node = np.random.uniform(0, 360, 4) | units.deg
    args_of_periapsis = np.random.uniform(0, 360, 4) | units.deg
    
    #Create the four planets as binaries with the sun and add them to the post_tack_giants_system
    for i in range(4):
        orbital_elements = get_orbital_elements_from_binary(present_day_solar_system[0]+ present_day_solar_system[i+1], G=constants.G)
        inclination = orbital_elements[5] #Make sure we have a sensable inclination for the giants
        
        
        sun_and_planet = new_binary_from_orbital_elements(post_tack_giants_system.mass[0], present_day_solar_system[i+1].mass, 
                                          a[i], 0, true_anomalies[i], inclination, long_of_ascending_node[i], args_of_periapsis[i], G=constants.G)
        
        planet = Particles(1)
        planet.name = present_day_solar_system[i+1].name
        planet.mass = present_day_solar_system[i+1].mass
        planet.radius = present_day_solar_system[i+1].radius
        planet.position = (sun_and_planet[1].x-sun_and_planet[0].x, sun_and_planet[1].y-sun_and_planet[0].y, sun_and_planet[1].z-sun_and_planet[0].z)
        planet.velocity = (sun_and_planet[1].vx-sun_and_planet[0].vx, sun_and_planet[1].vy-sun_and_planet[0].vy, sun_and_planet[1].vz-sun_and_planet[0].vz)
        post_tack_giants_system.add_particle(planet) 
        
    return post_tack_giants_system
예제 #7
0
def vanilla_tack_evolver(complete_pre_tack_system, converter, N_objects, times,
                         save_file_times):
    #Initialise the gravity code and add the particles to it

    gravity_code = MercuryWayWard(converter)
    gravity_code.initialize_code()

    gravity_code.central_particle.add_particle(complete_pre_tack_system[0])
    gravity_code.orbiters.add_particles(complete_pre_tack_system[1:])
    gravity_code.commit_particles

    channel = gravity_code.particles.new_channel_to(complete_pre_tack_system)

    #----------------------------------------------------------------------------------------------------
    #Here we define the 'correct' sma's for the different migrations. Also, the initial
    #planetary inclinations are stored for later use.

    initial_sma = np.array([3.5, 4.5, 6.013, 8.031]) | units.AU
    saturn_sma = np.array([1.5, 4.5, 6.013, 8.031]) | units.AU
    outward_sma = np.array([1.5, 1.5 *
                            ((3 / 2)**(2 / 3)), 6.013, 8.031]) | units.AU
    post_tack_sma = np.array([5.4, 7.1, 10.5, 13.]) | units.AU
    current_sma = [3.5, 4.5, 6.013, 8.031] | units.AU

    inclinations = [0, 0, 0, 0] | units.deg

    for k in range(4):
        orbital_elements = get_orbital_elements_from_binary(
            complete_pre_tack_system[0] + complete_pre_tack_system[k + 1],
            G=constants.G)
        inclinations[k] = orbital_elements[5]
    #----------------------------------------------------------------------------------------------------
    #Here we define the parameters used in the 'semi_major_axis_next_step' functions
    #The sma's are based on exact resonances. The time_scales are taken from literature.
    #The 0 values will be changed during the evolution of the model.
    #pre_resonant is used in the outward migration, when jupiter and saturn are
    #already in resonance with eachother, so that pre_resonant = True

    a_start = [1.5, 1.5 * ((3 / 2)**(2 / 3)), 0, 0] | units.AU
    a_end = [
        5.4, 5.4 * ((3 / 2)**(2 / 3)), 5.4 *
        ((3 / 2)**(2 / 3) * (9 / 5)**(2 / 3)), 5.4 * ((3 / 2)**(2 / 3) *
                                                      (5 / 2)**(2 / 3))
    ] | units.AU
    time_start = [1.025 * 10**5, 1.025 * 10**5, 0, 0] | units.yr
    time_scale = [5 * 10**5, 5 * 10**5, 0, 0] | units.yr

    resonances = [2 / 3, 3 / 2, 9 / 5, 5 / 2]
    pre_resonant = [False, False, True, True]

    outward_migration_started = False

    dead_comets = []

    #----------------------------------------------------------------------------------------------------
    #Below, the evolution starts.

    for i in tqdm(range(len(times) - 1)):
        gravity_code.evolve_model(times[i])
        channel.copy()

        #Save the model when we want it to
        if times[i] in save_file_times:
            write_set_to_file(
                gravity_code.orbiters,
                directory + 'Vanilla_Tack_run' + str(run_number) + '_time=' +
                str(np.log10(times[i].value_in(units.yr)))[0:5] + '.hdf5',
                format='hdf5',
                overwrite_file=True)

        #For each timestep determine the current sma's
        for j in range(4):
            current_sma[j] = sma_determinator(gravity_code.central_particle,
                                              gravity_code.orbiters[j])

        #-----------------------------------------------------------------------------------------------------
        #This chunk of code describes the inward migration of jupiter
        #The first orbiter and the second particle in the gravity_code.
        if times[i] < 10**5 | units.yr:
            #This pushes Jupiter slightly inward
            sma_next_step = semi_major_axis_next_step_in_jup(
                times[i + 1], 10**5 | units.yr, 3.5 | units.AU, 1.5 | units.AU)

            binary = Particles(0)
            binary.add_particle(gravity_code.central_particle)
            binary.add_particle(gravity_code.orbiters[0])

            orbital_params = get_orbital_elements_from_binary(binary,
                                                              G=constants.G)
            true_anomaly, ascending_node, pericenter = orbital_params[4].in_(
                units.deg), orbital_params[6].in_(
                    units.deg), orbital_params[7].in_(units.deg)

            sun_and_planet = new_binary_from_orbital_elements(
                1 | units.MSun,
                orbital_params[1],
                sma_next_step,
                0,
                true_anomaly,
                inclinations[0],
                ascending_node,
                pericenter,
                G=constants.G)

            gravity_code.particles[1].position = (sun_and_planet[1].x -
                                                  (0 | units.AU),
                                                  sun_and_planet[1].y -
                                                  (0 | units.AU),
                                                  sun_and_planet[1].z -
                                                  (0 | units.AU))
            gravity_code.particles[1].velocity = (sun_and_planet[1].vx -
                                                  (0 | units.kms),
                                                  sun_and_planet[1].vy -
                                                  (0 | units.kms),
                                                  sun_and_planet[1].vz -
                                                  (0 | units.kms))

            #During the tack, the masses of the planets increase towards their current values
            gravity_code.particles[2].mass *= 2**(1.5 / (10**5))
            gravity_code.particles[3].mass *= 1.2**(1.5 / (10**5))
            gravity_code.particles[4].mass *= 1.2**(1.5 / (10**5))

            #This keeps the other planets in place
            for j in range(3):
                binary = Particles(0)
                binary.add_particle(gravity_code.central_particle)
                binary.add_particle(gravity_code.orbiters[j + 1])

                orbital_params = get_orbital_elements_from_binary(
                    binary, G=constants.G)
                true_anomaly, ascending_node, pericenter = orbital_params[
                    4].in_(units.deg), orbital_params[6].in_(
                        units.deg), orbital_params[7].in_(units.deg)

                sun_and_planet = new_binary_from_orbital_elements(
                    1 | units.MSun,
                    orbital_params[1],
                    initial_sma[1 + j],
                    0,
                    true_anomaly,
                    inclinations[j + 1],
                    ascending_node,
                    pericenter,
                    G=constants.G)

                gravity_code.particles[j + 2].position = (sun_and_planet[1].x -
                                                          (0 | units.AU),
                                                          sun_and_planet[1].y -
                                                          (0 | units.AU),
                                                          sun_and_planet[1].z -
                                                          (0 | units.AU))
                gravity_code.particles[j + 2].velocity = (
                    sun_and_planet[1].vx - (0 | units.kms),
                    sun_and_planet[1].vy - (0 | units.kms),
                    sun_and_planet[1].vz - (0 | units.kms))

        #------------------------------------------------------------------------------------------------------------
        #This chunk of code describes the inward migration of saturn
        elif 1 * 10**5 | units.yr <= times[i] < 1.025 * 10**5 | units.yr:
            #This pushes Saturn slightly inward
            sma_next_step = semi_major_axis_next_step_in_sat(
                times[i + 1], 2.5 * 10**3 | units.yr, 4.5 | units.AU,
                1.5 * ((3 / 2)**(2 / 3)) | units.AU)

            binary = Particles(0)
            binary.add_particle(gravity_code.central_particle)
            binary.add_particle(gravity_code.orbiters[1])

            orbital_params = get_orbital_elements_from_binary(binary,
                                                              G=constants.G)
            true_anomaly, ascending_node, pericenter = orbital_params[4].in_(
                units.deg), orbital_params[6].in_(
                    units.deg), orbital_params[7].in_(units.deg)

            sun_and_planet = new_binary_from_orbital_elements(
                1 | units.MSun,
                orbital_params[1],
                sma_next_step,
                0,
                true_anomaly,
                inclinations[1],
                ascending_node,
                pericenter,
                G=constants.G)

            gravity_code.particles[2].position = (sun_and_planet[1].x -
                                                  (0 | units.AU),
                                                  sun_and_planet[1].y -
                                                  (0 | units.AU),
                                                  sun_and_planet[1].z -
                                                  (0 | units.AU))
            gravity_code.particles[2].velocity = (sun_and_planet[1].vx -
                                                  (0 | units.kms),
                                                  sun_and_planet[1].vy -
                                                  (0 | units.kms),
                                                  sun_and_planet[1].vz -
                                                  (0 | units.kms))

            gravity_code.particles[2].mass *= 1.5**(0.5 / (2500))
            gravity_code.particles[3].mass *= (17.15 / 6)**(0.5 / (5 * 10**5))
            gravity_code.particles[4].mass *= (14.54 / 6)**(0.5 / (5 * 10**5))

            #This keeps the other planets in place
            for j in [0, 2, 3]:
                binary = Particles(0)
                binary.add_particle(gravity_code.central_particle)
                binary.add_particle(gravity_code.orbiters[j])

                orbital_params = get_orbital_elements_from_binary(
                    binary, G=constants.G)
                true_anomaly, ascending_node, pericenter = orbital_params[
                    4].in_(units.deg), orbital_params[6].in_(
                        units.deg), orbital_params[7].in_(units.deg)

                sun_and_planet = new_binary_from_orbital_elements(
                    1 | units.MSun,
                    orbital_params[1],
                    saturn_sma[j],
                    0,
                    true_anomaly,
                    inclinations[j],
                    ascending_node,
                    pericenter,
                    G=constants.G)

                gravity_code.particles[j + 1].position = (sun_and_planet[1].x -
                                                          (0 | units.AU),
                                                          sun_and_planet[1].y -
                                                          (0 | units.AU),
                                                          sun_and_planet[1].z -
                                                          (0 | units.AU))
                gravity_code.particles[j + 1].velocity = (
                    sun_and_planet[1].vx - (0 | units.kms),
                    sun_and_planet[1].vy - (0 | units.kms),
                    sun_and_planet[1].vz - (0 | units.kms))

        #------------------------------------------------------------------------------------------------------------
        #This chunk of code describes the outward migration of all planets
        elif 1.025 * 10**5 | units.yr <= times[i] < 6 * 10**5 | units.yr:

            #This bit checks if uranus and neptune already should start migrating
            for k in range(4):
                if pre_resonant[k] == True:
                    if current_sma[k] / current_sma[1] < (resonances[k])**(2 /
                                                                           3):
                        pre_resonant[k] = False
                        a_start[k] = current_sma[k]
                        time_start[k] = times[i]
                        time_scale[k] = (6 * 10**5 | units.yr) - times[i]

            #If pre_resonant == False, pushes the planet outward. If true, keeps it in place
            for l in range(4):
                if pre_resonant[l] == False:
                    sma_next_step = semi_major_axis_next_step_out(
                        times[i + 1], time_start[l], a_end[l], a_start[l],
                        time_scale[l])

                    binary = Particles(0)
                    binary.add_particle(gravity_code.central_particle)
                    binary.add_particle(gravity_code.orbiters[l])

                    orbital_params = get_orbital_elements_from_binary(
                        binary, G=constants.G)
                    true_anomaly, ascending_node, pericenter = orbital_params[
                        4].in_(units.deg), orbital_params[6].in_(
                            units.deg), orbital_params[7].in_(units.deg)

                    sun_and_planet = new_binary_from_orbital_elements(
                        1 | units.MSun,
                        orbital_params[1],
                        sma_next_step,
                        0,
                        true_anomaly,
                        inclinations[l],
                        ascending_node,
                        pericenter,
                        G=constants.G)

                    gravity_code.particles[l + 1].position = (
                        sun_and_planet[1].x - (0 | units.AU),
                        sun_and_planet[1].y - (0 | units.AU),
                        sun_and_planet[1].z - (0 | units.AU))
                    gravity_code.particles[l + 1].velocity = (
                        sun_and_planet[1].vx - (0 | units.kms),
                        sun_and_planet[1].vy - (0 | units.kms),
                        sun_and_planet[1].vz - (0 | units.kms))

                else:
                    binary = Particles(0)
                    binary.add_particle(gravity_code.central_particle)
                    binary.add_particle(gravity_code.orbiters[l])

                    orbital_params = get_orbital_elements_from_binary(
                        binary, G=constants.G)
                    true_anomaly, ascending_node, pericenter = orbital_params[
                        4].in_(units.deg), orbital_params[6].in_(
                            units.deg), orbital_params[7].in_(units.deg)

                    sun_and_planet = new_binary_from_orbital_elements(
                        1 | units.MSun,
                        orbital_params[1],
                        outward_sma[l],
                        0,
                        true_anomaly,
                        inclinations[l],
                        ascending_node,
                        pericenter,
                        G=constants.G)

                    gravity_code.particles[l + 1].position = (
                        sun_and_planet[1].x - (0 | units.AU),
                        sun_and_planet[1].y - (0 | units.AU),
                        sun_and_planet[1].z - (0 | units.AU))
                    gravity_code.particles[l + 1].velocity = (
                        sun_and_planet[1].vx - (0 | units.kms),
                        sun_and_planet[1].vy - (0 | units.kms),
                        sun_and_planet[1].vz - (0 | units.kms))

            gravity_code.particles[3].mass *= (17.15 / 6)**(15 / (5 * 10**5))
            gravity_code.particles[4].mass *= (14.54 / 6)**(15 / (5 * 10**5))

        #------------------------------------------------------------------------------------------------------------

        else:
            #---------------------------------------------------------------------------------------------------------------

            for l in range(4):
                if abs(current_sma[l] / post_tack_sma[l]) > 1.25 or abs(
                        current_sma[l] / post_tack_sma[l]
                ) < 0.75:  #The orbits are too much perturbed, so we end the simulation
                    return

                elif abs(current_sma[l] / post_tack_sma[l]) > 1.05 or abs(
                        current_sma[l] / post_tack_sma[l]
                ) < 0.95:  #The orbits are slightly perturbed, so we redefinie them
                    print("Here", complete_pre_tack_system[l + 1].name,
                          "was redefined")
                    binary = Particles(0)
                    binary.add_particle(gravity_code.central_particle)
                    binary.add_particle(gravity_code.orbiters[l])

                    orbital_params = get_orbital_elements_from_binary(
                        binary, G=constants.G)
                    true_anomaly, ascending_node, pericenter = orbital_params[
                        4].in_(units.deg), orbital_params[6].in_(
                            units.deg), orbital_params[7].in_(units.deg)

                    sun_and_planet = new_binary_from_orbital_elements(
                        1 | units.MSun,
                        orbital_params[1],
                        post_tack_sma[l],
                        0,
                        true_anomaly,
                        inclinations[l],
                        ascending_node,
                        pericenter,
                        G=constants.G)

                    gravity_code.particles[l + 1].position = (
                        sun_and_planet[1].x - (0 | units.AU),
                        sun_and_planet[1].y - (0 | units.AU),
                        sun_and_planet[1].z - (0 | units.AU))
                    gravity_code.particles[l + 1].velocity = (
                        sun_and_planet[1].vx - (0 | units.kms),
                        sun_and_planet[1].vy - (0 | units.kms),
                        sun_and_planet[1].vz - (0 | units.kms))
                else:
                    pass
        #----------------------------------------------------------------------------------------------------------------------
        #Here we look for 'escaped' and 'out of bounds' comets
            out_of_bounds, escaped_comets = [], []
            for i in range(len(gravity_code.orbiters)):
                if gravity_code.orbiters[i].position.length() > 500 | units.AU:
                    escaped_comets.append(gravity_code.orbiters[i])
                if gravity_code.orbiters[i].position.length(
                ) > 250000 | units.AU:
                    out_of_bounds.append(gravity_code.orbiters[i])
                    dead_comets.append(gravity_code.orbiters[i])
            for particle in out_of_bounds:
                complete_pre_tack_system.remove_particle(particle)
                complete_pre_tack_system.synchronize_to(gravity_code.particles)
            if i % 1000 == 0:
                print("The amount of currently escaped comets is ",
                      len(escaped_comets))
                print("The amount of dead comets is ", len(dead_comets))

        if i % 1000 == 0:
            print("The sma's are: ", current_sma[0], current_sma[1],
                  current_sma[2], current_sma[3])

    gravity_code.stop()
    return complete_pre_tack_system
예제 #8
0
def vanilla_evolver(particle_system, converter, N_objects, end_time, time_step):
    
    names = ['Sun', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
    
    gravity_code = MercuryWayWard()
    gravity_code.initialize_code()
    
    gravity_code.central_particle.add_particle(particle_system[0])
    gravity_code.orbiters.add_particles(particle_system[1:])
    gravity_code.commit_particles
    
    ch_g2l = gravity_code.particles.new_channel_to(particle_system)
    
    times = np.arange(0., end_time, time_step) | units.yr
    
    dead_comets = []
    #---------------------------------------------------------------------------------------------------------
    sma = [0, 0, 0, 0] | units.AU
    correct_sma = [5.4, 7.1, 10.5, 13] | units.AU
    eccentricities = [0, 0, 0, 0]
    inclinations = [0, 0, 0, 0] | units.deg
    
    system = new_solar_system()
    system = system[system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only
    system.move_to_center()
    for k in range(4):
        orbital_elements = get_orbital_elements_from_binary(system[0]+ system[k+1], G=constants.G)
        inclinations[k] =  orbital_elements[5]
    #------------------------------------------------------------------------------------------------------------
    
    
    
    for i in tqdm(range(len(times))):
        gravity_code.evolve_model(times[i])
        ch_g2l.copy()
        
        #---------------------------------------------------------------------------------------------------------------
        for j in range(4):
            sma[j] = sma_determinator(gravity_code.central_particle, gravity_code.orbiters[j])
        
        for l in range(4):
            if abs(sma[l]/correct_sma[l]) > 1.25 or abs(sma[l]/correct_sma[l]) < 0.75:
                return
        
            elif abs(sma[l]/correct_sma[l]) > 1.05 or abs(sma[l]/correct_sma[l]) < 0.95:
                print("Here", names[l+1], "was redefined")
                binary = Particles(0)
                binary.add_particle(gravity_code.central_particle)
                binary.add_particle(gravity_code.orbiters[l])

                orbital_params = get_orbital_elements_from_binary(binary, G = constants.G)
                true_anomaly, ascending_node, pericenter = orbital_params[4].in_(units.deg), orbital_params[6].in_(units.deg), orbital_params[7].in_(units.deg)

                sun_and_plan = new_binary_from_orbital_elements(1 | units.MSun, orbital_params[1], 
                                                      correct_sma[l], eccentricities[l], true_anomaly, inclinations[l], ascending_node, pericenter, G=constants.G)

                gravity_code.particles[l+1].position = (sun_and_plan[1].x-sun_and_plan[0].x, sun_and_plan[1].y-sun_and_plan[0].y, sun_and_plan[1].z-sun_and_plan[0].z)
                gravity_code.particles[l+1].velocity = (sun_and_plan[1].vx-sun_and_plan[0].vx, sun_and_plan[1].vy-sun_and_plan[0].vy, sun_and_plan[1].vz-sun_and_plan[0].vz)
            else:
                pass
        #----------------------------------------------------------------------------------------------------------------------
        
        
        
            
        if i%1000 == 0:
            write_set_to_file(gravity_code.orbiters, directory + 'Vanilla_run16_time=' + str(np.log10(times[i].value_in(units.yr)))[0:5] + '.hdf5', format='hdf5', overwrite_file = True)
        
        out_of_bounds, escaped_comets = [], []
        for i in range(len(particle_system)):
            if particle_system[i].position.length() > 500 | units.AU:
                escaped_comets.append(particle_system[i].name)
                if particle_system[i].position.length() > 250000 | units.AU:
                    out_of_bounds.append(particle_system[i])
                    dead_comets.append(particle_system[i])
        for particle in out_of_bounds:
            particle_system.remove_particle(particle)
            particle_system.synchronize_to(gravity_code.particles)
            
        print("The amount of currently escaped comets is ", len(escaped_comets))
        print("The amount of dead comets is ", len(dead_comets))
        print("The planetary positions are ", gravity_code.orbiters[0].position.length().in_(units.AU), gravity_code.orbiters[1].position.length().in_(units.AU), gravity_code.orbiters[2].position.length().in_(units.AU), gravity_code.orbiters[3].position.length().in_(units.AU))
    
    gravity_code.stop()
    write_set_to_file(gravity_code.orbiters, directory + 'Vanilla_run16_final.hdf5', format='hdf5', overwrite_file = True)
    return particle_system
예제 #9
0
def MWG_evolver(complete_post_tack_system, converter, N_objects, potential, end_time, time_step):
    #Initialise the gravity code and add the particles to it
    gravity_code = Huayno(converter)
    gravity_code.particles.add_particles(complete_post_tack_system)
    channel = gravity_code.particles.new_channel_to(complete_post_tack_system)
    
    gravity_bridge = 0
    gravity_bridge = bridge.Bridge(use_threading=False)
    gravity_bridge.add_system(gravity_code, (potential,))
    gravity_bridge.timestep = 100 |units.yr
    
    times = np.arange(0., end_time, time_step) | units.yr #All time steps to which we want to evolve the model
    
    #---------------------------------------------------------------------------------------------------------
    #Here we define the planetary orbital parameters that should be returned to if the planets start moving too much 
    current_sma = np.array([0, 0, 0, 0]) | units.AU
    correct_sma =  np.array([5.4, 7.1, 10.5, 13]) | units.AU
    inclinations =  np.array([0, 0, 0, 0]) | units.deg
    
    
    system = new_solar_system()
    system = system[system.mass > 10**-5 | units.MSun] # Takes gas giants and Sun only
    system.move_to_center()
    for k in range(4):
        orbital_elements = get_orbital_elements_from_binary(system[0]+ system[k+1], G=constants.G)
        inclinations[k] =  orbital_elements[5]
    #------------------------------------------------------------------------------------------------------------
    dead_comets = [] #Here all 'dead' comets are stored
    
    #Below the evolving starts
    for i in tqdm(range(len(times))):
        gravity_bridge.evolve_model(times[i])
        channel.copy()
        
        #---------------------------------------------------------------------------------------------------------------
        #Here we check if the planetary orbits are still 'correct' and act for three degrees of incorrectness.
        for j in range(4):
            current_sma[j] = sma_determinator(gravity_code.particles[0], gravity_code.particles[j+1])
        
        for l in range(4):
            if abs(current_sma[l]/correct_sma[l]) > 1.25 or abs(current_sma[l]/correct_sma[l]) < 0.75: #The orbits are too much perturbed, so we end the simulation
                return
        
            elif abs(current_sma[l]/correct_sma[l]) > 1.05 or abs(current_sma[l]/correct_sma[l]) < 0.95: #The orbits are slightly perturbed, so we redefinie them
                print("Here", complete_post_tack_system[l+1].name, "was redefined")
                binary = Particles(0)
                binary.add_particle(gravity_code.particles[0])
                binary.add_particle(gravity_code.particles[l+1])

                orbital_params = get_orbital_elements_from_binary(binary, G = constants.G)
                true_anomaly, ascending_node, pericenter = orbital_params[4].in_(units.deg), orbital_params[6].in_(units.deg), orbital_params[7].in_(units.deg)

                sun_and_plan = new_binary_from_orbital_elements(1 | units.MSun, orbital_params[1], #We keep the current angles, but change the a, e and i back
                                                      correct_sma[l], 0, true_anomaly, inclinations[l], ascending_node, pericenter, G=constants.G)
                
                gravity_code.particles[l+1].position = (sun_and_plan[1].x+gravity_code.particles[0].x, sun_and_plan[1].y+gravity_code.particles[0].y, sun_and_plan[1].z+gravity_code.particles[0].z)
                gravity_code.particles[l+1].velocity = (sun_and_plan[1].vx+gravity_code.particles[0].vx, sun_and_plan[1].vy+gravity_code.particles[0].vy, sun_and_plan[1].vz+gravity_code.particles[0].vz)
            else: #The orbits do not need changing
                pass
        #----------------------------------------------------------------------------------------------------------------------
        #Once we checked for the orbital correctness, we can save data 
        
        if i%4000 == 0:
            write_set_to_file(gravity_code.particles, directory + 'MWG_run' + str(run_number) +'_time=' + str(np.log10(times[i].value_in(units.yr)))[0:5] + '.hdf5', format='hdf5', overwrite_file = True)
            
        #--------------------------------------------------------------------------------------------------------------------
        #Here we look for 'escaped' and 'out of bounds' comets
        out_of_bounds, escaped_comets = [], []
        for i in range(len(gravity_code.particles)):
            if (gravity_code.particles[i].position-gravity_code.particles[0].position).length() > 500 | units.AU:
                escaped_comets.append(gravity_code.particles[i])
                if (gravity_code.particles[i].position-gravity_code.particles[0].position).length() > 250000 | units.AU:
                    out_of_bounds.append(gravity_code.particles[i])
                    dead_comets.append(gravity_code.particles[i])
        for particle in out_of_bounds: #Out of bounds comets are removed completely
            complete_post_tack_system.remove_particle(particle)
            complete_post_tack_system.synchronize_to(gravity_code.particles)
            
        
        if i%100 == 0:
            print("The amount of currently escaped comets is ", len(escaped_comets))
            print("The amount of dead comets is ", len(dead_comets))
            for m in range(4):
                print(complete_post_tack_system[m+1].name, " is at ", (gravity_code.particles[m+1].position-gravity_code.particles[0].position).length().in_(units.AU))
    
        
    gravity_code.stop()
    write_set_to_file(gravity_code.orbiters, directory + 'MWG_run' + str(run_number) +'_final.hdf5', format='hdf5', overwrite_file = True)
    return complete_post_tack