Esempio n. 1
0
def _evaluateplanarPotentials(Pot, R, phi=None, t=0., dR=0, dphi=0):
    from galpy.potential_src.Potential import _isNonAxi
    isList = isinstance(Pot, list)
    nonAxi = _isNonAxi(Pot)
    if nonAxi and phi is None:
        raise PotentialError(
            "The (list of) planarPotential instances is non-axisymmetric, but you did not provide phi"
        )
    if isList and nu.all([isinstance(p, planarPotential) for p in Pot]):
        sum = 0.
        for pot in Pot:
            if nonAxi:
                sum += pot._call_nodecorator(R, phi=phi, t=t, dR=dR, dphi=dphi)
            else:
                sum += pot._call_nodecorator(R, t=t, dR=dR, dphi=dphi)
        return sum
    elif isinstance(Pot, planarPotential):
        if nonAxi:
            return Pot._call_nodecorator(R, phi=phi, t=t, dR=dR, dphi=dphi)
        else:
            return Pot._call_nodecorator(R, t=t, dR=dR, dphi=dphi)
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'evaluatePotentials' is neither a Potential-instance or a list of such instances"
        )
Esempio n. 2
0
def _evaluateplanarRforces(Pot, R, phi=None, t=0.):
    """Raw, undecorated function for internal use"""
    from galpy.potential_src.Potential import _isNonAxi
    isList = isinstance(Pot, list)
    nonAxi = _isNonAxi(Pot)
    if nonAxi and phi is None:
        raise PotentialError(
            "The (list of) planarPotential instances is non-axisymmetric, but you did not provide phi"
        )
    if isinstance(Pot,list) \
            and nu.all([isinstance(p,planarPotential) for p in Pot]):
        sum = 0.
        for pot in Pot:
            if nonAxi:
                sum += pot._Rforce_nodecorator(R, phi=phi, t=t)
            else:
                sum += pot._Rforce_nodecorator(R, t=t)
        return sum
    elif isinstance(Pot, planarPotential):
        if nonAxi:
            return Pot._Rforce_nodecorator(R, phi=phi, t=t)
        else:
            return Pot._Rforce_nodecorator(R, t=t)
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'evaluatePotentials' is neither a Potential-instance or a list of such instances"
        )
Esempio n. 3
0
def evaluateplanarPotentials(R,Pot,phi=None,t=0.,dR=0,dphi=0):
    """
    NAME:

       evaluateplanarPotentials

    PURPOSE:

       evaluate a (list of) planarPotential instance(s)

    INPUT:

       R - Cylindrical radius

       Pot - (list of) planarPotential instance(s)

       phi= azimuth (optional)

       t= time (optional)

       dR=, dphi= if set to non-zero integers, return the dR,dphi't derivative instead

    OUTPUT:

       Phi(R(,phi,t))

    HISTORY:

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

    """
    isList= isinstance(Pot,list)
    if isList:
        isAxis= [not p.isNonAxi for p in Pot]
        nonAxi= not nu.prod(nu.array(isAxis))
    else:
        nonAxi= Pot.isNonAxi
    if nonAxi and phi is None:
        raise PotentialError("The (list of) planarPotential instances is non-axisymmetric, but you did not provide phi")
    if isinstance(Pot,list) \
            and nu.all([isinstance(p,planarPotential) for p in Pot]):
        sum= 0.
        for pot in Pot:
            if nonAxi:
                sum+= pot(R,phi=phi,t=t,dR=dR,dphi=dphi)
            else:
                sum+= pot(R,t=t,dR=dR,dphi=dphi)
        return sum
    elif isinstance(Pot,planarPotential):
        if nonAxi:
            return Pot(R,phi=phi,t=t,dR=dR,dphi=dphi)
        else:
            return Pot(R,t=t,dR=dR,dphi=dphi)
    else: #pragma: no cover 
        raise PotentialError("Input to 'evaluatePotentials' is neither a Potential-instance or a list of such instances")
