Exemplo n.º 1
0
def MWRfo(ldeg, bdeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    #rforce1 = evaluateRforces(MWPotential2014, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    #rfsun = evaluateRforces(MWPotential2014, Rskpc/Rskpc,0.0/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    rforce1 = evaluateRforces(MWPotential2014, Rpkpc / Rskpc, zkpc / Rskpc) * (
        (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rfsun = evaluateRforces(MWPotential2014, Rskpc / Rskpc, 0.0 / Rskpc) * (
        (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rf0 = rforce1 * coslam + rfsun * math.cos(l)  #m/ss
    rf = rf0 * math.cos(b) / par.c  # s-1
    return rf
Exemplo n.º 2
0
def estimateDeltaStaeckel(R,z,pot=None):
    """
    NAME:
       estimateDeltaStaeckel
    PURPOSE:
       Estimate a good value for delta using eqn. (9) in Sanders (2012)
    INPUT:
       R,z = coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit)
       pot= Potential instance or list thereof
    OUTPUT:
       delta
    HISTORY:
       2013-08-28 - Written - Bovy (IAS)
    """
    if pot is None:
        raise IOError("pot= needs to be set to a Potential instance or list thereof")
    if isinstance(R,nu.ndarray):
        delta2= nu.array([(z[ii]**2.-R[ii]**2. #eqn. (9) has a sign error
                           +(3.*R[ii]*evaluatezforces(R[ii],z[ii],pot)
                             -3.*z[ii]*evaluateRforces(R[ii],z[ii],pot)
                             +R[ii]*z[ii]*(evaluateR2derivs(R[ii],z[ii],pot)
                                           -evaluatez2derivs(R[ii],z[ii],pot)))/evaluateRzderivs(R[ii],z[ii],pot)) for ii in range(len(R))])
        indx= (delta2 < 0.)*(delta2 > -10.**-10.)
        delta2[indx]= 0.
        delta2= nu.median(delta2[True-nu.isnan(delta2)])
    else:
        delta2= (z**2.-R**2. #eqn. (9) has a sign error
                 +(3.*R*evaluatezforces(R,z,pot)
                   -3.*z*evaluateRforces(R,z,pot)
                   +R*z*(evaluateR2derivs(R,z,pot)
                         -evaluatez2derivs(R,z,pot)))/evaluateRzderivs(R,z,pot))
        if delta2 < 0. and delta2 > -10.**-10.: delta2= 0.
    return nu.sqrt(delta2)
Exemplo n.º 3
0
def accmaps(npix=200):
    #First setup the potential, the following are the best-fit parameters from the Sec. 5 of our paper
    #params= numpy.array([-1.33663190049,0.998420232634,-3.49031638164,0.31949840593,-1.63965169376])
    params= numpy.array([-1.33663190049,0.998420232634,-3.0736938150237028,0.31949840593,-1.63965169376]) #this has a scale height of 360 pc
    try:
        pot= setup_potential(params)
    except RuntimeError: #if this set of parameters gives a nonsense potential
        raise
    #Setup grid and output
    Rs= numpy.linspace(0.01,20.,npix)/_REFR0
    Zs= numpy.linspace(0.,20.,npix)/_REFR0
    accR_dm= numpy.empty((len(Rs),len(Zs)))
    accZ_dm= numpy.empty((len(Rs),len(Zs)))
    accR_baryon= numpy.empty((len(Rs),len(Zs)))
    accZ_baryon= numpy.empty((len(Rs),len(Zs)))
    #Calculate accelerations
    for ii in range(len(Rs)):
        for jj in range(len(Zs)):
            accR_dm[ii,jj]= potential.evaluateRforces(Rs[ii],Zs[jj],[pot[0]])
            accZ_dm[ii,jj]= potential.evaluatezforces(Rs[ii],Zs[jj],[pot[0]])
            accR_baryon[ii,jj]= potential.evaluateRforces(Rs[ii],Zs[jj],pot[1:])
            accZ_baryon[ii,jj]= potential.evaluatezforces(Rs[ii],Zs[jj],pot[1:])
    accR_dm*= bovy_conversion.force_in_10m13kms2(_REFV0*params[1],_REFR0)
    accZ_dm*= bovy_conversion.force_in_10m13kms2(_REFV0*params[1],_REFR0)
    accR_baryon*= bovy_conversion.force_in_10m13kms2(_REFV0*params[1],_REFR0)
    accZ_baryon*= bovy_conversion.force_in_10m13kms2(_REFV0*params[1],_REFR0)
    return (accR_dm,accZ_dm,accR_baryon,accZ_baryon,Rs,Zs)
def MWBHRfo(bdeg, ldeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = Rpkpcfunc(dkpc, b, l, Rskpc)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    MWPotential2014.append(
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(Vs, Rskpc)))

    rforce1 = evaluateRforces(MWPotential2014, Rpkpc / Rskpc,
                              zkpc / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                  Vs, Rskpc)

    rfsun = evaluateRforces(MWPotential2014, Rskpc / Rskpc,
                            0.0 / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                Vs, Rskpc)

    #rf = (rforce1-rfsun)*conversion*math.cos(b) # s-1
    rf0 = rforce1 * coslam + rfsun * math.cos(l)
    rf = rf0 * conversion * math.cos(b)  # s-1

    return rf
Exemplo n.º 5
0
 def _Rforce(self,R,z,phi=0.,t=0.):
     if self._interpRforce and self._enable_c:
         if isinstance(R,float):
             R= numpy.array([R])
         if isinstance(z,float):
             z= numpy.array([z])
         if self._zsym:
             return eval_force_c(self,R,numpy.fabs(z))[0]
         else:
             return eval_force_c(self,R,z)[0]
     from galpy.potential import evaluateRforces
     if self._interpRforce:
         if isinstance(R,float):
             return self._Rforce(numpy.array([R]),numpy.array([z]))
         out= numpy.empty_like(R)
         indx= (R >= self._rgrid[0])*(R <= self._rgrid[-1])
         if numpy.sum(indx) > 0:
             if self._zsym:
                 if self._logR:
                     out[indx]= self._rforceInterp.ev(numpy.log(R[indx]),numpy.fabs(z[indx]))
                 else:
                     out[indx]= self._rforceInterp.ev(R[indx],numpy.fabs(z[indx]))
             else:
                 if self._logR:
                     out[indx]= self._rforceInterp.ev(numpy.log(R[indx]),z[indx])
                 else:
                     out[indx]= self._rforceInterp.ev(R[indx],z[indx])
         if numpy.sum(True-indx) > 0:
             out[True-indx]= evaluateRforces(R[True-indx],
                                             z[True-indx],
                                             self._origPot)
         return out
     else:
         return evaluateRforces(R,z,self._origPot)
Exemplo n.º 6
0
def MWBHRfo(ldeg, bdeg, dkpc):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    MWPotential2014BH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    rforce1 = evaluateRforces(
        MWPotential2014BH, Rpkpc / Rskpc, zkpc / Rskpc) * (
            (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rfsun = evaluateRforces(MWPotential2014BH, Rskpc / Rskpc, 0.0 / Rskpc) * (
        (Vs * 1000.)**2.) / (Rskpc * par.kpctom)  #m/ss

    rf0 = rforce1 * coslam + rfsun * math.cos(l)  #m/ss
    rf = rf0 * math.cos(b) / par.c  # s-1
    return rf
Exemplo n.º 7
0
def fdotdotSB2cal(ldeg, bdeg, dkpc, mul, mub):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)

    zkpc = par.z(ldeg, bdeg, dkpc)

    fex_pl = excGal.Expl(ldeg, bdeg, dkpc)

    fex_z = excGal.Exz(ldeg, bdeg, dkpc)

    fex_shk = Shk.Exshk(dkpc, mul, mub)

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = MWPotential2014

    appl = evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    res1 = 2. * (mastorad / yrts) * (mub *
                                     ((math.sin(b) / c) *
                                      (appl * coslam + aspl * math.cos(l)) -
                                      (math.cos(b) / c) * apz) - mul *
                                     (math.sin(l) / c) *
                                     (appl * (Rskpc / Rpkpc) - aspl))

    res2 = 2. * fex_tot * (math.cos(b) * math.cos(l) * (aspl / c) +
                           (mastorad / yrts) * mub *
                           (1000. * Vs / c) * math.sin(b) * math.sin(l) -
                           (mastorad / yrts) * mul *
                           (1000. * Vs / c) * math.cos(l))

    res = res1 + res2
    return res
def force_pal5(pot: PotentialType,
               dpal5: float,
               ro: float = REFR0,
               vo: float = REFV0) -> Tuple[float]:
    """Return the force at Pal5.

    Parameters
    ----------
    pot: Potential, list
    dpal5: float
    ro, vo: float

    Return
    ------
    force: tuple
        [fx, fy, fz]

    """
    from galpy import potential
    from galpy.util import bovy_coords

    # First compute the location based on the distance
    l5, b5 = bovy_coords.radec_to_lb(229.018, -0.124, degree=True)
    X5, Y5, Z5 = bovy_coords.lbd_to_XYZ(l5, b5, dpal5, degree=True)
    R5, p5, Z5 = bovy_coords.XYZ_to_galcencyl(X5, Y5, Z5, Xsun=ro, Zsun=0.025)

    args: list = [pot, R5 / ro, Z5 / ro]
    kws: dict = {"phi": p5, "use_physical": True, "ro": ro, "vo": vo}

    return (
        potential.evaluateRforces(*args, **kws),
        potential.evaluatezforces(*args, **kws),
        potential.evaluatephiforces(*args, **kws),
    )
def calAcc(r, v) : 
    N = r.shape[0]
    a = np.zeros([N,3])
    dt_min = np.ones(N)*1e5*yrs
    dr = r
    dx = r[:,0]
    dy = r[:,1]
    dz = r[:,2]
    dv = v
    dr_gp = np.sqrt(dx*dx + dy*dy)/(r0*kpc) # galpy units
    dz_gp = dz/(r0*kpc)
    drNorm = np.linalg.norm(dr, axis = 1)
    acc = None
    if useNFW : 
        m, rho, sigma = NFWmass( drNorm)
        acc = -G*m/(drNorm*drNorm)[:,np.newaxis]*dr/drNorm[:,np.newaxis]
    elif useHernquist:
        m, rho, sigma = hernquistmass( drNorm)
        acc = -G*m/(drNorm*drNorm)[:,np.newaxis]*dr/drNorm[:,np.newaxis]
    else : 
        acc = np.zeros([dr_gp.size,3])
        conv = 1e-13*1e5
        for i, x_gp, y_gp, r_gp, z_gp in zip(range(dr_gp.size), dx/(r0*kpc), dy/(r0*kpc), dr_gp, dz_gp) : 
            a = gp.evaluateRforces(MWpot,r_gp,z_gp)*bovy_conversion.force_in_10m13kms2(v0,r0)*conv
            acc[i,0] = a*x_gp/r_gp
            acc[i,1] = a*y_gp/r_gp
            acc[i,2] = gp.evaluatezforces(MWpot,r_gp,z_gp)*bovy_conversion.force_in_10m13kms2(v0,r0)*conv
    dt_rmin = np.min(drNorm/np.linalg.norm(dv, axis=1))
    dt_amin = np.min(np.linalg.norm(dv,axis=1)/np.maximum(np.linalg.norm(acc,axis=1), TINY))
    dt_min = min(dt_rmin, dt_amin)
    if(args.use_DF) : 
        acc = acc + accDF( r, v)
    return acc, dt_min
Exemplo n.º 10
0
    def get_gravity_at_point(self, eps, x, y, z):

        R = np.sqrt(x.value_in(units.kpc)**2. + y.value_in(units.kpc)**2.)
        zed = z.value_in(units.kpc)
        phi = np.arctan2(y.value_in(units.kpc), x.value_in(units.kpc))

        Rforce = potential.evaluateRforces(self.pot,
                                           R / self.ro,
                                           zed / self.ro,
                                           phi=phi,
                                           t=self.tgalpy)
        phiforce = potential.evaluatephiforces(
            self.pot, R / self.ro, zed / self.ro, phi=phi,
            t=self.tgalpy) / (R / self.ro)
        zforce = potential.evaluatezforces(self.pot,
                                           R / self.ro,
                                           zed / self.ro,
                                           phi=phi,
                                           t=self.tgalpy)

        ax = (Rforce * np.cos(phi) -
              phiforce * np.sin(phi)) * bovy_conversion.force_in_kmsMyr(
                  ro=self.ro, vo=self.vo) | units.kms * units.myr**-1
        ay = (Rforce * np.sin(phi) +
              phiforce * np.cos(phi)) * bovy_conversion.force_in_kmsMyr(
                  ro=self.ro, vo=self.vo) | units.kms * units.myr**-1
        az = zforce * bovy_conversion.force_in_kmsMyr(
            ro=self.ro, vo=self.vo) | units.kms * units.myr**-1

        return ax, ay, az
Exemplo n.º 11
0
def MWBHRfo(ldeg, sigl, bdeg, sigb, dkpc, sigd):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, sigl, bdeg, sigb, dkpc, sigd)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    '''
    bp= PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
    mp= MiyamotoNagaiPotential(a=3./8.,b=0.28/8.,normalize=.6)
    np= NFWPotential(a=16./8.,normalize=.35)
    kp = KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))
    MWBH = [bp,mp,np,kp]

    rforce1 = evaluateRforces(MWBH, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    rfsun = evaluateRforces(MWBH, Rskpc/Rskpc,0.0/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)
    '''

    #MWPotential2014.append(KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(Vs,Rskpc)))

    #rforce1 = evaluateRforces(MWPotential2014, Rpkpc/Rskpc,zkpc/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    #rfsun = evaluateRforces(MWPotential2014, Rskpc/Rskpc,0.0/Rskpc)*bovy_conversion.force_in_kmsMyr(Vs,Rskpc)

    MWPotential2014wBH = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]
    rforce1 = evaluateRforces(MWPotential2014wBH, Rpkpc / Rskpc,
                              zkpc / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                  Vs, Rskpc)

    rfsun = evaluateRforces(MWPotential2014wBH, Rskpc / Rskpc,
                            0.0 / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                Vs, Rskpc)

    #rf = (rforce1-rfsun)*conversion*math.cos(b) # s-1
    rf0 = rforce1 * coslam + rfsun * math.cos(l)
    rf = rf0 * conversion * math.cos(b)  # s-1
    return rf
Exemplo n.º 12
0
    def _Rforce(self, R, z, phi=0.0, t=0.0):
        from galpy.potential import evaluateRforces

        if self._interpRforce:
            out = numpy.empty_like(R)
            indx = (R >= self._rgrid[0]) * (R <= self._rgrid[-1]) * (z <= self._zgrid[-1]) * (z >= self._zgrid[0])
            if numpy.sum(indx) > 0:
                if self._enable_c:
                    out[indx] = eval_force_c(self, R[indx], z[indx])[0] / self._amp
                else:
                    if self._logR:
                        out[indx] = self._rforceInterp.ev(numpy.log(R[indx]), z[indx])
                    else:
                        out[indx] = self._rforceInterp.ev(R[indx], z[indx])
            if numpy.sum(True - indx) > 0:
                out[True - indx] = evaluateRforces(R[True - indx], z[True - indx], self._origPot)
            return out
        else:
            return evaluateRforces(R, z, self._origPot)
Exemplo n.º 13
0
def test_vcirc():
    #test the circular velocity of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, fig. 1-3
    #and their formula eq. (10)

    #_____model parameters______
    #surface ratios of disk and halo:
    ac_Ds = [50.  ,50.  ,50.  ,50. ,50. ,50.  ,40. ,40. ,40. ]
    ac_Hs = [1.005,1.005,1.005,1.01,1.01,1.01 ,1.02,1.02,1.02 ]
    #disk contribution to total mass:
    ks    = [0.05 ,0.06 ,0.07 ,0.07,0.1 ,0.125,0.1 ,0.12,0.125]
    #focal distance:
    Delta = 1.

    for ii in range(9):
        ac_D = ac_Ds[ii]
        ac_H = ac_Hs[ii]
        k    = ks[ii]
        
        #_____setup potential_____
        #first try, not normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=    k ,ac=ac_D,Delta=Delta,normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1.-k),ac=ac_H,Delta=Delta,normalize=False)
        pot = [V_D,V_H]
        #normalization according to Batsleer & Dejonghe 1994:
        V00 = evaluatePotentials(pot,0.,0.)
        #second try, normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=    k  / (-V00),ac=ac_D,Delta=Delta,normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1.-k) / (-V00),ac=ac_H,Delta=Delta,normalize=False)
        pot = [V_D,V_H]
        
        #_____calculate rotation curve_____
        Rs = numpy.linspace(0.,20.,100)
        z = 0.
        vcirc_calc = numpy.sqrt(-Rs * evaluateRforces(pot,Rs,z))
            
        #_____vcirc by Batsleer & Dejonghe eq. (10) (with proper Jacobian)_____
        def vc2w(R):
            g_D = Delta**2 / (1.-ac_D**2)
            a_D = g_D - Delta**2
            g_H = Delta**2 / (1.-ac_H**2)
            a_H = g_H - Delta**2
            l = R**2 - a_D
            q = a_H - a_D
            termD = numpy.sqrt(l  )*(numpy.sqrt(l  ) + numpy.sqrt(-g_D  ))**2
            termH = numpy.sqrt(l-q)*(numpy.sqrt(l-q) + numpy.sqrt(-g_D-q))**2
            return R**2 * (k / termD + (1.-k) / termH)
        vcirc_formula = numpy.sqrt(vc2w(Rs)/(-V00))

        assert numpy.all(numpy.fabs(vcirc_calc - vcirc_formula) < 10**-8.), \
                'Calculated circular velocity for KuzminKutuzovStaeckelPotential '+ \
                'does not agree with eq. (10) (corrected by proper Jacobian) '+ \
                'by Batsleer & Dejonghe (1994)'

    return None
Exemplo n.º 14
0
 def _Rforce(self,R,z,phi=0.,t=0.):
     from galpy.potential import evaluateRforces
     if self._interpRforce:
         out= numpy.empty_like(R)
         indx= (R >= self._rgrid[0])*(R <= self._rgrid[-1])\
             *(z <= self._zgrid[-1])*(z >= self._zgrid[0])
         if numpy.sum(indx) > 0:
             if self._enable_c:
                 out[indx]= eval_force_c(self,R[indx],z[indx])[0]/self._amp
             else:
                 if self._logR:
                     out[indx]= self._rforceInterp.ev(numpy.log(R[indx]),z[indx])
                 else:
                     out[indx]= self._rforceInterp.ev(R[indx],z[indx])
         if numpy.sum(True^indx) > 0:
             out[True^indx]= evaluateRforces(self._origPot,
                                             R[True^indx],
                                             z[True^indx])
         return out
     else:
         return evaluateRforces(self._origPot,R,z)
def force_pal5(pot,dpal5,ro,vo):
    """Return the force at Pal5"""
    # First compute the location based on the distance
    l5, b5= bovy_coords.radec_to_lb(229.018,-0.124,degree=True)
    X5,Y5,Z5= bovy_coords.lbd_to_XYZ(l5,b5,dpal5,degree=True)
    R5,p5,Z5= bovy_coords.XYZ_to_galcencyl(X5,Y5,Z5,Xsun=ro,Zsun=0.025)
    return (potential.evaluateRforces(pot,R5/ro,Z5/ro,phi=p5,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatezforces(pot,R5/ro,Z5/ro,phi=p5,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatephiforces(pot,R5/ro,Z5/ro,phi=p5,
                                        use_physical=True,ro=ro,vo=vo))
def force_gd1(pot,ro,vo):
    """Return the force at GD-1"""
    # Just use R=12.5 kpc, Z= 6.675 kpc, phi=0
    R1= 12.5
    Z1= 6.675
    p1= 0.
    return (potential.evaluateRforces(pot,R1/ro,Z1/ro,phi=p1,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatezforces(pot,R1/ro,Z1/ro,phi=p1,
                                      use_physical=True,ro=ro,vo=vo),
            potential.evaluatephiforces(pot,R1/ro,Z1/ro,phi=p1,
                                        use_physical=True,ro=ro,vo=vo))
Exemplo n.º 17
0
def obj(x,data,bp,dp,hp):
    #x=[fd,fh,vc,rs,hdisk]
    if x[0] > 1. or x[0] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if x[1] > 1. or x[1] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if (1.-x[0]-x[1]) > 1. or (1.-x[0]-x[1]) < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if x[2] < 0. or x[3] < 0. or x[4] < 0.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if x[2] > 2. or x[3] > 10. or x[4] > 2.: return numpy.finfo(numpy.dtype(numpy.float64)).max
    if False:
        #Renormalize potentials, intially normalized to 1./3. each
        bp= copy.deepcopy(bp)
        dp= copy.deepcopy(dp)
        hp= copy.deepcopy(hp)
        bp._amp*= (1.-x[0]-x[1])**2.*9.
        dp._amp*= x[0]**2.*9.
        hp._amp*= x[1]**2.*9.
        #Re-define disk scale length and halo scale length
        if _dexp:
            dp._hr= x[4]
        else:
            dp._a= x[4]
        hp._a= x[3]
    else:
        #Set-up
        bp= HernquistPotential(a=0.6/_REFR0,normalize=1.-x[0]-x[1])
        if _dexp:
            dp= DoubleExponentialDiskPotential(normalize=x[0],
                                               hr=x[4],
                                               hz=0.3/_REFR0)
        else:
            dp= MiyamotoNagaiPotential(normalize=x[0],
                                       a=x[4],
                                       b=0.3/_REFR0)
        hp= NFWPotential(normalize=x[1],
                         a=x[3])
    #Re-normalize data
    vcircdata= copy.copy(data)
    vcircdata[:,1]/= x[2]
    vcircdata[:,2]/= x[2]
    #Vcirc chi2
    vcmodel= numpy.zeros(vcircdata.shape[0])
    for ii in range(vcircdata.shape[0]):
        vcmodel[ii]= numpy.sqrt(vcircdata[ii,0]\
                                    *numpy.fabs(evaluateRforces(vcircdata[ii,0],
                                                                0.,[bp,dp,hp])))
    #print vcircdata[:,0], vcmodel
    chi2= numpy.sum((vcircdata[:,1]-vcmodel)**2./vcircdata[:,2]**2.)
    #Add scale length measurement
    chi2+= (x[4]-_diskscale)**2./_diskscaleerr**2.
    #Add dark matter density at the Solar radius
    #print hp.dens(1.,0.),_rhodm*x[2]**2.
    #chi2+= (hp.dens(1.,0.)-_rhodm*x[2]**2.)**2./_rhodmerr**2./x[2]**4.
    return chi2
Exemplo n.º 18
0
def estimateDeltaStaeckel(R, z, pot=None):
    """
    NAME:
       estimateDeltaStaeckel
    PURPOSE:
       Estimate a good value for delta using eqn. (9) in Sanders (2012)
    INPUT:
       R,z = coordinates (if these are arrays, the median estimated delta is returned, i.e., if this is an orbit)
       pot= Potential instance or list thereof
    OUTPUT:
       delta
    HISTORY:
       2013-08-28 - Written - Bovy (IAS)
    """
    if pot is None:  #pragma: no cover
        raise IOError(
            "pot= needs to be set to a Potential instance or list thereof")
    if isinstance(R, nu.ndarray):
        delta2 = nu.array([
            (
                z[ii]**2. - R[ii]**2.  #eqn. (9) has a sign error
                + (3. * R[ii] * evaluatezforces(R[ii], z[ii], pot) - 3. *
                   z[ii] * evaluateRforces(R[ii], z[ii], pot) + R[ii] * z[ii] *
                   (evaluateR2derivs(R[ii], z[ii], pot) -
                    evaluatez2derivs(R[ii], z[ii], pot))) /
                evaluateRzderivs(R[ii], z[ii], pot)) for ii in range(len(R))
        ])
        indx = (delta2 < 0.) * (delta2 > -10.**-10.)
        delta2[indx] = 0.
        delta2 = nu.median(delta2[True - nu.isnan(delta2)])
    else:
        delta2 = (
            z**2. - R**2.  #eqn. (9) has a sign error
            + (3. * R * evaluatezforces(R, z, pot) -
               3. * z * evaluateRforces(R, z, pot) + R * z *
               (evaluateR2derivs(R, z, pot) - evaluatez2derivs(R, z, pot))) /
            evaluateRzderivs(R, z, pot))
        if delta2 < 0. and delta2 > -10.**-10.: delta2 = 0.
    return nu.sqrt(delta2)
Exemplo n.º 19
0
def accHernquistfix(x,y,z):
    x = x/kpctocm
    y = y/kpctocm
    z = z/kpctocm
    r = np.sqrt( x**2 + y**2)
    pot = HernquistPotential(2.e12*u.M_sun , 30e3*u.pc)
    az = evaluatezforces(pot,r*u.kpc , z*u.kpc)
    ar = evaluateRforces(pot,r*u.kpc , z*u.kpc)
    az = -az*1.e5/(1.e6*3.15e7)
    ar = ar*1.e5/(1.e6*3.15e7)
    ax = -ar*x/r
    ay = -ar*y/r
    return ax,ay,az
Exemplo n.º 20
0
def MWRfo(ldeg, sigl, bdeg, sigb, dkpc, sigd):

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad
    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    Rpkpc = par.Rpkpc(ldeg, sigl, bdeg, sigb, dkpc, sigd)
    zkpc = dkpc * math.sin(b)
    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)

    rforce1 = evaluateRforces(MWPotential2014, Rpkpc / Rskpc,
                              zkpc / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                  Vs, Rskpc)

    rfsun = evaluateRforces(MWPotential2014, Rskpc / Rskpc,
                            0.0 / Rskpc) * bovy_conversion.force_in_kmsMyr(
                                Vs, Rskpc)

    rf0 = rforce1 * coslam + rfsun * math.cos(l)
    rf = rf0 * conversion * math.cos(b)  # s-1
    return rf
Exemplo n.º 21
0
def rv(x, y, z):

    conv = bovy_conversion.force_in_pcMyr2(220., 8) * u.pc / (
        u.Myr**2)  ##Unit conversion

    x *= u.kpc
    y *= u.kpc
    z *= u.kpc

    ##Sun's location
    sx = 8 * u.kpc
    sy = 0 * u.kpc
    sz = 4 * u.kpc

    sun_ar = evaluateRforces(poten, sx, sz, phi=0 * u.deg) * conv
    sun_az = evaluatezforces(poten, sx, sz, phi=0 * u.deg) * conv

    sun_acc = Vector(sun_ar, 0 * conv, sun_az)

    star_ar = evaluateRforces(poten, np.sqrt(x**2 + y**2), z,
                              phi=0 * u.deg) * conv
    star_az = evaluatezforces(poten, np.sqrt(x**2 + y**2), z,
                              phi=0 * u.deg) * conv

    star_acc = Vector(star_ar, 0 * conv, star_az)

    heliocentric_acc = Vector(star_acc.x - sun_acc.x, star_acc.y - sun_acc.y,
                              star_acc.z - sun_acc.z)

    r = Vector(sx - x, sy - y, sz - z)

    acc = r.project(heliocentric_acc)

    delta_v = (acc.mag * 10 * u.yr).to(u.cm / u.s)

    return delta_v, r
Exemplo n.º 22
0
 def _getForces(folder):
     loc = "SCFAnalysis/Orbits/{0}".format(folder)
     Acos = nu.load(loc + "/Acos.npy")
     a_nfw = 200./8
     orbits_pos =nu.load(TIMEORBITS.format(loc, TIME,0.004,1*units.Myr))
     scf = potential.SCFPotential(Acos=Acos, a=a_nfw, normalize=.35)
     ps= potential.PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
     mn= potential.MiyamotoNagaiPotential(a=3./8.,b=0.28/8.,normalize=.6)
     MWPotential= [ps,mn,scf]
     x,y,z = orbits_pos[-1,1:4]
     R, phi, z = rect_to_cyl(x,y,z)
     print "(R,z,phi) = ({0}, {1}, {2})".format(R,z,phi)
     Rforce = potential.evaluateRforces(MWPotential, R,z,phi)
     zforce = potential.evaluatezforces(MWPotential, R,z,phi)
     phiforce = potential.evaluatephiforces(MWPotential, R,z,phi)
     return Rforce, zforce, phiforce
Exemplo n.º 23
0
def FRStaeckel(u,v,pot,delta):
    """
    NAME:
       FRStaeckel
    PURPOSE:
       return the radial force
    INPUT:
       u - confocal u
       v - confocal v
       pot - potential
       delta - focus
    OUTPUT:
       FR(u,v)
    HISTORY:
       2012-11-30 - Written - Bovy (IAS)
    """
    R,z= bovy_coords.uv_to_Rz(u,v,delta=delta)
    return evaluateRforces(R,z,pot)
Exemplo n.º 24
0
def FRStaeckel(u, v, pot, delta):  #pragma: no cover because unused
    """
    NAME:
       FRStaeckel
    PURPOSE:
       return the radial force
    INPUT:
       u - confocal u
       v - confocal v
       pot - potential
       delta - focus
    OUTPUT:
       FR(u,v)
    HISTORY:
       2012-11-30 - Written - Bovy (IAS)
    """
    R, z = bovy_coords.uv_to_Rz(u, v, delta=delta)
    return evaluateRforces(R, z, pot)
Exemplo n.º 25
0
def accMWpot(x,y,z,alpha=1.8, rc=1.9, a=3., b=0.28):
    x = x/kpctocm
    y = y/kpctocm
    z = z/kpctocm
    r = np.sqrt( x**2 + y**2)
    bp= gp.PowerSphericalPotentialwCutoff(alpha=1.8,rc=1.9/8.,normalize=0.05)
    mp= gp.MiyamotoNagaiPotential(a=a/8.,b=b/8.,normalize=.6)
    nfw= gp.NFWPotential(a=16/8.,normalize=.35)
    #print(help(MWPotential2014))
    #pot = [bp,mp,nfw]
    pot = MWPotential2014
    az = evaluatezforces(pot,r*u.kpc , z*u.kpc)*bovy_conversion.force_in_kmsMyr(Vlsr/1e5,8.122)
    ar = evaluateRforces(pot,r*u.kpc , z*u.kpc)*bovy_conversion.force_in_kmsMyr(Vlsr/1e5,8.122)
    ar = ar*1.e5/(1.e6*3.15e7)
    az = -az*1.e5/(1.e6*3.15e7)

    ax = -ar*x/r
    ay = -ar*y/r
    return ax,ay,az
Exemplo n.º 26
0
def calAcc(r, v):
    N = r.shape[0]
    a = np.zeros([N, 3])
    dt_min = np.ones(N) * 1e5 * yrs
    dr = r
    dx = r[:, 0]
    dy = r[:, 1]
    dz = r[:, 2]
    dv = v
    dr_gp = np.sqrt(dx * dx + dy * dy) / (r0 * kpc)  # galpy units
    dz_gp = dz / (r0 * kpc)
    drNorm = np.linalg.norm(dr, axis=1)
    acc = None
    if useNFW:
        m, rho, sigma = NFWmass(drNorm)
        acc = -G * m / (drNorm *
                        drNorm)[:, np.newaxis] * dr / drNorm[:, np.newaxis]
    elif useHernquist:
        m, rho, sigma = hernquistmass(drNorm)
        acc = -G * m / (drNorm *
                        drNorm)[:, np.newaxis] * dr / drNorm[:, np.newaxis]
    else:
        acc = np.zeros([dr_gp.size, 3])
        conv = 1e-13 * 1e5
        for i, x_gp, y_gp, r_gp, z_gp in zip(range(dr_gp.size),
                                             dx / (r0 * kpc), dy / (r0 * kpc),
                                             dr_gp, dz_gp):
            a = gp.evaluateRforces(MWpot, r_gp,
                                   z_gp) * bovy_conversion.force_in_10m13kms2(
                                       v0, r0) * conv
            acc[i, 0] = a * x_gp / r_gp
            acc[i, 1] = a * y_gp / r_gp
            acc[i, 2] = gp.evaluatezforces(
                MWpot, r_gp, z_gp) * bovy_conversion.force_in_10m13kms2(
                    v0, r0) * conv
    dt_rmin = np.min(drNorm / np.linalg.norm(dv, axis=1))
    dt_amin = np.min(
        np.linalg.norm(dv, axis=1) /
        np.maximum(np.linalg.norm(acc, axis=1), TINY))
    dt_min = min(dt_rmin, dt_amin)
    if (args.use_DF):
        acc = acc + accDF(r, v)
    return acc, dt_min
Exemplo n.º 27
0
def force_gd1(pot, ro, vo):
    """Return the force at GD-1.

    Parameters
    ----------
    pot: Potential
    ro, vo: float

    Return
    ------
    force: tuple
        [fx, fy, fz]

    """
    # Just use R=12.5 kpc, Z= 6.675 kpc, phi=0
    R1 = 12.5
    Z1 = 6.675
    p1 = 0.0

    return (
        potential.evaluateRforces(pot,
                                  R1 / ro,
                                  Z1 / ro,
                                  phi=p1,
                                  use_physical=True,
                                  ro=ro,
                                  vo=vo),
        potential.evaluatezforces(pot,
                                  R1 / ro,
                                  Z1 / ro,
                                  phi=p1,
                                  use_physical=True,
                                  ro=ro,
                                  vo=vo),
        potential.evaluatephiforces(pot,
                                    R1 / ro,
                                    Z1 / ro,
                                    phi=p1,
                                    use_physical=True,
                                    ro=ro,
                                    vo=vo),
    )
Exemplo n.º 28
0
def calAcc(r, v) : 
    N = r.shape[0]
    dr = r
    dx = r[:,0]
    dy = r[:,1]
    dz = r[:,2]
    dv = v
    dr_gp = np.sqrt(dx*dx + dy*dy)/(r0*kpc) # galpy units
    dz_gp = dz/(r0*kpc)
    drNorm = np.linalg.norm(dr, axis = 1)
    acc = None
    if useNFW : 
        m, rho, sigma = NFWmass( drNorm)
        acc = -G*m/(drNorm*drNorm)[:,np.newaxis]*dr/drNorm[:,np.newaxis]
    elif useHernquist:
        m, rho, sigma = hernquistmass( drNorm)
        acc = (-G*m/(drNorm*drNorm*drNorm))[:,np.newaxis]*dr#[:,np.newaxis]*dr
    else : 
        acc = np.zeros([dr_gp.size,3])
        conv = 1e-13*1e5
        for i, x_gp, y_gp, r_gp, z_gp in zip(range(dr_gp.size), dx/(r0*kpc), dy/(r0*kpc), dr_gp, dz_gp) : 
            a = gp.evaluateRforces(MWpot,r_gp,z_gp)*bovy_conversion.force_in_10m13kms2(v0,r0)*conv
            acc[i,0] = a*x_gp/r_gp
            acc[i,1] = a*y_gp/r_gp
            acc[i,2] = gp.evaluatezforces(MWpot,r_gp,z_gp)*bovy_conversion.force_in_10m13kms2(v0,r0)*conv
    dt_rmin = np.min(drNorm/np.linalg.norm(dv, axis=1))
    dt_amin = np.min(np.linalg.norm(dv,axis=1)/np.maximum(np.linalg.norm(acc,axis=1), TINY))
    dt_min = min(dt_rmin, dt_amin)
    if(useDF) : 
        acc[:Nsat,:] = acc[:Nsat,:] + accDF( r[:Nsat,:], v[:Nsat,:])
    if(useTestParticles and Nsat < N and runSat) :
        # include accelerations from other satellites for test particles
        for i in range(Nsat) : 
            rsat = r[i]
            dr = r[Nsat:,:] - rsat[np.newaxis,:]
            drNorm = np.linalg.norm( dr, axis=1)
            m, rho, sigma = hernquistmass( drNorm, m0=msat[i], vc200=vc200sat[i], r200=r200sat[i], c0=c0sat[i])
            acc[Nsat:,:] =  acc[Nsat:,:] - (G*m/(drNorm*drNorm*drNorm))[:,np.newaxis]*dr
    return acc, dt_min
Exemplo n.º 29
0
def del_E(coord, custom_potential=None):
    """
    NAME:
        del_E

    PURPOSE:
        Given (m,6) array for a list of the position and velocity of stars in
        Cartesian coordinate, return the gradient vectors of energy in Cartesian
        form, in the corresponding row order.
        Assumes input and out put are in natrual unit.
        
    INPUT:
        coord = array([[x, y, z, vx, vy, vz], ...])
                where each row represents the coordinate of a star

    OUTPUT:
        del_E = gradient in Cartesian coordinate
                where each row represents the gradient of a star

    HISTORY:
        2018-07-10 - Written - Samuel Wong
        2018-07-24 - Changed to an array of points - Samuel Wong
    """
    if custom_potential == None:
        potential = MWPotential2014
    else:
        potential = custom_potential
    x, y, z, vx, vy, vz = coord.T
    R, vR, vT, z, vz, phi = rect_to_cyl(x, y, z, vx, vy, vz).T
    # get the force of the potential in cylindrical form
    F_phi = evaluatephiforces(potential, R, z, phi) / R
    F_R = evaluateRforces(potential, R, z, phi)
    F_z = evaluatezforces(potential, R, z, phi)
    # return the gradient in Cartesian coordinate
    gradient = [
        F_phi * np.sin(phi) - F_R * np.cos(phi),
        -F_R * np.sin(phi) - F_phi * np.cos(phi), -F_z, vx, vy, vz
    ]
    return np.array(gradient).T
Exemplo n.º 30
0
def _a_integrand(T,y,b,w,pot,compt):
    t = T/(1-T*T)
    X = b+w*t+y*numpy.array([0,1,0])
    r = numpy.sqrt(numpy.sum(X**2))
    return (1+T*T)/(1-T*T)**2*evaluateRforces(r,0.,pot)*X[compt]/r
Exemplo n.º 31
0
def fdotdotSB1cal(ldeg, bdeg, dkpc, mul, mub, vrad):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)

    zkpc = par.z(ldeg, bdeg, dkpc)

    fex_pl = excGal.Expl(ldeg, bdeg, dkpc)

    fex_z = excGal.Exz(ldeg, bdeg, dkpc)

    fex_shk = Shk.Exshk(dkpc, mul, mub)

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = MWPotential2014

    appl = -evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = -evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) /
                                          Rpkpc) * math.sin(l)

    aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l))
    aTb1 = appl * coslam * math.sin(b) + apz * math.cos(b) + aspl * math.cos(
        l) * math.sin(b)
    aTnet1 = (aTl1**2. + aTb1**2.)**(0.5)
    alphaV1 = math.atan2(mub, mul) / par.degtorad
    alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad
    if alphaV1 < 0.:
        alphaV = 360. + alphaV1
    else:
        alphaV = alphaV1

    if alphaA1 < 0.:
        alphaA = 360. + alphaA1
    else:
        alphaA = alphaA1
    alpha = abs(alphaA - alphaV)

    aT1 = 2. * appl * aspl * coslpluslam
    aT2 = (c * (fex_pl + fex_z))**2.
    aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2
    #if aTsq < 0.0:
    aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5

    zdot = (1000.0 * vrad) * math.sin(b) + (mastorad / yrts) * mub * (
        dkpc * kpctom) * math.cos(b)
    Rpdot = (1. / (Rpkpc * kpctom)) * (
        ((dkpc * kpctom) *
         (math.cos(b)**2.) - Rs * math.cos(b) * math.cos(l)) *
        (1000.0 * vrad) + (Rs * (dkpc * kpctom) * math.sin(b) * math.cos(l) -
                           ((dkpc * kpctom)**2.) * math.cos(b) * math.sin(b)) *
        ((mastorad / yrts) * mub) + Rs * (dkpc * kpctom) * math.sin(l) *
        ((mastorad / yrts) * mul))

    phiR2 = normjerktoSI * evaluateR2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc)
    phiz2 = normjerktoSI * evaluatez2derivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc)
    phiRz = normjerktoSI * evaluateRzderivs(MWPot, Rpkpc / Rskpc, zkpc / Rskpc)
    phiR2sun = normjerktoSI * evaluateR2derivs(MWPot, Rskpc / Rskpc,
                                               0.0 / Rskpc)
    phiRzsun = normjerktoSI * evaluateRzderivs(MWPot, Rskpc / Rskpc,
                                               0.0 / Rskpc)
    aspldot = phiR2sun * Rpdot + phiRzsun * zdot
    appldot = phiR2 * Rpdot + phiRz * zdot
    if b > 0:
        apzdot = phiRz * Rpdot + phiz2 * zdot
    else:
        apzdot = -(phiRz * Rpdot + phiz2 * zdot)

    #if coslam != 0.0 and Rpkpc != 0.0 and math.cos(b) != 0.0:

    lamdot = (1. / coslam) * ((Rs * math.cos(l) * ((mastorad / yrts) * mul)) /
                              ((Rpkpc * kpctom) * math.cos(b)) -
                              (Rs * math.sin(l) /
                               ((Rpkpc * kpctom)**2.)) * Rpdot)
    ardot1 = math.sin(b) * (appl * coslam + aspl * math.cos(l)) * (
        (mastorad / yrts) * mub)
    ardot2 = math.cos(b) * (appldot * coslam + aspldot * math.cos(l))
    ardot3 = apzdot * math.sin(abs(b))
    ardot4 = appl * math.cos(b) * (Rskpc * math.sin(l) / Rpkpc) * lamdot
    ardot5 = aspl * math.sin(l) * ((mastorad / yrts) * mul)
    ardot6 = abs(apz) * math.cos(b) * ((mastorad / yrts) * mub) * (b / abs(b))
    ardot = ardot1 - ardot2 - ardot3 + ardot4 + ardot5 - ardot6

    jerkt = (1. / c) * (ardot - aT *
                        ((mastorad / yrts) * muT) * math.cos(alpha))
    return jerkt
