Exemplo n.º 1
0
    def Er(self,R,z,vR,vz,E,Lz,sinh2u0,u0):
        """
        NAME:
           Er
        PURPOSE:
           calculate the 'radial energy'
        INPUT:
           R, z, vR, vz - coordinates
           E - energy
           Lz - angular momentum
           sinh2u0, u0 - sinh^2 and u0
        OUTPUT:
           Er
        HISTORY:
           2012-11-29 - Written - Bovy (IAS)
        """                           
        u,v= bovy_coords.Rz_to_uv(R,z,self._delta)
        pu= (vR*numpy.cosh(u)*numpy.sin(v)
             +vz*numpy.sinh(u)*numpy.cos(v)) #no delta, bc we will divide it out
        out= (pu**2./2.+Lz**2./2./self._delta**2.*(1./numpy.sinh(u)**2.-1./sinh2u0)
              -E*(numpy.sinh(u)**2.-sinh2u0)
              +(numpy.sinh(u)**2.+1.)*actionAngleStaeckel.potentialStaeckel(u,numpy.pi/2.,self._pot,self._delta)
              -(sinh2u0+1.)*actionAngleStaeckel.potentialStaeckel(u0,numpy.pi/2.,self._pot,self._delta))
#              +(numpy.sinh(u)**2.+numpy.sin(v)**2.)*actionAngleStaeckel.potentialStaeckel(u,v,self._pot,self._delta)
#              -(sinh2u0+numpy.sin(v)**2.)*actionAngleStaeckel.potentialStaeckel(u0,v,self._pot,self._delta))
        return out
Exemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     """
     NAME:
        __init__
     PURPOSE:
        initialize an actionAngleStaeckelSingle object
     INPUT:
        Either:
           a) R,vR,vT,z,vz
           b) Orbit instance: initial condition used if that's it, orbit(t)
              if there is a time given as well
           pot= potential or list of potentials
     OUTPUT:
     HISTORY:
        2012-11-27 - Written - Bovy (IAS)
     """
     actionAngle.__init__(self, *args, **kwargs)
     if not 'pot' in kwargs:  #pragma: no cover
         raise IOError("Must specify pot= for actionAngleStaeckelSingle")
     self._pot = kwargs['pot']
     if not 'delta' in kwargs:  #pragma: no cover
         raise IOError("Must specify delta= for actionAngleStaeckel")
     self._delta = kwargs['delta']
     #Pre-calculate everything
     self._ux, self._vx = bovy_coords.Rz_to_uv(self._R,
                                               self._z,
                                               delta=self._delta)
     self._sinvx = nu.sin(self._vx)
     self._cosvx = nu.cos(self._vx)
     self._coshux = nu.cosh(self._ux)
     self._sinhux = nu.sinh(self._ux)
     self._pux = self._delta * (self._vR * self._coshux * self._sinvx +
                                self._vz * self._sinhux * self._cosvx)
     self._pvx = self._delta * (self._vR * self._sinhux * self._cosvx -
                                self._vz * self._coshux * self._sinvx)
     EL = self.calcEL()
     self._E = EL[0]
     self._Lz = EL[1]
     #Determine umin and umax
     self._u0 = kwargs.pop(
         'u0', self._ux)  #u0 as defined by Binney does not matter for a
     #single action evaluation, so we don't determine it here
     self._sinhu0 = nu.sinh(self._u0)
     self._potu0v0 = potentialStaeckel(self._u0, self._vx, self._pot,
                                       self._delta)
     self._I3U= self._E*self._sinhux**2.-self._pux**2./2./self._delta**2.\
         -self._Lz**2./2./self._delta**2./self._sinhux**2.
     self._potupi2 = potentialStaeckel(self._ux, nu.pi / 2., self._pot,
                                       self._delta)
     dV = (self._coshux**2. * self._potupi2 -
           (self._sinhux**2. + self._sinvx**2.) *
           potentialStaeckel(self._ux, self._vx, self._pot, self._delta))
     self._I3V= -self._E*self._sinvx**2.+self._pvx**2./2./self._delta**2.\
         +self._Lz**2./2./self._delta**2./self._sinvx**2.\
         -dV
     self.calcUminUmax()
     self.calcVmin()
     return None
