Пример #1
0
def evolve_quadruple(N_output, end_time, m1, m2, m3, m4, aA, aB, aC, eA, eB, eC, iA, iB, iC, ApA, ApB, ApC, LANA, LANB, LANC):

    masses = [m1, m2, m3, m4]
    semimajor_axis = [aA, aB, aC]
    eccentricity = [eA, eB, eC]
    inclination = numpy.deg2rad([iA, iB, iC])
    argument_of_percienter = numpy.deg2rad([ApA, ApB, ApC])
    longitude_of_ascending_node = numpy.deg2rad([LANA, LANB, LANC])
    print longitude_of_ascending_node
    
    N_bodies = 4
    N_binaries = N_bodies-1
    particles, binaries = initialize_multiple_system(N_bodies, masses, semimajor_axis, eccentricity, inclination, argument_of_percienter, longitude_of_ascending_node)

    code = SecularMultiple()
    code.particles.add_particles(particles)

    channel_from_particles_to_code = particles.new_channel_to(code.particles)
    channel_from_code_to_particles = code.particles.new_channel_to(particles)
    channel_from_particles_to_code.copy()

    ### set up some arrays for plotting ###
    print_smas_AU = [[] for x in range(N_binaries)]
    print_rps_AU = [[] for x in range(N_binaries)]
    print_parent_is_deg = [[] for x in range(N_binaries)]
    print_times_Myr = []

    time = 0.0|units.yr
    output_time_step = end_time/float(N_output)
    while time <= end_time:
        time += output_time_step
        code.evolve_model(time)

        channel_from_code_to_particles.copy()
        print '='*50
        print 't/Myr',time.value_in(units.Myr)
        print 'e',binaries.eccentricity
        print 'i/deg', numpy.rad2deg(binaries.inclination)
        print 'AP/deg', \
            numpy.rad2deg(binaries.argument_of_pericenter)  
        print 'LAN/deg', \
            numpy.rad2deg(binaries.longitude_of_ascending_node)
            
        ### write to output arrays ###
        print_times_Myr.append(time.value_in(units.Myr))
        for index_binary in range(N_binaries):
            print_smas_AU[index_binary].append( binaries[index_binary].semimajor_axis.value_in(units.AU) )
            print_rps_AU[index_binary].append( binaries[index_binary].semimajor_axis.value_in(units.AU)*(1.0 - binaries[index_binary].eccentricity) )
            print_parent_is_deg[index_binary].append( numpy.rad2deg(binaries[index_binary].inclination_relative_to_parent) )

    ### compute the `canonical' maximum eccentricity/periapsis distance that applies in the quadrupole-order test-particle limit if the `outer' binary is replaced by a point mass ###
    print inclination[0],inclination[2],longitude_of_ascending_node[0],longitude_of_ascending_node[2]
    i_AC_init = compute_mutual_inclination(inclination[0],inclination[2],longitude_of_ascending_node[0],longitude_of_ascending_node[2])
    i_BC_init = compute_mutual_inclination(inclination[1],inclination[2],longitude_of_ascending_node[1],longitude_of_ascending_node[2])
    
    canonical_rp_min_A_AU = (semimajor_axis[0]*(1.0 - numpy.sqrt( 1.0 - (5.0/3.0)*numpy.cos(i_AC_init)**2 ) )).value_in(units.AU)
    canonical_rp_min_B_AU = (semimajor_axis[1]*(1.0 - numpy.sqrt( 1.0 - (5.0/3.0)*numpy.cos(i_BC_init)**2 ) )).value_in(units.AU)

    data = print_times_Myr,print_smas_AU,print_rps_AU,print_parent_is_deg,canonical_rp_min_A_AU,canonical_rp_min_B_AU
    return data
Пример #2
0
    def test7(self):
        """
        test collision detection in 3-body system
        """

        particles = create_nested_multiple(3,[1.0|units.MSun, 1.2|units.MSun, 0.9|units.MSun], [1.0|units.AU, 100.0|units.AU], [0.1, 0.5], [0.01, 80.0*numpy.pi/180.0], [0.01, 0.01], [0.01, 0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries

        binaries.check_for_physical_collision_or_orbit_crossing = True
        stars.radius = 0.03 | units.AU

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-2 | units.Myr
        tend = 1.0e-1 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()

        while (t<tend):
            t+=dt
            code.evolve_model(t)
            flag = code.flag
            channel_from_code.copy()

            print 'secular_breakdown_has_occurred',binaries.secular_breakdown_has_occurred
            print 'dynamical_instability_has_occurred',binaries.dynamical_instability_has_occurred
            print 'physical_collision_or_orbit_crossing_has_occurred',binaries.physical_collision_or_orbit_crossing_has_occurred
            print 'minimum_periapse_distance_has_occurred',binaries.minimum_periapse_distance_has_occurred
            print 'RLOF_at_pericentre_has_occurred',binaries.RLOF_at_pericentre_has_occurred

            if flag == 2:
                print 'root found'
                break
            print 't_end',code.model_time.value_in(units.Myr)

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure()
            plot = fig.add_subplot(2,1,1)
            plot.plot(t_print_array.value_in(units.Myr),e_print_array.value_in(units.none))

            plot = fig.add_subplot(2,1,2)
            plot.plot(t_print_array.value_in(units.Myr),a_print_array.value_in(units.AU)*(1.0-e_print_array.value_in(units.none)))
            plot.axhline(y = stars[0].radius.value_in(units.AU) + stars[1].radius.value_in(units.AU),color='k')

            pyplot.show()
Пример #3
0
    def test1(self):
        """
        test reference system of Naoz et al. (2009)
        """
        particles = create_nested_multiple(3,[1.0|units.MSun, 1.0|units.MJupiter, 40.0|units.MJupiter], [6.0|units.AU,100.0|units.AU], [0.001,0.6], [0.0001,65.0*numpy.pi/180.0],[45.0*numpy.pi/180.0,0.0001],[0.01,0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = False

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)


        channel_to_code.copy()
        self.assertEquals(0.6, code.particles[particles.is_binary][1].eccentricity)

        t = 0.0 | units.Myr
        dt = 1.0e-2 | units.Myr
        tend = 3.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        INCL_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t<tend):
            t+=dt
            N+=1
            code.evolve_model(t)
            print 't/Myr = ',code.model_time.value_in(units.Myr)

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            INCL_print_array.append(binaries[0].inclination_relative_to_parent | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter | units.none)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16,10))
            plot1 = fig.add_subplot(2,1,1)
            plot2 = fig.add_subplot(2,1,2,yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),(180.0/numpy.pi)*INCL_print_array.value_in(units.none), color='k')
            plot2.plot(t_print_array.value_in(units.Myr),1.0-e_print_array.value_in(units.none), color='k')

            fontsize = 15
            plot1.set_ylabel("$i$",fontsize=fontsize)
            plot2.set_ylabel("$1-e$",fontsize=fontsize)
            plot2.set_xlabel("$t/\mathrm{Myr}$",fontsize=fontsize)

            pyplot.show()