Exemplo n.º 32
0
def test_vcirc():
    #test the circular velocity of the KuzminKutuzovStaeckelPotential
    #using parameters from Batsleer & Dejonghe 1994, fig. 1-3
    #and their formula eq. (10)

    #_____model parameters______
    #surface ratios of disk and halo:
    ac_Ds = [50., 50., 50., 50., 50., 50., 40., 40., 40.]
    ac_Hs = [1.005, 1.005, 1.005, 1.01, 1.01, 1.01, 1.02, 1.02, 1.02]
    #disk contribution to total mass:
    ks = [0.05, 0.06, 0.07, 0.07, 0.1, 0.125, 0.1, 0.12, 0.125]
    #focal distance:
    Delta = 1.

    for ii in range(9):
        ac_D = ac_Ds[ii]
        ac_H = ac_Hs[ii]
        k = ks[ii]

        #_____setup potential_____
        #first try, not normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=k,
                                             ac=ac_D,
                                             Delta=Delta,
                                             normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1. - k),
                                             ac=ac_H,
                                             Delta=Delta,
                                             normalize=False)
        pot = [V_D, V_H]
        #normalization according to Batsleer & Dejonghe 1994:
        V00 = evaluatePotentials(pot, 0., 0.)
        #second try, normalized:
        V_D = KuzminKutuzovStaeckelPotential(amp=k / (-V00),
                                             ac=ac_D,
                                             Delta=Delta,
                                             normalize=False)
        V_H = KuzminKutuzovStaeckelPotential(amp=(1. - k) / (-V00),
                                             ac=ac_H,
                                             Delta=Delta,
                                             normalize=False)
        pot = [V_D, V_H]

        #_____calculate rotation curve_____
        Rs = numpy.linspace(0., 20., 100)
        z = 0.
        vcirc_calc = numpy.sqrt(-Rs * evaluateRforces(pot, Rs, z))

        #_____vcirc by Batsleer & Dejonghe eq. (10) (with proper Jacobian)_____
        def vc2w(R):
            g_D = Delta**2 / (1. - ac_D**2)
            a_D = g_D - Delta**2
            g_H = Delta**2 / (1. - ac_H**2)
            a_H = g_H - Delta**2
            l = R**2 - a_D
            q = a_H - a_D
            termD = numpy.sqrt(l) * (numpy.sqrt(l) + numpy.sqrt(-g_D))**2
            termH = numpy.sqrt(l - q) * (numpy.sqrt(l - q) +
                                         numpy.sqrt(-g_D - q))**2
            return R**2 * (k / termD + (1. - k) / termH)

        vcirc_formula = numpy.sqrt(vc2w(Rs) / (-V00))

        assert numpy.all(numpy.fabs(vcirc_calc - vcirc_formula) < 10**-8.), \
                'Calculated circular velocity for KuzminKutuzovStaeckelPotential '+ \
                'does not agree with eq. (10) (corrected by proper Jacobian) '+ \
                'by Batsleer & Dejonghe (1994)'

    return None
