예제 #1
0
    def test_from_elements(self):
        j = 5
        k = 2
        Zstar = 0.1
        libfac = 0.5
        a10 = 3.
        a1 = 3.1
        G = 2.
        m1 = 1.e-7
        m2 = 1.e-4
        ecom = 0.05
        phiecom = 0.7

        avars = Andoyer.from_elements(j,
                                      k,
                                      Zstar,
                                      libfac,
                                      a10,
                                      a1,
                                      G,
                                      m1=m1,
                                      m2=m2,
                                      Zcom=ecom,
                                      phiZcom=phiecom)
        self.assertAlmostEqual(avars.Zstar, Zstar, delta=1.e-12)
        self.assertAlmostEqual(avars.Zcom, ecom, delta=1.e-15)
        self.assertAlmostEqual(avars.phiZcom, phiecom, delta=1.e-15)
        sim = avars.to_Simulation()
        self.assertAlmostEqual(
            sim.particles[1].a, a1, delta=3 * ((a1 - a10) / a10)**
            2)  # should match to O(da/a)^2, atrue=1, a10=a10
예제 #2
0
def get_resonant(seed, Nplanets=3):
    r = random.Random()
    r.seed(seed)

    Phiprimecrits = [0, 1., -2. / 3.]
    pairs = ['inner', 'outer', 'split']

    k = r.randint(1, 2)
    pairindex = r.randint(0, 2)
    pair = pairs[pairindex]
    m1 = logunif(r, 1.e-7, 1.e-4)
    m2 = logunif(r, 1.e-7, 1.e-4)
    eH = ((m1 + m2) / 3.)**(1. / 3.)
    ehillstable = 3.5 * eH
    jmax = k / (1 - 1 / (1 + 3.5 * eH)**1.5)
    if pair == 'split':
        if Nplanets == 2:
            return  # don't want 2planet systems 60 hill radii apart
        maxHillradii = 60.  # 3rd planet will go in middle so draw up to 60
    else:
        maxHillradii = 30.
    jmin = max(k + 1, k / (1 - 1 / (1 + maxHillradii * eH)**1.5))
    jmin = int(np.ceil(jmin))
    jmax = int(np.floor(jmax))
    if k == 2:  # if k = 2, want odd j so we don't get e.g. 8:6 = 4:3
        if jmin % 2 == 0:  # even
            jmin += 1
        if jmax % 2 == 0:
            jmax -= 1
    j = r.randrange(
        jmin, jmax + 1,
        k)  # choose randomly between limits in steps of k e.g. (3,5,7,9)
    a1 = 1.
    a2 = (float(j) / (j - k))**(2. / 3.)
    ecross1 = (a2 - a1) / a1
    ecross2 = (a2 - a1) / a2
    emin1 = m2 / ecross1**2
    emin2 = m1 / ecross2**2
    emin = max(
        emin1, emin2
    )  # take as min Z the larger of the kicks a planet gets at conjunction
    emin = max(
        emin, (m1 + m2)**(1. / k)
    )  # below mtot^1/k, the resonant term is smaller than the second order mass terms we ignore
    emax = min(ecross1, ecross2)

    avars = Andoyer(j=j, k=k, X=0, Y=0, m1=m1, m2=m2)
    Phiprimecrit = Phiprimecrits[k]
    Xcrit = get_Xstarres(k, Phiprimecrit)
    Phicrit = 0.5 * Xcrit**2
    emin = max(
        avars.Phi_to_Z(Phicrit), emin
    )  # first quantity is value of Z at bifurcation when res first appears

    Zstar = logunif(r, emin, emax)
    libfac = logunif(r, 3.e-3, 3)
    negative = r.randint(0, 1)
    if negative:
        libfac *= -1

    Zcom = logunif(r, emin, emax)
    avars = Andoyer.from_elements(j=j,
                                  k=k,
                                  Zstar=Zstar,
                                  libfac=libfac,
                                  m1=m1,
                                  m2=m2,
                                  Zcom=Zcom,
                                  phiZcom=r.uniform(0, 2 * np.pi),
                                  theta=r.uniform(0, 2 * np.pi),
                                  theta1=r.uniform(0, 2 * np.pi))
    tmax = r.uniform(0, 10 * avars.tlib)
    H = AndoyerHamiltonian(avars)
    H.integrate(tmax)
    pvars = avars.to_Poincare()
    ps = pvars.particles
    if Nplanets == 3:
        m3 = logunif(r, 1.e-7, 1.e-4)
        pvarssorted = Poincare(G=pvars.G)

        if pair == "inner":
            eH = ((m2 + m3) / 3.)**(1. / 3.)
            beta = r.uniform(3.5, 30)
            a3 = a2 * (1 + beta * eH)
            ecross3 = (a3 - a2) / a3
            emin3 = m2 / ecross3**2
            e3 = logunif(r, emin3, ecross3)
            pvarssorted.add(m=ps[1].m,
                            M=ps[1].M,
                            a=ps[1].a,
                            e=ps[1].e,
                            gamma=ps[1].gamma,
                            l=ps[1].l)
            pvarssorted.add(m=ps[2].m,
                            M=ps[2].M,
                            a=ps[2].a,
                            e=ps[2].e,
                            gamma=ps[2].gamma,
                            l=ps[2].l)
            pvarssorted.add(m=m3,
                            M=1,
                            a=a3,
                            e=e3,
                            gamma=r.uniform(0, 2 * np.pi),
                            l=r.uniform(0, 2 * np.pi))

        elif pair == "outer":
            eH = ((m1 + m3) / 3.)**(1. / 3.)
            beta = r.uniform(3.5, 30)
            a3 = a1 / (1 + beta * eH)
            ecross3 = (a1 - a3) / a3
            emin3 = m1 / ecross3**2
            e3 = logunif(r, emin3, ecross3)
            pvarssorted.add(m=m3,
                            M=1,
                            a=a3,
                            e=e3,
                            gamma=r.uniform(0, 2 * np.pi),
                            l=r.uniform(0, 2 * np.pi))
            pvarssorted.add(m=ps[1].m,
                            M=ps[1].M,
                            a=ps[1].a,
                            e=ps[1].e,
                            gamma=ps[1].gamma,
                            l=ps[1].l)
            pvarssorted.add(m=ps[2].m,
                            M=ps[2].M,
                            a=ps[2].a,
                            e=ps[2].e,
                            gamma=ps[2].gamma,
                            l=ps[2].l)

        elif pair == "split":
            eH1 = ((m1 + m3) / 3.)**(1. / 3.)
            eH2 = ((m2 + m3) / 3.)**(1. / 3.)
            amin = a1 * (1 + 3.5 * eH1)
            amax = min(a1 * (1 + 30 * eH1), a2 / (1 + 3.5 * eH2))
            if amin > amax:
                seed += 900000
                return get_resonant(
                    seed=seed)  # draw new sample (may not be 'split')
            a3 = r.uniform(amin, amax)
            ecross3 = min((a3 - a1) / a1, (a2 - a3) / a3)
            emin3 = max(m1 / ((a3 - a1) / a3)**2, m2 / ((a2 - a3) / a3)**2)
            e3 = logunif(r, emin3, ecross3)
            pvarssorted.add(m=ps[1].m,
                            M=ps[1].M,
                            a=ps[1].a,
                            e=ps[1].e,
                            gamma=ps[1].gamma,
                            l=ps[1].l)
            pvarssorted.add(m=m3,
                            M=1,
                            a=a3,
                            e=e3,
                            gamma=r.uniform(0, 2 * np.pi),
                            l=r.uniform(0, 2 * np.pi))
            pvarssorted.add(m=ps[2].m,
                            M=ps[2].M,
                            a=ps[2].a,
                            e=ps[2].e,
                            gamma=ps[2].gamma,
                            l=ps[2].l)

        sim = pvarssorted.to_Simulation()
    else:
        sim = avars.to_Simulation()
    # add inclinations and scale s.t. a1 = 1, Mprimary=1. and G = 4*pi**2
    ps = sim.particles

    siminc = rebound.Simulation()
    siminc.G = 4 * np.pi**2

    dscale = ps[1].a
    tscale = ps[1].P
    mscale = siminc.G * dscale**3 / tscale**2  # ps[0].m + ps[1].m

    siminc.add(m=ps[0].m / mscale,
               x=ps[0].x / dscale,
               y=ps[0].y / dscale,
               vx=ps[0].vx / dscale * tscale,
               vy=ps[0].vy / dscale * tscale)
    for p in ps[1:]:
        siminc.add(m=p.m / mscale,
                   a=p.a / dscale,
                   e=p.e,
                   inc=logunif(r, 1.e-3, 1.e-1),
                   Omega=r.uniform(0, 2 * np.pi),
                   pomega=p.pomega,
                   l=p.l)
        rH = siminc.particles[-1].a * (siminc.particles[-1].m / 3. /
                                       siminc.particles[0].m)**(1. / 3.)
        siminc.particles[-1].r = rH
    siminc.move_to_com()
    siminc.integrator = "whfast"
    siminc.dt = 2. * np.sqrt(3) / 100. * siminc.particles[1].P
    siminc.ri_whfast.safe_mode = 0
    siminc.collision = "line"
    return siminc, j, k, pairindex, Zstar, libfac, Zcom