Esempio n. 4
0
def evaluateplanarR2derivs(Pot, R, phi=None, t=0.):
    """
    NAME:

       evaluateplanarR2derivs

    PURPOSE:

       evaluate the second radial derivative of a (list of) planarPotential instance(s)

    INPUT:

       Pot - (list of) planarPotential instance(s)

       R - Cylindrical radius (can be Quantity)

       phi= azimuth (optional; can be Quantity)

       t= time (optional; can be Quantity)

    OUTPUT:

       F_R(R(,phi,t))

    HISTORY:

       2010-10-09 - Written - Bovy (IAS)

    """
    from galpy.potential_src.Potential import _isNonAxi
    isList = isinstance(Pot, list)
    nonAxi = _isNonAxi(Pot)
    if nonAxi and phi is None:
        raise PotentialError(
            "The (list of) planarPotential instances is non-axisymmetric, but you did not provide phi"
        )
    if isinstance(Pot,list) \
            and nu.all([isinstance(p,planarPotential) for p in Pot]):
        sum = 0.
        for pot in Pot:
            if nonAxi:
                sum += pot.R2deriv(R, phi=phi, t=t, use_physical=False)
            else:
                sum += pot.R2deriv(R, t=t, use_physical=False)
        return sum
    elif isinstance(Pot, planarPotential):
        if nonAxi:
            return Pot.R2deriv(R, phi=phi, t=t, use_physical=False)
        else:
            return Pot.R2deriv(R, t=t, use_physical=False)
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'evaluatePotentials' is neither a Potential-instance or a list of such instances"
        )
Esempio n. 5
0
def evaluateplanarR2derivs(R,Pot,phi=None,t=0.):
    """
    NAME:

       evaluateplanarR2derivs

    PURPOSE:

       evaluate the second radial derivative of a (list of) planarPotential instance(s)

    INPUT:

       R - Cylindrical radius

       Pot - (list of) planarPotential instance(s)

       phi= azimuth (optional)

       t= time (optional)

    OUTPUT:

       F_R(R(,phi,t))

    HISTORY:

       2010-10-09 - Written - Bovy (IAS)

    """
    isList= isinstance(Pot,list)
    if isList:
        isAxis= [not p.isNonAxi for p in Pot]
        nonAxi= not nu.prod(nu.array(isAxis))
    else:
        nonAxi= Pot.isNonAxi
    if nonAxi and phi is None:
        raise PotentialError("The (list of) planarPotential instances is non-axisymmetric, but you did not provide phi")
    if isinstance(Pot,list) \
            and nu.all([isinstance(p,planarPotential) for p in Pot]):
        sum= 0.
        for pot in Pot:
            if nonAxi:
                sum+= pot.R2deriv(R,phi=phi,t=t)
            else:
                sum+= pot.R2deriv(R,t=t)
        return sum
    elif isinstance(Pot,planarPotential):
        if nonAxi:
            return Pot.R2deriv(R,phi=phi,t=t)
        else:
            return Pot.R2deriv(R,t=t)
    else: #pragma: no cover 
        raise PotentialError("Input to 'evaluatePotentials' is neither a Potential-instance or a list of such instances")
Esempio n. 6
0
    def phiforce(self,R,phi=0.,t=0.):
        """
        NAME:

           phiforce

        PURPOSE:

           evaluate the phi force

        INPUT:

           R - Cylindrical radius

           phi= azimuth (optional)

           t= time (optional)

        OUTPUT:

           F_\phi(R,(\phi,t)))

        HISTORY:

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

        """
        try:
            return self._amp*self._phiforce(R,phi=phi,t=t)
        except AttributeError: #pragma: no cover
            raise PotentialError("'_phiforce' function not implemented for this potential")
Esempio n. 7
0
 def _call_nodecorator(self, x, t=0.):
     # Separate, so it can be used during orbit integration
     try:
         return self._amp * self._evaluate(x, t=t)
     except AttributeError:  #pragma: no cover
         raise PotentialError(
             "'_evaluate' function not implemented for this potential")
Esempio n. 8
0
    def phi2deriv(self,R,phi=0.,t=0.):
        """
        NAME:

           phi2deriv

        PURPOSE:

           evaluate the second azimuthal derivative

        INPUT:

           R - Cylindrical radius

           phi= azimuth (optional)

           t= time (optional)

        OUTPUT:

           d2phi/daz2

        HISTORY:

           2014-04-06 - Written - Bovy (IAS)

        """
        try:
            return self._amp*self._phi2deriv(R,phi=phi,t=t)
        except AttributeError: #pragma: no cover
            raise PotentialError("'_phi2deriv' function not implemented for this potential")      
Esempio n. 9
0
 def _phiforce_nodecorator(self, R, phi=0., t=0.):
     # Separate, so it can be used during orbit integration
     try:
         return self._amp * self._phiforce(R, phi=phi, t=t)
     except AttributeError:  #pragma: no cover
         raise PotentialError(
             "'_phiforce' function not implemented for this potential")