Exemplo n.º 33
0
def plhalo_from_dlnvcdlnr(dlnvcdlnr,diskpot,bulgepot,fh):
    """Calculate the halo's shape corresponding to this rotation curve derivative"""
    #First calculate the derivatives dvc^2/dR of disk and bulge
    dvcdr_disk= -potential.evaluateRforces(1.,0.,diskpot)+potential.evaluateR2derivs(1.,0.,diskpot)
    dvcdr_bulge= -potential.evaluateRforces(1.,0.,bulgepot)+potential.evaluateR2derivs(1.,0.,bulgepot)
    return 2.-(2.*dlnvcdlnr-dvcdr_disk-dvcdr_bulge)/fh
def plotForceField(savefig: Optional[str] = None):
    """Plot MW Force Field.

    Parameters
    ----------
    savefic: str, optional

    """
    p_b15_pal5gd1_voro = fit(fitc=True,
                             c=None,
                             addpal5=True,
                             addgd1=True,
                             fitvoro=True,
                             mc16=True)

    # Set up potential
    p_b15 = p_b15_pal5gd1_voro[0]
    ro, vo = REFR0, REFV0
    pot = setup_potential(p_b15, p_b15_pal5gd1_voro[0][-1], False, False, ro,
                          vo)
    # Compute force field
    Rs = np.linspace(0.01, 20.0, 51)
    zs = np.linspace(-20.0, 20.0, 151)
    mRs, mzs = np.meshgrid(Rs, zs, indexing="ij")
    forces = np.zeros((len(Rs), len(zs), 2))
    potvals = np.zeros((len(Rs), len(zs)))
    for ii in tqdm(range(len(Rs))):
        for jj in tqdm(range(len(zs))):
            forces[ii, jj, 0] = potential.evaluateRforces(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )
            forces[ii, jj, 1] = potential.evaluatezforces(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )
            potvals[ii, jj] = potential.evaluatePotentials(
                pot,
                mRs[ii, jj] / ro,
                mzs[ii, jj] / ro,
                use_physical=True,
                ro=ro,
                vo=vo,
            )

    fig = plt.figure(figsize=(8, 16))
    skip = 10  # Make sure to keep zs symmetric!!
    scale = 35.0
    # Don't plot these
    # forces[(mRs < 5.)*(np.fabs(mzs) < 4.)]= np.nan
    forces[(mRs < 2.0) * (np.fabs(mzs) < 5.0)] = np.nan
    bovy_plot.bovy_dens2d(
        potvals.T,
        origin="lower",
        cmap="viridis",
        xrange=[Rs[0], Rs[-1]],
        yrange=[zs[0], zs[-1]],
        xlabel=r"$R\,(\mathrm{kpc})$",
        ylabel=r"$Z\,(\mathrm{kpc})$",
        contours=True,
        aspect=1.0,
    )
    plt.quiver(
        mRs[1::skip, 5:-1:skip],
        mzs[1::skip, 5:-1:skip],
        forces[1::skip, 5:-1:skip, 0],
        forces[1::skip, 5:-1:skip, 1],
        scale=scale,
    )
    # Add a few lines pointing to the GC
    for angle in tqdm(np.linspace(0.0, np.pi / 2.0, 8)):
        plt.plot((0.0, 100.0 * np.cos(angle)), (0.0, 100.0 * np.sin(angle)),
                 "k:")
        plt.plot((0.0, 100.0 * np.cos(angle)), (0.0, -100.0 * np.sin(angle)),
                 "k:")
    # Add measurements
    # Pal 5
    plt.quiver((8.0, ), (16.0, ), (-0.8, ), (-1.82, ),
               color="w",
               zorder=10,
               scale=scale)
    # GD-1
    plt.quiver(
        (12.5, ),
        (6.675, ),
        (-2.51, ),
        (-1.47, ),
        color="w",
        zorder=10,
        scale=scale,
    )
    # Disk + flat APOGEE rotation curve:
    # Use Bovy & Tremaine (2012) method for translating F_R in the plane to F_R
    # at 1.1 kpc: dFr/dz = dFz / dR
    diskrs = np.linspace(5.5, 8.5, 3)
    diskfzs = (-67.0 * np.exp(-(diskrs - 8.0) / 2.7) /
               bovy_conversion.force_in_2piGmsolpc2(220.0, 8.0) *
               bovy_conversion.force_in_kmsMyr(220.0, 8.0))
    diskfrs = (-(218.0**2.0 / diskrs) * bovy_conversion._kmsInPcMyr / 1000.0 -
               1.1 * diskfzs / 2.7)
    plt.quiver(
        diskrs,
        1.1 * np.ones_like(diskrs),
        diskfrs,
        diskfzs,
        color="w",
        zorder=10,
        scale=scale,
    )
    # Labels
    bovy_plot.bovy_text(5.8, 16.0, r"$\mathbf{Pal\ 5}$", color="w", size=17.0)
    bovy_plot.bovy_text(12.5, 7.0, r"$\mathbf{GD-1}$", color="w", size=17.0)
    bovy_plot.bovy_text(8.65,
                        0.5,
                        r"$\mathbf{disk\ stars}$",
                        color="w",
                        size=17.0)

    if savefig is not None:
        fig.savefig(savefig)

    return fig