Пример #4
0
    def test8(self):
        """
        test minimum periapse occurrence
        """

        particles = create_nested_multiple(
            3, [1.0 | units.MSun, 1.2 | units.MSun, 0.9 | units.MSun],
            [1.0 | units.AU, 100.0 | units.AU], [0.1, 0.5],
            [0.01, 80.0 * numpy.pi / 180.0], [0.01, 0.01], [0.01, 0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries

        binaries.check_for_minimum_periapse_distance = True
        rp_min = 0.1 | units.AU
        binaries.check_for_minimum_periapse_distance_value = rp_min

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 5.0e-3 | units.Myr
        tend = 1.0e-1 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()

        while (t < tend):
            t += dt
            code.evolve_model(t)
            flag = code.flag
            channel_from_code.copy()

            print('secular_breakdown_has_occurred',
                  binaries.secular_breakdown_has_occurred)
            print('dynamical_instability_has_occurred',
                  binaries.dynamical_instability_has_occurred)
            print('physical_collision_or_orbit_crossing_has_occurred',
                  binaries.physical_collision_or_orbit_crossing_has_occurred)
            print('minimum_periapse_distance_has_occurred',
                  binaries.minimum_periapse_distance_has_occurred)
            print('RLOF_at_pericentre_has_occurred',
                  binaries.RLOF_at_pericentre_has_occurred)

            if flag == 2:
                print('root found')
                break
            print('t_end', code.model_time.value_in(units.Myr))

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
Пример #5
0
    def test3(self):
        """
        test GW emission in 2-body system + collision detection
        """
        particles = create_nested_multiple(
            2, [1.0 | units.MSun, 1.0 | units.MJupiter], [0.1 | units.AU],
            [0.994], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries
        stars.radius = 0.0001 | units.AU

        binaries.check_for_physical_collision_or_orbit_crossing = True
        binaries.include_pairwise_25PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        tend = 1.0 | units.Gyr
        N = 0
        t = 0.0 | units.Myr
        dt = 100.0 | units.Myr
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)
            flag = code.flag

            if flag == 2:
                print('root found')
                break

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            print('e', binaries.eccentricity, 'a/AU',
                  binaries.semimajor_axis.value_in(units.AU), 'rp/AU',
                  (binaries.semimajor_axis *
                   (1.0 - binaries.eccentricity)).value_in(units.AU))
Пример #6
0
    def test2(self):
        """
        test 1PN precession in 2-body system
        """
        particles = create_nested_multiple(
            2, [1.0 | units.MSun, 1.0 | units.MJupiter], [1.0 | units.AU],
            [0.99], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-1 | units.Myr
        tend = 1.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)

            channel_from_code.copy()

            print('t/Myr', t.value_in(units.Myr), 'omega',
                  binaries[0].argument_of_pericenter | units.none)
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

        a = binaries[0].semimajor_axis
        e = binaries[0].eccentricity
        M = binaries[0].mass
        rg = constants.G * M / (constants.c**2)
        P = 2.0 * numpy.pi * numpy.sqrt(a**3 / (constants.G * M))
        t_1PN = (1.0 / 3.0) * P * (1.0 - e**2) * (a / rg)
Пример #7
0
    def test1(self):
        """
        test reference system of Naoz et al. (2009)
        """
        particles = create_nested_multiple(
            3, [1.0 | units.MSun, 1.0 | units.MJupiter, 40.0 | units.MJupiter],
            [6.0 | units.AU, 100.0 | units.AU], [0.001, 0.6],
            [0.0001, 65.0 * numpy.pi / 180.0],
            [45.0 * numpy.pi / 180.0, 0.0001], [0.01, 0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = False

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()
        self.assertEqual(0.6,
                         code.particles[particles.is_binary][1].eccentricity)

        t = 0.0 | units.Myr
        dt = 1.0e-2 | units.Myr
        tend = 3.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        INCL_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)
            print('t/Myr = ', code.model_time.value_in(units.Myr))

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            INCL_print_array.append(binaries[0].inclination_relative_to_parent
                                    | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)
    def test7(self):
        """
        test collision detection in 3-body system
        """

        particles = create_nested_multiple(
            3, [1.0 | units.MSun, 1.2 | units.MSun, 0.9 | units.MSun],
            [1.0 | units.AU, 100.0 | units.AU], [0.1, 0.5],
            [0.01, 80.0 * numpy.pi / 180.0], [0.01, 0.01], [0.01, 0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries

        binaries.check_for_physical_collision_or_orbit_crossing = True
        stars.radius = 0.03 | units.AU

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-2 | units.Myr
        tend = 1.0e-1 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()

        while (t < tend):
            t += dt
            code.evolve_model(t)
            flag = code.flag
            channel_from_code.copy()

            print('secular_breakdown_has_occurred',
                  binaries.secular_breakdown_has_occurred)
            print('dynamical_instability_has_occurred',
                  binaries.dynamical_instability_has_occurred)
            print('physical_collision_or_orbit_crossing_has_occurred',
                  binaries.physical_collision_or_orbit_crossing_has_occurred)
            print('minimum_periapse_distance_has_occurred',
                  binaries.minimum_periapse_distance_has_occurred)
            print('RLOF_at_pericentre_has_occurred',
                  binaries.RLOF_at_pericentre_has_occurred)

            if flag == 2:
                print('root found')
                break
            print('t_end', code.model_time.value_in(units.Myr))

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure()
            plot = fig.add_subplot(2, 1, 1)
            plot.plot(t_print_array.value_in(units.Myr),
                      e_print_array.value_in(units.none))

            plot = fig.add_subplot(2, 1, 2)
            plot.plot(
                t_print_array.value_in(units.Myr),
                a_print_array.value_in(units.AU) *
                (1.0 - e_print_array.value_in(units.none)))
            plot.axhline(y=stars[0].radius.value_in(units.AU) +
                         stars[1].radius.value_in(units.AU),
                         color='k')

            pyplot.show()
    def test6(self):
        """
        test precession due to rotation
        """

        M = 1.0 | units.MJupiter
        R = 1.5 | units.RJupiter
        m_per = 1.0 | units.MSun
        a0 = 30.0 | units.AU
        e0 = 0.999
        P0 = 2.0 * numpy.pi * numpy.sqrt(a0**3 / (constants.G * (M + m_per)))
        n0 = 2.0 * numpy.pi / P0

        aF = a0 * (1.0 - e0**2)
        nF = numpy.sqrt(constants.G * (M + m_per) / (aF**3))

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [1.0e-5],
                                           [1.0e-5], [1.0e-5])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R
        particles[1].spin_vec_x = 0.0 | 1.0 / units.day
        particles[1].spin_vec_y = 0.0 | 1.0 / units.day
        Omega_PS0 = n0 * (33.0 / 10.0) * pow(a0 / aF, 3.0 / 2.0)
        particles[1].spin_vec_z = Omega_PS0

        k_L = 0.51
        k_AM = k_L / 2.0
        rg = 0.25
        particles[1].tides_method = 1
        particles[1].include_tidal_friction_terms = False
        particles[1].include_tidal_bulges_precession_terms = False
        particles[1].include_rotation_precession_terms = True
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-5
        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_gyration_radius = rg

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e1 | units.Myr
        tend = 1.0e2 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        Omega_vec = [
            particles[1].spin_vec_x, particles[1].spin_vec_y,
            particles[1].spin_vec_z
        ]
        Omega = numpy.sqrt(Omega_vec[0]**2 + Omega_vec[1]**2 + Omega_vec[2]**2)
        print('Omega/n', Omega / n0)

        g_dot_rot = n0 * (1.0 + m_per / M) * k_AM * pow(
            R / a0, 5.0) * (Omega / n0)**2 / ((1.0 - e0**2)**2)
        t_rot = 2.0 * numpy.pi / g_dot_rot
        print('t_rot/Myr', t_rot.value_in(units.Myr))

        N = 0
        while (t < tend):
            t += dt
            code.evolve_model(t)
            print('flag', code.flag, t, binaries[0].semimajor_axis,
                  binaries[0].eccentricity)

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            N += 1
        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16, 10))
            plot1 = fig.add_subplot(4, 1, 1)
            plot2 = fig.add_subplot(4, 1, 2, yscale="log")
            plot3 = fig.add_subplot(4, 1, 3, yscale="log")
            plot4 = fig.add_subplot(4, 1, 4, yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),
                       AP_print_array.value_in(units.none),
                       color='r')
            points = numpy.linspace(0.0, tend.value_in(units.Myr), N)
            AP = 0.01 + 2.0 * numpy.pi * points / (t_rot.value_in(units.Myr))
            AP = (AP + numpy.pi) % (2.0 *
                                    numpy.pi) - numpy.pi  ### -pi < AP < pi
            plot1.plot(points, AP, color='g')

            plot2.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs(
                           (AP - AP_print_array.value_in(units.none)) / AP),
                       color='r')
            plot3.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((a0 - a_print_array) / a0),
                       color='r')
            plot4.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((e0 - e_print_array) / e0),
                       color='r')

            fontsize = 15
            plot1.set_ylabel("$\omega$", fontsize=fontsize)
            plot2.set_ylabel("$|(\omega_p-\omega)/\omega_p|$",
                             fontsize=fontsize)
            plot3.set_ylabel("$|(a_0-a)/a_0|$", fontsize=fontsize)
            plot4.set_ylabel("$|(e_0-e)/e_0|$", fontsize=fontsize)

            pyplot.show()