Exemplo n.º 3
0
def actionAngleStaeckel_c(pot, delta, R, vR, vT, z, vz, u0=None, order=10):
    """
    NAME:
       actionAngleStaeckel_c
    PURPOSE:
       Use C to calculate actions using the Staeckel approximation
    INPUT:
       pot - Potential or list of such instances
       delta - focal length of prolate spheroidal coordinates
       R, vR, vT, z, vz - coordinates (arrays)
       u0= (None) if set, u0 to use
       order= (10) order of Gauss-Legendre integration of the relevant integrals
    OUTPUT:
       (jr,jz,err)
       jr,jz : array, shape (len(R))
       err - non-zero if error occured
    HISTORY:
       2012-12-01 - Written - Bovy (IAS)
    """
    if u0 is None:
        u0, dummy = bovy_coords.Rz_to_uv(R, z, delta=numpy.atleast_1d(delta))
    #Parse the potential
    npot, pot_type, pot_args = _parse_pot(pot, potforactions=True)

    #Parse delta
    delta = numpy.atleast_1d(delta)
    ndelta = len(delta)

    #Set up result arrays
    jr = numpy.empty(len(R))
    jz = numpy.empty(len(R))
    err = ctypes.c_int(0)

    #Set up the C code
    ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE')
    actionAngleStaeckel_actionsFunc = _lib.actionAngleStaeckel_actions
    actionAngleStaeckel_actionsFunc.argtypes = [
        ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.int32, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ctypes.POINTER(ctypes.c_int)
    ]

    #Array requirements, first store old order
    f_cont = [
        R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'],
        vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'],
        vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'],
        delta.flags['F_CONTIGUOUS']
    ]
    R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W'])
    vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W'])
    vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W'])
    z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W'])
    vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W'])
    u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W'])
    delta = numpy.require(delta, dtype=numpy.float64, requirements=['C', 'W'])
    jr = numpy.require(jr, dtype=numpy.float64, requirements=['C', 'W'])
    jz = numpy.require(jz, dtype=numpy.float64, requirements=['C', 'W'])

    #Run the C code
    actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0,
                                    ctypes.c_int(npot), pot_type, pot_args,
                                    ctypes.c_int(ndelta), delta,
                                    ctypes.c_int(order), jr, jz,
                                    ctypes.byref(err))

    #Reset input arrays
    if f_cont[0]: R = numpy.asfortranarray(R)
    if f_cont[1]: vR = numpy.asfortranarray(vR)
    if f_cont[2]: vT = numpy.asfortranarray(vT)
    if f_cont[3]: z = numpy.asfortranarray(z)
    if f_cont[4]: vz = numpy.asfortranarray(vz)
    if f_cont[5]: u0 = numpy.asfortranarray(u0)
    if f_cont[6]: delta = numpy.asfortranarray(delta)

    return (jr, jz, err.value)
Exemplo n.º 4
0
def actionAngleUminUmaxVminStaeckel_c(pot, delta, R, vR, vT, z, vz, u0=None):
    """
    NAME:
       actionAngleUminUmaxVminStaeckel_c
    PURPOSE:
       Use C to calculate umin, umax, and vmin using the Staeckel approximation
    INPUT:
       pot - Potential or list of such instances
       delta - focal length of prolate spheroidal coordinates
       R, vR, vT, z, vz - coordinates (arrays)
    OUTPUT:
       (umin,umax,vmin,err)
       umin,umax,vmin : array, shape (len(R))
       err - non-zero if error occured
    HISTORY:
       2017-12-12 - Written - Bovy (UofT)
    """
    if u0 is None:
        u0, dummy = bovy_coords.Rz_to_uv(R, z, delta=numpy.atleast_1d(delta))
    #Parse the potential
    from galpy.orbit.integrateFullOrbit import _parse_pot
    npot, pot_type, pot_args = _parse_pot(pot, potforactions=True)

    #Parse delta
    delta = numpy.atleast_1d(delta)
    ndelta = len(delta)

    #Set up result arrays
    umin = numpy.empty(len(R))
    umax = numpy.empty(len(R))
    vmin = numpy.empty(len(R))
    err = ctypes.c_int(0)

    #Set up the C code
    ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE')
    actionAngleStaeckel_actionsFunc = _lib.actionAngleStaeckel_uminUmaxVmin
    actionAngleStaeckel_actionsFunc.argtypes = [
        ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.int32, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ctypes.POINTER(ctypes.c_int)
    ]

    #Array requirements, first store old order
    f_cont = [
        R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'],
        vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'],
        vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS'],
        delta.flags['F_CONTIGUOUS']
    ]
    R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W'])
    vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W'])
    vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W'])
    z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W'])
    vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W'])
    u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W'])
    delta = numpy.require(delta, dtype=numpy.float64, requirements=['C', 'W'])
    umin = numpy.require(umin, dtype=numpy.float64, requirements=['C', 'W'])
    umax = numpy.require(umax, dtype=numpy.float64, requirements=['C', 'W'])
    vmin = numpy.require(vmin, dtype=numpy.float64, requirements=['C', 'W'])

    #Run the C code
    actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0,
                                    ctypes.c_int(npot), pot_type, pot_args,
                                    ctypes.c_int(ndelta), delta, umin, umax,
                                    vmin, ctypes.byref(err))

    #Reset input arrays
    if f_cont[0]: R = numpy.asfortranarray(R)
    if f_cont[1]: vR = numpy.asfortranarray(vR)
    if f_cont[2]: vT = numpy.asfortranarray(vT)
    if f_cont[3]: z = numpy.asfortranarray(z)
    if f_cont[4]: vz = numpy.asfortranarray(vz)
    if f_cont[5]: u0 = numpy.asfortranarray(u0)
    if f_cont[6]: delta = numpy.asfortranarray(delta)

    return (umin, umax, vmin, err.value)