Exemplo n.º 35
0
    def __init__(self,
                 RZPot=None,rgrid=(numpy.log(0.01),numpy.log(20.),101),
                 zgrid=(0.,1.,101),logR=True,
                 interpPot=False,interpRforce=False,interpzforce=False,
                 interpDens=False,
                 interpvcirc=False,
                 interpdvcircdr=False,
                 interpepifreq=False,interpverticalfreq=False,
                 ro=None,vo=None,
                 use_c=False,enable_c=False,zsym=True,
                 numcores=None):
        """
        NAME:

           __init__

        PURPOSE:

           Initialize an interpRZPotential instance

        INPUT:

           RZPot - RZPotential to be interpolated

           rgrid - R grid to be given to linspace as in rs= linspace(*rgrid)

           zgrid - z grid to be given to linspace as in zs= linspace(*zgrid)

           logR - if True, rgrid is in the log of R so logrs= linspace(*rgrid)

           interpPot, interpRforce, interpzforce, interpDens,interpvcirc, interpepifreq, interpverticalfreq, interpdvcircdr= if True, interpolate these functions

           use_c= use C to speed up the calculation of the grid

           enable_c= enable use of C for interpolations

           zsym= if True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g.,  zgrid=(0.,1.,101)).

           numcores= if set to an integer, use this many cores (only used for vcirc, dvcircdR, epifreq, and verticalfreq; NOT NECESSARILY FASTER, TIME TO MAKE SURE)

           ro=, vo= distance and velocity scales for translation into internal units (default from configuration file)

        OUTPUT:

           instance

        HISTORY:

           2010-07-21 - Written - Bovy (NYU)

           2013-01-24 - Started with new implementation - Bovy (IAS)

        """
        if isinstance(RZPot,interpRZPotential):
            from galpy.potential import PotentialError
            raise PotentialError('Cannot setup interpRZPotential with another interpRZPotential')
        # Propagate ro and vo
        roSet= True
        voSet= True
        if ro is None:
            if isinstance(RZPot,list):
                ro= RZPot[0]._ro
                roSet= RZPot[0]._roSet
            else:
                ro= RZPot._ro
                roSet= RZPot._roSet
        if vo is None:
            if isinstance(RZPot,list):
                vo= RZPot[0]._vo
                voSet= RZPot[0]._voSet
            else:
                vo= RZPot._vo
                voSet= RZPot._voSet
        Potential.__init__(self,amp=1.,ro=ro,vo=vo)
        # Turn off physical if it hadn't been on
        if not roSet: self._roSet= False
        if not voSet: self._voSet= False
        self._origPot= RZPot
        self._rgrid= numpy.linspace(*rgrid)
        self._logR= logR
        if self._logR:
            self._rgrid= numpy.exp(self._rgrid)
            self._logrgrid= numpy.log(self._rgrid)
        self._zgrid= numpy.linspace(*zgrid)
        self._interpPot= interpPot
        self._interpRforce= interpRforce
        self._interpzforce= interpzforce
        self._interpDens= interpDens
        self._interpvcirc= interpvcirc
        self._interpdvcircdr= interpdvcircdr
        self._interpepifreq= interpepifreq
        self._interpverticalfreq= interpverticalfreq
        self._enable_c= enable_c*ext_loaded
        self.hasC= self._enable_c
        self._zsym= zsym
        if interpPot:
            if use_c*ext_loaded:
                self._potGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid)
            else:
                from galpy.potential import evaluatePotentials
                potGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        potGrid[ii,jj]= evaluatePotentials(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._potGrid= potGrid
            if self._logR:
                self._potInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._potGrid,
                                                                 kx=3,ky=3,s=0.)
            else:
                self._potInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._potGrid,
                                                                 kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._potGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._potGrid)
        if interpRforce:
            if use_c*ext_loaded:
                self._rforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,rforce=True)
            else:
                from galpy.potential import evaluateRforces
                rforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        rforceGrid[ii,jj]= evaluateRforces(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._rforceGrid= rforceGrid
            if self._logR:
                self._rforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                    self._zgrid,
                                                                    self._rforceGrid,
                                                                    kx=3,ky=3,s=0.)
            else:
                self._rforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                    self._zgrid,
                                                                    self._rforceGrid,
                                                                    kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._rforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._rforceGrid)
        if interpzforce:
            if use_c*ext_loaded:
                self._zforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,zforce=True)
            else:
                from galpy.potential import evaluatezforces
                zforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
                for ii in range(len(self._rgrid)):
                    for jj in range(len(self._zgrid)):
                        zforceGrid[ii,jj]= evaluatezforces(self._origPot,self._rgrid[ii],self._zgrid[jj])
                self._zforceGrid= zforceGrid
            if self._logR:
                self._zforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                    self._zgrid,
                                                                    self._zforceGrid,
                                                                    kx=3,ky=3,s=0.)
            else:
                self._zforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                    self._zgrid,
                                                                    self._zforceGrid,
                                                                    kx=3,ky=3,s=0.)
            if enable_c*ext_loaded:
                self._zforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._zforceGrid)
        if interpDens:
            from galpy.potential import evaluateDensities
            densGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
            for ii in range(len(self._rgrid)):
                for jj in range(len(self._zgrid)):
                    densGrid[ii,jj]= evaluateDensities(self._origPot,self._rgrid[ii],self._zgrid[jj])
            self._densGrid= densGrid
            if self._logR:
                self._densInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                  self._zgrid,
                                                                  numpy.log(self._densGrid+10.**-10.),
                                                                  kx=3,ky=3,s=0.)
            else:
                self._densInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                  self._zgrid,
                                                                  numpy.log(self._densGrid+10.**-10.),
                                                                  kx=3,ky=3,s=0.)
        if interpvcirc:
            from galpy.potential import vcirc
            if not numcores is None:
                self._vcircGrid= multi.parallel_map((lambda x: vcirc(self._origPot,self._rgrid[x])),
                                                    list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._vcircGrid= numpy.array([vcirc(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._vcircGrid,k=3)
            else:
                self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._vcircGrid,k=3)
        if interpdvcircdr:
            from galpy.potential import dvcircdR
            if not numcores is None:
                self._dvcircdrGrid= multi.parallel_map((lambda x: dvcircdR(self._origPot,self._rgrid[x])),
                                                       list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._dvcircdrGrid= numpy.array([dvcircdR(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._dvcircdrGrid,k=3)
            else:
                self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._dvcircdrGrid,k=3)
        if interpepifreq:
            from galpy.potential import epifreq
            if not numcores is None:
                self._epifreqGrid= numpy.array(multi.parallel_map((lambda x: epifreq(self._origPot,self._rgrid[x])),
                                                      list(range(len(self._rgrid))),numcores=numcores))
            else:
                self._epifreqGrid= numpy.array([epifreq(self._origPot,r) for r in self._rgrid])
            indx= True^numpy.isnan(self._epifreqGrid)
            if numpy.sum(indx) < 4:
                if self._logR:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=1)
                else:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=1)
            else:
                if self._logR:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=3)
                else:
                    self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=3)
        if interpverticalfreq:
            from galpy.potential import verticalfreq
            if not numcores is None:
                self._verticalfreqGrid= multi.parallel_map((lambda x: verticalfreq(self._origPot,self._rgrid[x])),
                                                       list(range(len(self._rgrid))),numcores=numcores)
            else:
                self._verticalfreqGrid= numpy.array([verticalfreq(self._origPot,r) for r in self._rgrid])
            if self._logR:
                self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._verticalfreqGrid,k=3)
            else:
                self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._verticalfreqGrid,k=3)
        return None