Пример #10
0
    def test4(self):
        """
        test tidal friction in 2-body system
        """

        M = 1.0 | units.MJupiter
        R = 40.0 | units.RJupiter
        m_per = 1.0 | units.MSun
        m = m_per
        mu = m * M / (m + M)
        a0 = 0.1 | units.AU
        e0 = 0.3
        P0 = 2.0 * numpy.pi * numpy.sqrt(a0**3 / (constants.G * (M + m_per)))
        n0 = 2.0 * numpy.pi / P0

        aF = a0 * (1.0 - e0**2)
        nF = numpy.sqrt(constants.G * (M + m_per) / (aF**3))

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [0.01],
                                           [0.01], [0.01])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R
        particles[1].spin_vec_x = 0.0 | 1.0 / units.day
        particles[1].spin_vec_y = 0.0 | 1.0 / units.day
        particles[1].spin_vec_z = 4.0e-2 | 1.0 / units.day

        k_L = 0.38
        k_AM = k_L / 2.0
        rg = 0.25
        tau = 0.66 | units.s

        I = rg * M * R**2
        alpha = I / (mu * a0**2)
        T = R**3 / (constants.G * M * tau)
        t_V = 3.0 * (1.0 + 1.0 / k_L) * T

        particles[1].tides_method = 2
        particles[1].include_tidal_friction_terms = True
        particles[1].include_tidal_bulges_precession_terms = False
        particles[1].include_rotation_precession_terms = False
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-8

        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_viscous_time_scale = t_V
        particles[1].tides_gyration_radius = rg

        tD = M * aF**8 / (3.0 * k_L * tau * constants.G * m_per *
                          (M + m_per) * R**5)
        particles[2].check_for_physical_collision_or_orbit_crossing = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        code.parameters.relative_tolerance = 1.0e-14

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-5 | units.Myr
        tend = 1.0e-4 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        n_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()
        spin_print_array = quantities.AdaptingVectorQuantity()

        while (t < tend):
            t += dt
            code.evolve_model(t)
            print('flag', code.flag, t, 'a/AU', binaries[0].semimajor_axis,
                  'e', binaries[0].eccentricity)

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            n_print_array.append(
                numpy.sqrt(constants.G * (M + m) /
                           (binaries[0].semimajor_axis**3)))
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)
            spin_print_array.append(
                numpy.sqrt(particles[1].spin_vec_x**2 +
                           particles[1].spin_vec_y**2 +
                           particles[1].spin_vec_z**2))

            binaries = particles[particles.is_binary]
            bodies = particles - binaries
            print('S_x', bodies.spin_vec_x.value_in(1.0 / units.day))
            print('S_y', bodies.spin_vec_y.value_in(1.0 / units.day))
            print('S_z', bodies.spin_vec_z.value_in(1.0 / units.day))
            print('=' * 50)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure()
            fontsize = 12

            N_p = 4
            plot1 = fig.add_subplot(N_p, 1, 1)
            plot1.plot(t_print_array.value_in(units.Myr),
                       a_print_array.value_in(units.AU),
                       color='r')
            plot1.set_ylabel("$a/\mathrm{AU}$", fontsize=fontsize)

            plot2 = fig.add_subplot(N_p, 1, 2)
            plot2.plot(t_print_array.value_in(units.Myr),
                       e_print_array.value_in(units.none),
                       color='k')
            plot2.set_ylabel("$e$", fontsize=fontsize)

            plot3 = fig.add_subplot(N_p, 1, 3, yscale="log")

            plot3.plot(t_print_array.value_in(units.Myr),
                       a_print_array.value_in(units.AU) *
                       (1.0 - e_print_array.value_in(units.none)**2),
                       color='k')
            plot3.axhline(y=a0.value_in(units.AU) * (1.0 - e0**2), color='k')
            plot3.set_ylabel("$a(1-e^2)/\mathrm{AU}$", fontsize=fontsize)

            plot4 = fig.add_subplot(N_p, 1, 4)
            plot4.plot(t_print_array.value_in(units.Myr),
                       spin_print_array / n_print_array)
            plot4.set_ylabel("$\Omega/n$", fontsize=fontsize)

            plot4.set_xlabel("$t/\mathrm{Myr}$", fontsize=fontsize)

            pyplot.show()