Exemplo n.º 5
0
def actionAngleFreqAngleStaeckel_c(pot, delta, R, vR, vT, z, vz, phi, u0=None):
    """
    NAME:
       actionAngleFreqAngleStaeckel_c
    PURPOSE:
       Use C to calculate actions, frequencies, and angles
       using the Staeckel approximation
    INPUT:
       pot - Potential or list of such instances
       delta - focal length of prolate spheroidal coordinates
       R, vR, vT, z, vz, phi - coordinates (arrays)
    OUTPUT:
       (jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez,err)
       jr,jz,Omegar,Omegaphi,Omegaz,Angler,Anglephi,Anglez : array, shape (len(R))
       err - non-zero if error occured
    HISTORY:
       2013-08-27 - Written - Bovy (IAS)
    """
    if u0 is None:
        u0, dummy = bovy_coords.Rz_to_uv(R, z, delta=delta)
    #Parse the potential
    npot, pot_type, pot_args = _parse_pot(pot, potforactions=True)

    #Set up result arrays
    jr = numpy.empty(len(R))
    jz = numpy.empty(len(R))
    Omegar = numpy.empty(len(R))
    Omegaphi = numpy.empty(len(R))
    Omegaz = numpy.empty(len(R))
    Angler = numpy.empty(len(R))
    Anglephi = numpy.empty(len(R))
    Anglez = numpy.empty(len(R))
    err = ctypes.c_int(0)

    #Set up the C code
    ndarrayFlags = ('C_CONTIGUOUS', 'WRITEABLE')
    actionAngleStaeckel_actionsFunc = _lib.actionAngleStaeckel_actionsFreqsAngles
    actionAngleStaeckel_actionsFunc.argtypes = [
        ctypes.c_int,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_int,
        ndpointer(dtype=numpy.int32, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags), ctypes.c_double,
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ndpointer(dtype=numpy.float64, flags=ndarrayFlags),
        ctypes.POINTER(ctypes.c_int)
    ]

    #Array requirements, first store old order
    f_cont = [
        R.flags['F_CONTIGUOUS'], vR.flags['F_CONTIGUOUS'],
        vT.flags['F_CONTIGUOUS'], z.flags['F_CONTIGUOUS'],
        vz.flags['F_CONTIGUOUS'], u0.flags['F_CONTIGUOUS']
    ]
    R = numpy.require(R, dtype=numpy.float64, requirements=['C', 'W'])
    vR = numpy.require(vR, dtype=numpy.float64, requirements=['C', 'W'])
    vT = numpy.require(vT, dtype=numpy.float64, requirements=['C', 'W'])
    z = numpy.require(z, dtype=numpy.float64, requirements=['C', 'W'])
    vz = numpy.require(vz, dtype=numpy.float64, requirements=['C', 'W'])
    u0 = numpy.require(u0, dtype=numpy.float64, requirements=['C', 'W'])
    jr = numpy.require(jr, dtype=numpy.float64, requirements=['C', 'W'])
    jz = numpy.require(jz, dtype=numpy.float64, requirements=['C', 'W'])
    Omegar = numpy.require(Omegar,
                           dtype=numpy.float64,
                           requirements=['C', 'W'])
    Omegaphi = numpy.require(Omegaphi,
                             dtype=numpy.float64,
                             requirements=['C', 'W'])
    Omegaz = numpy.require(Omegaz,
                           dtype=numpy.float64,
                           requirements=['C', 'W'])
    Angler = numpy.require(Angler,
                           dtype=numpy.float64,
                           requirements=['C', 'W'])
    Anglephi = numpy.require(Anglephi,
                             dtype=numpy.float64,
                             requirements=['C', 'W'])
    Anglez = numpy.require(Anglez,
                           dtype=numpy.float64,
                           requirements=['C', 'W'])

    #Run the C code
    actionAngleStaeckel_actionsFunc(len(R), R, vR, vT, z, vz, u0,
                                    ctypes.c_int(npot), pot_type, pot_args,
                                    ctypes.c_double(delta), jr, jz, Omegar,
                                    Omegaphi, Omegaz, Angler, Anglephi, Anglez,
                                    ctypes.byref(err))

    #Reset input arrays
    if f_cont[0]: R = numpy.asfortranarray(R)
    if f_cont[1]: vR = numpy.asfortranarray(vR)
    if f_cont[2]: vT = numpy.asfortranarray(vT)
    if f_cont[3]: z = numpy.asfortranarray(z)
    if f_cont[4]: vz = numpy.asfortranarray(vz)
    if f_cont[5]: u0 = numpy.asfortranarray(u0)

    badAngle = Anglephi != 9999.99
    Anglephi[badAngle] = (Anglephi[badAngle] + phi[badAngle] %
                          (2. * numpy.pi)) % (2. * numpy.pi)
    Anglephi[Anglephi < 0.] += 2. * numpy.pi

    return (jr, jz, Omegar, Omegaphi, Omegaz, Angler, Anglephi, Anglez,
            err.value)