Exemplo n.º 36
0
 def __init__(self,
              RZPot=None,rgrid=(0.01,2.,101),zgrid=(0.,0.2,101),logR=False,
              interpPot=False,interpRforce=False,interpzforce=False,
              interpDens=False,
              interpvcirc=False,
              interpdvcircdr=False,
              interpepifreq=False,interpverticalfreq=False,
              use_c=False,enable_c=False,zsym=True,
              numcores=None):
     """
     NAME:
        __init__
     PURPOSE:
        Initialize an interpRZPotential instance
     INPUT:
        RZPot - RZPotential to be interpolated
        rgrid - R grid to be given to linspace
        zgrid - z grid to be given to linspace
        logR - if True, rgrid is in the log of R
        interpPot, interpRfoce, interpzforce, interpDens,interpvcirc, interpeopifreq, interpverticalfreq, interpdvcircdr= if True, interpolate these functions
        use_c= use C to speed up the calculation
        enable_c= enable use of C for interpolations
        zsym= if True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g.,  zgrid=(0.,1.,101)).
        numcores= if set to an integer, use this many cores (only used for vcirc, dvcircdR, epifreq, and verticalfreq; NOT NECESSARILY FASTER, TIME TO MAKE SURE)
     OUTPUT:
        instance
     HISTORY:
        2010-07-21 - Written - Bovy (NYU)
        2013-01-24 - Started with new implementation - Bovy (IAS)
     """
     Potential.__init__(self,amp=1.)
     self.hasC= True
     self._origPot= RZPot
     self._rgrid= numpy.linspace(*rgrid)
     self._logR= logR
     if self._logR:
         self._rgrid= numpy.exp(self._rgrid)
         self._logrgrid= numpy.log(self._rgrid)
     self._zgrid= numpy.linspace(*zgrid)
     self._interpPot= interpPot
     self._interpRforce= interpRforce
     self._interpzforce= interpzforce
     self._interpDens= interpDens
     self._interpvcirc= interpvcirc
     self._interpdvcircdr= interpdvcircdr
     self._interpepifreq= interpepifreq
     self._interpverticalfreq= interpverticalfreq
     self._enable_c= enable_c*ext_loaded
     self._zsym= zsym
     if interpPot:
         if use_c*ext_loaded:
             self._potGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid)
         else:
             from galpy.potential import evaluatePotentials
             potGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     potGrid[ii,jj]= evaluatePotentials(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._potGrid= potGrid
         if self._logR:
             self._potInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                              self._zgrid,
                                                              self._potGrid,
                                                              kx=3,ky=3,s=0.)
         else:
             self._potInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                              self._zgrid,
                                                              self._potGrid,
                                                              kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._potGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._potGrid)
     if interpRforce:
         if use_c*ext_loaded:
             self._rforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,rforce=True)
         else:
             from galpy.potential import evaluateRforces
             rforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     rforceGrid[ii,jj]= evaluateRforces(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._rforceGrid= rforceGrid
         if self._logR:
             self._rforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._rforceGrid,
                                                                 kx=3,ky=3,s=0.)
         else:
             self._rforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._rforceGrid,
                                                                 kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._rforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._rforceGrid)
     if interpzforce:
         if use_c*ext_loaded:
             self._zforceGrid, err= calc_potential_c(self._origPot,self._rgrid,self._zgrid,zforce=True)
         else:
             from galpy.potential import evaluatezforces
             zforceGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     zforceGrid[ii,jj]= evaluatezforces(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._zforceGrid= zforceGrid
         if self._logR:
             self._zforceInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                                 self._zgrid,
                                                                 self._zforceGrid,
                                                                 kx=3,ky=3,s=0.)
         else:
             self._zforceInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                                 self._zgrid,
                                                                 self._zforceGrid,
                                                                 kx=3,ky=3,s=0.)
         if enable_c*ext_loaded:
             self._zforceGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._zforceGrid)
     if interpDens:
         if False:
             raise NotImplementedError("Using C to calculate an interpolation grid for the density is not supported currently")
             self._densGrid, err= calc_dens_c(self._origPot,self._rgrid,self._zgrid)
         else:
             from galpy.potential import evaluateDensities
             densGrid= numpy.zeros((len(self._rgrid),len(self._zgrid)))
             for ii in range(len(self._rgrid)):
                 for jj in range(len(self._zgrid)):
                     densGrid[ii,jj]= evaluateDensities(self._rgrid[ii],self._zgrid[jj],self._origPot)
             self._densGrid= densGrid
         if self._logR:
             self._densInterp= interpolate.RectBivariateSpline(self._logrgrid,
                                                               self._zgrid,
                                                               numpy.log(self._densGrid+10.**-10.),
                                                               kx=3,ky=3,s=0.)
         else:
             self._densInterp= interpolate.RectBivariateSpline(self._rgrid,
                                                               self._zgrid,
                                                               numpy.log(self._densGrid+10.**-10.),
                                                               kx=3,ky=3,s=0.)
         if False:
             self._densGrid_splinecoeffs= calc_2dsplinecoeffs_c(self._densGrid)
     if interpvcirc:
         from galpy.potential import vcirc
         if not numcores is None:
             self._vcircGrid= multi.parallel_map((lambda x: vcirc(self._origPot,self._rgrid[x])),
                                                 range(len(self._rgrid)),numcores=numcores)
         else:
             self._vcircGrid= numpy.array([vcirc(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._vcircGrid,k=3)
         else:
             self._vcircInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._vcircGrid,k=3)
     if interpdvcircdr:
         from galpy.potential import dvcircdR
         if not numcores is None:
             self._dvcircdrGrid= multi.parallel_map((lambda x: dvcircdR(self._origPot,self._rgrid[x])),
                                                    range(len(self._rgrid)),numcores=numcores)
         else:
             self._dvcircdrGrid= numpy.array([dvcircdR(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._dvcircdrGrid,k=3)
         else:
             self._dvcircdrInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._dvcircdrGrid,k=3)
     if interpepifreq:
         from galpy.potential import epifreq
         if not numcores is None:
             self._epifreqGrid= multi.parallel_map((lambda x: epifreq(self._origPot,self._rgrid[x])),
                                                   range(len(self._rgrid)),numcores=numcores)
         else:
             self._epifreqGrid= numpy.array([epifreq(self._origPot,r) for r in self._rgrid])
         indx= True-numpy.isnan(self._epifreqGrid)
         if numpy.sum(indx) < 4:
             if self._logR:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=1)
             else:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=1)
         else:
             if self._logR:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid[indx],self._epifreqGrid[indx],k=3)
             else:
                 self._epifreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid[indx],self._epifreqGrid[indx],k=3)
     if interpverticalfreq:
         from galpy.potential import verticalfreq
         if not numcores is None:
             self._verticalfreqGrid= multi.parallel_map((lambda x: verticalfreq(self._origPot,self._rgrid[x])),
                                                    range(len(self._rgrid)),numcores=numcores)
         else:
             self._verticalfreqGrid= numpy.array([verticalfreq(self._origPot,r) for r in self._rgrid])
         if self._logR:
             self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._logrgrid,self._verticalfreqGrid,k=3)
         else:
             self._verticalfreqInterp= interpolate.InterpolatedUnivariateSpline(self._rgrid,self._verticalfreqGrid,k=3)
     return None