Пример #11
0
    def test3(self):
        """
        test GW emission in 2-body system + collision detection
        """
        particles = create_nested_multiple(
            2, [1.0 | units.MSun, 1.0 | units.MJupiter], [0.1 | units.AU],
            [0.994], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries
        stars.radius = 0.0001 | units.AU

        binaries.check_for_physical_collision_or_orbit_crossing = True
        binaries.include_pairwise_25PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        tend = 1.0 | units.Gyr
        N = 0
        t = 0.0 | units.Myr
        dt = 100.0 | units.Myr
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)
            flag = code.flag

            if flag == 2:
                print('root found')
                break

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            print('e', binaries.eccentricity, 'a/AU',
                  binaries.semimajor_axis.value_in(units.AU), 'rp/AU',
                  (binaries.semimajor_axis *
                   (1.0 - binaries.eccentricity)).value_in(units.AU))

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16, 10))
            plot1 = fig.add_subplot(2, 1, 1)
            plot2 = fig.add_subplot(2, 1, 2, yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),
                       e_print_array.value_in(units.none),
                       color='r')

            plot2.plot(t_print_array.value_in(units.Myr),
                       a_print_array.value_in(units.AU),
                       color='r')

            fontsize = 15
            plot1.set_ylabel("$e$", fontsize=fontsize)
            plot2.set_ylabel("$a/\mathrm{AU}$", fontsize=fontsize)
            plot2.set_xlabel("$t/\mathrm{Myr}$", fontsize=fontsize)

            pyplot.show()
Пример #12
0
    def test2(self):
        """
        test 1PN precession in 2-body system
        """
        particles = create_nested_multiple(
            2, [1.0 | units.MSun, 1.0 | units.MJupiter], [1.0 | units.AU],
            [0.99], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-1 | units.Myr
        tend = 1.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)

            channel_from_code.copy()

            print('t/Myr', t.value_in(units.Myr), 'omega',
                  binaries[0].argument_of_pericenter | units.none)
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

        a = binaries[0].semimajor_axis
        e = binaries[0].eccentricity
        M = binaries[0].mass
        rg = constants.G * M / (constants.c**2)
        P = 2.0 * numpy.pi * numpy.sqrt(a**3 / (constants.G * M))
        t_1PN = (1.0 / 3.0) * P * (1.0 - e**2) * (a / rg)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16, 10))
            plot1 = fig.add_subplot(4, 1, 1)
            plot2 = fig.add_subplot(4, 1, 2, yscale="log")
            plot3 = fig.add_subplot(4, 1, 3, yscale="log")
            plot4 = fig.add_subplot(4, 1, 4, yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),
                       AP_print_array.value_in(units.none),
                       color='r')
            points = numpy.linspace(0.0, tend.value_in(units.Myr), N)
            AP = 0.01 + 2.0 * numpy.pi * points / (t_1PN.value_in(units.Myr))
            AP = (AP + numpy.pi) % (2.0 *
                                    numpy.pi) - numpy.pi  ### -pi < AP < pi
            plot1.plot(points, AP, color='g')

            plot2.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs(
                           (AP - AP_print_array.value_in(units.none)) / AP),
                       color='r')
            plot3.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((a - a_print_array) / a),
                       color='r')
            plot4.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((e - e_print_array) / e),
                       color='r')

            fontsize = 15
            plot1.set_ylabel("$\omega$", fontsize=fontsize)
            plot2.set_ylabel("$|(\omega_p-\omega)/\omega_p|$",
                             fontsize=fontsize)
            plot3.set_ylabel("$|(a_0-a)/a_0|$", fontsize=fontsize)
            plot4.set_ylabel("$|(e_0-e)/e_0|$", fontsize=fontsize)

            pyplot.show()
Пример #13
0
    def test1(self):
        """
        test reference system of Naoz et al. (2009)
        """
        particles = create_nested_multiple(
            3, [1.0 | units.MSun, 1.0 | units.MJupiter, 40.0 | units.MJupiter],
            [6.0 | units.AU, 100.0 | units.AU], [0.001, 0.6],
            [0.0001, 65.0 * numpy.pi / 180.0],
            [45.0 * numpy.pi / 180.0, 0.0001], [0.01, 0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = False

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()
        self.assertEqual(0.6,
                         code.particles[particles.is_binary][1].eccentricity)

        t = 0.0 | units.Myr
        dt = 1.0e-2 | units.Myr
        tend = 3.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        INCL_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t < tend):
            t += dt
            N += 1
            code.evolve_model(t)
            print('t/Myr = ', code.model_time.value_in(units.Myr))

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            INCL_print_array.append(binaries[0].inclination_relative_to_parent
                                    | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16, 10))
            plot1 = fig.add_subplot(2, 1, 1)
            plot2 = fig.add_subplot(2, 1, 2, yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr), (180.0 / numpy.pi) *
                       INCL_print_array.value_in(units.none),
                       color='k')
            plot2.plot(t_print_array.value_in(units.Myr),
                       1.0 - e_print_array.value_in(units.none),
                       color='k')

            fontsize = 15
            plot1.set_ylabel("$i$", fontsize=fontsize)
            plot2.set_ylabel("$1-e$", fontsize=fontsize)
            plot2.set_xlabel("$t/\mathrm{Myr}$", fontsize=fontsize)

            pyplot.show()
Пример #14
0
    def test2(self):
        """
        test 1PN precession in 2-body system
        """
        particles = create_nested_multiple(2,[1.0|units.MSun, 1.0|units.MJupiter], [1.0|units.AU], [0.99], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]

        binaries.include_pairwise_1PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-1 | units.Myr
        tend = 1.0e0 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        N = 0
        while (t<tend):
            t+=dt
            N+=1
            code.evolve_model(t)

            channel_from_code.copy()

            print 't/Myr',t.value_in(units.Myr),'omega',binaries[0].argument_of_pericenter | units.none
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter | units.none)


        a = binaries[0].semimajor_axis
        e = binaries[0].eccentricity
        M = binaries[0].mass
        rg = constants.G*M/(constants.c**2)
        P = 2.0*numpy.pi*numpy.sqrt(a**3/(constants.G*M))
        t_1PN = (1.0/3.0)*P*(1.0-e**2)*(a/rg)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16,10))
            plot1 = fig.add_subplot(4,1,1)
            plot2 = fig.add_subplot(4,1,2,yscale="log")
            plot3 = fig.add_subplot(4,1,3,yscale="log")
            plot4 = fig.add_subplot(4,1,4,yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),AP_print_array.value_in(units.none), color='r')
            points = numpy.linspace(0.0,tend.value_in(units.Myr),N)
            AP = 0.01 +2.0*numpy.pi*points/(t_1PN.value_in(units.Myr))
            AP = (AP+numpy.pi)%(2.0*numpy.pi) - numpy.pi ### -pi < AP < pi
            plot1.plot(points,AP,color='g')

            plot2.plot(t_print_array.value_in(units.Myr),numpy.fabs( (AP - AP_print_array.value_in(units.none))/AP ), color='r')
            plot3.plot(t_print_array.value_in(units.Myr),numpy.fabs((a-a_print_array)/a), color='r')
            plot4.plot(t_print_array.value_in(units.Myr),numpy.fabs((e-e_print_array)/e), color='r')

            fontsize = 15
            plot1.set_ylabel("$\omega$",fontsize=fontsize)
            plot2.set_ylabel("$|(\omega_p-\omega)/\omega_p|$",fontsize=fontsize)
            plot3.set_ylabel("$|(a_0-a)/a_0|$",fontsize=fontsize)
            plot4.set_ylabel("$|(e_0-e)/e_0|$",fontsize=fontsize)

            pyplot.show()