Esempio n. 10
0
    def force(self, x, t=0.):
        """
        NAME:

           force

        PURPOSE:

           evaluate the force

        INPUT:

           x - position

           t= time (optional)

        OUTPUT:

           F(x,t)

        HISTORY:

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

        """
        try:
            return self._amp * self._force(x, t=t)
        except AttributeError:  #pragma: no cover
            raise PotentialError(
                "'_force' function not implemented for this potential")
Esempio n. 11
0
    def Rphideriv(self, R, phi=0., t=0.):
        """
        NAME:

           Rphideriv

        PURPOSE:

           evaluate the mixed radial and azimuthal  derivative

        INPUT:

           R - Cylindrical radius (can be Quantity)

           phi= azimuth (optional can be Quantity)

           t= time (optional; can be Quantity)

        OUTPUT:

           d2phi/dR d az

        HISTORY:

           2014-05-21 - Written - Bovy (IAS)

        """
        try:
            return self._amp * self._Rphideriv(R, phi=phi, t=t)
        except AttributeError:  #pragma: no cover
            raise PotentialError(
                "'_Rphideriv' function not implemented for this potential")
Esempio n. 12
0
def _evaluatelinearForces(Pot,x,t=0.):
    """Raw, undecorated function for internal use"""
    if isinstance(Pot,list):
        sum= 0.
        for pot in Pot:
            sum+= pot._force_nodecorator(x,t=t)
        return sum
    elif isinstance(Pot,linearPotential):
        return Pot._force_nodecorator(x,t=t)
    else: #pragma: no cover
        raise PotentialError("Input to 'evaluateForces' is neither a linearPotential-instance or a list of such instances")
 def _call_nodecorator(self,R,phi=0.,t=0.,dR=0,dphi=0):
     # Separate, so it can be used during orbit integration
     if dR == 0 and dphi == 0:
         try:
             return self._amp*self._evaluate(R,phi=phi,t=t)
         except AttributeError: #pragma: no cover
             raise PotentialError("'_evaluate' function not implemented for this potential")
     elif dR == 1 and dphi == 0:
         return -self.Rforce(R,phi=phi,t=t,use_physical=False)
     elif dR == 0 and dphi == 1:
         return -self.phiforce(R,phi=phi,t=t,use_physical=False)
     elif dR == 2 and dphi == 0:
         return self.R2deriv(R,phi=phi,t=t,use_physical=False)
     elif dR == 0 and dphi == 2:
         return self.phi2deriv(R,phi=phi,t=t,use_physical=False)
     elif dR == 1 and dphi == 1:
         return self.Rphideriv(R,phi=phi,t=t,use_physical=False)
Esempio n. 14
0
def RZToverticalPotential(RZPot, R):
    """
    NAME:

       RZToverticalPotential

    PURPOSE:

       convert a RZPotential to a vertical potential at a given R

    INPUT:

       RZPot - RZPotential instance or list of such instances

       R - Galactocentric radius at which to evaluate the vertical potential (can be Quantity)

    OUTPUT:

       (list of) linearPotential instance(s)

    HISTORY:

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

    """
    if _APY_LOADED and isinstance(R, units.Quantity):
        if hasattr(RZPot, '_ro'):
            R = R.to(units.kpc).value / RZPot._ro
        else:
            R = R.to(units.kpc).value / RZPot[0]._ro
    if isinstance(RZPot, list):
        out = []
        for pot in RZPot:
            if isinstance(pot, linearPotential):
                out.append(pot)
            else:
                out.append(verticalPotential(pot, R))
        return out
    elif isinstance(RZPot, Potential):
        return verticalPotential(RZPot, R)
    elif isinstance(RZPot, linearPotential):
        return RZPot
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'RZToverticalPotential' is neither an RZPotential-instance or a list of such instances"
        )