Exemplo n.º 37
0
 def my_f_cylr(self, r, ang, *args, **kwargs):
     """Return the force in cylindical R direction at (r, theta)"""
     z, r_cyl = self.spherical_to_cylindrical(r, ang)
     return evaluateRforces(self.func, r_cyl / self.R0,
                            z / self.R0) * self.force_to_kpckms2
Exemplo n.º 38
0
def fdotdotSB3calBH(ldeg, bdeg, dkpc, mul, mub, vrad):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    Rpkpc = par.Rpkpc(ldeg, bdeg, dkpc)

    zkpc = par.z(ldeg, bdeg, dkpc)

    fex_pl = excGalBH.Expl(ldeg, bdeg, dkpc)

    fex_z = excGalBH.Exz(ldeg, bdeg, dkpc)

    fex_shk = Shk.Exshk(dkpc, mul, mub)

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    appl = evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) /
                                          Rpkpc) * math.sin(l)

    aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l))
    aTb1 = appl * coslam * math.sin(b) - apz * math.cos(b) + aspl * math.cos(
        l) * math.sin(b)
    aTnet1 = (aTl1**2. + aTb1**2.)**(0.5)
    alphaV1 = math.atan2(mub, mul) / par.degtorad
    alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad
    if alphaV1 < 0.:
        alphaV = 360. + alphaV1
    else:
        alphaV = alphaV1

    if alphaA1 < 0.:
        alphaA = 360. + alphaA1
    else:
        alphaA = alphaA1
    alpha = abs(alphaA - alphaV)

    aT1 = 2. * appl * aspl * coslpluslam
    aT2 = (c * (fex_pl + fex_z))**2.
    aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2
    #if aTsq < 0.0:
    aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5

    yrts = par.yrts
    c = par.c
    mastorad = par.mastorad

    #tsbvrad = (1./c)*(3.*(1000.0*vrad)*(((mastorad/yrts)*muT)**2.))
    tsbt = (1. / c) * (aT * ((mastorad / yrts) * muT) * math.cos(alpha) - 3. *
                       (1000.0 * vrad) * (((mastorad / yrts) * muT)**2.))
    return tsbt