Пример #15
0
    def test6(self):
        """
        test precession due to rotation
        """

        M = 1.0 | units.MJupiter
        R = 1.5 | units.RJupiter
        m_per = 1.0 | units.MSun
        a0 = 30.0 | units.AU
        e0 = 0.999
        P0 = 2.0 * numpy.pi * numpy.sqrt(a0**3 / (constants.G * (M + m_per)))
        n0 = 2.0 * numpy.pi / P0

        aF = a0 * (1.0 - e0**2)
        nF = numpy.sqrt(constants.G * (M + m_per) / (aF**3))

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [1.0e-5],
                                           [1.0e-5], [1.0e-5])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R
        particles[1].spin_vec_x = 0.0 | 1.0 / units.day
        particles[1].spin_vec_y = 0.0 | 1.0 / units.day
        Omega_PS0 = n0 * (33.0 / 10.0) * pow(a0 / aF, 3.0 / 2.0)
        particles[1].spin_vec_z = Omega_PS0

        k_L = 0.51
        k_AM = k_L / 2.0
        rg = 0.25
        particles[1].tides_method = 1
        particles[1].include_tidal_friction_terms = False
        particles[1].include_tidal_bulges_precession_terms = False
        particles[1].include_rotation_precession_terms = True
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-5
        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_gyration_radius = rg

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e1 | units.Myr
        tend = 1.0e2 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        Omega_vec = [
            particles[1].spin_vec_x, particles[1].spin_vec_y,
            particles[1].spin_vec_z
        ]
        Omega = numpy.sqrt(Omega_vec[0]**2 + Omega_vec[1]**2 + Omega_vec[2]**2)
        print('Omega/n', Omega / n0)

        g_dot_rot = n0 * (1.0 + m_per / M) * k_AM * pow(
            R / a0, 5.0) * (Omega / n0)**2 / ((1.0 - e0**2)**2)
        t_rot = 2.0 * numpy.pi / g_dot_rot
        print('t_rot/Myr', t_rot.value_in(units.Myr))

        N = 0
        while (t < tend):
            t += dt
            code.evolve_model(t)
            print('flag', code.flag, t, binaries[0].semimajor_axis,
                  binaries[0].eccentricity)

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            N += 1
Пример #16
0
    def test5(self):
        """
        test precession due to tidal bulges
        """

        M = 1.0 | units.MJupiter
        R = 1.0 | units.RJupiter
        m_per = 1.0 | units.MSun
        a0 = 30.0 | units.AU
        e0 = 0.999
        P0 = 2.0 * numpy.pi * numpy.sqrt(a0**3 / (constants.G * (M + m_per)))
        n0 = 2.0 * numpy.pi / P0

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [0.01],
                                           [0.01], [0.01])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R

        k_L = 0.41
        k_AM = k_L / 2.0

        particles[1].tides_method = 0
        particles[1].include_tidal_friction_terms = False
        particles[1].include_tidal_bulges_precession_terms = True
        particles[1].include_rotation_precession_terms = False
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-5
        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_gyration_radius = 0.25

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e1 | units.Myr
        tend = 1.0e2 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        g_dot_TB = (15.0 / 8.0) * n0 * (8.0 + 12.0 * e0**2 + e0**4) * (
            m_per / M) * k_AM * pow(R / a0, 5.0) / pow(1.0 - e0**2, 5.0)
        t_TB = 2.0 * numpy.pi / g_dot_TB

        N = 0
        while (t < tend):
            t += dt
            code.evolve_model(t)
            print('flag', code.flag, t, binaries[0].semimajor_axis,
                  binaries[0].eccentricity)

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            N += 1
Пример #17
0
    def test3(self):
        """
        test GW emission in 2-body system + collision detection
        """
        particles = create_nested_multiple(2,[1.0|units.MSun, 1.0|units.MJupiter], [0.1|units.AU], [0.994], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]
        stars = particles - binaries
        stars.radius = 0.0001 | units.AU

        binaries.check_for_physical_collision_or_orbit_crossing = True
        binaries.include_pairwise_25PN_terms = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        tend = 1.0 | units.Gyr
        N = 0
        t = 0.0 | units.Myr
        dt = 100.0 | units.Myr
        while (t<tend):
            t+=dt
            N+=1
            code.evolve_model(t)
            flag = code.flag

            if flag == 2:
                print 'root found'
                break

            channel_from_code.copy()
            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter | units.none)

            print 'e',binaries.eccentricity,'a/AU',binaries.semimajor_axis.value_in(units.AU),'rp/AU',(binaries.semimajor_axis*(1.0-binaries.eccentricity)).value_in(units.AU)

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16,10))
            plot1 = fig.add_subplot(2,1,1)
            plot2 = fig.add_subplot(2,1,2,yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),e_print_array.value_in(units.none), color='r')

            plot2.plot(t_print_array.value_in(units.Myr),a_print_array.value_in(units.AU), color='r')

            fontsize = 15
            plot1.set_ylabel("$e$",fontsize=fontsize)
            plot2.set_ylabel("$a/\mathrm{AU}$",fontsize=fontsize)
            plot2.set_xlabel("$t/\mathrm{Myr}$",fontsize=fontsize)

            pyplot.show()
