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" )
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" )
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")
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" )
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")
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")
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")
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")
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")
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")
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")
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)
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" )
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)
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" )
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" )
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" )
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" )