Exemplo n.º 39
0
def impulse_deltav_general_orbitintegration(v,x,b,w,x0,v0,pot,tmax,galpot,
                                            tmaxfac=10.,nsamp=1000,
                                            integrate_method='symplec4_c'):
    """
    NAME:

       impulse_deltav_general_orbitintegration

    PURPOSE:

       calculate the delta velocity to due an encounter with a general spherical potential NOT in the impulse approximation by integrating each particle in the underlying galactic potential; allows for arbitrary velocity vectors and arbitrary shaped streams.

    INPUT:

       v - velocity of the stream (nstar,3)

       x - position along the stream (nstar,3)

       b - impact parameter

       w - velocity of the subhalo (3)

       x0 - position of closest approach (3)

       v0 - velocity of stream at closest approach (3)

       pot - Potential object or list thereof (should be spherical)

       tmax - maximum integration time

       galpot - galpy Potential object or list thereof

       nsamp(1000) - number of forward integration points

       integrate_method= ('symplec4_c') orbit integrator to use (see Orbit.integrate)

    OUTPUT:

       deltav (nstar,3)

    HISTORY:

       2015-08-17 - SANDERS

    """
    if len(v.shape) == 1: v= numpy.reshape(v,(1,3))
    if len(x.shape) == 1: x= numpy.reshape(x,(1,3))
    nstar,ndim=numpy.shape(v)
    b0 = numpy.cross(w,v0)
    b0 *= b/numpy.sqrt(numpy.sum(b0**2))
    times = numpy.linspace(0.,tmax,nsamp)
    xres = numpy.zeros(shape=(len(x),nsamp*2-1,3))
    R, phi, z= bovy_coords.rect_to_cyl(x[:,0],x[:,1],x[:,2])
    vR, vp, vz= bovy_coords.rect_to_cyl_vec(v[:,0],v[:,1],v[:,2],
                                            R,phi,z,cyl=True)
    for i in range(nstar):
        o = Orbit([R[i],vR[i],vp[i],z[i],vz[i],phi[i]])
        o.integrate(times,galpot,method=integrate_method)
        xres[i,nsamp:,0]=o.x(times)[1:]
        xres[i,nsamp:,1]=o.y(times)[1:]
        xres[i,nsamp:,2]=o.z(times)[1:]
        oreverse = o.flip()
        oreverse.integrate(times,galpot,method=integrate_method)
        xres[i,:nsamp,0]=oreverse.x(times)[::-1]
        xres[i,:nsamp,1]=oreverse.y(times)[::-1]
        xres[i,:nsamp,2]=oreverse.z(times)[::-1]
    times = numpy.concatenate((-times[::-1],times[1:]))
    nsamp = len(times)
    X = b0+xres-x0-numpy.outer(times,w)
    r = numpy.sqrt(numpy.sum(X**2,axis=-1))
    acc = (numpy.reshape(evaluateRforces(r.flatten(),0.,pot),(nstar,nsamp))/r)[:,:,numpy.newaxis]*X
    return integrate.simps(acc,x=times,axis=1)
Exemplo n.º 40
0
def spiral_arms_potential(FR_frac=1.,
                          t_on=-5.,
                          tgrow=2,
                          tstream=5.,
                          axi_pot=MWPotential2014,
                          cos=True,
                          N=2,
                          pat_speed=24.5,
                          pitch_angle=9.9,
                          r_ref=8.,
                          Rs=7.,
                          phi0=26.,
                          H=0.3):

    phi0 = np.radians(phi0)
    omega = pat_speed * (ro / vo)
    alpha = numpy.radians(pitch_angle)
    r_ref /= ro
    Rs /= ro
    H /= ro

    # percentage of the radial force to set the amplitude of the spiral
    FR_frac = FR_frac * 0.01

    if cos:
        Cs = [8. / (3. * numpy.pi), 0.5, 8. / (15. * numpy.pi)]

    else:
        Cs = [1]

    #compute max radial force for amp=1
    pp = np.linspace(0., 2. * np.pi, 1000)
    FR_nonaxi = []
    spiral_pot_amp1 = SpiralArmsPotential(amp=1.,
                                          N=N,
                                          omega=omega,
                                          alpha=alpha,
                                          phi_ref=phi0,
                                          r_ref=r_ref,
                                          H=H,
                                          Rs=Rs,
                                          Cs=Cs)
    turn_physical_off(spiral_pot_amp1)

    for ii in range(len(pp)):
        FR_nonaxi.append(
            potential.evaluateRforces(spiral_pot_amp1,
                                      R=8. / ro,
                                      z=0.,
                                      phi=pp[ii],
                                      t=0.))

    interp_FR_nonaxi = interpolate.InterpolatedUnivariateSpline(pp, FR_nonaxi)

    #fmin, because radial force is negative
    max_phi = optimize.fmin(interp_FR_nonaxi, 0., disp=0)

    max_FR_nonaxi = interp_FR_nonaxi(max_phi)[0]

    #compute the radial force due to the axisymmetric potential
    FR_axi = potential.evaluateRforces(axi_pot, R=8. / ro, z=0., t=0.)

    #compute the correct amplitude
    amp = numpy.abs(FR_frac * FR_axi / max_FR_nonaxi)

    #setup spiral potential with correct amplitude
    spiralpot = SpiralArmsPotential(amp=amp,
                                    N=N,
                                    omega=omega,
                                    alpha=alpha,
                                    phi_ref=phi0,
                                    r_ref=r_ref,
                                    H=H,
                                    Rs=Rs,
                                    Cs=Cs)

    #grow the spirals

    Tspiral = 2. * np.pi / np.abs(omega)  #bar period in galpy units.
    t_on = t_on / bovy_conversion.time_in_Gyr(vo, ro)
    tsteady = tgrow * Tspiral
    tform = t_on - tsteady  #- because past is negative

    #if t_on >= t_pal5_age, then Pal 5 sees the spirals always on
    if np.abs(t_on) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        print('not growing spiral')
        MWspiralpot = axi_pot + [spiralpot]
        turn_physical_off(MWspiralpot)

        return (MWspiralpot)

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) >= tstream:
        print("tform > age of stream")

    elif np.abs(tform) * bovy_conversion.time_in_Gyr(vo, ro) < tstream:
        print('growing spiral')

        spiralpot_grow = DehnenWrap(amp=1.,
                                    pot=spiralpot,
                                    tform=tform,
                                    tsteady=tsteady)
        turn_physical_off(spiralpot_grow)
        MWspiralpot = axi_pot + [spiralpot_grow]
        return MWspiralpot