Пример #18
0
    def test4(self):
        """
        test tidal friction in 2-body system
        """

        M = 1.0|units.MJupiter
        R = 40.0|units.RJupiter
        m_per = 1.0|units.MSun
        m = m_per
        mu = m*M/(m+M)
        a0 = 0.1 | units.AU
        e0 = 0.3
        P0 = 2.0*numpy.pi*numpy.sqrt(a0**3/(constants.G*(M+m_per)))
        n0 = 2.0*numpy.pi/P0

        aF = a0*(1.0-e0**2)
        nF = numpy.sqrt( constants.G*(M+m_per)/(aF**3) )

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [0.01], [0.01], [0.01])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R
        particles[1].spin_vec_x = 0.0 | 1.0/units.day
        particles[1].spin_vec_y = 0.0 | 1.0/units.day
        particles[1].spin_vec_z = 4.0e-2 | 1.0/units.day

        k_L = 0.38
        k_AM = k_L/2.0
        rg = 0.25
        tau = 0.66 | units.s

        I = rg*M*R**2
        alpha = I/(mu*a0**2)
        T = R**3/(constants.G*M*tau)
        t_V = 3.0*(1.0 + 1.0/k_L)*T

        particles[1].tides_method = 2
        particles[1].include_tidal_friction_terms = True
        particles[1].include_tidal_bulges_precession_terms = False
        particles[1].include_rotation_precession_terms = False
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-8

        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_viscous_time_scale = t_V
        particles[1].tides_gyration_radius = rg

        tD = M*aF**8/(3.0*k_L*tau*constants.G*m_per*(M+m_per)*R**5)
        particles[2].check_for_physical_collision_or_orbit_crossing = True

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        code.parameters.relative_tolerance = 1.0e-14

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e-5 | units.Myr
        tend = 1.0e-4 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        n_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()
        spin_print_array = quantities.AdaptingVectorQuantity()

        while (t<tend):
            t+=dt
            code.evolve_model(t)
            print 'flag',code.flag,t,'a/AU',binaries[0].semimajor_axis,'e',binaries[0].eccentricity

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            n_print_array.append(numpy.sqrt(constants.G*(M+m)/(binaries[0].semimajor_axis**3)))
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter | units.none)
            spin_print_array.append( numpy.sqrt( particles[1].spin_vec_x**2 + particles[1].spin_vec_y**2 + particles[1].spin_vec_z**2) )

            binaries = particles[particles.is_binary]
            bodies = particles - binaries
            print 'S_x',bodies.spin_vec_x.value_in(1.0/units.day)
            print 'S_y',bodies.spin_vec_y.value_in(1.0/units.day)
            print 'S_z',bodies.spin_vec_z.value_in(1.0/units.day)
            print '='*50

        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure()
            fontsize=12

            N_p = 4
            plot1 = fig.add_subplot(N_p,1,1)
            plot1.plot(t_print_array.value_in(units.Myr),a_print_array.value_in(units.AU), color='r')
            plot1.set_ylabel("$a/\mathrm{AU}$",fontsize=fontsize)

            plot2 = fig.add_subplot(N_p,1,2)
            plot2.plot(t_print_array.value_in(units.Myr),e_print_array.value_in(units.none),color='k')
            plot2.set_ylabel("$e$",fontsize=fontsize)

            plot3 = fig.add_subplot(N_p,1,3,yscale="log")

            plot3.plot(t_print_array.value_in(units.Myr),a_print_array.value_in(units.AU)*(1.0-e_print_array.value_in(units.none)**2),color='k')
            plot3.axhline(y = a0.value_in(units.AU)*(1.0 - e0**2), color='k')
            plot3.set_ylabel("$a(1-e^2)/\mathrm{AU}$",fontsize=fontsize)

            plot4 = fig.add_subplot(N_p,1,4)
            plot4.plot(t_print_array.value_in(units.Myr),spin_print_array/n_print_array)
            plot4.set_ylabel("$\Omega/n$",fontsize=fontsize)

            plot4.set_xlabel("$t/\mathrm{Myr}$",fontsize=fontsize)

            pyplot.show()
Пример #19
0
    def test5(self):
        """
        test precession due to tidal bulges
        """

        M = 1.0 | units.MJupiter
        R = 1.0 | units.RJupiter
        m_per = 1.0 | units.MSun
        a0 = 30.0 | units.AU
        e0 = 0.999
        P0 = 2.0 * numpy.pi * numpy.sqrt(a0**3 / (constants.G * (M + m_per)))
        n0 = 2.0 * numpy.pi / P0

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [0.01],
                                           [0.01], [0.01])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R

        k_L = 0.41
        k_AM = k_L / 2.0

        particles[1].tides_method = 0
        particles[1].include_tidal_friction_terms = False
        particles[1].include_tidal_bulges_precession_terms = True
        particles[1].include_rotation_precession_terms = False
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-5
        particles[1].tides_apsidal_motion_constant = k_AM

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e1 | units.Myr
        tend = 1.0e2 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        g_dot_TB = (15.0 / 8.0) * n0 * (8.0 + 12.0 * e0**2 + e0**4) * (
            m_per / M) * k_AM * pow(R / a0, 5.0) / pow(1.0 - e0**2, 5.0)
        t_TB = 2.0 * numpy.pi / g_dot_TB

        N = 0
        while (t < tend):
            t += dt
            code.evolve_model(t)
            print 'flag', code.flag, t, binaries[0].semimajor_axis, binaries[
                0].eccentricity

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter
                                  | units.none)

            N += 1
        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16, 10))
            plot1 = fig.add_subplot(4, 1, 1)
            plot2 = fig.add_subplot(4, 1, 2, yscale="log")
            plot3 = fig.add_subplot(4, 1, 3, yscale="log")
            plot4 = fig.add_subplot(4, 1, 4, yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),
                       AP_print_array.value_in(units.none),
                       color='r')
            points = numpy.linspace(0.0, tend.value_in(units.Myr), N)
            AP = 0.01 + 2.0 * numpy.pi * points / (t_TB.value_in(units.Myr))
            AP = (AP + numpy.pi) % (2.0 *
                                    numpy.pi) - numpy.pi  ### -pi < AP < pi
            plot1.plot(points, AP, color='g')

            plot2.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs(
                           (AP - AP_print_array.value_in(units.none)) / AP),
                       color='r')
            plot3.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((a0 - a_print_array) / a0),
                       color='r')
            plot4.plot(t_print_array.value_in(units.Myr),
                       numpy.fabs((e0 - e_print_array) / e0),
                       color='r')

            fontsize = 15
            plot1.set_ylabel("$\omega$", fontsize=fontsize)
            plot2.set_ylabel("$|(\omega_p-\omega)/\omega_p|$",
                             fontsize=fontsize)
            plot3.set_ylabel("$|(a_0-a)/a_0|$", fontsize=fontsize)
            plot4.set_ylabel("$|(e_0-e)/e_0|$", fontsize=fontsize)

            pyplot.show()