Esempio n. 15
0
    def __call__(self,R,phi=0.,t=0.,dR=0,dphi=0):
        """
        NAME:

           __call__

        PURPOSE:

           evaluate the potential

        INPUT: 

           R - Cylindrica radius

           phi= azimuth (optional)

           t= time (optional)

           dR=, dphi= if set to non-zero integers, return the dR,dphi't derivative

        OUTPUT:

           Phi(R(,phi,t)))

        HISTORY:

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

        """
        if dR == 0 and dphi == 0:
            try:
                return self._amp*self._evaluate(R,phi=phi,t=t)
            except AttributeError: #pragma: no cover
                raise PotentialError("'_evaluate' function not implemented for this potential")
        elif dR == 1 and dphi == 0:
            return -self.Rforce(R,phi=phi,t=t)
        elif dR == 0 and dphi == 1:
            return -self.phiforce(R,phi=phi,t=t)
        elif dR == 2 and dphi == 0:
            return self.R2deriv(R,phi=phi,t=t)
        elif dR == 0 and dphi == 2:
            return self.phi2deriv(R,phi=phi,t=t)
        elif dR == 1 and dphi == 1:
            return self.Rphideriv(R,phi=phi,t=t)
Esempio n. 16
0
def toPlanarPotential(Pot):
    """
    NAME:

       toPlanarPotential

    PURPOSE:

       convert an Potential to a planarPotential in the mid-plane (z=0)

    INPUT:

       Pot - Potential instance or list of such instances (existing planarPotential instances are just copied to the output)

    OUTPUT:

       planarPotential instance(s)

    HISTORY:

       2016-06-11 - Written - Bovy (UofT)

    """
    if isinstance(Pot, list):
        out = []
        for pot in Pot:
            if isinstance(pot, planarPotential):
                out.append(pot)
            elif pot.isNonAxi:
                out.append(planarPotentialFromFullPotential(pot))
            else:
                out.append(planarPotentialFromRZPotential(pot))
        return out
    elif isinstance(Pot, Potential) and Pot.isNonAxi:
        return planarPotentialFromFullPotential(Pot)
    elif isinstance(Pot, Potential):
        return planarPotentialFromRZPotential(Pot)
    elif isinstance(Pot, planarPotential):
        return Pot
    else:
        raise PotentialError(
            "Input to 'toPlanarPotential' is neither an Potential-instance or a list of such instances"
        )
Esempio n. 17
0
def RZToverticalPotential(RZPot, R):
    """
    NAME:

       RZToverticalPotential

    PURPOSE:

       convert a RZPotential to a vertical potential at a given R

    INPUT:

       RZPot - RZPotential instance or list of such instances

       R - Galactocentric radius at which to evaluate the vertical potential

    OUTPUT:

       (list of) linearPotential instance(s)

    HISTORY:

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

    """
    if isinstance(RZPot, list):
        out = []
        for pot in RZPot:
            if isinstance(pot, linearPotential):
                out.append(pot)
            else:
                out.append(verticalPotential(pot, R))
        return out
    elif isinstance(RZPot, Potential):
        return verticalPotential(RZPot, R)
    elif isinstance(RZPot, linearPotential):
        return RZPot
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'RZToverticalPotential' is neither an RZPotential-instance or a list of such instances"
        )
Esempio n. 18
0
def RZToplanarPotential(RZPot):
    """
    NAME:

       RZToplanarPotential

    PURPOSE:

       convert an RZPotential to a planarPotential in the mid-plane (z=0)

    INPUT:

       RZPot - RZPotential instance or list of such instances (existing planarPotential instances are just copied to the output)

    OUTPUT:

       planarPotential instance(s)

    HISTORY:

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

    """
    if isinstance(RZPot, list):
        out = []
        for pot in RZPot:
            if isinstance(pot, planarPotential):
                out.append(pot)
            else:
                out.append(planarPotentialFromRZPotential(pot))
        return out
    elif isinstance(RZPot, Potential):
        return planarPotentialFromRZPotential(RZPot)
    elif isinstance(RZPot, planarPotential):
        return RZPot
    else:
        raise PotentialError(
            "Input to 'RZToplanarPotential' is neither an RZPotential-instance or a list of such instances"
        )
Esempio n. 19
0
def evaluatelinearForces(x, Pot, t=0.):
    """
    NAME:

       evaluatelinearForces

    PURPOSE:

       evaluate the forces due to a list of potentials

    INPUT:

       x - evaluate forces at this position

       Pot - (list of) linearPotential instance(s)

       t - time to evaluate at

    OUTPUT:

       force(x,t)

    HISTORY:

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

    """
    if isinstance(Pot, list):
        sum = 0.
        for pot in Pot:
            sum += pot.force(x, t=t)
        return sum
    elif isinstance(Pot, linearPotential):
        return Pot.force(x, t=t)
    else:  #pragma: no cover
        raise PotentialError(
            "Input to 'evaluateForces' is neither a linearPotential-instance or a list of such instances"
        )