Exemplo n.º 41
0
def fdotdotexcwBHcal(ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, f, fdotobs, vrad,
                     fex_pl, fex_z, fex_shk):

    Rskpc = par.Rskpc
    Vs = par.Vs
    conversion = par.conversion
    yrts = par.yrts
    c = par.c
    kpctom = par.kpctom
    Rs = Rskpc * kpctom
    mastorad = par.mastorad

    normpottoSI = par.normpottoSI
    normForcetoSI = par.normForcetoSI
    normjerktoSI = par.normjerktoSI

    b = bdeg * par.degtorad
    l = ldeg * par.degtorad

    fex_tot = fex_pl + fex_z + fex_shk

    #mub = mu_alpha #mas/yr
    #mul = mu_delta

    muT = (mub**2. + mul**2.)**0.5
    #MWPotential2014= [MWPotential2014,KeplerPotential(amp=4*10**6./bovy_conversion.mass_in_msol(par.Vs,par.Rskpc))]
    MWPot = [
        MWPotential2014,
        KeplerPotential(amp=4 * 10**6. /
                        bovy_conversion.mass_in_msol(par.Vs, par.Rskpc))
    ]

    appl = evaluateRforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI
    aspl = evaluateRforces(MWPot, Rskpc / Rskpc, 0.0 / Rskpc) * normForcetoSI
    apz = evaluatezforces(MWPot, Rpkpc / Rskpc, zkpc / Rskpc) * normForcetoSI

    be = (dkpc / Rskpc) * math.cos(b) - math.cos(l)
    coslam = be * (Rskpc / Rpkpc)
    coslpluslam = math.cos(l) * coslam - (Rskpc * math.sin(l) /
                                          Rpkpc) * math.sin(l)

    aTl1 = -(appl * (Rskpc * math.sin(l) / Rpkpc) - aspl * math.sin(l))
    aTb1 = appl * coslam * math.sin(b) - apz * math.cos(b) + aspl * math.cos(
        l) * math.sin(b)
    aTnet1 = (aTl1**2. + aTb1**2.)**(0.5)
    alphaV1 = math.atan2(mub, mul) / par.degtorad
    alphaA1 = math.atan2(aTb1, aTl1) / par.degtorad
    if alphaV1 < 0.:
        alphaV = 360. + alphaV1
    else:
        alphaV = alphaV1

    if alphaA1 < 0.:
        alphaA = 360. + alphaA1
    else:
        alphaA = alphaA1
    alpha = abs(alphaA - alphaV)

    aT1 = 2. * appl * aspl * coslpluslam
    aT2 = (c * (fex_pl + fex_z))**2.
    aTsq = appl**2. + aspl**2. + aT1 + apz**2. - aT2
    #if aTsq < 0.0:
    aT = (appl**2. + aspl**2. + aT1 + apz**2. - aT2)**0.5

    Combterm = fdotdotSB1cal(
        ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, vrad, coslam,
        alpha, appl, apz, aspl, aT, MWPot) + fdotdotSB2cal(
            ldeg, bdeg, dkpc, mul, mub, Rpkpc, zkpc, fex_pl, fex_z, fex_shk,
            appl, apz, aspl) + fdotdotSB3cal(vrad, aT, muT, alpha)

    fddotfex = -Combterm + fdotdotSB4cal(f, fdotobs, fex_pl, fex_z, fex_shk)

    #fdotint = fdotobs-fs*fex_tot
    #fddotint = fddotobs-fs*fddotfex

    return fddotfex
Exemplo n.º 42
0
    def sample(self, n, returndt=False, integrate=True, xy=False, lb=False):
        """
        NAME:

            sample

        PURPOSE:

            sample from the DF

        INPUT:

            n - number of points to return

            returndt= (False) if True, also return the time since the star was stripped
            
            integrate= (True) if True, integrate the orbits to the present time, if False, return positions at stripping (probably want to combine with returndt=True then to make sense of them!)

            xy= (False) if True, return Galactocentric rectangular coordinates

            lb= (False) if True, return Galactic l,b,d,vlos,pmll,pmbb coordinates

        OUTPUT:

            (R,vR,vT,z,vz,phi) of points on the stream in 6,N array

        HISTORY:

            2018-07-31 - Written - Bovy (IAS)

        """
        if xy or lb:
            raise NotImplementedError(
                "xy=True and lb=True options currently not implemented")
        # First sample times
        dt = numpy.random.uniform(size=n) * self._tdisrupt
        # Build all rotation matrices
        rot, rot_inv = self._setup_rot(dt)
        # Compute progenitor position in the instantaneous frame
        xyzpt = numpy.einsum(
            'ijk,ik->ij', rot,
            numpy.array([
                self._progenitor.x(-dt),
                self._progenitor.y(-dt),
                self._progenitor.z(-dt)
            ]).T)
        vxyzpt = numpy.einsum(
            'ijk,ik->ij', rot,
            numpy.array([
                self._progenitor.vx(-dt),
                self._progenitor.vy(-dt),
                self._progenitor.vz(-dt)
            ]).T)
        Rpt, phipt, Zpt = bovy_coords.rect_to_cyl(xyzpt[:, 0], xyzpt[:, 1],
                                                  xyzpt[:, 2])
        vRpt, vTpt, vZpt = bovy_coords.rect_to_cyl_vec(vxyzpt[:, 0],
                                                       vxyzpt[:, 1],
                                                       vxyzpt[:, 2],
                                                       Rpt,
                                                       phipt,
                                                       Zpt,
                                                       cyl=True)
        # Sample positions and velocities in the instantaneous frame
        k = self._meankvec + numpy.random.normal(
            size=n)[:, numpy.newaxis] * self._sigkvec
        try:
            rtides = rtide(self._rtpot,
                           Rpt,
                           Zpt,
                           phi=phipt,
                           t=-dt,
                           M=self._progenitor_mass,
                           use_physical=False)
            vcs = numpy.sqrt(-Rpt * evaluateRforces(
                self._rtpot, Rpt, Zpt, phi=phipt, t=-dt, use_physical=False))
        except (ValueError, TypeError):
            rtides = numpy.array([
                rtide(self._rtpot,
                      Rpt[ii],
                      Zpt[ii],
                      phi=phipt[ii],
                      t=-dt[ii],
                      M=self._progenitor_mass,
                      use_physical=False) for ii in range(len(Rpt))
            ])
            vcs = numpy.array([
                numpy.sqrt(-Rpt[ii] * evaluateRforces(self._rtpot,
                                                      Rpt[ii],
                                                      Zpt[ii],
                                                      phi=phipt[ii],
                                                      t=-dt[ii],
                                                      use_physical=False))
                for ii in range(len(Rpt))
            ])
        rtides_as_frac = rtides / Rpt
        RpZst = numpy.array([
            Rpt + k[:, 0] * rtides, phipt + k[:, 5] * rtides_as_frac,
            k[:, 3] * rtides_as_frac
        ]).T
        vRTZst = numpy.array([
            vRpt * (1. + k[:, 1]), vTpt + k[:, 2] * vcs * rtides_as_frac,
            k[:, 4] * vcs * rtides_as_frac
        ]).T
        # Now rotate these back to the galactocentric frame
        xst, yst, zst = bovy_coords.cyl_to_rect(RpZst[:, 0], RpZst[:, 1],
                                                RpZst[:, 2])
        vxst, vyst, vzst = bovy_coords.cyl_to_rect_vec(vRTZst[:, 0], vRTZst[:,
                                                                            1],
                                                       vRTZst[:, 2], RpZst[:,
                                                                           1])
        xyzs = numpy.einsum('ijk,ik->ij', rot_inv,
                            numpy.array([xst, yst, zst]).T)
        vxyzs = numpy.einsum('ijk,ik->ij', rot_inv,
                             numpy.array([vxst, vyst, vzst]).T)
        Rs, phis, Zs = bovy_coords.rect_to_cyl(xyzs[:, 0], xyzs[:, 1], xyzs[:,
                                                                            2])
        vRs, vTs, vZs = bovy_coords.rect_to_cyl_vec(vxyzs[:, 0],
                                                    vxyzs[:, 1],
                                                    vxyzs[:, 2],
                                                    Rs,
                                                    phis,
                                                    Zs,
                                                    cyl=True)
        out = numpy.empty((6, n))
        if integrate:
            # Now integrate the orbits
            for ii in range(n):
                o = Orbit(
                    [Rs[ii], vRs[ii], vTs[ii], Zs[ii], vZs[ii], phis[ii]])
                o.integrate(numpy.linspace(-dt[ii], 0., 10001), self._pot)
                o = o(0.)
                out[:, ii] = [o.R(), o.vR(), o.vT(), o.z(), o.vz(), o.phi()]
        else:
            out[0] = Rs
            out[1] = vRs
            out[2] = vTs
            out[3] = Zs
            out[4] = vZs
            out[5] = phis
        if returndt:
            return (out, dt)
        else:
            return out