Пример #20
0
def run_secularmultiple(particle_set, end_time, start_time=(0 |units.Myr), \
                        N_output=100, debug_mode=False, genT4System=False, \
                        exportData=True, useAMD=True, GCode = None, \
                        KeySystemID=None, SEVCode=None):
    '''Does what it says on the tin.'''
    try:
        hierarchical_test = [x for x in particle_set if x.is_binary == True]
        print("The supplied set has", len(hierarchical_test),
              "node particles and is a tree.")
        py_particles = particle_set
    except:
        print("The supplied set is NOT a tree set! Building tree ...")
        py_particles = get_full_hierarchical_structure(particle_set,
                                                       KeySystemID=KeySystemID,
                                                       SEVCode=SEVCode)
        hierarchical_test = [x for x in py_particles if x.is_binary == True]
        print("Tree has been built with", len(hierarchical_test),
              "node particles.")
    nodes = py_particles.select(lambda x: x == True, ["is_binary"])
    Num_nodes = len(nodes)
    stellarCollisionOccured = False

    if GCode == None:
        code = SecularMultiple()
    else:
        code = GCode

    if exportData:
        plot_a_AU = defaultdict(list)
        plot_e = defaultdict(list)
        plot_peri_AU = defaultdict(list)
        plot_stellar_inc_deg = defaultdict(list)
        if useAMD:
            plot_AMDBeta = defaultdict(list)
        plot_times_Myr = []

    if genT4System:
        print(nodes.inclination)
        nodes.inclination = [-18.137, 0.0, 23.570] | units.deg
        print(nodes.inclination)

    if debug_mode:
        print('=' * 50)
        print('t/kyr', 0.00)
        print('a/AU', nodes.semimajor_axis)
        print('p/day', nodes.period)
        print('e', nodes.eccentricity)
        print('i/deg', nodes.inclination)
        print('AP/deg', \
            nodes.argument_of_pericenter)
        print('LAN/deg', \
            nodes.longitude_of_ascending_node)
    #print(py_particles)
    code.particles.add_particles(py_particles)
    #code.commit_particles()
    #print(code.particles.semimajor_axis)

    code.model_time = start_time
    #print(py_particles.id, py_particles.semimajor_axis)
    channel_from_particles_to_code = py_particles.new_channel_to(
        code.particles)
    channel_from_code_to_particles = code.particles.new_channel_to(
        py_particles)
    #print(py_particles.id, py_particles.semimajor_axis)

    channel_from_particles_to_code.copy(
    )  #copy_attributes(['semimajor_axis', 'eccentricity', \
    #'longitude_of_ascending_node', 'argument_of_pericenter', 'inclination'])
    #print('This is After the First Channel Copy:', code.particles.semimajor_axis)
    time = start_time
    if useAMD:
        #print(py_particles.id, py_particles.mass)
        jovianParent = get_jovian_parent(py_particles)
        output_time_step = 1000 * jovianParent.period.value_in(
            units.Myr) | units.Myr
        PS = initialize_PlanetarySystem_from_HierarchicalSet(py_particles)
        PS.get_SystemBetaValues()
        if exportData:
            for planet in PS.planets:
                plot_AMDBeta[planet.id].append(planet.AMDBeta)
    else:
        output_time_step = end_time / float(N_output)

    if exportData:
        plot_times_Myr.append(time.value_in(units.Myr))
        for i, node in enumerate(nodes):
            plot_a_AU[node.child2.id].append(
                node.semimajor_axis.value_in(units.AU))
            plot_e[node.child2.id].append(node.eccentricity)
            plot_peri_AU[node.child2.id].append(
                node.semimajor_axis.value_in(units.AU) *
                (1.0 - node.eccentricity))
            plot_stellar_inc_deg[node.child2.id].append(
                node.inclination.value_in(units.deg))
    counter = 0
    while time <= end_time:
        #print('Start of Time Loop')
        #print(output_time_step)
        time += output_time_step
        counter += 1
        #print(time)
        #print(code.model_time)
        #print(code.particles.semimajor_axis)
        code.evolve_model(time)
        #print('Evolved model to:', time.value_in(units.Myr), "Myr")
        #print(code.particles.semimajor_axis)
        channel_from_code_to_particles.copy()
        #channel_from_code_to_particles.copy_attributes(['semimajor_axis', 'eccentricity', \
        #'longitude_of_ascending_node', 'argument_of_pericenter', 'inclination'])
        #print('Hello')
        py_particles.time = time
        if exportData:
            plot_times_Myr.append(time.value_in(units.Myr))
            nodes = py_particles.select(lambda x: x == True, ["is_binary"])
            for i, node in enumerate(nodes):
                plot_a_AU[node.child2.id].append(
                    node.semimajor_axis.value_in(units.AU))
                plot_e[node.child2.id].append(node.eccentricity)
                plot_peri_AU[node.child2.id].append(
                    node.semimajor_axis.value_in(units.AU) *
                    (1.0 - node.eccentricity))
                plot_stellar_inc_deg[node.child2.id].append(
                    node.inclination.value_in(units.deg))

        if time == end_time + output_time_step:
            map_node_oe_to_lilsis(py_particles)

        if debug_mode:
            if time == end_time or time == output_time_step:
                print('=' * 50)
                print('t/kyr', time.value_in(units.kyr))
                print('a/AU', nodes.semimajor_axis)
                print('p/day', nodes.period)
                print('e', nodes.eccentricity)
                print('i/deg', nodes.inclination)
                print('AP/deg', \
                    nodes.argument_of_pericenter)
                print('LAN/deg', \
                    nodes.longitude_of_ascending_node)
        # Check for Planet Destruction from Star
        #print(py_particles.id, py_particles.semimajor_axis)
        temp = check_for_stellar_collision(py_particles)
        #print(temp)
        # Returns 'None' if No Destruction!
        if temp != None:
            code.stop()
            code = SecularMultiple()
            code.model_time = time
            py_particles = Particles()
            py_particles.add_particles(temp)
            code.particles.add_particles(py_particles)
            py_particles.time = time
            #code.commit_particles()
            channel_from_particles_to_code = py_particles.new_channel_to(
                code.particles)
            channel_from_code_to_particles = code.particles.new_channel_to(
                py_particles)
            channel_from_particles_to_code.copy()
            nodes = py_particles.select(lambda x: x == True, ["is_binary"])
            stellarCollisionOccured = True
            if useAMD:
                PS = initialize_PlanetarySystem_from_HierarchicalSet(
                    py_particles)
            #channel_from_code_to_particles.copy_attributes(['semimajor_axis', 'eccentricity', \
            #'longitude_of_ascending_node', 'argument_of_pericenter', 'inclination'])
        #print(code.particles.semimajor_axis)
        # AMD Checking
        if useAMD:
            PS = update_oe_for_PlanetarySystem(PS, py_particles)
            PS.get_SystemBetaValues()
            if exportData:
                for planet in PS.planets:
                    plot_AMDBeta[planet.id].append(planet.AMDBeta)
            if counter % 100 == 0 and len(
                    PS.planets.select(lambda x: x < 1.0, ["AMDBeta"])) > 1:
                break

    if GCode == None:
        code.stop()
    else:
        code = reset_secularmultiples(code)
    if exportData:
        if useAMD:
            data = plot_times_Myr, plot_a_AU, plot_e, plot_peri_AU, plot_stellar_inc_deg, plot_AMDBeta
        else:
            data = plot_times_Myr, plot_a_AU, plot_e, plot_peri_AU, plot_stellar_inc_deg
    else:
        data = None
    # Set the Output Code to be the New Code if a Stellar Collision Occured.
    if stellarCollisionOccured:
        newcode = code
    else:
        newcode = None
    return py_particles, data, newcode
def evolve_quadruple(N_output, end_time, m1, m2, m3, m4, aA, aB, aC, eA, eB,
                     eC, iA, iB, iC, ApA, ApB, ApC, LANA, LANB, LANC):

    masses = [m1, m2, m3, m4]
    semimajor_axis = [aA, aB, aC]
    eccentricity = [eA, eB, eC]
    inclination = numpy.deg2rad([iA, iB, iC])
    argument_of_percienter = numpy.deg2rad([ApA, ApB, ApC])
    longitude_of_ascending_node = numpy.deg2rad([LANA, LANB, LANC])
    print longitude_of_ascending_node

    N_bodies = 4
    N_binaries = N_bodies - 1
    particles, binaries = initialize_multiple_system(
        N_bodies, masses, semimajor_axis, eccentricity, inclination,
        argument_of_percienter, longitude_of_ascending_node)

    code = SecularMultiple()
    code.particles.add_particles(particles)

    channel_from_particles_to_code = particles.new_channel_to(code.particles)
    channel_from_code_to_particles = code.particles.new_channel_to(particles)
    channel_from_particles_to_code.copy()

    ### set up some arrays for plotting ###
    print_smas_AU = [[] for x in range(N_binaries)]
    print_rps_AU = [[] for x in range(N_binaries)]
    print_parent_is_deg = [[] for x in range(N_binaries)]
    print_times_Myr = []

    time = 0.0 | units.yr
    output_time_step = end_time / float(N_output)
    while time <= end_time:
        time += output_time_step
        code.evolve_model(time)

        channel_from_code_to_particles.copy()
        print '=' * 50
        print 't/Myr', time.value_in(units.Myr)
        print 'e', binaries.eccentricity
        print 'i/deg', numpy.rad2deg(binaries.inclination)
        print 'AP/deg', \
            numpy.rad2deg(binaries.argument_of_pericenter)
        print 'LAN/deg', \
            numpy.rad2deg(binaries.longitude_of_ascending_node)

        ### write to output arrays ###
        print_times_Myr.append(time.value_in(units.Myr))
        for index_binary in range(N_binaries):
            print_smas_AU[index_binary].append(
                binaries[index_binary].semimajor_axis.value_in(units.AU))
            print_rps_AU[index_binary].append(
                binaries[index_binary].semimajor_axis.value_in(units.AU) *
                (1.0 - binaries[index_binary].eccentricity))
            print_parent_is_deg[index_binary].append(
                numpy.rad2deg(
                    binaries[index_binary].inclination_relative_to_parent))

    ### compute the `canonical' maximum eccentricity/periapsis distance that applies in the quadrupole-order test-particle limit if the `outer' binary is replaced by a point mass ###
    print inclination[0], inclination[2], longitude_of_ascending_node[
        0], longitude_of_ascending_node[2]
    i_AC_init = compute_mutual_inclination(inclination[0], inclination[2],
                                           longitude_of_ascending_node[0],
                                           longitude_of_ascending_node[2])
    i_BC_init = compute_mutual_inclination(inclination[1], inclination[2],
                                           longitude_of_ascending_node[1],
                                           longitude_of_ascending_node[2])

    canonical_rp_min_A_AU = (
        semimajor_axis[0] *
        (1.0 - numpy.sqrt(1.0 -
                          (5.0 / 3.0) * numpy.cos(i_AC_init)**2))).value_in(
                              units.AU)
    canonical_rp_min_B_AU = (
        semimajor_axis[1] *
        (1.0 - numpy.sqrt(1.0 -
                          (5.0 / 3.0) * numpy.cos(i_BC_init)**2))).value_in(
                              units.AU)

    data = print_times_Myr, print_smas_AU, print_rps_AU, print_parent_is_deg, canonical_rp_min_A_AU, canonical_rp_min_B_AU
    return data
Пример #22
0
    def test6(self):
        """
        test precession due to rotation
        """

        M = 1.0|units.MJupiter
        R = 1.5|units.RJupiter
        m_per = 1.0|units.MSun
        a0 = 30.0 | units.AU
        e0 = 0.999
        P0 = 2.0*numpy.pi*numpy.sqrt(a0**3/(constants.G*(M+m_per)))
        n0 = 2.0*numpy.pi/P0

        aF = a0*(1.0-e0**2)
        nF = numpy.sqrt( constants.G*(M+m_per)/(aF**3) )

        particles = create_nested_multiple(2, [m_per, M], [a0], [e0], [1.0e-5], [1.0e-5], [1.0e-5])
        binaries = particles[particles.is_binary]
        particles[0].radius = 1.0 | units.RSun
        particles[1].radius = R
        particles[1].spin_vec_x = 0.0 | 1.0/units.day
        particles[1].spin_vec_y = 0.0 | 1.0/units.day
        Omega_PS0 = n0*(33.0/10.0)*pow(a0/aF,3.0/2.0)
        particles[1].spin_vec_z = Omega_PS0


        k_L = 0.51
        k_AM = k_L/2.0
        rg = 0.25
        particles[1].tides_method = 1
        particles[1].include_tidal_friction_terms = False
        particles[1].include_tidal_bulges_precession_terms = False
        particles[1].include_rotation_precession_terms = True
        particles[1].minimum_eccentricity_for_tidal_precession = 1.0e-5
        particles[1].tides_apsidal_motion_constant = k_AM
        particles[1].tides_gyration_radius = rg

        code = SecularMultiple(redirection='none')
        code.particles.add_particles(particles)

        channel_to_code = particles.new_channel_to(code.particles)
        channel_from_code = code.particles.new_channel_to(particles)

        channel_to_code.copy()

        t = 0.0 | units.Myr
        dt = 1.0e1 | units.Myr
        tend = 1.0e2 | units.Myr

        t_print_array = quantities.AdaptingVectorQuantity()
        a_print_array = quantities.AdaptingVectorQuantity()
        e_print_array = quantities.AdaptingVectorQuantity()
        AP_print_array = quantities.AdaptingVectorQuantity()

        Omega_vec = [particles[1].spin_vec_x,particles[1].spin_vec_y,particles[1].spin_vec_z]
        Omega = numpy.sqrt(Omega_vec[0]**2 + Omega_vec[1]**2 + Omega_vec[2]**2)
        print 'Omega/n',Omega/n0

        g_dot_rot = n0*(1.0 + m_per/M)*k_AM*pow(R/a0,5.0)*(Omega/n0)**2/((1.0-e0**2)**2)
        t_rot = 2.0*numpy.pi/g_dot_rot
        print 't_rot/Myr',t_rot.value_in(units.Myr)

        N=0
        while (t<tend):
            t+=dt
            code.evolve_model(t)
            print 'flag',code.flag,t,binaries[0].semimajor_axis,binaries[0].eccentricity

            channel_from_code.copy()

            t_print_array.append(t)
            a_print_array.append(binaries[0].semimajor_axis)
            e_print_array.append(binaries[0].eccentricity | units.none)
            AP_print_array.append(binaries[0].argument_of_pericenter | units.none)

            N+=1
        if HAS_MATPLOTLIB == True:
            fig = pyplot.figure(figsize=(16,10))
            plot1 = fig.add_subplot(4,1,1)
            plot2 = fig.add_subplot(4,1,2,yscale="log")
            plot3 = fig.add_subplot(4,1,3,yscale="log")
            plot4 = fig.add_subplot(4,1,4,yscale="log")

            plot1.plot(t_print_array.value_in(units.Myr),AP_print_array.value_in(units.none), color='r')
            points = numpy.linspace(0.0,tend.value_in(units.Myr),N)
            AP = 0.01 +2.0*numpy.pi*points/(t_rot.value_in(units.Myr))
            AP = (AP+numpy.pi)%(2.0*numpy.pi) - numpy.pi ### -pi < AP < pi
            plot1.plot(points,AP,color='g')

            plot2.plot(t_print_array.value_in(units.Myr),numpy.fabs( (AP - AP_print_array.value_in(units.none))/AP ), color='r')
            plot3.plot(t_print_array.value_in(units.Myr),numpy.fabs((a0-a_print_array)/a0), color='r')
            plot4.plot(t_print_array.value_in(units.Myr),numpy.fabs((e0-e_print_array)/e0), color='r')

            fontsize = 15
            plot1.set_ylabel("$\omega$",fontsize=fontsize)
            plot2.set_ylabel("$|(\omega_p-\omega)/\omega_p|$",fontsize=fontsize)
            plot3.set_ylabel("$|(a_0-a)/a_0|$",fontsize=fontsize)
            plot4.set_ylabel("$|(e_0-e)/e_0|$",fontsize=fontsize)

            pyplot.show()