diff --git a/galpy/potential/AdiabaticContractionWrapperPotential.py b/galpy/potential/AdiabaticContractionWrapperPotential.py index b795294aa..c622e17a1 100644 --- a/galpy/potential/AdiabaticContractionWrapperPotential.py +++ b/galpy/potential/AdiabaticContractionWrapperPotential.py @@ -18,9 +18,12 @@ class AdiabaticContractionWrapperPotential(interpSphericalPotential): """AdiabaticContractionWrapperPotential: Wrapper to adiabatically contract a DM halo in response to the growth of a baryonic component. Use for example as:: - dm= AdiabaticContractionWrapperPotential(pot=MWPotential2014[2],baryonpot=MWPotential2014[:2]) + dm= AdiabaticContractionWrapperPotential( + pot=MWPotential2014[2], + baryonpot=MWPotential2014[:2] + ) - to contract the dark-matter halo in MWPotential2014 according to the baryon distribution within it. The basic physics of the adiabatic contraction is that a fraction `f_bar` of the mass in the original potential `pot` cools adiabatically to form a baryonic component `baryonpot`; this wrapper computes the resulting dark-matter potential using different approximations in the literature. + to contract the dark-matter halo in ``MWPotential2014`` according to the baryon distribution within it. The basic physics of the adiabatic contraction is that a fraction ``f_bar`` of the mass in the original potential ``pot`` cools adiabatically to form a baryonic component ``baryonpot``; this wrapper computes the resulting dark-matter potential using different approximations in the literature. """ @@ -37,44 +40,44 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a AdiabaticContractionWrapper Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof representing the density that is adiabatically contracted - - baryonpot - Potential instance or list thereof representing the density of baryons whose growth causes the contraction - - method= ('cautun') Type of adiabatic-contraction formula: - - * 'cautun' for that from Cautun et al. 2020 (`2020MNRAS.494.4291C `__), - * 'blumenthal' for that from Blumenthal et al. 1986 (`1986ApJ...301...27B 1986ApJ...301...27B `__) - * 'gnedin' for that from Gnedin et al. 2004 (`2004ApJ...616...16G `__) - - f_bar= (0.157) universal baryon fraction; if None, calculated from pot and baryonpot assuming that at rmax the halo contains the universal baryon fraction; leave this at the default value unless you know what you are doing - - rmin= (None) minimum radius to consider (default: rmax/2500; don't set this to zero) - - rmax= (50.) maximum radius to consider (can be Quantity) - - ro, vo= standard unit-conversion parameters - - OUTPUT: - - (none) - - HISTORY: - - 2021-03-21 - Started based on Marius Cautun's code - Bovy (UofT) - + Initialize a AdiabaticContractionWrapper Potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + pot : Potential instance or list thereof, optional + Representing the density that is adiabatically contracted. + baryonpot : Potential instance or list thereof, optional + Representing the density of baryons whose growth causes the contraction. + method : {'cautun', 'blumenthal', 'gnedin'}, optional + Type of adiabatic-contraction formula: + + - 'cautun' for that from Cautun et al. 2020 [1]_; + - 'blumenthal' for that from Blumenthal et al. 1986 [2]_; + - 'gnedin' for that from Gnedin et al. 2004 [3]_. + + (default: 'cautun') + f_bar : float, optional + Universal baryon fraction; if None, calculated from pot and baryonpot assuming that at rmax the halo contains the universal baryon fraction; leave this at the default value unless you know what you are doing (default: 0.157). + rmin : float, optional + Minimum radius to consider (default: rmax/2500; don't set this to zero). + rmax : float or Quantity, optional + Maximum radius to consider (default: 50.). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2021-03-21 - Started based on Marius Cautun's code - Bovy (UofT) + + References + ---------- + .. [1] Cautun, M et al. (2020), Mon. Not. Roy. Astron. Soc., 494, 4291. ADS: https://ui.adsabs.harvard.edu/abs/2020MNRAS.494.4291C + .. [2] Blumenthal et al. (1986), Astrophys. J., 301, 27. ADS: https://ui.adsabs.harvard.edu/abs/1986ApJ...301...27B + .. [3] Gnedin et al. (2004), Astrophys. J., 616, 16. ADS: https://ui.adsabs.harvard.edu/abs/2004ApJ...616...16G """ # Initialize with Force just to parse (ro,vo) Force.__init__(self, ro=ro, vo=vo) diff --git a/galpy/potential/AnyAxisymmetricRazorThinDiskPotential.py b/galpy/potential/AnyAxisymmetricRazorThinDiskPotential.py index 4a7ed86a5..f02f66f54 100644 --- a/galpy/potential/AnyAxisymmetricRazorThinDiskPotential.py +++ b/galpy/potential/AnyAxisymmetricRazorThinDiskPotential.py @@ -15,42 +15,35 @@ class AnyAxisymmetricRazorThinDiskPotential(Potential): - r"""Class that implements the potential of an arbitrary axisymmetric, razor-thin disk with surface density :math:`\Sigma(R)`""" + """Class that implements the potential of an arbitrary axisymmetric, razor-thin disk with surface density :math:`\\Sigma(R)`""" def __init__( self, - surfdens=lambda R: 1.5 * numpy.exp(-3.0 * R), amp=1.0, + surfdens=lambda R: 1.5 * numpy.exp(-3.0 * R), normalize=False, ro=None, vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize the potential of an arbitrary axisymmetric disk - - INPUT: - - surfdens= (1.5 e^[-R/0.3]) function of a single variable that gives the surface density as a function of radius (can return a Quantity) - - amp= (1.) amplitude to be applied to the potential - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - AnyAxisymmetricRazorThinDiskPotential object - - HISTORY: - - 2021-01-04 - Written - Bovy (UofT) + Potential of an arbitrary axisymmetric disk. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential. Default is 1.0. + surfdens : callable, optional + Function of a single variable that gives the surface density as a function of radius (can return a Quantity). Default is ``lambda R: 1.5 * numpy.exp(-3.0 * R)``. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Default is False. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2021-01-04 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo) @@ -99,21 +92,6 @@ def __init__( @check_potential_inputs_not_arrays def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ if R == 0 and z == 0: return self._pot_zero elif numpy.isinf(R**2 + z**2): @@ -131,21 +109,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - F_R at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ R2 = R**2 z2 = z**2 @@ -172,21 +135,6 @@ def rforceint(a): @check_potential_inputs_not_arrays def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - F_z at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ if z == 0: return 0.0 z2 = z**2 @@ -213,21 +161,6 @@ def zforceint(a): @check_potential_inputs_not_arrays def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the 2nd radial derivative at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2 Phi / dR2 at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ R2 = R**2 z2 = z**2 @@ -262,21 +195,6 @@ def r2derivint(a): @check_potential_inputs_not_arrays def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the 2nd vertical derivative at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2 Phi / dz2 at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ R2 = R**2 z2 = z**2 @@ -304,21 +222,6 @@ def z2derivint(a): @check_potential_inputs_not_arrays def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed radial, vertical derivative at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2 Phi / dRdz at (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ R2 = R**2 z2 = z**2 @@ -359,19 +262,4 @@ def rzderivint(a): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Sigma (R,z) - HISTORY: - 2021-01-04 - Written - Bovy (UofT) - """ return self._sdens(R) diff --git a/galpy/potential/AnySphericalPotential.py b/galpy/potential/AnySphericalPotential.py index 30f104998..35d3ef902 100644 --- a/galpy/potential/AnySphericalPotential.py +++ b/galpy/potential/AnySphericalPotential.py @@ -17,40 +17,31 @@ class AnySphericalPotential(SphericalPotential): def __init__( self, - dens=lambda r: 0.64 / r / (1 + r) ** 3, amp=1.0, + dens=lambda r: 0.64 / r / (1 + r) ** 3, normalize=False, ro=None, vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize the potential of an arbitrary spherical density distribution - - INPUT: - - dens= (0.64/r/(1+r)**3) function of a single variable that gives the density as a function of radius (can return a Quantity) - - amp= (1.) amplitude to be applied to the potential - - normalize - if True, normalize such that vc(1.,0.)=1., or, if - given as a number, such that the force is this fraction - of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2021-01-05 - Written - Bovy (UofT) + Initialize the potential of an arbitrary spherical density distribution. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential. Default is 1.0. + dens : callable, optional + A function of a single variable that gives the density as a function of radius (can return a Quantity). Default is ``lambda r: 0.64 / r / (1 + r) ** 3``. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2021-01-05 - Written - Bovy (UofT) """ SphericalPotential.__init__(self, amp=amp, ro=ro, vo=vo) diff --git a/galpy/potential/BurkertPotential.py b/galpy/potential/BurkertPotential.py index 2b7356918..4c60499f4 100644 --- a/galpy/potential/BurkertPotential.py +++ b/galpy/potential/BurkertPotential.py @@ -19,36 +19,29 @@ class BurkertPotential(SphericalPotential): def __init__(self, amp=1.0, a=2.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Burkert-density potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - a = scale radius (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if - given as a number, such that the force is this fraction - of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2013-04-10 - Written - Bovy (IAS) - - 2020-03-30 - Re-implemented using SphericalPotential - Bovy (UofT) - + Initialize a Burkert-density potential [1]_. + + Parameters + ---------- + amp : float or Quantity + Amplitude to be applied to the potential. Can be a Quantity with units of mass density or Gxmass density. + a : float or Quantity + Scale radius. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Default is False. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013-04-10 - Written - Bovy (IAS) + - 2020-03-30 - Re-implemented using SphericalPotential - Bovy (UofT) + + References + ---------- + .. [1] Burkert (1995), Astrophysical Journal, 447, L25. ADS: https://ui.adsabs.harvard.edu/abs/1995ApJ...447L..25B. """ SphericalPotential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="density") a = conversion.parse_length(a, ro=self._ro, vo=self._vo) @@ -109,21 +102,6 @@ def _rdens(self, r, t=0.0): return 1.0 / (1.0 + x) / (1.0 + x**2.0) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the surface density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) x = r / self.a Rpa = numpy.sqrt(R**2.0 + self.a**2.0) diff --git a/galpy/potential/ChandrasekharDynamicalFrictionForce.py b/galpy/potential/ChandrasekharDynamicalFrictionForce.py index 5ac933ded..89e07ac2b 100644 --- a/galpy/potential/ChandrasekharDynamicalFrictionForce.py +++ b/galpy/potential/ChandrasekharDynamicalFrictionForce.py @@ -31,7 +31,7 @@ class ChandrasekharDynamicalFrictionForce(DissipativeForce): \\Lambda = \\frac{r/\\gamma}{\\mathrm{max}\\left(r_{\\mathrm{hm}},GM/|\\mathbf{v}|^2\\right)}\\,, - where :math:`\\gamma` is a constant. This :math:`\\gamma` should be the absolute value of the logarithmic slope of the density :math:`\\gamma = |\\mathrm{d} \\ln \\rho / \\mathrm{d} \\ln r|`, although for :math:`\\gamma<1` it is advisable to set :math:`\\gamma=1`. Implementation here roughly follows `2016MNRAS.463..858P `__ and earlier work. + where :math:`\\gamma` is a constant. This :math:`\\gamma` should be the absolute value of the logarithmic slope of the density :math:`\\gamma = |\\mathrm{d} \\ln \\rho / \\mathrm{d} \\ln r|`, although for :math:`\\gamma<1` it is advisable to set :math:`\\gamma=1`. Implementation here roughly follows [2]_ and earlier work. """ @@ -51,52 +51,45 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Chandrasekhar Dynamical Friction force - - INPUT: - - amp - amplitude to be applied to the potential (default: 1) - - GMs - satellite mass; can be a Quantity with units of mass or Gxmass; can be adjusted after initialization by setting obj.GMs= where obj is your ChandrasekharDynamicalFrictionForce instance (note that the mass of the satellite can *not* be changed simply by multiplying the instance by a number, because he mass is not only used as an amplitude) - - rhm - half-mass radius of the satellite (set to zero for a black hole; can be a Quantity); can be adjusted after initialization by setting obj.rhm= where obj is your ChandrasekharDynamicalFrictionForce instance - - gamma - Free-parameter in :math:`\\Lambda` - - dens - Potential instance or list thereof that represents the density [default: LogarithmicHaloPotential(normalize=1.,q=1.)] - - sigmar= (None) function that gives the velocity dispersion as a function of r (has to be in natural units!); if None, computed from the dens potential using the spherical Jeans equation (in galpy.df.jeans) assuming zero anisotropy; if set to a lambda function, *the object cannot be pickled* (so set it to a real function) - - cont_lnLambda= (False) if set to a number, use a constant ln(Lambda) instead with this value - - minr= (0.0001) minimum r at which to apply dynamical friction: at r < minr, friction is set to zero (can be a Quantity) - - Interpolation: - - maxr= (25) maximum r for which sigmar gets interpolated; for best performance set this to the maximum r you will consider (can be a Quantity) - - nr= (501) number of radii to use in the interpolation of sigmar - - You can check that sigmar is interpolated correctly by comparing the methods sigmar [the interpolated version] and sigmar_orig [the original or directly computed version] - - OUTPUT: - - (none) - - HISTORY: - - 2011-12-26 - Started - Bovy (NYU) - - 2018-03-18 - Re-started: updated to r dependent Lambda form and integrated into galpy framework - Bovy (UofT) - - 2018-07-23 - Calculate sigmar from the Jeans equation and interpolate it; allow GMs and rhm to be set on the fly - Bovy (UofT) - + Initialize a Chandrasekhar Dynamical Friction force [1]_. + + Parameters + ---------- + amp : float + Amplitude to be applied to the potential (default: 1). + GMs : float or Quantity + Satellite mass; can be a Quantity with units of mass or Gxmass; can be adjusted after initialization by setting obj.GMs= where obj is your ChandrasekharDynamicalFrictionForce instance (note that the mass of the satellite can *not* be changed simply by multiplying the instance by a number, because he mass is not only used as an amplitude). + rhm : float or Quantity + Half-mass radius of the satellite (set to zero for a black hole); can be adjusted after initialization by setting obj.rhm= where obj is your ChandrasekharDynamicalFrictionForce instance. + gamma : float + Free-parameter in :math:`\\Lambda`. + dens : Potential instance or list thereof, optional + Potential instance or list thereof that represents the density [default: LogarithmicHaloPotential(normalize=1.,q=1.)]. + sigmar : callable, optional + Function that gives the velocity dispersion as a function of r (has to be in natural units!); if None, computed from the dens potential using the spherical Jeans equation (in galpy.df.jeans) assuming zero anisotropy; if set to a lambda function, *the object cannot be pickled* (so set it to a real function). + const_lnLambda : bool, optional + If set to a number, use a constant ln(Lambda) instead with this value. + minr : float or Quantity, optional + Minimum r at which to apply dynamical friction: at r < minr, friction is set to zero. + maxr : float or Quantity, optional + Maximum r for which sigmar gets interpolated; for best performance set this to the maximum r you will consider. + nr : int, optional + Number of radii to use in the interpolation of sigmar. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2011-12-26 - Started - Bovy (NYU) + - 2018-03-18 - Re-started: updated to r dependent Lambda form and integrated into galpy framework - Bovy (UofT) + - 2018-07-23 - Calculate sigmar from the Jeans equation and interpolate it; allow GMs and rhm to be set on the fly - Bovy (UofT) + + References + ---------- + .. [1] Chandrasekhar, S. (1943), Astrophysical Journal, 97, 255. ADS: http://adsabs.harvard.edu/abs/1943ApJ....97..255C. + .. [2] Petts, J. A., Gualandris, A., Read, J. I., & Bovy, J. (2016), Monthly Notices of the Royal Astronomical Society, 463, 858. ADS: http://adsabs.harvard.edu/abs/2016MNRAS.463..858P. """ DissipativeForce.__init__(self, amp=amp * GMs, ro=ro, vo=vo, amp_units="mass") rhm = conversion.parse_length(rhm, ro=self._ro) @@ -186,17 +179,24 @@ def rhm(self, new_rhm): def lnLambda(self, r, v): """ - NAME: - lnLambda - PURPOSE: - evaluate the Coulomb logarithm :math:`\\ln \\Lambda` - INPUT: - r - spherical radius (natural units) - v - current velocity in cylindrical coordinates (natural units) - OUTPUT: - Coulomb logarithm - HISTORY: - 2018-03-18 - Started - Bovy (UofT) + Evaluate the Coulomb logarithm ln Lambda. + + Parameters + ---------- + r : float + Spherical radius (natural units). + v : float + Current velocity in cylindrical coordinates (natural units). + + Returns + ------- + lnLambda : float + Coulomb logarithm. + + Notes + ----- + - 2018-03-18 - Started - Bovy (UofT) + """ if self._lnLambda: lnLambda = self._lnLambda @@ -227,22 +227,6 @@ def _calc_force(self, R, phi, z, v, t): ) def _Rforce(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the radial force - HISTORY: - 2018-03-18 - Started - Bovy (UofT) - """ new_hash = hashlib.md5( numpy.array([R, phi, z, v[0], v[1], v[2], t]) ).hexdigest() @@ -251,22 +235,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0, v=None): return self._cached_force * v[0] def _phitorque(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the azimuthal torque - HISTORY: - 2018-03-18 - Started - Bovy (UofT) - """ new_hash = hashlib.md5( numpy.array([R, phi, z, v[0], v[1], v[2], t]) ).hexdigest() @@ -275,22 +243,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0, v=None): return self._cached_force * v[1] * R def _zforce(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the vertical force - HISTORY: - 2018-03-18 - Started - Bovy (UofT) - """ new_hash = hashlib.md5( numpy.array([R, phi, z, v[0], v[1], v[2], t]) ).hexdigest() diff --git a/galpy/potential/CorotatingRotationWrapperPotential.py b/galpy/potential/CorotatingRotationWrapperPotential.py index 52ca67a43..7176de7bc 100644 --- a/galpy/potential/CorotatingRotationWrapperPotential.py +++ b/galpy/potential/CorotatingRotationWrapperPotential.py @@ -26,35 +26,30 @@ def __init__( self, amp=1.0, pot=None, vpo=1.0, beta=0.0, to=0.0, pa=0.0, ro=None, vo=None ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a CorotatingRotationWrapper Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof; this potential is made to rotate around the z axis by the wrapper - - vpo= (1.) amplitude of the circular-velocity curve (can be a Quantity) - - beta= (0.) power-law amplitude of the circular-velocity curve - - to= (0.) reference time at which the potential == pot - - pa= (0.) the position angle (can be a Quantity) - - OUTPUT: - - (none) - - HISTORY: - - 2018-02-21 - Started - Bovy (UofT) + Initialize a CorotatingRotationWrapper Potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + pot : Potential instance or list thereof, optional + This potential is made to rotate around the z axis by the wrapper. + vpo : float or Quantity, optional + Amplitude of the circular-velocity curve. + beta : float, optional + Power-law amplitude of the circular-velocity curve. + to : float or Quantity, optional + Reference time at which the potential == pot. + pa : float or Quantity, optional + The position angle. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-02-21 - Started - Bovy (UofT) """ vpo = conversion.parse_velocity(vpo, vo=self._vo) diff --git a/galpy/potential/CosmphiDiskPotential.py b/galpy/potential/CosmphiDiskPotential.py index 9796a0bbf..c61bf889c 100644 --- a/galpy/potential/CosmphiDiskPotential.py +++ b/galpy/potential/CosmphiDiskPotential.py @@ -38,46 +38,38 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize an cosmphi disk potential - - INPUT: - - amp= amplitude to be applied to the potential (default: - 1.), degenerate with phio below, but kept for overall - consistency with potentials - - m= cos( m * (phi - phib) ), integer - - p= power-law index of the phi(R) = (R/Ro)^p part - - r1= (1.) normalization radius for the amplitude (can be Quantity); amp x phio is only the potential at (R,phi) = (r1,pib) when r1 > rb; otherwise more complicated - - rb= (None) if set, break radius for power-law: potential R^p at R > Rb, R^-p at R < Rb, potential and force continuous at Rb - - - Either: - - a) phib= angle (in rad; default=25 degree; or can be Quantity) - - phio= potential perturbation (in terms of phio/vo^2 if vo=1 at Ro=1; or can be Quantity with units of velocity-squared) - - b) cp, sp= m * phio * cos(m * phib), m * phio * sin(m * phib); can be Quantity with units of velocity-squared) - - OUTPUT: - - (none) - - HISTORY: - - 2011-10-27 - Started - Bovy (IAS) - - 2017-09-16 - Added break radius rb - Bovy (UofT) + Initialize a CosmphiDiskPotential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.), degenerate with phio below, but kept for overall consistency with potentials. + m : int, optional + m in cos(m * phi - m * phib). + p : float + Power-law index of the phi(R) = (R/Ro)^p part. + r1 : float or Quantity, optional + Normalization radius for the amplitude (can be Quantity); amp x phio is only the potential at (R,phi) = (r1,pib) when r1 > rb; otherwise more complicated. + rb : float or Quantity, optional + If set, break radius for power-law: potential R^p at R > Rb, R^-p at R < Rb, potential and force continuous at Rb. + phib : float or Quantity, optional + Angle (in rad; default=25 degree). + phio : float or Quantity, optional + Potential perturbation (in terms of phio/vo^2 if vo=1 at Ro=1; or can be Quantity). + cp : float or Quantity, optional + m * phio * cos(m * phib); can be Quantity with units of velocity-squared. + sp : float or Quantity, optional + m * phio * sin(m * phib); can be Quantity with units of velocity-squared. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Either specify (phib, phio) or (cp, sp). + - 2011-10-27 - Started - Bovy (IAS) + - 2017-09-16 - Added break radius rb - Bovy (UofT) """ planarPotential.__init__(self, amp=amp, ro=ro, vo=vo) @@ -114,20 +106,6 @@ def __init__( self.hasC_dxdv = True def _evaluate(self, R, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - Phi(R,phi,t) - HISTORY: - 2011-10-19 - Started - Bovy (IAS) - """ if R < self._rb: return ( self._mphio @@ -145,20 +123,6 @@ def _evaluate(self, R, phi=0.0, t=0.0): ) def _Rforce(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2011-10-19 - Written - Bovy (IAS) - """ if R < self._rb: return ( -self._p @@ -178,20 +142,6 @@ def _Rforce(self, R, phi=0.0, t=0.0): ) def _phitorque(self, R, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2011-10-19 - Written - Bovy (IAS) - """ if R < self._rb: return ( self._mphio diff --git a/galpy/potential/DehnenBarPotential.py b/galpy/potential/DehnenBarPotential.py index f6e7f4e2f..a523478b2 100644 --- a/galpy/potential/DehnenBarPotential.py +++ b/galpy/potential/DehnenBarPotential.py @@ -96,9 +96,9 @@ def __init__( tsteady : float, optional Time from tform at which the bar is fully grown / bar period (default: -tform/2, so the perturbation is fully grown at tform/2). ro : float or Quantity, optional - Distance from the Galactic center to the observer (can be Quantity). + Distance scale for translation into internal units (default from configuration file). vo : float or Quantity, optional - Circular velocity at ro (can be Quantity). + Velocity scale for translation into internal units (default from configuration file). Notes ----- @@ -173,21 +173,6 @@ def _smooth(self, t): return smooth def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z,phi,t) - HISTORY: - 2010-11-24 - Started - Bovy (NYU) - """ # Calculate relevant time smooth = self._smooth(t) r2 = R**2.0 + z**2.0 @@ -243,21 +228,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ # Calculate relevant time smooth = self._smooth(t) r = numpy.sqrt(R**2.0 + z**2.0) @@ -315,21 +285,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ # Calculate relevant time smooth = self._smooth(t) r2 = R**2.0 + z**2.0 @@ -374,21 +329,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2017-06-23 - Written - Bovy (NYU) - """ # Calculate relevant time smooth = self._smooth(t) r = numpy.sqrt(R**2.0 + z**2.0) @@ -734,21 +674,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _phizderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phizderiv - PURPOSE: - evaluate the mixed azimuthal, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed azimuthal, vertical derivative - HISTORY: - 2021-04-30 - Written - Bovy (UofT) - """ # Calculate relevant time smooth = self._smooth(t) r = numpy.sqrt(R**2.0 + z**2.0) @@ -806,51 +731,36 @@ def _phizderiv(self, R, z, phi=0.0, t=0.0): def tform(self): # pragma: no cover """ - NAME: - - tform - - PURPOSE: - - return formation time of the bar - - INPUT: + Return formation time of the bar. - (none) + Returns + ------- + tform : float + Formation time of the bar in normalized units. - OUTPUT: + Other Parameters + ---------------- + none - tform in normalized units - - HISTORY: - - 2011-03-08 - Written - Bovy (NYU) + Notes + ----- + - 2011-03-08 - Written - Bovy (NYU) """ return self._tform def OmegaP(self): """ - NAME: - - - OmegaP - - PURPOSE: + Return the pattern speed. - return the pattern speed + Returns + ------- + float + The pattern speed. - INPUT: - - (none) - - OUTPUT: - - pattern speed - - HISTORY: - - 2011-10-10 - Written - Bovy (IAS) + Notes + ----- + - 2011-10-10 - Written - Bovy (IAS) """ return self._omegab diff --git a/galpy/potential/DehnenSmoothWrapperPotential.py b/galpy/potential/DehnenSmoothWrapperPotential.py index 351de6997..8c08f5ce0 100644 --- a/galpy/potential/DehnenSmoothWrapperPotential.py +++ b/galpy/potential/DehnenSmoothWrapperPotential.py @@ -29,35 +29,29 @@ def __init__( self, amp=1.0, pot=None, tform=-4.0, tsteady=None, decay=False, ro=None, vo=None ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a DehnenSmoothWrapper Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof; the amplitude of this will be grown by this wrapper - - tform - start of growth (can be a Quantity) - - tsteady - time from tform at which the potential is fully grown (default: -tform/2, st the perturbation is fully grown at tform/2; can be a Quantity) - - decay= (False) if True, decay the amplitude instead of growing it (as 1-grow) - - OUTPUT: - - (none) - - HISTORY: - - 2017-06-26 - Started - Bovy (UofT) - - 2018-10-07 - Added 'decay' option - Bovy (UofT) + Initialize a DehnenSmoothWrapper Potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + pot : Potential instance or list thereof, optional + The amplitude of this will be grown by this wrapper. + tform : float or Quantity, optional + Start of growth (default: -4.0). + tsteady : float or Quantity, optional + Time from tform at which the potential is fully grown (default: -tform/2, so the perturbation is fully grown at tform/2). + decay : bool, optional + If True, decay the amplitude instead of growing it (as 1-grow). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2017-06-26 - Started - Bovy (UofT) + - 2018-10-07 - Added 'decay' option - Bovy (UofT) """ tform = conversion.parse_time(tform, ro=self._ro, vo=self._vo) diff --git a/galpy/potential/DiskSCFPotential.py b/galpy/potential/DiskSCFPotential.py index bebb60129..be0003a15 100644 --- a/galpy/potential/DiskSCFPotential.py +++ b/galpy/potential/DiskSCFPotential.py @@ -64,55 +64,52 @@ def __init__( vo=None, ): """ - NAME: + Initialize a DiskSCFPotential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1); cannot have units currently. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + dens : callable + Function of R,z[,phi optional] that gives the density [in natural units, cannot return a Quantity currently]. + N : int, optional + Number of radial basis functions to use in the SCF expansion. + L : int, optional + Number of angular basis functions to use in the SCF expansion. + a : float or Quantity, optional + Scale radius for the SCF expansion. + radial_order : int, optional + Order of the radial basis functions to use in the SCF expansion. + costheta_order : int, optional + Order of the angular basis functions to use in the SCF expansion. + phi_order : int, optional + Order of the azimuthal basis functions to use in the SCF expansion. + Sigma : dict or callable + Either a dictionary of surface density (example: {'type':'exp','h':1./3.,'amp':1.,'Rhole':0.} for amp x exp(-Rhole/R-R/h) ) or a function of R that gives the surface density. + hz : dict or callable + Either a dictionary of vertical profile, either 'exp' or 'sech2' (example {'type':'exp','h':1./27.} for exp(-|z|/h)/[2h], sech2 is sech^2(z/[2h])/[4h]) or a function of z that gives the vertical profile. + Sigma_amp : float, optional + Amplitude to apply to all Sigma functions. + dSigmadR : callable, optional + Function that gives d Sigma / d R. + d2SigmadR2 : callable, optional + Function that gives d^2 Sigma / d R^2. + Hz : callable, optional + Function of z such that d^2 Hz(z) / d z^2 = hz. + dHzdz : callable, optional + Function of z that gives d Hz(z) / d z. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Either specify (Sigma,hz) or (Sigma_amp,Sigma,dSigmadR,d2SigmadR2,hz,Hz,dHzdz) + - Written - Bovy (UofT) - 2016-12-26 - __init__ - - PURPOSE: - - initialize a DiskSCF Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); cannot have units currently - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - dens= function of R,z[,phi optional] that gives the density [in natural units, cannot return a Quantity currently] - - N=, L=, a=, radial_order=, costheta_order=, phi_order= keywords setting parameters for SCF solution for Phi_ME (see :ref:`scf_compute_coeffs_axi ` or :ref:`scf_compute_coeffs ` depending on whether :math:`\\rho(R,\\phi,z)` is axisymmetric or not) - - Either: - - (a) Sigma= Dictionary of surface density (example: {'type':'exp','h':1./3.,'amp':1.,'Rhole':0.} for amp x exp(-Rhole/R-R/h) ) - - hz= Dictionary of vertical profile, either 'exp' or 'sech2' (example {'type':'exp','h':1./27.} for exp(-|z|/h)/[2h], sech2 is sech^2(z/[2h])/[4h]) - - (b) Sigma= function of R that gives the surface density - - dSigmadR= function that gives d Sigma / d R - - d2SigmadR2= function that gives d^2 Sigma / d R^2 - - Sigma_amp= amplitude to apply to all Sigma functions - - hz= function of z that gives the vertical profile - - Hz= function of z such that d^2 Hz(z) / d z^2 = hz - - dHzdz= function of z that gives d Hz(z) / d z - - In both of these cases lists of arguments can be given for multiple disk components; can't mix (a) and (b) in these lists; if hz is a single item the same vertical profile is assumed for all Sigma - - OUTPUT: - - DiskSCFPotential object - - HISTORY: - - 2016-12-26 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units=None) a = conversion.parse_length(a, ro=self._ro) @@ -182,14 +179,6 @@ def __init__( return None def _parse_Sigma(self, Sigma_amp, Sigma, dSigmadR, d2SigmadR2): - """ - NAME: - _parse_Sigma - PURPOSE: - Parse the various input options for Sigma* functions - HISTORY: - 2016-12-27 - Written - Bovy (UofT/CCA) - """ if isinstance(Sigma, dict): Sigma = [Sigma] try: @@ -248,14 +237,6 @@ def _parse_Sigma_dict_indiv(self, Sigma): return (ta, ts, tds, td2s) def _parse_hz(self, hz, Hz, dHzdz): - """ - NAME: - _parse_hz - PURPOSE: - Parse the various input options for Sigma* functions - HISTORY: - 2016-12-27 - Written - Bovy (UofT/CCA) - """ if isinstance(hz, dict): hz = [hz] try: @@ -336,21 +317,6 @@ def _parse_hz_dict_indiv(self, hz): return (th, tH, tdH) def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z, phi) - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf(R, z, phi=phi, use_physical=False) for a, s, H in zip(self._Sigma_amp, self._Sigma, self._Hz): @@ -358,21 +324,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return out def _Rforce(self, R, z, phi=0, t=0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - radial force at (R,z, phi) - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.Rforce(R, z, phi=phi, use_physical=False) for a, ds, H in zip(self._Sigma_amp, self._dSigmadR, self._Hz): @@ -380,21 +331,6 @@ def _Rforce(self, R, z, phi=0, t=0): return out def _zforce(self, R, z, phi=0, t=0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - vertical force at (R,z, phi) - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.zforce(R, z, phi=phi, use_physical=False) for a, s, ds, H, dH in zip( @@ -404,39 +340,9 @@ def _zforce(self, R, z, phi=0, t=0): return out def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2016-12-26 - Written - Bovy (UofT) - """ return self._scf.phitorque(R, z, phi=phi, use_physical=False) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.R2deriv(R, z, phi=phi, use_physical=False) for a, ds, d2s, H in zip( @@ -453,21 +359,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): return out def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.z2deriv(R, z, phi=phi, use_physical=False) for a, s, ds, d2s, h, H, dH in zip( @@ -492,21 +383,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): return out def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.Rzderiv(R, z, phi=phi, use_physical=False) for a, ds, d2s, H, dH in zip( @@ -524,39 +400,9 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): return out def _phi2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ return self._scf.phi2deriv(R, z, phi=phi, use_physical=False) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - density at (R,z, phi) - HISTORY: - 2016-12-26 - Written - Bovy (UofT/CCA) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = self._scf.dens(R, z, phi=phi, use_physical=False) for a, s, ds, d2s, h, H, dH in zip( @@ -574,20 +420,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): return out def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate spherical - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-09 - Written - Bovy (UofT) - """ if not z is None: # pragma: no cover raise AttributeError # Hack to fall back to general out = self._scf.mass(R, z=None, use_physical=False) diff --git a/galpy/potential/DoubleExponentialDiskPotential.py b/galpy/potential/DoubleExponentialDiskPotential.py index d5f4849f9..c444875c5 100644 --- a/galpy/potential/DoubleExponentialDiskPotential.py +++ b/galpy/potential/DoubleExponentialDiskPotential.py @@ -42,42 +42,32 @@ def __init__( de_n=10000, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a double-exponential disk potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - hr - disk scale-length (can be Quantity) - - hz - scale-height (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - de_h= (1e-3) step used in numerical integration - - de_b= (10000) number of points used in numerical integration (use 1000 for a lower accuracy version that is typically still high accuracy enough, but faster) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - DoubleExponentialDiskPotential object - - HISTORY: - - 2010-04-16 - Written - Bovy (NYU) - - 2013-01-01 - Re-implemented using faster integration techniques - Bovy (IAS) - - 2020-12-24 - Re-implemented again using more accurate integration techniques for Bessel integrals - Bovy (UofT) - + Initialize a double exponential disk potential + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density. + hr : float or Quantity, optional + Disk scale-length. + hz : float or Quantity, optional + Scale-height. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + de_h : float, optional + Step used in numerical integration. + de_n : int, optional + Number of points used in numerical integration (use 1000 for a lower accuracy version that is typically still high accuracy enough, but faster). + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-04-16 - Written - Bovy (NYU) + - 2013-01-01 - Re-implemented using faster integration techniques - Bovy (IAS) + - 2020-12-24 - Re-implemented again using more accurate integration techniques for Bessel integrals - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="density") hr = conversion.parse_length(hr, ro=self._ro) @@ -135,21 +125,29 @@ def __init__( def _evaluate(self, R, z, phi=0.0, t=0.0, dR=0, dphi=0): """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z) - HISTORY: - 2010-04-16 - Written - Bovy (NYU) - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate the potential at (R,z) + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + Potential at (R,z) + + Notes + ----- + - 2010-04-16 - Written - Bovy (NYU) + - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ if isinstance(R, (float, int)): floatIn = True @@ -189,21 +187,29 @@ def _evaluate(self, R, z, phi=0.0, t=0.0, dR=0, dphi=0): @check_potential_inputs_not_arrays def _Rforce(self, R, z, phi=0.0, t=0.0): """ - NAME: - Rforce - PURPOSE: - evaluate radial force K_R (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - K_R (R,z) - HISTORY: - 2010-04-16 - Written - Bovy (NYU) - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate radial force K_R (R,z) + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + Radial force (R,z) + + Notes + ----- + - 2010-04-16 - Written - Bovy (NYU) + - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ fun = ( lambda x: x @@ -225,21 +231,29 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _zforce(self, R, z, phi=0.0, t=0.0): """ - NAME: - zforce - PURPOSE: - evaluate vertical force K_z (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - K_z (R,z) - HISTORY: - 2010-04-16 - Written - Bovy (NYU) - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate vertical force K_z (R,z) + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + Vertical force (R,z) + + Notes + ----- + - 2010-04-16 - Written - Bovy (NYU) + - 2012-12-26 - New method using Gaussian quadrature between zeros - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ fun = ( lambda x: (self._alpha**2.0 + (x / R) ** 2.0) ** -1.5 @@ -267,20 +281,28 @@ def _zforce(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _R2deriv(self, R, z, phi=0.0, t=0.0): """ - NAME: - R2deriv - PURPOSE: - evaluate R2 derivative - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - -d K_R (R,z) d R - HISTORY: - 2012-12-27 - Written - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate radial force K_R (R,z) R2 derivative + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + -d K_R (R,z) d R + + Notes + ----- + - 2012-12-27 - Written - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ fun = ( lambda x: x**2 @@ -305,20 +327,28 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _z2deriv(self, R, z, phi=0.0, t=0.0): """ - NAME: - z2deriv - PURPOSE: - evaluate z2 derivative - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - -d K_Z (R,z) d Z - HISTORY: - 2012-12-26 - Written - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate vertical force K_Z (R,z) Z2 derivative + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + -d K_Z (R,z) d Z + + Notes + ----- + - 2012-12-26 - Written - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ fun = ( lambda x: (self._alpha**2.0 + (x / R) ** 2.0) ** -1.5 @@ -342,20 +372,28 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rzderiv(self, R, z, phi=0.0, t=0.0): """ - NAME: - Rzderiv - PURPOSE: - evaluate the mixed R,z derivative - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) + Evaluate mixed R,z derivative d2phi/dR/dz. + + Parameters + ---------- + R : float + Cylindrical Galactocentric radius + z : float + Vertical height + phi : float, optional + Azimuth (default: 0.0) + t : float, optional + Time (default: 0.0) + + Returns + ------- + float + d2phi/dR/dz + + Notes + ----- + - 2013-08-28 - Written - Bovy (IAS) + - 2020-12-24 - New method using Ogata's Bessel integral formula - Bovy (UofT) """ fun = ( lambda x: (self._alpha**2.0 + (x / R) ** 2.0) ** -1.5 @@ -380,39 +418,9 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): return -out def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - rho (R,z) - HISTORY: - 2010-08-08 - Written - Bovy (NYU) - """ return numpy.exp(-self._alpha * R - self._beta * numpy.fabs(z)) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Sigma (R,z) - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ return ( 2.0 * numpy.exp(-self._alpha * R) diff --git a/galpy/potential/EllipsoidalPotential.py b/galpy/potential/EllipsoidalPotential.py index 0be932e37..56c4fcc51 100644 --- a/galpy/potential/EllipsoidalPotential.py +++ b/galpy/potential/EllipsoidalPotential.py @@ -48,39 +48,32 @@ def __init__( amp_units=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a ellipsoidal potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units that depend on the specific spheroidal potential - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units (passed to Potential.__init__) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2018-08-06 - Started - Bovy (UofT) + Initialize an ellipsoidal potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units that depend on the specific spheroidal potential. + b : float, optional + y-to-x axis ratio of the density. + c : float, optional + z-to-x axis ratio of the density. + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis (rad or Quantity). + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + amp_units : str, optional + Type of units that amp should have if it has units (passed to Potential.__init__). + + Notes + ----- + - 2018-08-06 - Started - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units=amp_units) @@ -140,21 +133,6 @@ def _setup_gl(self, glorder): @check_potential_inputs_not_arrays def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2016-05-30 - Started - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -181,21 +159,6 @@ def _evaluate_xyz(self, x, y, z): @check_potential_inputs_not_arrays def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2016-06-09 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -225,21 +188,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2016-06-09 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -269,21 +217,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2016-06-09 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -333,21 +266,6 @@ def _force_xyz(self, x, y, z, i): @check_potential_inputs_not_arrays def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2016-06-15 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -366,21 +284,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed radial, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, vertical derivative - HISTORY: - 2016-06-15 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -394,21 +297,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2016-06-15 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -420,21 +308,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _phi2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - HISTORY: - 2016-06-15 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -455,21 +328,6 @@ def _phi2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rphideriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rphideriv - PURPOSE: - evaluate the mixed radial, azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, azimuthal derivative - HISTORY: - 2016-06-15 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -491,21 +349,6 @@ def _Rphideriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _phizderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phizderiv - PURPOSE: - evaluate the mixed azimuthal, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, azimuthal derivative - HISTORY: - 2021-04-30 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -542,21 +385,6 @@ def _2ndderiv_xyz(self, x, y, z, i, j): @check_potential_inputs_not_arrays def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2018-08-06 - Written - Bovy (UofT) - """ x, y, z = coords.cyl_to_rect(R, phi, z) if self._aligned: xp, yp, zp = x, y, z @@ -567,20 +395,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): return self._mdens(m) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to z=inf - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-08 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( @@ -592,18 +406,6 @@ def _mass(self, R, z=None, t=0.0): ) def OmegaP(self): - """ - NAME: - OmegaP - PURPOSE: - return the pattern speed - INPUT: - (none) - OUTPUT: - pattern speed - HISTORY: - 2016-05-31 - Written - Bovy (UofT) - """ return 0.0 diff --git a/galpy/potential/EllipticalDiskPotential.py b/galpy/potential/EllipticalDiskPotential.py index ca0ce97f5..78596ef7e 100644 --- a/galpy/potential/EllipticalDiskPotential.py +++ b/galpy/potential/EllipticalDiskPotential.py @@ -36,44 +36,37 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize an Elliptical disk potential - - phi(R,phi) = phio (R/Ro)^p cos[2(phi-phib)] - - INPUT: - - amp= amplitude to be applied to the potential (default: - 1.), see twophio below - - tform= start of growth (to smoothly grow this potential (can be Quantity) - - tsteady= time delay at which the perturbation is fully grown (default: 2.; can be Quantity) - - p= power-law index of the phi(R) = (R/Ro)^p part - - r1= (1.) normalization radius for the amplitude (can be Quantity) - - Either: - - a) phib= angle (in rad; default=25 degree; or can be Quantity) - - twophio= potential perturbation (in terms of 2phio/vo^2 if vo=1 at Ro=1; can be Quantity with units of velocity-squared) - - b) cp, sp= twophio * cos(2phib), twophio * sin(2phib) (can be Quantity with units of velocity-squared) - - OUTPUT: - - (none) - - HISTORY: - - 2011-10-19 - Started - Bovy (IAS) + Initialize an Elliptical disk potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.), see twophio below. + tform : float or Quantity, optional + Start of growth (to smoothly grow this potential). + tsteady : float or Quantity, optional + Time delay at which the perturbation is fully grown (default: 2.). + p : float, optional + Power-law index of the phi(R) = (R/Ro)^p part. + r1 : float or Quantity, optional + Normalization radius for the amplitude. + phib : float or Quantity, optional + Angle (in rad; default=25 degree). + twophio : float or Quantity, optional + Potential perturbation (in terms of 2phio/vo^2 if vo=1 at Ro=1). + cp : float or Quantity, optional + Twophio * cos(2phib). + sp : float or Quantity, optional + Twophio * sin(2phib). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Specify either (phib,twophio) or (cp,sp). + - 2011-10-19 - Started - Bovy (IAS) """ planarPotential.__init__(self, amp=amp, ro=ro, vo=vo) @@ -108,20 +101,6 @@ def __init__( self._tsteady = self._tform + 2.0 def _evaluate(self, R, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - Phi(R,phi,t) - HISTORY: - 2011-10-19 - Started - Bovy (IAS) - """ # Calculate relevant time if not self._tform is None: if t < self._tform: @@ -148,20 +127,6 @@ def _evaluate(self, R, phi=0.0, t=0.0): ) def _Rforce(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2011-10-19 - Written - Bovy (IAS) - """ # Calculate relevant time if not self._tform is None: if t < self._tform: @@ -189,20 +154,6 @@ def _Rforce(self, R, phi=0.0, t=0.0): ) def _phitorque(self, R, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2011-10-19 - Written - Bovy (IAS) - """ # Calculate relevant time if not self._tform is None: if t < self._tform: @@ -304,27 +255,17 @@ def _Rphideriv(self, R, phi=0.0, t=0.0): * numpy.sin(2.0 * (phi - self._phib)) ) - def tform(self): # pragma: no cover + def tform(self): """ - NAME: - - tform - - PURPOSE: - - return formation time of the perturbation - - INPUT: - - (none) - - OUTPUT: - - tform in normalized units - - HISTORY: + Return formation time of the perturbation. - 2011-10-19 - Written - Bovy (IAS) + Returns + ------- + float + Formation time of the perturbation in normalized units. + Notes + ----- + - 2011-10-19 - Written - Bovy (IAS) """ return self._tform diff --git a/galpy/potential/FerrersPotential.py b/galpy/potential/FerrersPotential.py index 3da031ff3..ae9056f6e 100644 --- a/galpy/potential/FerrersPotential.py +++ b/galpy/potential/FerrersPotential.py @@ -50,38 +50,34 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Ferrers potential - - INPUT: - - amp - total mass of the ellipsoid determines the amplitude of the potential; can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - n - power of Ferrers density (n > 0) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - omegab - rotation speed of the ellipsoid (can be Quantity) - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - + Initialize a Ferrers potential. + + Parameters + ---------- + amp : float or Quantity, optional + Total mass of the ellipsoid determines the amplitude of the potential. + a : float or Quantity, optional + Scale radius. + n : int, optional + Power of Ferrers density (n > 0). + b : float, optional + y-to-x axis ratio of the density. + c : float, optional + z-to-x axis ratio of the density. + omegab : float or Quantity, optional + Rotation speed of the ellipsoid. + pa : float or Quantity, optional + If set, the position angle of the x axis (rad or Quantity). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2011-02-23: Written - Bovy (NYU) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") a = conversion.parse_length(a, ro=self._ro) @@ -110,19 +106,6 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - """ if not self.isNonAxi: phi = 0.0 x, y, z = coords.cyl_to_rect(R, phi, z) @@ -146,38 +129,12 @@ def _evaluate_xyz(self, x, y, z=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE:T - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - """ if not self.isNonAxi: phi = 0.0 self._compute_xyzforces(R, z, phi, t) return numpy.cos(phi) * self._cached_Fx + numpy.sin(phi) * self._cached_Fy def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - """ if not self.isNonAxi: phi = 0.0 self._compute_xyzforces(R, z, phi, t) @@ -186,19 +143,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - """ if not self.isNonAxi: phi = 0.0 self._compute_xyzforces(R, z, phi, t) @@ -272,19 +216,6 @@ def _zforce_xyz(self, x, y, z): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) @@ -303,19 +234,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed radial, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, vertical derivative - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) @@ -328,38 +246,12 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): return numpy.cos(phi) * phixz + numpy.sin(phi) * phiyz def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) return self._2ndderiv_xyz(x, y, z, 2, 2) def _phi2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) @@ -382,19 +274,6 @@ def _phi2deriv(self, R, z, phi=0.0, t=0.0): ) + R * (numpy.cos(phi) * Fx + numpy.sin(phi) * Fy) def _Rphideriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rphideriv - PURPOSE: - evaluate the mixed radial, azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, azimuthal derivative - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) @@ -418,21 +297,6 @@ def _Rphideriv(self, R, z, phi=0.0, t=0.0): ) def _phizderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phizderiv - PURPOSE: - evaluate the mixed azimuthal, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed azimuthal, vertical derivative - HISTORY: - 2021-04-30 - Written - Bovy (UofT) - """ if not self.isNonAxi: phi = 0.0 x, y, z = self._compute_xyz(R, phi, z, t) @@ -466,19 +330,6 @@ def _2ndderiv_xyz(self, x, y, z, i, j): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - """ x, y, z = self._compute_xyz(R, phi, z, t) m2 = x**2 / self._a2 + y**2 / self._b2 + z**2 / self._c2 if m2 < 1: @@ -487,16 +338,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): return 0.0 def OmegaP(self): - """ - NAME: - OmegaP - PURPOSE: - return the pattern speed - INPUT: - (none) - OUTPUT: - pattern speed - """ return self._omegab def rot(self, t=0.0, transposed=False): diff --git a/galpy/potential/FlattenedPowerPotential.py b/galpy/potential/FlattenedPowerPotential.py index 439810367..798d749c4 100644 --- a/galpy/potential/FlattenedPowerPotential.py +++ b/galpy/potential/FlattenedPowerPotential.py @@ -39,38 +39,30 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a flattened power-law potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of velocity-squared - - alpha - power - - q - flattening - - core - core radius (can be Quantity) - - r1= (1.) reference radius for amplitude (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2013-01-09 - Written - Bovy (IAS) - + Initialize a flattened power-law potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential. Can be a Quantity with units of velocity squared. + alpha : float, optional + Power-law exponent. + q : float, optional + Flattening parameter. + core : float or Quantity, optional + Core radius. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + r1 : float or Quantity, optional + Reference radius for amplitude. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013-01-09 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="velocity2") core = conversion.parse_length(core, ro=self._ro) @@ -89,21 +81,6 @@ def __init__( self.hasC_dens = True def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2013-01-09 - Started - Bovy (IAS) - """ if self.alpha == 0.0: return 1.0 / 2.0 * numpy.log(R**2.0 + z**2.0 / self.q2 + self.core2) else: @@ -111,21 +88,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return -(m2 ** (-self.alpha / 2.0)) / self.alpha def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-07-10 - Written - Bovy (NYU) - """ if self.alpha == 0.0: return -R / (R**2.0 + z**2.0 / self.q2 + self.core2) else: @@ -133,21 +95,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): return -(m2 ** (-self.alpha / 2.0 - 1.0)) * R def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-10 - Written - Bovy (NYU) - """ if self.alpha == 0.0: return -z / self.q2 / (R**2.0 + z**2.0 / self.q2 + self.core2) else: @@ -155,21 +102,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return -(m2 ** (-self.alpha / 2.0 - 1.0)) * z / self.q2 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rderiv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (NYU) - """ if self.alpha == 0.0: denom = 1.0 / (R**2.0 + z**2.0 / self.q2 + self.core2) return denom - 2.0 * R**2.0 * denom**2.0 @@ -180,21 +112,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2012-07-26 - Written - Bovy (IAS@MPIA) - """ if self.alpha == 0.0: denom = 1.0 / (R**2.0 + z**2.0 / self.q2 + self.core2) return denom / self.q2 - 2.0 * z**2.0 * denom**2.0 / self.q2**2.0 @@ -208,21 +125,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2013-01-09 - Written - Bovy (IAS) - """ if self.alpha == 0.0: return ( 1.0 diff --git a/galpy/potential/GaussianAmplitudeWrapperPotential.py b/galpy/potential/GaussianAmplitudeWrapperPotential.py index 015a92b4c..c54fe2422 100644 --- a/galpy/potential/GaussianAmplitudeWrapperPotential.py +++ b/galpy/potential/GaussianAmplitudeWrapperPotential.py @@ -18,32 +18,26 @@ class GaussianAmplitudeWrapperPotential(parentWrapperPotential): def __init__(self, amp=1.0, pot=None, to=0.0, sigma=1.0, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a GaussianAmplitudeWrapper Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof; this potential is made to rotate around the z axis by the wrapper - - to= (0.) time at which the Gaussian peaks - - sigma= (1.) standard deviation of the Gaussian (can be a Quantity) - - OUTPUT: - - (none) - - HISTORY: - - 2018-02-21 - Started - Bovy (UofT) - + Initialize a GaussianAmplitudeWrapper Potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential. Default is 1.0. + pot : Potential instance or list thereof, optional + This potential is made to rotate around the z axis by the wrapper. + to : float or Quantity, optional + Time at which the Gaussian peaks. Default is 0.0. + sigma : float or Quantity, optional + Standard deviation of the Gaussian. Default is 1.0. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-02-21 - Started - Bovy (UofT) """ to = conversion.parse_time(to, ro=self._ro, vo=self._vo) sigma = conversion.parse_time(sigma, ro=self._ro, vo=self._vo) diff --git a/galpy/potential/HenonHeilesPotential.py b/galpy/potential/HenonHeilesPotential.py index ac96a8549..b1923adce 100644 --- a/galpy/potential/HenonHeilesPotential.py +++ b/galpy/potential/HenonHeilesPotential.py @@ -17,129 +17,39 @@ class HenonHeilesPotential(planarPotential): def __init__(self, amp=1.0, ro=None, vo=None): """ - NAME: + Initialize a Henon-Heiles potential - __init__ - - PURPOSE: - - initialize a Henon-Heiles potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - OUTPUT: - - (none) - - HISTORY: - - 2017-10-16 - Written - Bovy (UofT) + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.) + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + Notes + ----- + - 2017-10-16 - Written - Bovy (UofT) """ planarPotential.__init__(self, amp=amp, ro=ro, vo=vo) self.hasC = True self.hasC_dxdv = True def _evaluate(self, R, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - Phi(R,phi,t) - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return 0.5 * R * R * (1.0 + 2.0 / 3.0 * R * numpy.sin(3.0 * phi)) def _Rforce(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return -R * (1.0 + R * numpy.sin(3.0 * phi)) def _phitorque(self, R, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return -(R**3.0) * numpy.cos(3.0 * phi) def _R2deriv(self, R, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return 1.0 + 2.0 * R * numpy.sin(3.0 * phi) def _phi2deriv(self, R, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return -3.0 * R**3.0 * numpy.sin(3.0 * phi) def _Rphideriv(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rphideriv - PURPOSE: - evaluate the mixed radial, azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the mixed radial, azimuthal derivative - HISTORY: - 2017-10-16 - Written - Bovy (UofT) - """ return 3.0 * R**2.0 * numpy.cos(3.0 * phi) diff --git a/galpy/potential/HomogeneousSpherePotential.py b/galpy/potential/HomogeneousSpherePotential.py index 3c3de32e6..bcaee9f08 100644 --- a/galpy/potential/HomogeneousSpherePotential.py +++ b/galpy/potential/HomogeneousSpherePotential.py @@ -22,32 +22,24 @@ class HomogeneousSpherePotential(Potential): def __init__(self, amp=1.0, R=1.1, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a homogeneous sphere potential - - INPUT: - - amp= amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - R= size of the sphere (can be Quantity) - - normalize= if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2019-12-20 - Written - Bovy (UofT) - + Initialize a homogeneous sphere potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential. Can be a Quantity with units of mass density or Gxmass density. + R : float or Quantity, optional + Size of the sphere. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2019-12-20 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="density") R = conversion.parse_length(R, ro=self._ro) @@ -63,21 +55,6 @@ def __init__(self, amp=1.0, R=1.1, normalize=False, ro=None, vo=None): self.hasC_dens = True def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return r2 - 3.0 * self._R2 @@ -85,21 +62,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return -2.0 * self._R3 / numpy.sqrt(r2) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return -2.0 * R @@ -107,21 +69,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): return -2.0 * self._R3 * R / r2**1.5 def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return -2.0 * z @@ -129,21 +76,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return -2.0 * self._R3 * z / r2**1.5 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rderiv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return 2.0 @@ -151,21 +83,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): return 2.0 * self._R3 / r2**1.5 - 6.0 * self._R3 * R**2.0 / r2**2.5 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return 2.0 @@ -173,21 +90,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): return 2.0 * self._R3 / r2**1.5 - 6.0 * self._R3 * z**2.0 / r2**2.5 def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return 0.0 @@ -195,21 +97,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): return -6.0 * self._R3 * R * z / r2**2.5 def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2019-12-20 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 if r2 < self._R2: return 1.5 / numpy.pi diff --git a/galpy/potential/IsochronePotential.py b/galpy/potential/IsochronePotential.py index 7a4e9ee1f..371a2da73 100644 --- a/galpy/potential/IsochronePotential.py +++ b/galpy/potential/IsochronePotential.py @@ -23,32 +23,24 @@ class IsochronePotential(Potential): def __init__(self, amp=1.0, b=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize an isochrone potential - - INPUT: - - amp= amplitude to be applied to the potential, the total mass (default: 1); can be a Quantity with units of mass or Gxmass - - b= scale radius of the isochrone potential (can be Quantity) - - normalize= if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2013-09-08 - Written - Bovy (IAS) - + Initialize an isochrone potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential, the total mass. Can be a Quantity with units of mass or Gxmass. + b : float or Quantity, optional + Scale radius of the isochrone potential. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Default is False. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013-09-08 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") b = conversion.parse_length(b, ro=self._ro) @@ -64,83 +56,23 @@ def __init__(self, amp=1.0, b=1.0, normalize=False, ro=None, vo=None): self.hasC_dens = True def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return -1.0 / (self.b + rb) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) dPhidrr = -1.0 / rb / (self.b + rb) ** 2.0 return dPhidrr * R def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) dPhidrr = -1.0 / rb / (self.b + rb) ** 2.0 return dPhidrr * z def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rderiv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return ( @@ -154,21 +86,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return ( @@ -182,41 +99,11 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return -R * z * (self.b + 3.0 * rb) / rb**3.0 / (self.b + rb) ** 3.0 def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2013-09-08 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return ( @@ -228,21 +115,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the surface density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 rb = numpy.sqrt(r2 + self.b2) return ( diff --git a/galpy/potential/IsothermalDiskPotential.py b/galpy/potential/IsothermalDiskPotential.py index 98b4a8ed5..a0661c544 100644 --- a/galpy/potential/IsothermalDiskPotential.py +++ b/galpy/potential/IsothermalDiskPotential.py @@ -21,27 +21,22 @@ class IsothermalDiskPotential(linearPotential): def __init__(self, amp=1.0, sigma=0.1, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - Initialize an IsothermalDiskPotential - - INPUT: - - amp - an overall amplitude - - sigma - velocity dispersion (can be a Quantity) - - OUTPUT: - - instance - - HISTORY: - - 2018-04-11 - Written - Bovy (UofT) + Initialize an IsothermalDiskPotential. + + Parameters + ---------- + amp : float, optional + An overall amplitude. + sigma : float or Quantity, optional + Velocity dispersion. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-04-11 - Written - Bovy (UofT) """ linearPotential.__init__(self, amp=amp, ro=ro, vo=vo) diff --git a/galpy/potential/KGPotential.py b/galpy/potential/KGPotential.py index e64b4f7d0..d8bdb3422 100644 --- a/galpy/potential/KGPotential.py +++ b/galpy/potential/KGPotential.py @@ -17,33 +17,28 @@ class KGPotential(linearPotential): """ - def __init__(self, K=1.15, F=0.03, D=1.8, amp=1.0, ro=None, vo=None): + def __init__(self, amp=1.0, K=1.15, F=0.03, D=1.8, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a KGPotential - - INPUT: - - K= K parameter (= :math:`2\\pi \\Sigma_{\\mathrm{disk}}`; specify either as surface density or directly as force [i.e., including :math:`2\\pi G`]; can be Quantity) - - F= F parameter (= :math:`4\\pi\\rho_{\\mathrm{halo}}`; specify either as density or directly as second potential derivative [i.e., including :math:`4\\pi G`]; can be Quantity) - - D= D parameter (natural units or Quantity length units) - - amp - an overall amplitude - - OUTPUT: - - instance - - HISTORY: - - 2010-07-12 - Written - Bovy (NYU) + Initialize a KGPotential + + Parameters + ---------- + amp : float or Quantity, optional + An overall amplitude, by default 1.0 + K : float or Quantity, optional + K parameter (= 2πΣ_disk; specify either as surface density or directly as force [i.e., including 2πG]), by default 1.15 + F : float or Quantity, optional + F parameter (= 4πρ_halo; specify either as density or directly as second potential derivative [i.e., including 4πG]), by default 0.03 + D : float or Quantity, optional + D parameter (natural units or Quantity length units), by default 1.8 + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-07-12 - Written - Bovy (NYU) """ linearPotential.__init__(self, amp=amp, ro=ro, vo=vo) diff --git a/galpy/potential/KingPotential.py b/galpy/potential/KingPotential.py index 801964007..2d080ff02 100644 --- a/galpy/potential/KingPotential.py +++ b/galpy/potential/KingPotential.py @@ -20,33 +20,26 @@ class KingPotential(interpSphericalPotential): def __init__(self, W0=2.0, M=3.0, rt=1.5, npt=1001, _sfkdf=None, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a King potential - - INPUT: - - W0= (2.) dimensionless central potential W0 = Psi(0)/sigma^2 (in practice, needs to be <~ 200, where the DF is essentially isothermal) - - M= (1.) total mass (can be a Quantity) - - rt= (1.) tidal radius (can be a Quantity) - - npt= (1001) number of points to use to solve for Psi(r) when solving the King DF - - ro=, vo= standard galpy unit scaling parameters - - OUTPUT: - - (none; sets up instance) - - HISTORY: - - 2020-07-11 - Written - Bovy (UofT) + Initialize a King potential + + Parameters + ---------- + W0 : float, optional + Dimensionless central potential W0 = Psi(0)/sigma^2 (in practice, needs to be <~ 200, where the DF is essentially isothermal). Default: 2. + M : float or Quantity, optional + Total mass. Default: 1. + rt : float or Quantity, optional + Tidal radius. Default: 1. + npt : int, optional + Number of points to use to solve for Psi(r) when solving the King DF. Default: 1001. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2020-07-11 - Written - Bovy (UofT) """ # Initialize with Force just to parse (ro,vo) diff --git a/galpy/potential/KuzminDiskPotential.py b/galpy/potential/KuzminDiskPotential.py index 85db3677d..877a2f8d8 100644 --- a/galpy/potential/KuzminDiskPotential.py +++ b/galpy/potential/KuzminDiskPotential.py @@ -23,31 +23,24 @@ class KuzminDiskPotential(Potential): def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Kuzmin disk Potential - - INPUT: - - amp - amplitude to be applied to the potential, the total mass (default: 1); can be a Quantity with units of mass density or Gxmass density - - a - scale length (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - KuzminDiskPotential object - - HISTORY: - - 2016-05-09 - Written - Aladdin + Initialize a Kuzmin disk Potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential, the total mass. Can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale length. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2016-05-09 - Written - Aladdin """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") @@ -62,93 +55,18 @@ def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z) - HISTORY: - 2016-05-09 - Written - Aladdin - """ return -self._denom(R, z) ** -0.5 def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force = -dphi/dR - HISTORY: - 2016-05-09 - Written - Aladdin - """ return -self._denom(R, z) ** -1.5 * R def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force = -dphi/dz - HISTORY: - 2016-05-09 - Written - Aladdin - """ return -numpy.sign(z) * self._denom(R, z) ** -1.5 * (self._a + numpy.fabs(z)) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2016-05-13 - Written - Aladdin - """ return self._denom(R, z) ** -1.5 - 3.0 * R**2 * self._denom(R, z) ** -2.5 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2016-05-13 - Written - Aladdin - """ a = self._a return ( self._denom(R, z) ** -1.5 @@ -156,21 +74,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2016-05-13 - Written - Aladdin - """ return ( -3 * numpy.sign(z) @@ -180,53 +83,10 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Sigma (R,z) - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ return self._a * (R**2 + self._a**2) ** -1.5 / 2.0 / numpy.pi def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to z=inf - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-04 - Written - Bovy (UofT) - """ return 1.0 - self._a / numpy.sqrt(R**2.0 + self._a**2.0) def _denom(self, R, z): - """ - NAME: - _denom - PURPOSE: - evaluate R^2 + (a + |z|)^2 which is used in the denominator - of most equations - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - OUTPUT: - R^2 + (a + |z|)^2 - HISTORY: - 2016-05-09 - Written - Aladdin - """ return R**2.0 + (self._a + numpy.fabs(z)) ** 2.0 diff --git a/galpy/potential/KuzminKutuzovStaeckelPotential.py b/galpy/potential/KuzminKutuzovStaeckelPotential.py index 45859ceaa..a96108638 100644 --- a/galpy/potential/KuzminKutuzovStaeckelPotential.py +++ b/galpy/potential/KuzminKutuzovStaeckelPotential.py @@ -26,34 +26,26 @@ class KuzminKutuzovStaeckelPotential(Potential): def __init__(self, amp=1.0, ac=5.0, Delta=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Kuzmin-Kutuzov Staeckel potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - ac - axis ratio of the coordinate surfaces; (a/c) = sqrt(-alpha) / sqrt(-gamma) (default: 5.) - - Delta - focal distance that defines the spheroidal coordinate system (default: 1.); Delta=sqrt(gamma-alpha) (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2015-02-15 - Written - Trick (MPIA) - + Initialize a Kuzmin-Kutuzov Staeckel potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential; can be a Quantity with units of mass density or Gxmass density. + ac : float, optional + Axis ratio of the coordinate surfaces; (a/c) = sqrt(-alpha) / sqrt(-gamma) (default: 5.). + Delta : float or Quantity, optional + Focal distance that defines the spheroidal coordinate system (default: 1.); Delta=sqrt(gamma-alpha). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2015-02-15 - Written - Trick (MPIA) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") Delta = conversion.parse_length(Delta, ro=self._ro) @@ -69,40 +61,10 @@ def __init__(self, amp=1.0, ac=5.0, Delta=1.0, normalize=False, ro=None, vo=None self.hasC_dxdv = True def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2015-02-15 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) return -1.0 / (numpy.sqrt(l) + numpy.sqrt(n)) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force = -dphi/dR - HISTORY: - 2015-02-13 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) jac = coords.Rz_to_lambdanu_jac(R, z, Delta=self._Delta) dldR = jac[0, 0] @@ -110,21 +72,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): return -(dldR * self._lderiv(l, n) + dndR * self._nderiv(l, n)) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2015-02-13 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) jac = coords.Rz_to_lambdanu_jac(R, z, Delta=self._Delta) dldz = jac[0, 1] @@ -132,21 +79,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return -(dldz * self._lderiv(l, n) + dndz * self._nderiv(l, n)) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2015-02-13 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) jac = coords.Rz_to_lambdanu_jac(R, z, Delta=self._Delta) hess = coords.Rz_to_lambdanu_hess(R, z, Delta=self._Delta) @@ -163,21 +95,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2015-02-13 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) jac = coords.Rz_to_lambdanu_jac(R, z, Delta=self._Delta) hess = coords.Rz_to_lambdanu_hess(R, z, Delta=self._Delta) @@ -194,21 +111,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2015-02-13 - Written - Trick (MPIA) - """ l, n = coords.Rz_to_lambdanu(R, z, ac=self._ac, Delta=self._Delta) jac = coords.Rz_to_lambdanu_jac(R, z, Delta=self._Delta) hess = coords.Rz_to_lambdanu_hess(R, z, Delta=self._Delta) @@ -228,49 +130,69 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): def _lderiv(self, l, n): """ - NAME: - _lderiv - PURPOSE: - evaluate the derivative w.r.t. lambda for this potential - INPUT: - l - prolate spheroidal coordinate lambda - n - prolate spheroidal coordinate nu - OUTPUT: - derivative w.r.t. lambda - HISTORY: - 2015-02-15 - Written - Trick (MPIA) + Evaluate the derivative w.r.t. lambda for this potential. + + Parameters + ---------- + l : float + Prolate spheroidal coordinate lambda. + n : float + Prolate spheroidal coordinate nu. + + Returns + ------- + float + Derivative w.r.t. lambda. + + Notes + ----- + - 2015-02-15 - Written - Trick (MPIA) """ return 0.5 / numpy.sqrt(l) / (numpy.sqrt(l) + numpy.sqrt(n)) ** 2 def _nderiv(self, l, n): """ - NAME: - _nderiv - PURPOSE: - evaluate the derivative w.r.t. nu for this potential - INPUT: - l - prolate spheroidal coordinate lambda - n - prolate spheroidal coordinate nu - OUTPUT: - derivative w.r.t. nu - HISTORY: - 2015-02-15 - Written - Trick (MPIA) + Evaluate the derivative w.r.t. nu for this potential. + + Parameters + ---------- + l : float + Prolate spheroidal coordinate lambda. + n : float + Prolate spheroidal coordinate nu. + + Returns + ------- + float + Derivative w.r.t. nu. + + Notes + ----- + - 2015-02-15 - Written - Trick (MPIA) + """ return 0.5 / numpy.sqrt(n) / (numpy.sqrt(l) + numpy.sqrt(n)) ** 2 def _l2deriv(self, l, n): """ - NAME: - _l2deriv - PURPOSE: - evaluate the second derivative w.r.t. lambda for this potential - INPUT: - l - prolate spheroidal coordinate lambda - n - prolate spheroidal coordinate nu - OUTPUT: - second derivative w.r.t. lambda - HISTORY: - 2015-02-15 - Written - Trick (MPIA) + Evaluate the second derivative w.r.t. lambda for this potential. + + Parameters + ---------- + l : float + Prolate spheroidal coordinate lambda. + n : float + Prolate spheroidal coordinate nu. + + Returns + ------- + float + Second derivative w.r.t. lambda. + + Notes + ----- + - 2015-02-15 - Written - Trick (MPIA) + """ number = -3.0 * numpy.sqrt(l) - numpy.sqrt(n) denom = 4.0 * l**1.5 * (numpy.sqrt(l) + numpy.sqrt(n)) ** 3 @@ -278,17 +200,24 @@ def _l2deriv(self, l, n): def _n2deriv(self, l, n): """ - NAME: - _n2deriv - PURPOSE: - evaluate the second derivative w.r.t. nu for this potential - INPUT: - l - prolate spheroidal coordinate lambda - n - prolate spheroidal coordinate nu - OUTPUT: - second derivative w.r.t. nu - HISTORY: - 2015-02-15 - Written - Trick (MPIA) + Evaluate the second derivative w.r.t. nu for this potential. + + Parameters + ---------- + l : float + Prolate spheroidal coordinate lambda. + n : float + Prolate spheroidal coordinate nu. + + Returns + ------- + float + Second derivative w.r.t. nu. + + Notes + ----- + - 2015-02-15 - Written - Trick (MPIA) + """ number = -numpy.sqrt(l) - 3.0 * numpy.sqrt(n) denom = 4.0 * n**1.5 * (numpy.sqrt(l) + numpy.sqrt(n)) ** 3 @@ -296,17 +225,24 @@ def _n2deriv(self, l, n): def _lnderiv(self, l, n): """ - NAME: - _lnderiv - PURPOSE: - evaluate the mixed derivative w.r.t. lambda and nu for this potential - INPUT: - l - prolate spheroidal coordinate lambda - n - prolate spheroidal coordinate nu - OUTPUT: - d2phi/dl/dn - HISTORY: - 2015-02-13 - Written - Trick (MPIA) + Evaluate the mixed derivative w.r.t. lambda and nu for this potential. + + Parameters + ---------- + l : float + Prolate spheroidal coordinate lambda. + n : float + Prolate spheroidal coordinate nu. + + Returns + ------- + float + Mixed derivative w.r.t. lambda and nu. + + Notes + ----- + - 2015-02-13 - Written - Trick (MPIA) + """ return -0.5 / ( numpy.sqrt(l) * numpy.sqrt(n) * (numpy.sqrt(l) + numpy.sqrt(n)) ** 3 diff --git a/galpy/potential/LogarithmicHaloPotential.py b/galpy/potential/LogarithmicHaloPotential.py index c201f81fe..93928cfd0 100644 --- a/galpy/potential/LogarithmicHaloPotential.py +++ b/galpy/potential/LogarithmicHaloPotential.py @@ -33,36 +33,28 @@ def __init__( self, amp=1.0, core=_CORE, q=1.0, b=None, normalize=False, ro=None, vo=None ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a logarithmic potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of velocity-squared - - core - core radius at which the logarithm is cut (can be Quantity) - - q - potential flattening (z/q)**2. - - b= (None) if set, shape parameter in y-direction (y --> y/b; see definition) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-04-02 - Started - Bovy (NYU) - + Initialize a logarithmic potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential; can be a Quantity with units of velocity-squared. + core : float or Quantity, optional + Core radius at which the logarithm is cut. + q : float + Potential flattening (z/q)**2. + b : float, optional + Shape parameter in y-direction (y --> y/b; see definition). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-04-02 - Started - Bovy (NYU) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="velocity2") core = conversion.parse_length(core, ro=self._ro) @@ -83,22 +75,6 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-04-02 - Started - Bovy (NYU) - 2010-04-30 - Adapted for R,z - Bovy (NYU) - """ if self.isNonAxi: return ( 1.0 @@ -113,20 +89,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return 1.0 / 2.0 * numpy.log(R**2.0 + (z / self._q) ** 2.0 + self._core2) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) return -Rt2 / R / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -134,20 +96,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): return -R / (R**2.0 + (z / self._q) ** 2.0 + self._core2) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) return -z / self._q**2.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -155,20 +103,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return -z / self._q**2.0 / (R**2.0 + (z / self._q) ** 2.0 + self._core2) def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) return ( @@ -182,20 +116,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0): return 0 def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - """ if self.isNonAxi: R2 = R**2.0 Rt2 = R2 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) @@ -236,21 +156,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) denom = 1.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -260,21 +165,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): return denom - 2.0 * R**2.0 * denom**2.0 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2012-07-25 - Written - Bovy (IAS@MPIA) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) denom = 1.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -288,21 +178,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2Phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) return ( @@ -323,21 +198,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _phi2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - HISTORY: - 2017-10-15 - Written - Bovy (UofT) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) denom = 1.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -353,21 +213,6 @@ def _phi2deriv(self, R, z, phi=0.0, t=0.0): return 0.0 def _Rphideriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rphideriv - PURPOSE: - evaluate the mixed R,phi derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2Phi/dR/dphi - HISTORY: - 2017-10-15 - Written - Bovy (UofT) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) denom = 1.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -381,21 +226,6 @@ def _Rphideriv(self, R, z, phi=0.0, t=0.0): return 0.0 def _phizderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phizderiv - PURPOSE: - evaluate the mixed phi,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2Phi/dz/dphi - HISTORY: - 2021-04-30 - Written - Bovy (UofT) - """ if self.isNonAxi: Rt2 = R**2.0 * (1.0 - self._1m1overb2 * numpy.sin(phi) ** 2.0) denom = 1.0 / (Rt2 + (z / self._q) ** 2.0 + self._core2) @@ -414,30 +244,6 @@ def _phizderiv(self, R, z, phi=0.0, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): - """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2014-12-18 - Written - Bovy (IAS) - - """ warnings.warn( "NEMO's LogPot does not allow flattening in z (for some reason); therefore, flip y and z in NEMO wrt galpy; also does not allow the triaxial b parameter", galpyWarning, diff --git a/galpy/potential/MN3ExponentialDiskPotential.py b/galpy/potential/MN3ExponentialDiskPotential.py index 105134aad..d4da6e798 100644 --- a/galpy/potential/MN3ExponentialDiskPotential.py +++ b/galpy/potential/MN3ExponentialDiskPotential.py @@ -42,37 +42,30 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a 3MN approximation to an exponential disk potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - hr - disk scale-length (can be Quantity) - - hz - scale-height (can be Quantity) - - sech= (False) if True, hz is the scale height of a sech vertical profile (default is exponential vertical profile) - - posdens= (False) if True, allow only positive density solutions (Table 2 in Smith et al. rather than Table 1) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - MN3ExponentialDiskPotential object - - HISTORY: - - 2015-02-07 - Written - Bovy (IAS) + Initialize a 3MN approximation to an exponential disk potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density. + hr : float or Quantity, optional + Disk scale-length. + hz : float or Quantity, optional + Scale-height. + sech : bool, optional + If True, hz is the scale height of a sech vertical profile (default is exponential vertical profile). + posdens : bool, optional + If True, allow only positive density solutions (Table 2 in Smith et al. rather than Table 1). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2015-02-07 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="density") @@ -147,21 +140,6 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0](R, z, phi=phi, t=t) + self._mn3[1](R, z, phi=phi, t=t) @@ -169,21 +147,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].Rforce(R, z, phi=phi, t=t) + self._mn3[1].Rforce(R, z, phi=phi, t=t) @@ -191,21 +154,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].zforce(R, z, phi=phi, t=t) + self._mn3[1].zforce(R, z, phi=phi, t=t) @@ -213,21 +161,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].dens(R, z, phi=phi, t=t) + self._mn3[1].dens(R, z, phi=phi, t=t) @@ -235,21 +168,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].R2deriv(R, z, phi=phi, t=t) + self._mn3[1].R2deriv(R, z, phi=phi, t=t) @@ -257,21 +175,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].z2deriv(R, z, phi=phi, t=t) + self._mn3[1].z2deriv(R, z, phi=phi, t=t) @@ -279,21 +182,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2015-02-07 - Written - Bovy (IAS) - """ return ( self._mn3[0].Rzderiv(R, z, phi=phi, t=t) + self._mn3[1].Rzderiv(R, z, phi=phi, t=t) @@ -302,30 +190,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): - """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2015-02-09 - Written - Bovy (IAS) - - """ out = "" # Loop through the self._mn3 MN potentials for ii in range(3): diff --git a/galpy/potential/MiyamotoNagaiPotential.py b/galpy/potential/MiyamotoNagaiPotential.py index bd578ce61..b05a6b648 100644 --- a/galpy/potential/MiyamotoNagaiPotential.py +++ b/galpy/potential/MiyamotoNagaiPotential.py @@ -65,61 +65,16 @@ def __init__(self, amp=1.0, a=1.0, b=0.1, normalize=False, ro=None, vo=None): self._nemo_accname = "MiyamotoNagai" def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-07-09 - Started - Bovy (NYU) - """ return -1.0 / numpy.sqrt( R**2.0 + (self._a + numpy.sqrt(z**2.0 + self._b2)) ** 2.0 ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ return -R / (R**2.0 + (self._a + numpy.sqrt(z**2.0 + self._b2)) ** 2.0) ** ( 3.0 / 2.0 ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ sqrtbz = numpy.sqrt(self._b2 + z**2.0) asqrtbz = self._a + sqrtbz if isinstance(R, float) and sqrtbz == asqrtbz: @@ -136,21 +91,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2010-08-08 - Written - Bovy (NYU) - """ sqrtbz = numpy.sqrt(self._b2 + z**2.0) asqrtbz = self._a + sqrtbz if isinstance(R, float) and sqrtbz == asqrtbz: @@ -166,21 +106,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ return ( 1.0 / (R**2.0 + (self._a + numpy.sqrt(z**2.0 + self._b2)) ** 2.0) ** 1.5 - 3.0 @@ -189,21 +114,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2012-07-25 - Written - Bovy (IAS@MPIA) - """ sqrtbz = numpy.sqrt(self._b2 + z**2.0) asqrtbz = self._a + sqrtbz if isinstance(R, float) and sqrtbz == asqrtbz: @@ -226,21 +136,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) / ((self._b2 + z**2.0) ** 1.5 * (R**2.0 + asqrtbz**2.0) ** 2.5) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ sqrtbz = numpy.sqrt(self._b2 + z**2.0) asqrtbz = self._a + sqrtbz if isinstance(R, float) and sqrtbz == asqrtbz: @@ -252,29 +147,5 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): - """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2014-12-18 - Written - Bovy (IAS) - - """ ampl = self._amp * vo**2.0 * ro return f"0,{ampl},{self._a*ro},{self._b*ro}" diff --git a/galpy/potential/MovingObjectPotential.py b/galpy/potential/MovingObjectPotential.py index 379d22428..34df51755 100644 --- a/galpy/potential/MovingObjectPotential.py +++ b/galpy/potential/MovingObjectPotential.py @@ -27,36 +27,26 @@ class MovingObjectPotential(Potential): def __init__(self, orbit, pot=None, amp=1.0, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a MovingObjectPotential - - INPUT: - - orbit - the Orbit of the object (Orbit object) - - pot - A potential object or list of potential objects representing the potential of the moving object; should be spherical, but this is not checked [default= PlummerPotential(amp=0.06,b=0.01)] - - amp (=1.) another amplitude to apply to the potential - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2011-04-10 - Started - Bovy (NYU) - - 2018-10-18 - Re-implemented to represent general object potentials using galpy potential models - James Lane (UofT) - + Initialize a MovingObjectPotential. + + Parameters + ---------- + orbit : galpy.orbit.Orbit + The orbit of the object. + pot : Potential object or list of Potential objects + A potential object or list of potential objects representing the potential of the moving object; should be spherical, but this is not checked. Default is `PlummerPotential(amp=0.06,b=0.01)`. + amp : float, optional + Another amplitude to apply to the potential. Default is 1.0. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2011-04-10 - Started - Bovy (NYU) + - 2018-10-18 - Re-implemented to represent general object potentials using galpy potential models - James Lane (UofT) """ - Potential.__init__(self, amp=amp, ro=ro, vo=vo) # If no potential supplied use a default Plummer sphere if pot is None: @@ -76,22 +66,6 @@ def __init__(self, orbit, pot=None, amp=1.0, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z, phi - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z,phi) - HISTORY: - 2011-04-10 - Started - Bovy (NYU) - 2018-10-18 - Updated for general object potential - James Lane (UofT) - """ # Cylindrical distance Rdist = _cylR(R, phi, self._orb.R(t), self._orb.phi(t)) orbz = self._orb.z(t) if self._orb.dim() == 3 else 0 @@ -99,22 +73,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return evaluatePotentials(self._pot, Rdist, orbz - z, t=t, use_physical=False) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2011-04-10 - Written - Bovy (NYU) - 2018-10-18 - Updated for general object potential - James Lane (UofT) - """ # Cylindrical distance Rdist = _cylR(R, phi, self._orb.R(t), self._orb.phi(t)) # Difference vector @@ -127,22 +85,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): return -RF * (numpy.cos(phi) * xd + numpy.sin(phi) * yd) / Rdist def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2011-04-10 - Written - Bovy (NYU) - 2018-10-18 - Updated for general object potential - James Lane (UofT) - """ # Cylindrical distance Rdist = _cylR(R, phi, self._orb.R(t), self._orb.phi(t)) # Difference vector @@ -152,22 +94,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return -evaluatezforces(self._pot, Rdist, zd, t=t, use_physical=False) def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2011-04-10 - Written - Bovy (NYU) - 2018-10-18 - Updated for general object potential - James Lane (UofT) - """ # Cylindrical distance Rdist = _cylR(R, phi, self._orb.R(t), self._orb.phi(t)) # Difference vector @@ -179,21 +105,6 @@ def _phitorque(self, R, z, phi=0.0, t=0.0): return -RF * R * (numpy.cos(phi) * yd - numpy.sin(phi) * xd) / Rdist def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2010-08-08 - Written - Bovy (NYU) - """ # Cylindrical distance Rdist = _cylR(R, phi, self._orb.R(t), self._orb.phi(t)) # Difference vector diff --git a/galpy/potential/NonInertialFrameForce.py b/galpy/potential/NonInertialFrameForce.py index 610e5e124..8817631fe 100644 --- a/galpy/potential/NonInertialFrameForce.py +++ b/galpy/potential/NonInertialFrameForce.py @@ -71,38 +71,31 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a NonInertialFrameForce - - INPUT: - - amp= (1.) amplitude to be applied to the potential (default: 1) - - Omega= (1.) Angular frequency of the rotation of the non-inertial frame as seen from an inertial one; can either be a function of time or a number (when the frequency is assumed to be Omega + Omegadot x t) and in each case can be a list [Omega_x,Omega_y,Omega_z] or a single value Omega_z (when not a function, can be a Quantity; when a function, need to take input time in internal units and output the frequency in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.freq_in_XXX conversion functions) - - Omegadot= (None) Time derivative of the angular frequency of the non-intertial frame's rotation. format should match Omega input ([list of] function[s] when Omega is one, number/list if Omega is a number/list; when a function, need to take input time in internal units and output the frequency derivative in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.freq_in_XXX conversion functions) - - x0= (None) Position vector x_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); list of functions [x_0x,x_0y,x_0z]; only necessary when considering both rotation and center-of-mass acceleration of the inertial frame (functions need to take input time in internal units and output the position in internal units; see galpy.util.conversion.time_in_Gyr and divided physical positions by the `ro` parameter in kpc) - - v0= (None) Velocity vector v_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); list of functions [v_0x,v_0y,v_0z]; only necessary when considering both rotation and center-of-mass acceleration of the inertial frame (functions need to take input time in internal units and output the velocity in internal units; see galpy.util.conversion.time_in_Gyr and divided physical positions by the `vo` parameter in km/s) - - a0= (None) Acceleration vector a_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); constant or a list of functions [a_0x,a_0y, a_0z] (functions need to take input time in internal units and output the acceleration in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.force_in_XXX conversion functions [force is actually acceleration in galpy]) - - OUTPUT: - - (none) - - HISTORY: - - 2022-03-02 - Started - Bovy (UofT) - - 2022-03-26 - Generalized Omega to any function of time - Bovy (UofT) - + Initialize a NonInertialFrameForce. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1). + Omega : float or list of floats or Quantity or list of Quantities or callable or list of callables, optional + Angular frequency of the rotation of the non-inertial frame as seen from an inertial one; can either be a function of time or a number (when the frequency is assumed to be Omega + Omegadot x t) and in each case can be a list [Omega_x,Omega_y,Omega_z] or a single value Omega_z (when not a function, can be a Quantity; when a function, need to take input time in internal units and output the frequency in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.freq_in_XXX conversion functions). + Omegadot : float or list of floats or Quantity or list of Quantities or callable or list of callables, optional + Time derivative of the angular frequency of the non-intertial frame's rotation. Format should match Omega input ([list of] function[s] when Omega is one, number/list if Omega is a number/list; when a function, need to take input time in internal units and output the frequency derivative in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.freq_in_XXX conversion functions). + x0 : list of callables, optional + Position vector x_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); list of functions [x_0x,x_0y,x_0z]; only necessary when considering both rotation and center-of-mass acceleration of the inertial frame (functions need to take input time in internal units and output the position in internal units; see galpy.util.conversion.time_in_Gyr and divided physical positions by the `ro` parameter in kpc). + v0 : list of callables, optional + Velocity vector v_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); list of functions [v_0x,v_0y,v_0z]; only necessary when considering both rotation and center-of-mass acceleration of the inertial frame (functions need to take input time in internal units and output the velocity in internal units; see galpy.util.conversion.time_in_Gyr and divided physical positions by the `vo` parameter in km/s). + a0 : float or list of callables, optional + Acceleration vector a_0 (cartesian) of the center of mass of the non-intertial frame (see definition in the class documentation); constant or a list of functions [a_0x,a_0y, a_0z] (functions need to take input time in internal units and output the acceleration in internal units; see galpy.util.conversion.time_in_Gyr and galpy.util.conversion.force_in_XXX conversion functions [force is actually acceleration in galpy]). + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2022-03-02 - Started - Bovy (UofT) + - 2022-03-26 - Generalized Omega to any function of time - Bovy (UofT) """ DissipativeForce.__init__(self, amp=amp, ro=ro, vo=vo) self._rot_acc = not Omega is None @@ -276,60 +269,12 @@ def _force(self, R, z, phi, t, v): return force def _Rforce(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this Force - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the radial force - HISTORY: - 2022-03-02 - Written - Bovy (UofT) - """ force = self._force(R, z, phi, t, v) return numpy.cos(phi) * force[0] + numpy.sin(phi) * force[1] def _phitorque(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this Force - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the azimuthal torque - HISTORY: - 2022-03-02 - Written - Bovy (UofT) - """ force = self._force(R, z, phi, t, v) return R * (-numpy.sin(phi) * force[0] + numpy.cos(phi) * force[1]) def _zforce(self, R, z, phi=0.0, t=0.0, v=None): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this Force - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - v= current velocity in cylindrical coordinates - OUTPUT: - the vertical force - HISTORY: - 2022-03-02 - Written - Bovy (UofT) - """ return self._force(R, z, phi, t, v)[2] diff --git a/galpy/potential/NullPotential.py b/galpy/potential/NullPotential.py index d86b63995..19ffa38d6 100644 --- a/galpy/potential/NullPotential.py +++ b/galpy/potential/NullPotential.py @@ -11,27 +11,20 @@ class NullPotential(Potential): def __init__(self, amp=1.0, ro=None, vo=None): """ - NAME: + Initialize a null potential: a constant potential with, thus, zero forces - __init__ + Parameters + ---------- + amp : float or Quantity, optional + Constant value of the potential (default: 1); can be a Quantity with units of velocity-squared + ro : float, optional + Distance scale for translation into internal units (default from configuration file) + vo : float, optional + Velocity scale for translation into internal units (default from configuration file) - PURPOSE: - - initialize a null potential: a constant potential with, thus, zero forces - - INPUT: - - amp - constant value of the potential (default: 1); can be a Quantity with units of velocity-squared - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2022-03-18 - Written - Bovy (UofT) + Notes + ----- + - 2022-03-18 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="velocity2") @@ -41,127 +34,22 @@ def __init__(self, amp=1.0, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 1.0 def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2Phi/dR/dz - HISTORY: - 2022-03-18 - Written - Bovy (UofT) - """ return 0.0 diff --git a/galpy/potential/PerfectEllipsoidPotential.py b/galpy/potential/PerfectEllipsoidPotential.py index c6a8fd407..39fee1df1 100644 --- a/galpy/potential/PerfectEllipsoidPotential.py +++ b/galpy/potential/PerfectEllipsoidPotential.py @@ -37,39 +37,32 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a perfect ellipsoid potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or G x mass - - a - scale radius (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2018-08-06 - Started - Bovy (UofT) + Initialize a perfect ellipsoid potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or G x mass. + a : float or Quantity, optional + Scale radius. + b : float, optional + Y-to-x axis ratio of the density. + c : float, optional + Z-to-x axis ratio of the density. + zvec : numpy.ndarray, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis (rad or Quantity). + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-08-06 - Started - Bovy (UofT) """ EllipsoidalPotential.__init__( @@ -112,20 +105,6 @@ def _mdens_deriv(self, m): return -4.0 * m * (self.a2 + m**2) ** -3 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-08 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( diff --git a/galpy/potential/PlummerPotential.py b/galpy/potential/PlummerPotential.py index 221e492ba..8225f9c48 100644 --- a/galpy/potential/PlummerPotential.py +++ b/galpy/potential/PlummerPotential.py @@ -22,32 +22,24 @@ class PlummerPotential(Potential): def __init__(self, amp=1.0, b=0.8, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Plummer potential - - INPUT: - - amp - amplitude to be applied to the potential, the total mass (default: 1); can be a Quantity with units of mass or Gxmass - - b - scale parameter (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2015-06-15 - Written - Bovy (IAS) - + Initialize a Plummer potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential, the total mass. Default is 1. Can be a Quantity with units of mass or Gxmass. + b : float or Quantity, optional + Scale parameter. Can be a Quantity. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. Default is False. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2015-06-15 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") self._b = conversion.parse_length(b, ro=self._ro) @@ -63,113 +55,26 @@ def __init__(self, amp=1.0, b=0.8, normalize=False, ro=None, vo=None): self._nemo_accname = "Plummer" def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2015-06-15 - Started - Bovy (IAS) - """ return -1.0 / numpy.sqrt(R**2.0 + z**2.0 + self._b2) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ dPhidrr = -((R**2.0 + z**2.0 + self._b2) ** -1.5) return dPhidrr * R def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ dPhidrr = -((R**2.0 + z**2.0 + self._b2) ** -1.5) return dPhidrr * z def _rforce_jax(self, r): - """ - NAME: - _rforce_jax - PURPOSE: - evaluate the spherical radial force for this potential using JAX - INPUT: - r - Galactocentric spherical radius - OUTPUT: - the radial force - HISTORY: - 2021-12-14 - Written - Lane (UofT) - """ # No need for actual JAX! return -self._amp * r * (r**2.0 + self._b2) ** -1.5 def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ return ( 3.0 / 4.0 / numpy.pi * self._b2 * (R**2.0 + z**2.0 + self._b2) ** -2.5 ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ Rb = R**2.0 + self._b2 return ( self._b2 @@ -182,77 +87,19 @@ def _surfdens(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ return (self._b2 - 2.0 * R**2.0 + z**2.0) * ( R**2.0 + z**2.0 + self._b2 ) ** -2.5 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ return (self._b2 + R**2.0 - 2.0 * z**2.0) * ( R**2.0 + z**2.0 + self._b2 ) ** -2.5 def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2015-06-15 - Written - Bovy (IAS) - """ return -3.0 * R * z * (R**2.0 + z**2.0 + self._b2) ** -2.5 def _ddensdr(self, r, t=0.0): - """ - NAME: - _ddensdr - PURPOSE: - evaluate the radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the density derivative - HISTORY: - 2021-12-15 - Written - Lane (UofT) - """ return ( self._amp * (-15.0) @@ -264,19 +111,6 @@ def _ddensdr(self, r, t=0.0): ) def _d2densdr2(self, r, t=0.0): - """ - NAME: - _d2densdr2 - PURPOSE: - evaluate the second radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the 2nd density derivative - HISTORY: - 2021-12-15 - Written - Lane (UofT) - """ return ( self._amp * (-15.0) @@ -291,17 +125,24 @@ def _d2densdr2(self, r, t=0.0): def _ddenstwobetadr(self, r, beta=0): """ - NAME: - _ddenstwobetadr - PURPOSE: - evaluate the radial density derivative x r^(2beta) for this potential - INPUT: - r - spherical radius - beta= (0) - OUTPUT: - d (rho x r^{2beta} ) / d r - HISTORY: - 2021-03-15 - Written - Lane (UofT) + Evaluate the radial density derivative x r^(2beta) for this potential. + + Parameters + ---------- + r : float + Spherical radius. + beta : int, optional + Power of r in the density derivative. Default is 0. + + Returns + ------- + float + The derivative of the density times r^(2beta). + + Notes + ----- + - 2021-03-15 - Written - Lane (UofT) + """ return ( self._amp @@ -317,20 +158,6 @@ def _ddenstwobetadr(self, r, beta=0): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2020-10-02 - Written - Bovy (UofT) - """ if z is not None: raise AttributeError # use general implementation r2 = R**2.0 @@ -338,29 +165,5 @@ def _mass(self, R, z=None, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): - """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2014-12-18 - Written - Bovy (IAS) - - """ ampl = self._amp * vo**2.0 * ro return f"0,{ampl},{self._b*ro}" diff --git a/galpy/potential/Potential.py b/galpy/potential/Potential.py index bac0be10d..69ab286b2 100644 --- a/galpy/potential/Potential.py +++ b/galpy/potential/Potential.py @@ -53,11 +53,6 @@ def check_potential_inputs_not_arrays(func): function Decorated function. - Raises - ------ - TypeError - If any of the inputs are arrays for Potentials that do not support array evaluation. - Notes ----- - 2017-summer - Written for SpiralArmsPotential - Jack Hong (UBC) @@ -1630,11 +1625,6 @@ def conc( float Concentration (scale/rvir). - Raises - ------ - AttributeError - If this potential does not have a '_scale' defined to base the concentration on or does not support calculating the virial radius. - Notes ----- - 2014-04-03: Written - Bovy (IAS) @@ -1672,11 +1662,6 @@ def nemo_accname(self): str Acceleration name. - Raises - ------ - AttributeError - If NEMO acceleration name is not supported for this potential. - Notes ----- - 2014-12-18: Written - Bovy (IAS) @@ -1705,11 +1690,6 @@ def nemo_accpars(self, vo, ro): str Accpars string. - Raises - ------ - AttributeError - If NEMO acceleration parameters are not supported for this potential. - Notes ----- - 2014-12-18: Written - Bovy (IAS) diff --git a/galpy/potential/PowerSphericalPotentialwCutoff.py b/galpy/potential/PowerSphericalPotentialwCutoff.py index 1198e27f2..635997b1b 100644 --- a/galpy/potential/PowerSphericalPotentialwCutoff.py +++ b/galpy/potential/PowerSphericalPotentialwCutoff.py @@ -31,36 +31,28 @@ def __init__( self, amp=1.0, alpha=1.0, rc=1.0, normalize=False, r1=1.0, ro=None, vo=None ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a power-law-density potential - - INPUT: - - amp= amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density - - alpha= inner power - - rc= cut-off radius (can be Quantity) - - r1= (1.) reference radius for amplitude (can be Quantity) - - normalize= if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2013-06-28 - Written - Bovy (IAS) - + Initialize a power-law-density potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential. Can be a Quantity with units of mass density or Gxmass density. + alpha : float, optional + Inner power. + rc : float or Quantity, optional + Cut-off radius. + r1 : float or Quantity, optional + Reference radius for amplitude. Default is 1.0. Can be Quantity. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013-06-28 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="density") r1 = conversion.parse_length(r1, ro=self._ro) @@ -80,21 +72,6 @@ def __init__( self._nemo_accname = "PowSphwCut" def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2013-06-28 - Started - Bovy (IAS) - """ r = numpy.sqrt(R**2.0 + z**2.0) out = ( 2.0 @@ -120,101 +97,26 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return out def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2013-06-26 - Written - Bovy (IAS) - """ r = numpy.sqrt(R * R + z * z) return -self._mass(r) * R / r**3.0 def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2013-06-26 - Written - Bovy (IAS) - """ r = numpy.sqrt(R * R + z * z) return -self._mass(r) * z / r**3.0 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rderiv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2013-06-28 - Written - Bovy (IAS) - """ r = numpy.sqrt(R * R + z * z) return 4.0 * numpy.pi * r ** (-2.0 - self.alpha) * numpy.exp( -((r / self.rc) ** 2.0) ) * R**2.0 + self._mass(r) / r**5.0 * (z**2.0 - 2.0 * R**2.0) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2013-06-28 - Written - Bovy (IAS) - """ r = numpy.sqrt(R * R + z * z) return 4.0 * numpy.pi * r ** (-2.0 - self.alpha) * numpy.exp( -((r / self.rc) ** 2.0) ) * z**2.0 + self._mass(r) / r**5.0 * (R**2.0 - 2.0 * z**2.0) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ r = numpy.sqrt(R * R + z * z) return ( R @@ -229,18 +131,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _rforce_jax(self, r): - """ - NAME: - _rforce_jax - PURPOSE: - evaluate the spherical radial force for this potential using JAX; use incomplete gamma implementation rather than hypergeometric, because JAX doesn't have the hypergeometric functions currently - INPUT: - r - Galactocentric spherical radius - OUTPUT: - the radial force - HISTORY: - 2022-05-10 - Written - Bovy (UofT) - """ if not _JAX_LOADED: # pragma: no cover raise ImportError( "Making use of the _rforce_jax function requires the google/jax library" @@ -256,19 +146,6 @@ def _rforce_jax(self, r): ) def _ddensdr(self, r, t=0.0): - """ - NAME: - _ddensdr - PURPOSE: - evaluate the radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the density derivative - HISTORY: - 2021-12-15 - Written - Lane (UofT) - """ return ( -self._amp * r ** (-1.0 - self.alpha) @@ -277,19 +154,6 @@ def _ddensdr(self, r, t=0.0): ) def _d2densdr2(self, r, t=0.0): - """ - NAME: - _d2densdr2 - PURPOSE: - evaluate the second radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the 2nd density derivative - HISTORY: - 2021-12-15 - Written - Lane (UofT) - """ return ( self._amp * r ** (-2.0 - self.alpha) @@ -305,17 +169,23 @@ def _d2densdr2(self, r, t=0.0): def _ddenstwobetadr(self, r, beta=0): """ - NAME: - _ddenstwobetadr - PURPOSE: - evaluate the radial density derivative x r^(2beta) for this potential - INPUT: - r - spherical radius - beta= (0) - OUTPUT: - d (rho x r^{2beta} ) / d r - HISTORY: - 2021-03-15 - Written - Lane (UofT) + Evaluate the radial density derivative x r^(2beta) for this potential. + + Parameters + ---------- + r : float + Spherical radius. + beta : int, optional + Power of r in the density derivative. Default is 0. + + Returns + ------- + float + The derivative of rho x r^{2beta} / d r. + + Notes + ----- + - 2021-03-15 - Written - Lane (UofT) """ if not _JAX_LOADED: # pragma: no cover raise ImportError( @@ -329,40 +199,10 @@ def _ddenstwobetadr(self, r, beta=0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2013-06-28 - Written - Bovy (IAS) - """ r = numpy.sqrt(R**2.0 + z**2.0) return 1.0 / r**self.alpha * numpy.exp(-((r / self.rc) ** 2.0)) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2013-XX-XX - Written - Bovy (IAS) - 2021-04-07 - Switched to hypergeometric function equivalent to incomplete gamma function for better behavior at alpha < -3 - Bovy (UofT) - """ if z is not None: raise AttributeError # use general implementation R = numpy.array(R) @@ -388,29 +228,5 @@ def _mass(self, R, z=None, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): - """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2014-12-18 - Written - Bovy (IAS) - - """ ampl = self._amp * vo**2.0 * ro ** (self.alpha - 2.0) return f"0,{ampl},{self.alpha},{self.rc*ro}" diff --git a/galpy/potential/PowerTriaxialPotential.py b/galpy/potential/PowerTriaxialPotential.py index 5702984ee..668889ff7 100644 --- a/galpy/potential/PowerTriaxialPotential.py +++ b/galpy/potential/PowerTriaxialPotential.py @@ -39,41 +39,34 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a triaxial power-law potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - alpha - power-law exponent - - r1= (1.) reference radius for amplitude (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2021-05-07 - Started - Bovy (UofT) + Initialize a triaxial power-law potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + alpha : float + Power-law exponent. + r1 : float or Quantity, optional + Reference radius for amplitude. + b : float + Y-to-x axis ratio of the density. + c : float + Z-to-x axis ratio of the density. + zvec : numpy.ndarray, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis (rad or Quantity). + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2021-05-07 - Started - Bovy (UofT) """ EllipsoidalPotential.__init__( diff --git a/galpy/potential/PseudoIsothermalPotential.py b/galpy/potential/PseudoIsothermalPotential.py index 964ed7e33..fe8e07313 100644 --- a/galpy/potential/PseudoIsothermalPotential.py +++ b/galpy/potential/PseudoIsothermalPotential.py @@ -19,32 +19,24 @@ class PseudoIsothermalPotential(Potential): def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a pseudo-isothermal potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - core radius (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2015-12-04 - Started - Bovy (UofT) - + Initialize a pseudo-isothermal potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential. + a : float or Quantity, optional + Core radius. + normalize : bool, int, or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2015-12-04 - Started - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") a = conversion.parse_length(a, ro=self._ro) @@ -61,21 +53,6 @@ def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2015-12-04 - Started - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) out = ( @@ -91,81 +68,21 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return out def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2015-12-04 - Started - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) return -(1.0 / r - self._a / r2 * numpy.arctan(r / self._a)) / self._a * R / r def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2015-12-04 - Started - Bovy (UofT) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) return -(1.0 / r - self._a / r2 * numpy.arctan(r / self._a)) / self._a * z / r def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2015-12-04 - Started - Bovy (UofT) - """ return ( 1.0 / (1.0 + (R**2.0 + z**2.0) / self._a2) / 4.0 / numpy.pi / self._a3 ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) return ( @@ -176,21 +93,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) / self._a def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2012-07-25 - Written - Bovy (IAS@MPIA) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) return ( @@ -201,21 +103,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) / self._a def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2Phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ r2 = R**2.0 + z**2.0 r = numpy.sqrt(r2) return ( diff --git a/galpy/potential/RazorThinExponentialDiskPotential.py b/galpy/potential/RazorThinExponentialDiskPotential.py index 3f34966dc..8d02d2155 100644 --- a/galpy/potential/RazorThinExponentialDiskPotential.py +++ b/galpy/potential/RazorThinExponentialDiskPotential.py @@ -31,32 +31,28 @@ def __init__( glorder=100, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a razor-thin-exponential disk potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of surface-mass or Gxsurface-mass - - hr - disk scale-length (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - RazorThinExponentialDiskPotential object - - HISTORY: - - 2012-12-27 - Written - Bovy (IAS) - + Class that implements a razor-thin exponential disk potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of surface-mass or Gxsurface-mass. + hr : float or Quantity, optional + Disk scale-length. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + new : bool, optional + If True, use a new implementation of the potential that is more accurate for small scale lengths (default: True). + glorder : int, optional + Gaussian quadrature order to use for numerical integration (default: 100). + + Notes + ----- + - 2012-12-27 - Written - Bovy (IAS) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="surfacedensity") hr = conversion.parse_length(hr, ro=self._ro) @@ -72,21 +68,6 @@ def __init__( self.normalize(normalize) def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z) - HISTORY: - 2012-12-26 - Written - Bovy (IAS) - """ if self._new: if numpy.fabs(z) < 10.0**-6.0: y = 0.5 * self._alpha * R @@ -111,21 +92,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - Rforce - PURPOSE: - evaluate radial force K_R (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - K_R (R,z) - HISTORY: - 2012-12-27 - Written - Bovy (IAS) - """ if self._new: # if R > 6.: return self._kp(R,z) if numpy.fabs(z) < 10.0**-6.0: @@ -179,21 +145,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - zforce - PURPOSE: - evaluate vertical force K_z (R,z) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - K_z (R,z) - HISTORY: - 2012-12-27 - Written - Bovy (IAS) - """ if self._new: # if R > 6.: return self._kp(R,z) if numpy.fabs(z) < 10.0**-6.0: @@ -243,21 +194,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - R2deriv - PURPOSE: - evaluate R2 derivative - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - -d K_R (R,z) d R - HISTORY: - 2012-12-27 - Written - Bovy (IAS) - """ if self._new: if numpy.fabs(z) < 10.0**-6.0: y = 0.5 * self._alpha * R @@ -272,56 +208,12 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): # pragma: no cover - """ - NAME: - z2deriv - PURPOSE: - evaluate z2 derivative - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - -d K_z (R,z) d z - HISTORY: - 2012-12-27 - Written - Bovy (IAS) - """ return numpy.infty def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Sigma (R,z) - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ return numpy.exp(-self._alpha * R) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to z=inf - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-04 - Written - Bovy (UofT) - """ return ( 2.0 * numpy.pi diff --git a/galpy/potential/RingPotential.py b/galpy/potential/RingPotential.py index 48f1b4432..fae7fce99 100644 --- a/galpy/potential/RingPotential.py +++ b/galpy/potential/RingPotential.py @@ -20,32 +20,24 @@ class RingPotential(Potential): def __init__(self, amp=1.0, a=0.75, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a circular ring potential - - INPUT: - - amp - mass of the ring (default: 1); can be a Quantity with units of mass or Gxmass - - a= (0.75) radius of the ring (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1.; note that because the force is always positive at r < a, this does not work if a > 1 - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2018-08-04 - Written - Bovy (UofT) - + Class that implements a circular ring potential. + + Parameters + ---------- + amp : float or Quantity, optional + Mass of the ring (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Radius of the ring (default: 0.75). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1.; note that because the force is always positive at r < a, this does not work if a > 1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-08-04 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") a = conversion.parse_length(a, ro=self._ro) @@ -64,21 +56,6 @@ def __init__(self, amp=1.0, a=0.75, normalize=False, ro=None, vo=None): self.hasC_dxdv = False def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ # Stable as r -> infty m = 4.0 * self.a / ((numpy.sqrt(R) + self.a / numpy.sqrt(R)) ** 2 + z**2 / R) return ( @@ -86,21 +63,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ m = 4.0 * R * self.a / ((R + self.a) ** 2 + z**2) return ( -2.0 @@ -120,21 +82,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ m = 4.0 * R * self.a / ((R + self.a) ** 2 + z**2) return ( -4.0 @@ -146,21 +93,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rderiv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ Raz2 = (R + self.a) ** 2 + z**2 Raz = numpy.sqrt(Raz2) m = 4.0 * R * self.a / Raz2 @@ -187,21 +119,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ Raz2 = (R + self.a) ** 2 + z**2 m = 4.0 * R * self.a / Raz2 # Explicitly swapped in zforce here, so the z/z can be cancelled @@ -226,21 +143,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ Raz2 = (R + self.a) ** 2 + z**2 m = 4.0 * R * self.a / Raz2 return ( diff --git a/galpy/potential/RotateAndTiltWrapperPotential.py b/galpy/potential/RotateAndTiltWrapperPotential.py index 576edb913..43f927df5 100644 --- a/galpy/potential/RotateAndTiltWrapperPotential.py +++ b/galpy/potential/RotateAndTiltWrapperPotential.py @@ -49,47 +49,32 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a RotateAndTiltWrapper Potential - - INPUT: - - amp= (1.) overall amplitude to apply to the potential - - pot= Potential instance or list thereof for the potential to rotate and tilt - - Orientation angles as - - galaxy_pa= rotation angle of the original potential around the original z axis (can be a Quantity) - - and either - - - 1) zvec= 3D vector specifying the direction of the rotated z axis - - 2) inclination= usual inclination angle (with the line-of-sight being the z axis) - - sky_pa= rotation angle around the inclined z axis (usual sky position angle measured from North) - - offset= optional static offset in Cartesian coordinates (can be a Quantity) - - OUTPUT: - - (none) - - HISTORY: - - 2021-03-29 - Started - Mackereth (UofT) - - 2021-04-18 - Added inclination, sky_pa, galaxy_pa setup - Bovy (UofT) - - 2022-03-14 - added offset kwarg - Mackereth (UofT) - + A potential that rotates and tilts another potential. + + Parameters + ---------- + amp : float, optional + Overall amplitude to apply to the potential. Default is 1.0. + inclination : float or Quantity, optional + Usual inclination angle (with the line-of-sight being the z axis). + galaxy_pa : float or Quantity, optional + Rotation angle of the original potential around the original z axis. + sky_pa : float or Quantity, optional + Rotation angle around the inclined z axis (usual sky position angle measured from North). + zvec : numpy.ndarray, optional + 3D vector specifying the direction of the rotated z axis. + offset : numpy.ndarray or Quantity, optional + Static offset in Cartesian coordinates. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2021-03-29 - Started - Mackereth (UofT) + - 2021-04-18 - Added inclination, sky_pa, galaxy_pa setup - Bovy (UofT) + - 2022-03-14 - added offset kwarg - Mackereth (UofT) """ WrapperPotential.__init__(self, amp=amp, pot=pot, ro=ro, vo=vo, _init=True) inclination = conversion.parse_angle(inclination) @@ -164,21 +149,6 @@ def __getattr__(self, attribute): @check_potential_inputs_not_arrays def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2021-04-18 - Written - Bovy (UofT) - """ x, y, z = coords.cyl_to_rect(R, phi, z) if not numpy.isinf(R) else (R, 0.0, z) if self._norot: xyzp = numpy.array([x, y, z]) @@ -191,61 +161,16 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2021-04-18 - Written - Bovy (UofT) - """ Fxyz = self._force_xyz(R, z, phi=phi, t=t) return numpy.cos(phi) * Fxyz[0] + numpy.sin(phi) * Fxyz[1] @check_potential_inputs_not_arrays def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque (torque) for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque (torque) - HISTORY: - 2021-04-18 - Written - Bovy (UofT) - """ Fxyz = self._force_xyz(R, z, phi=phi, t=t) return R * (-numpy.sin(phi) * Fxyz[0] + numpy.cos(phi) * Fxyz[1]) @check_potential_inputs_not_arrays def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2021-04-18 - Written - Bovy (UofT) - """ return self._force_xyz(R, z, phi=phi, t=t)[2] def _force_xyz(self, R, z, phi=0.0, t=0.0): @@ -267,21 +192,6 @@ def _force_xyz(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2021-04-19 - Written - Bovy (UofT) - """ phi2 = self._2ndderiv_xyz(R, z, phi=phi, t=t) return ( numpy.cos(phi) ** 2.0 * phi2[0, 0] @@ -291,60 +201,15 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed radial, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, vertical derivative - HISTORY: - 2021-04-19 - Written - Bovy (UofT) - """ phi2 = self._2ndderiv_xyz(R, z, phi=phi, t=t) return numpy.cos(phi) * phi2[0, 2] + numpy.sin(phi) * phi2[1, 2] @check_potential_inputs_not_arrays def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second vertical derivative - HISTORY: - 2021-04-19 - Written - Bovy (UofT) - """ return self._2ndderiv_xyz(R, z, phi=phi, t=t)[2, 2] @check_potential_inputs_not_arrays def _phi2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phi2deriv - PURPOSE: - evaluate the second azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second azimuthal derivative - HISTORY: - 2021-04-19 - Written - Bovy (UofT) - """ Fxyz = self._force_xyz(R, z, phi=phi, t=t) phi2 = self._2ndderiv_xyz(R, z, phi=phi, t=t) return R**2.0 * ( @@ -355,21 +220,6 @@ def _phi2deriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _Rphideriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rphideriv - PURPOSE: - evaluate the mixed radial, azimuthal derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, azimuthal derivative - HISTORY: - 2021-04-19 - Written - Bovy (UofT) - """ Fxyz = self._force_xyz(R, z, phi=phi, t=t) phi2 = self._2ndderiv_xyz(R, z, phi=phi, t=t) return ( @@ -381,21 +231,6 @@ def _Rphideriv(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _phizderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phizderiv - PURPOSE: - evaluate the mixed azimuthal, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed azimuthal, vertical derivative - HISTORY: - 2021-04-30 - Written - Bovy (UofT) - """ phi2 = self._2ndderiv_xyz(R, z, phi=phi, t=t) return R * (numpy.cos(phi) * phi2[1, 2] - numpy.sin(phi) * phi2[0, 2]) @@ -471,21 +306,6 @@ def _2ndderiv_xyz(self, R, z, phi=0.0, t=0.0): @check_potential_inputs_not_arrays def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2021-04-18 - Written - Bovy (UofT) - """ x, y, z = coords.cyl_to_rect(R, phi, z) if not numpy.isinf(R) else (R, 0.0, z) if self._norot: xyzp = numpy.array([x, y, z]) diff --git a/galpy/potential/SCFPotential.py b/galpy/potential/SCFPotential.py index 1a7019f0c..5903721c5 100644 --- a/galpy/potential/SCFPotential.py +++ b/galpy/potential/SCFPotential.py @@ -60,36 +60,28 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a SCF Potential from a set of expansion coefficients (use SCFPotential.from_density to directly initialize from a density) - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - Acos - The real part of the expansion coefficient (NxLxL matrix, or optionally NxLx1 if Asin=None) - - Asin - The imaginary part of the expansion coefficient (NxLxL matrix or None) - - a - scale length (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - SCFPotential object - - HISTORY: - - 2016-05-13 - Written - Aladdin Seaifan (UofT) - + Initialize a SCF Potential from a set of expansion coefficients (use SCFPotential.from_density to directly initialize from a density) + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + Acos : numpy.ndarray, optional + The real part of the expansion coefficient (NxLxL matrix, or optionally NxLx1 if Asin=None). + Asin : numpy.ndarray, optional + The imaginary part of the expansion coefficient (NxLxL matrix or None). + a : float or Quantity, optional + Scale length. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2016-05-13 - Written - Aladdin Seaifan (UofT) """ NumericalPotentialDerivativesMixin.__init__( self, {} @@ -172,41 +164,38 @@ def from_density( vo=None, ): """ - NAME: - - from_density - - PURPOSE: - - initialize an SCF Potential from from a given density - - INPUT: - - dens - density function that takes parameters R, z and phi; z and phi are optional for spherical profiles, phi is optional for axisymmetric profiles. The density function must take input positions in internal units (R/ro, z/ro), but can return densities in physical units. You can use the member dens of Potential instances or the density from evaluateDensities - - N - Number of radial basis functions - - L - Number of costheta basis functions; for non-axisymmetric profiles also sets the number of azimuthal (phi) basis functions to M = 2L+1) - - a - expansion scale length (can be Quantity) - - symmetry= (None) symmetry of the profile to assume: 'spherical', 'axisymmetry', or None (for the general, non-axisymmetric case) - - radial_order - Number of sample points for the radial integral. If None, radial_order=max(20, N + 3/2L + 1) - - costheta_order - Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1) - - phi_order - Number of sample points of the phi integral. If None, If costheta_order=max(20, L + 1) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - SCFPotential object - - HISTORY: - - 2022-06-20 - Written - Jo Bovy (UofT) + Initialize an SCF Potential from a given density. + + Parameters + ---------- + dens : function + Density function that takes parameters R, z and phi; z and phi are optional for spherical profiles, phi is optional for axisymmetric profiles. The density function must take input positions in internal units (R/ro, z/ro), but can return densities in physical units. You can use the member dens of Potential instances or the density from evaluateDensities. + N : int + Number of radial basis functions. + L : int, optional + Number of costheta basis functions; for non-axisymmetric profiles also sets the number of azimuthal (phi) basis functions to M = 2L+1). + a : float or Quantity, optional + Expansion scale length. + symmetry : {'spherical','axisymmetry',None}, optional + Symmetry of the profile to assume. None is the general, non-axisymmetric case. + radial_order : int, optional + Number of sample points for the radial integral. If None, radial_order=max(20, N + 3/2L + 1). + costheta_order : int, optional + Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1). + phi_order : int, optional + Number of sample points of the phi integral. If None, If costheta_order=max(20, L + 1). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Returns + ------- + SCFPotential object + + Notes + ----- + - Written - Jo Bovy (UofT) - 2022-06-20 """ # Dummy object for ro/vo handling, to ensure consistency @@ -265,17 +254,23 @@ def from_density( def _Nroot(self, L, M): """ - NAME: - _Nroot - PURPOSE: - Evaluate the square root of equation (3.15) with the (2 - del_m,0) term outside the square root - INPUT: - L - evaluate Nroot for 0 <= l <= L - M - evaluate Nroot for 0 <= m <= M - OUTPUT: - The square root of equation (3.15) with the (2 - del_m,0) outside - HISTORY: - 2016-05-16 - Written - Aladdin Seaifan (UofT) + Evaluate the square root of equation (3.15) with the (2 - del_m,0) term outside the square root. + + Parameters + ---------- + L : int + Evaluate Nroot for 0 <= l <= L. + M : int + Evaluate Nroot for 0 <= m <= M. + + Returns + ------- + numpy.ndarray + The square root of equation (3.15) with the (2 - del_m,0) outside. + + Notes + ----- + - Written on 2016-05-16 by Aladdin Seaifan (UofT). """ NN = numpy.zeros((L, M), float) l = numpy.arange(0, L)[:, numpy.newaxis] @@ -288,16 +283,21 @@ def _Nroot(self, L, M): def _calculateXi(self, r): """ - NAME: - _calculateXi - PURPOSE: - Calculate xi given r - INPUT: - r - Evaluate at radius r - OUTPUT: - xi - HISTORY: - 2016-05-18 - Written - Aladdin Seaifan (UofT) + Calculate xi given r. + + Parameters + ---------- + r : float + Evaluate at radius r. + + Returns + ------- + xi : float + The calculated xi. + + Notes + ----- + - 2016-05-18 - Written - Aladdin Seaifan (UofT) """ a = self._a if r == 0: @@ -307,18 +307,25 @@ def _calculateXi(self, r): def _rhoTilde(self, r, N, L): """ - NAME: - _rhoTilde - PURPOSE: - Evaluate rho_tilde as defined in equation 3.9 and 2.24 for 0 <= n < N and 0 <= l < L - INPUT: - r - Evaluate at radius r - N - size of the N dimension - L - size of the L dimension - OUTPUT: - rho tilde - HISTORY: - 2016-05-17 - Written - Aladdin Seaifan (UofT) + Evaluate rho_tilde as defined in equation 3.9 and 2.24 for 0 <= n < N and 0 <= l < L + + Parameters + ---------- + r : float + Evaluate at radius r + N : int + size of the N dimension + L : int + size of the L dimension + + Returns + ------- + numpy.ndarray + The value of rho tilde + + Notes + ----- + - Written on 2016-05-17 by Aladdin Seaifan (UofT) """ xi = self._calculateXi(r) CC = _C(xi, N, L) @@ -338,18 +345,26 @@ def _rhoTilde(self, r, N, L): def _phiTilde(self, r, N, L): """ - NAME: - _phiTilde - PURPOSE: - Evaluate phi_tilde as defined in equation 3.10 and 2.25 for 0 <= n < N and 0 <= l < L - INPUT: - r - Evaluate at radius r - N - size of the N dimension - L - size of the L dimension - OUTPUT: - phi tilde - HISTORY: - 2016-05-17 - Written - Aladdin Seaifan (UofT) + Evaluate phi_tilde as defined in equation 3.10 and 2.25 for 0 <= n < N and 0 <= l < L + + Parameters + ---------- + r : float + Evaluate at radius r + N : int + size of the N dimension + L : int + size of the L dimension + + Returns + ------- + numpy.ndarray + phi tilde + + Notes + ----- + - Written on 2016-05-17 by Aladdin Seaifan (UofT) + """ xi = self._calculateXi(r) CC = _C(xi, N, L) @@ -371,19 +386,27 @@ def _phiTilde(self, r, N, L): def _compute(self, funcTilde, R, z, phi): """ - NAME: - _compute - PURPOSE: - evaluate the NxLxM density or potential - INPUT: - funcTidle - must be _rhoTilde or _phiTilde - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - OUTPUT: - An NxLxM density or potential at (R,z, phi) - HISTORY: - 2016-05-18 - Written - Aladdin Seaifan (UofT) + Evaluate the NxLxM density or potential + + Parameters + ---------- + funcTilde : function + Must be _rhoTilde or _phiTilde + R : float + Cylindrical Galactocentric radius + z : float + vertical height + phi : float + azimuth + + Returns + ------- + numpy.ndarray + An NxLxM density or potential at (R,z, phi) + + Notes + ----- + - Written on 2016-05-18 by Aladdin Seaifan (UofT) """ Acos, Asin = self._Acos, self._Asin N, L, M = Acos.shape @@ -408,19 +431,27 @@ def _compute(self, funcTilde, R, z, phi): def _computeArray(self, funcTilde, R, z, phi): """ - NAME: - _computeArray - PURPOSE: - evaluate the density or potential for a given array of coordinates - INPUT: - funcTidle - must be _rhoTilde or _phiTilde - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - OUTPUT: - density or potential evaluated at (R,z, phi) - HISTORY: - 2016-06-02 - Written - Aladdin Seaifan (UofT) + Evaluate the density or potential for a given array of coordinates. + + Parameters + ---------- + funcTilde : function + Must be _rhoTilde or _phiTilde. + R : array_like + Cylindrical Galactocentric radius. + z : array_like + Vertical height. + phi : array_like + Azimuth. + + Returns + ------- + array_like + Density or potential evaluated at (R,z, phi). + + Notes + ----- + - 2016-06-02 - Written - Aladdin Seaifan (UofT) """ R = numpy.array(R, dtype=float) z = numpy.array(z, dtype=float) @@ -441,41 +472,11 @@ def _computeArray(self, funcTilde, R, z, phi): return func def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - density at (R,z, phi) - HISTORY: - 2016-05-17 - Written - Aladdin Seaifan (UofT) - """ if not self.isNonAxi and phi is None: phi = 0.0 return self._computeArray(self._rhoTilde, R, z, phi) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate spherical - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-09 - Written - Bovy (UofT) - 2021-03-18 - Switched to using Gauss' theorem - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general # when integrating over spherical volume, all non-zero l,m vanish @@ -485,40 +486,11 @@ def _mass(self, R, z=None, t=0.0): ) def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - potential at (R,z, phi) - HISTORY: - 2016-05-17 - Written - Aladdin Seaifan (UofT) - """ if not self.isNonAxi and phi is None: phi = 0.0 return self._computeArray(self._phiTilde, R, z, phi) def _dphiTilde(self, r, N, L): - """ - NAME: - _dphiTilde - PURPOSE: - Evaluate the derivative of phiTilde with respect to r - INPUT: - r - spherical radius - N - size of the N dimension - L - size of the L dimension - OUTPUT: - the derivative of phiTilde with respect to r - HISTORY: - 2016-06-06 - Written - Aladdin Seaifan (UofT) - """ a = self._a l = numpy.arange(0, L, dtype=float)[numpy.newaxis, :] n = numpy.arange(0, N, dtype=float)[:, numpy.newaxis] @@ -533,21 +505,7 @@ def _dphiTilde(self, r, N, L): ) def _computeforce(self, R, z, phi=0, t=0): - """ - NAME: - _computeforce - PURPOSE: - Evaluate the first derivative of Phi with respect to R, z and phi - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - dPhi/dr, dPhi/dtheta, dPhi/dphi - HISTORY: - 2016-06-07 - Written - Aladdin Seaifan (UofT) - """ + """Computes dPhi/dr, dPhi/dtheta, dPhi/dphi""" Acos, Asin = self._Acos, self._Asin N, L, M = Acos.shape r, theta, phi = coords.cyl_to_spher(R, z, phi) @@ -584,22 +542,31 @@ def _computeforce(self, R, z, phi=0, t=0): def _computeforceArray(self, dr_dx, dtheta_dx, dphi_dx, R, z, phi): """ - NAME: - _computeforceArray - PURPOSE: - evaluate the forces in the x direction for a given array of coordinates - INPUT: - dr_dx - the derivative of r with respect to the chosen variable x - dtheta_dx - the derivative of theta with respect to the chosen variable x - dphi_dx - the derivative of phi with respect to the chosen variable x - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - The forces in the x direction - HISTORY: - 2016-06-02 - Written - Aladdin Seaifan (UofT) + Evaluate the forces in the x direction for a given array of coordinates. + + Parameters + ---------- + dr_dx : array_like + The derivative of r with respect to the chosen variable x. + dtheta_dx : array_like + The derivative of theta with respect to the chosen variable x. + dphi_dx : array_like + The derivative of phi with respect to the chosen variable x. + R : array_like + Cylindrical Galactocentric radius. + z : array_like + Vertical height. + phi : array_like + Azimuth. + + Returns + ------- + numpy.ndarray + The forces in the x direction. + + Notes + ----- + - 2016-06-02 - Written - Aladdin Seaifan (UofT) """ R = numpy.array(R, dtype=float) z = numpy.array(z, dtype=float) @@ -631,21 +598,6 @@ def _computeforceArray(self, dr_dx, dtheta_dx, dphi_dx, R, z, phi): return force def _Rforce(self, R, z, phi=0, t=0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - radial force at (R,z, phi) - HISTORY: - 2016-06-06 - Written - Aladdin Seaifan (UofT) - """ if not self.isNonAxi and phi is None: phi = 0.0 r, theta, phi = coords.cyl_to_spher(R, z, phi) @@ -656,21 +608,6 @@ def _Rforce(self, R, z, phi=0, t=0): return self._computeforceArray(dr_dR, dtheta_dR, dphi_dR, R, z, phi) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - vertical force at (R,z, phi) - HISTORY: - 2016-06-06 - Written - Aladdin Seaifan (UofT) - """ if not self.isNonAxi and phi is None: phi = 0.0 r, theta, phi = coords.cyl_to_spher(R, z, phi) @@ -681,21 +618,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): return self._computeforceArray(dr_dz, dtheta_dz, dphi_dz, R, z, phi) def _phitorque(self, R, z, phi=0, t=0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuth force at (R,z, phi) - INPUT: - R - Cylindrical Galactocentric radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - azimuth force at (R,z, phi) - HISTORY: - 2016-06-06 - Written - Aladdin Seaifan (UofT) - """ if not self.isNonAxi and phi is None: phi = 0.0 r, theta, phi = coords.cyl_to_spher(R, z, phi) @@ -725,22 +647,31 @@ def _RToxi(r, a=1): def _C(xi, N, L, alpha=lambda x: 2 * x + 3.0 / 2, singleL=False): """ - NAME: - _C - PURPOSE: - Evaluate C_n,l (the Gegenbauer polynomial) for 0 <= l < L and 0<= n < N - INPUT: - xi - radial transformed variable - N - Size of the N dimension - L - Size of the L dimension - alpha = A lambda function of l. Default alpha = 2l + 3/2 - singleL= (False), if True only compute the L-th polynomial - OUTPUT: - An LxN Gegenbauer Polynomial - HISTORY: - 2016-05-16 - Written - Aladdin Seaifan (UofT) - 2021-02-22 - Upgraded to array xi - Bovy (UofT) - 2021-02-22 - Added singleL for use in compute...nbody - Bovy (UofT) + Evaluate the Gegenbauer polynomial for 0 <= l < L and 0<= n < N + + Parameters + ---------- + xi : float + Radial transformed variable + N : int + Size of the N dimension + L : int + Size of the L dimension + alpha : function, optional + A lambda function of l. Default alpha = 2l + 3/2 + singleL : bool, optional + If True only compute the L-th polynomial (default: False) + + Returns + ------- + numpy.ndarray + An LxN Gegenbauer Polynomial + + Notes + ----- + - 2016-05-16 - Written - Aladdin Seaifan (UofT) + - 2021-02-22 - Upgraded to array xi - Bovy (UofT) + - 2021-02-22 - Added singleL for use in compute...nbody - Bovy (UofT) """ floatIn = False if isinstance(xi, (float, int)): @@ -780,33 +711,28 @@ def _dC(xi, N, L): def scf_compute_coeffs_spherical_nbody(pos, N, mass=1.0, a=1.0): """ - NAME: - - scf_compute_coeffs_spherical_nbody - - PURPOSE: - - Numerically compute the expansion coefficients for a spherical expansion for a given $N$-body set of points - - INPUT: - - pos - positions of particles in rectangular coordinates with shape [3,n] - - N - size of the Nth dimension of the expansion coefficients - - mass= (1.) mass of particles (scalar or array with size n) - - a= (1.) parameter used to scale the radius - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2020-11-18 - Written - Morgan Bennett (UofT) - - 2021-02-22 - Sped-up - Bovy (UofT) + Numerically compute the expansion coefficients for a spherical expansion for a given $N$-body set of points + + Parameters + ---------- + pos : array_like + Positions of particles in rectangular coordinates with shape [3,n] + N : int + Size of the Nth dimension of the expansion coefficients + mass : float or array_like, optional + Mass of particles (scalar or array with size n), by default 1.0 + a : float, optional + Parameter used to scale the radius, by default 1.0 + + Returns + ------- + tuple + Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2020-11-18 - Written - Morgan Bennett (UofT) + - 2021-02-22 - Sped-up - Bovy (UofT) """ Acos = numpy.zeros((N, 1, 1), float) @@ -832,32 +758,27 @@ def _scf_compute_determine_dens_kwargs(dens, param): def scf_compute_coeffs_spherical(dens, N, a=1.0, radial_order=None): """ - NAME: - - scf_compute_coeffs_spherical - - PURPOSE: - - Numerically compute the expansion coefficients for a given spherical density - - INPUT: - - dens - A density function that takes a parameter R - - N - size of expansion coefficients - - a= (1.) parameter used to scale the radius - - radial_order - Number of sample points of the radial integral. If None, radial_order=max(20, N + 1) - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2016-05-18 - Written - Aladdin Seaifan (UofT) - + Numerically compute the expansion coefficients for a given spherical density + + Parameters + ---------- + dens : function + A density function that takes a parameter R + N : int + Size of expansion coefficients + a : float, optional + Parameter used to scale the radius (default is 1.0) + radial_order : int, optional + Number of sample points of the radial integral. If None, radial_order=max(20, N + 1) (default is None) + + Returns + ------- + tuple + (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2016-05-18 - Written - Aladdin Seaifan (UofT) """ numOfParam = 0 try: @@ -901,34 +822,29 @@ def integrand(xi): def scf_compute_coeffs_axi_nbody(pos, N, L, mass=1.0, a=1.0): """ - NAME: - - scf_compute_coeffs_axi_nbody - - PURPOSE: - - Numerically compute the expansion coefficients for a given $N$-body set of points assuming that the density is axisymmetric - - INPUT: - - pos - positions of particles in rectangular coordinates with shape [3,n] - - N - size of the Nth dimension of the expansion coefficients - - L - size of the Lth dimension of the expansion coefficients - - mass= (1.) mass of particles (scalar or array with size n) - - a= (1.) parameter used to scale the radius - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2021-02-22 - Written based on general code - Bovy (UofT) - + Numerically compute the expansion coefficients for a given $N$-body set of points assuming that the density is axisymmetric + + Parameters + ---------- + pos : numpy.ndarray + Positions of particles in rectangular coordinates with shape [3,n] + N : int + Size of the Nth dimension of the expansion coefficients + L : int + Size of the Lth dimension of the expansion coefficients + mass : float or array_like, optional + Mass of particles (scalar or array with size n), by default 1.0 + a : float, optional + Parameter used to scale the radius, by default 1.0 + + Returns + ------- + tuple + Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2021-02-22 - Written based on general code - Bovy (UofT) """ r = numpy.sqrt(pos[0] ** 2 + pos[1] ** 2 + pos[2] ** 2) costheta = pos[2] / r @@ -970,36 +886,31 @@ def scf_compute_coeffs_axi_nbody(pos, N, L, mass=1.0, a=1.0): def scf_compute_coeffs_axi(dens, N, L, a=1.0, radial_order=None, costheta_order=None): """ - NAME: - - scf_compute_coeffs_axi - - PURPOSE: - - Numerically compute the expansion coefficients for a given axi-symmetric density - - INPUT: - - dens - A density function that takes a parameter R and z - - N - size of the Nth dimension of the expansion coefficients - - L - size of the Lth dimension of the expansion coefficients - - a - parameter used to shift the basis functions - - radial_order - Number of sample points of the radial integral. If None, radial_order=max(20, N + 3/2L + 1) - - costheta_order - Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1) - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2016-05-20 - Written - Aladdin Seaifan (UofT) - + Numerically compute the expansion coefficients for a given axi-symmetric density + + Parameters + ---------- + dens : function + A density function that takes parameters R and z + N : int + Size of the Nth dimension of the expansion coefficients + L : int + Size of the Lth dimension of the expansion coefficients + a : float, optional + Parameter used to shift the basis functions (default is 1.0) + radial_order : int, optional + Number of sample points of the radial integral. If None, radial_order=max(20, N + 3/2L + 1) (default is None) + costheta_order : int, optional + Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1) (default is None) + + Returns + ------- + tuple + (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2016-05-20 - Written - Aladdin Seaifan (UofT) """ numOfParam = 0 try: @@ -1061,33 +972,29 @@ def integrand(xi, costheta): def scf_compute_coeffs_nbody(pos, N, L, mass=1.0, a=1.0): """ - NAME: - - scf_compute_coeffs_nbody - - PURPOSE: - - Numerically compute the expansion coefficients for a given $N$-body set of points - - INPUT: - - pos - positions of particles in rectangular coordinates with shape [3,n] - - N - size of the Nth dimension of the expansion coefficients - - L - size of the Lth and Mth dimension of the expansion coefficients - - mass= (1.) mass of particles (scalar or array with size n) - - a= (1.) parameter used to scale the radius - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2020-11-18 - Written - Morgan Bennett (UofT) + Numerically compute the expansion coefficients for a given $N$-body set of points + + Parameters + ---------- + pos : numpy.ndarray + Positions of particles in rectangular coordinates with shape [3,n] + N : int + Size of the Nth dimension of the expansion coefficients + L : int + Size of the Lth and Mth dimension of the expansion coefficients + mass : float or array_like, optional + Mass of particles (scalar or array with size n), by default 1.0 + a : float, optional + Parameter used to scale the radius, by default 1.0 + + Returns + ------- + tuple + Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2020-11-18 - Written - Morgan Bennett (UofT) """ r = numpy.sqrt(pos[0] ** 2 + pos[1] ** 2 + pos[2] ** 2) @@ -1147,37 +1054,33 @@ def scf_compute_coeffs( dens, N, L, a=1.0, radial_order=None, costheta_order=None, phi_order=None ): """ - NAME: - - scf_compute_coeffs - - PURPOSE: - - Numerically compute the expansion coefficients for a given triaxial density - - INPUT: - - dens - A density function that takes a parameter R, z and phi - - N - size of the Nth dimension of the expansion coefficients - - L - size of the Lth and Mth dimension of the expansion coefficients - - a - parameter used to shift the basis functions - - radial_order - Number of sample points of the radial integral. If None, radial_order=max(20, N + 3/2L + 1) - - costheta_order - Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1) - - phi_order - Number of sample points of the phi integral. If None, If costheta_order=max(20, L + 1) - - OUTPUT: - - (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ - - HISTORY: - - 2016-05-27 - Written - Aladdin Seaifan (UofT) + Numerically compute the expansion coefficients for a given triaxial density + + Parameters + ---------- + dens : function + A density function that takes parameters R, z and phi + N : int + Size of the Nth dimension of the expansion coefficients + L : int + Size of the Lth and Mth dimension of the expansion coefficients + a : float, optional + Parameter used to shift the basis functions (default is 1.0) + radial_order : int, optional + Number of sample points of the radial integral. If None, radial_order=max(20, N + 3/2L + 1) (default is None) + costheta_order : int, optional + Number of sample points of the costheta integral. If None, If costheta_order=max(20, L + 1) (default is None) + phi_order : int, optional + Number of sample points of the phi integral. If None, If costheta_order=max(20, L + 1) (default is None) + + Returns + ------- + tuple + (Acos,Asin) - Expansion coefficients for density dens that can be given to SCFPotential.__init__ + + Notes + ----- + - 2016-05-27 - Written - Aladdin Seaifan (UofT) """ dens_kw = _scf_compute_determine_dens_kwargs(dens, [0.1, 0.1, 0.1]) @@ -1253,19 +1156,23 @@ def integrand(xi, costheta, phi): def _cartesian(arraySizes, out=None): """ - NAME: - cartesian - PURPOSE: - Generate a cartesian product of input arrays. - INPUT: - arraySizes - list of size of arrays - out - Array to place the cartesian product in. - OUTPUT: + Generate a cartesian product of input arrays. + + Parameters + ---------- + arraySizes : list + list of size of arrays + out : numpy.ndarray, optional + Array to place the cartesian product in. + + Returns + ------- + numpy.ndarray 2-D array of shape (product(arraySizes), len(arraySizes)) containing cartesian products - formed of input arrays. - HISTORY: - 2016-06-02 - Obtained from - http://stackoverflow.com/questions/1208118/using-numpy-to-build-an-array-of-all-combinations-of-two-arrays + + Notes + ----- + - 2016-06-02 - Obtained from http://stackoverflow.com/questions/1208118/using-numpy-to-build-an-array-of-all-combinations-of-two-arrays """ arrays = [] for i in range(len(arraySizes)): @@ -1289,23 +1196,28 @@ def _cartesian(arraySizes, out=None): def _gaussianQuadrature(integrand, bounds, Ksample=[20], roundoff=0): """ - NAME: - _gaussianQuadrature - PURPOSE: - Numerically take n integrals over a function that returns a float or an array - INPUT: - integrand - The function you're integrating over. - bounds - The bounds of the integral in the form of [[a_0, b_0], [a_1, b_1], ... , [a_n, b_n]] - where a_i is the lower bound and b_i is the upper bound - Ksample - Number of sample points in the form of [K_0, K_1, ..., K_n] where K_i is the sample point - of the ith integral. - roundoff - if the integral is less than this value, round it to 0. - OUTPUT: - The integral of the function integrand - HISTORY: - 2016-05-24 - Written - Aladdin Seaifan (UofT) + Numerically take n integrals over a function that returns a float or an array + + Parameters + ---------- + integrand : function + The function you're integrating over. + bounds : list + The bounds of the integral in the form of [[a_0, b_0], [a_1, b_1], ... , [a_n, b_n]] where a_i is the lower bound and b_i is the upper bound + Ksample : list, optional + Number of sample points in the form of [K_0, K_1, ..., K_n] where K_i is the sample point of the ith integral. (default is [20]) + roundoff : float, optional + if the integral is less than this value, round it to 0. (default is 0) + + Returns + ------- + numpy.ndarray + The integral of the function integrand + + Notes + ----- + - 2016-05-24 - Written - Aladdin Seaifan (UofT) """ - ##Maps the sample point and weights xp = numpy.zeros((len(bounds), numpy.max(Ksample)), float) wp = numpy.zeros((len(bounds), numpy.max(Ksample)), float) diff --git a/galpy/potential/SnapshotRZPotential.py b/galpy/potential/SnapshotRZPotential.py index cb30030c8..17ead93b6 100644 --- a/galpy/potential/SnapshotRZPotential.py +++ b/galpy/potential/SnapshotRZPotential.py @@ -32,34 +32,25 @@ class SnapshotRZPotential(Potential): def __init__(self, s, num_threads=None, nazimuths=4, ro=None, vo=None): """ - NAME: - - - __init__ - - PURPOSE: - - Initialize a SnapshotRZ potential object - - INPUT: - - s - a simulation snapshot loaded with pynbody - - num_threads= (4) number of threads to use for calculation - - nazimuths= (4) number of azimuths to average over - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - instance - - HISTORY: - - 2013 - Written - Rok Roskar (ETH) - - 2014-11-24 - Edited for merging into main galpy - Bovy (IAS) + Initialize a SnapshotRZ potential object + + Parameters + ---------- + s : pynbody.snapshot + A simulation snapshot loaded with pynbody. + num_threads : int, optional + Number of threads to use for calculation. Default is None. + nazimuths : int, optional + Number of azimuths to average over. Default is 4. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013 - Written - Rok Roskar (ETH) + - 2014-11-24 - Edited for merging into main galpy - Bovy (IAS) """ if not _PYNBODY_LOADED: # pragma: no cover @@ -169,48 +160,43 @@ def __init__( use_pkdgrav=False, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize an InterpSnapshotRZPotential instance - - INPUT: - - s - a simulation snapshot loaded with pynbody - - 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, interpepifreq, interpverticalfreq= if True, interpolate these functions (interpPot=True also interpolates the R and zforce) - - 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 - - nazimuths= (4) number of azimuths to average over - - use_pkdgrav= (False) use PKDGRAV to calculate the snapshot's potential and forces (CURRENTLY NOT IMPLEMENTED) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - instance - - HISTORY: - - 2013 - Written - Rok Roskar (ETH) - - 2014-11-24 - Edited for merging into main galpy - Bovy (IAS) - + Initialize an InterpSnapshotRZPotential instance + + Parameters + ---------- + s : pynbody.snapshot + A simulation snapshot loaded with pynbody. + rgrid : tuple, optional + R grid to be given to linspace as in rs= linspace(*rgrid). + zgrid : tuple, optional + z grid to be given to linspace as in zs= linspace(*zgrid). + interpepifreq : bool, optional + If True, interpolate the epicycle frequencies (default: False). + interpverticalfreq : bool, optional + If True, interpolate the vertical frequencies (default: False). + interpPot : bool, optional + If True, interpolate the potential (default: True). + enable_c : bool, optional + If True, use C for the interpolation (default: True). + logR : bool, optional + If True, rgrid is in the log of R so logrs= linspace(*rgrid) (default: True). + zsym : bool, optional + If True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g., zgrid=(0.,1.,101)). + numcores : int, optional + Number of cores to use for the interpolation (default: from pynbody configuration). + nazimuths : int, optional + Number of azimuths to average over (default: 4). + use_pkdgrav : bool, optional + If True, use PKDGRAV to calculate the snapshot's potential and forces (default: False). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2013 - Written - Rok Roskar (ETH) + - 2014-11-24 - Edited for merging into main galpy - Bovy (IAS) """ if not _PYNBODY_LOADED: # pragma: no cover raise ImportError( diff --git a/galpy/potential/SoftenedNeedleBarPotential.py b/galpy/potential/SoftenedNeedleBarPotential.py index 2e344283b..70e62ce28 100644 --- a/galpy/potential/SoftenedNeedleBarPotential.py +++ b/galpy/potential/SoftenedNeedleBarPotential.py @@ -40,39 +40,32 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a softened-needle bar potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass - - a= (4.) Bar half-length (can be Quantity) - - b= (1.) Triaxial softening length (can be Quantity) - - c= (1.) Prolate softening length (can be Quantity) - - pa= (0.4) The position angle of the x axis (rad or Quantity) - - omegab= (1.8) Pattern speed (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2016-11-02 - Started - Bovy (UofT) + Initialize a softened-needle bar potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass. + a : float or Quantity, optional + Bar half-length. + b : float , optional + Triaxial softening length (can be Quantity). + c : float, optional + Prolate softening length (can be Quantity). + pa : float or Quantity, optional + The position angle of the x axis. + omegab : float or Quantity, optional + Pattern speed. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2016-11-02 - Started - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") @@ -97,97 +90,25 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2016-11-02 - Started - Bovy (UofT) - """ x, y, z = self._compute_xyz(R, phi, z, t) Tp, Tm = self._compute_TpTm(x, y, z) return numpy.log((x - self._a + Tm) / (x + self._a + Tp)) / 2.0 / self._a def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2016-11-02 - Written - Bovy (UofT) - """ self._compute_xyzforces(R, z, phi, t) return numpy.cos(phi) * self._cached_Fx + numpy.sin(phi) * self._cached_Fy def _phitorque(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2016-11-02 - Written - Bovy (UofT) - """ self._compute_xyzforces(R, z, phi, t) return R * ( -numpy.sin(phi) * self._cached_Fx + numpy.cos(phi) * self._cached_Fy ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2016-11-02 - Written - Bovy (UofT) - """ self._compute_xyzforces(R, z, phi, t) return self._cached_Fz def OmegaP(self): - """ - NAME: - OmegaP - PURPOSE: - return the pattern speed - INPUT: - (none) - OUTPUT: - pattern speed - HISTORY: - 2016-11-02 - Written - Bovy (UofT) - """ return self._omegab def _compute_xyz(self, R, phi, z, t): @@ -243,21 +164,6 @@ def _zforce_xyz(self, x, y, z, Tp, Tm): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2016-11-04 - Written - Bovy (UofT/CCA) - """ x, y, z = self._compute_xyz(R, phi, z, t) zc = numpy.sqrt(z**2.0 + self._c2) bzc2 = (self._b + zc) ** 2.0 diff --git a/galpy/potential/SolidBodyRotationWrapperPotential.py b/galpy/potential/SolidBodyRotationWrapperPotential.py index 3c914c56c..b1dd82b01 100644 --- a/galpy/potential/SolidBodyRotationWrapperPotential.py +++ b/galpy/potential/SolidBodyRotationWrapperPotential.py @@ -19,31 +19,26 @@ class SolidBodyRotationWrapperPotential(parentWrapperPotential): def __init__(self, amp=1.0, pot=None, omega=1.0, pa=0.0, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a SolidBodyRotationWrapper Potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof; this potential is made to rotate around the z axis by the wrapper - - omega= (1.) the pattern speed (can be a Quantity) - - pa= (0.) the position angle (can be a Quantity) - - OUTPUT: - - (none) - - HISTORY: - - 2017-08-22 - Started - Bovy (UofT) + Initialize a SolidBodyRotationWrapper Potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential. Default is 1.0. + pot : Potential instance or list thereof + This potential is made to rotate around the z axis by the wrapper. + omega : float or Quantity, optional + The pattern speed. Default is 1.0. + pa : float or Quantity, optional + The position angle. Default is 0.0. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2017-08-22 - Started - Bovy (UofT) """ omega = conversion.parse_frequency(omega, ro=self._ro, vo=self._vo) @@ -54,18 +49,6 @@ def __init__(self, amp=1.0, pot=None, omega=1.0, pa=0.0, ro=None, vo=None): self.hasC_dxdv = True def OmegaP(self): - """ - NAME: - OmegaP - PURPOSE: - return the pattern speed - INPUT: - (none) - OUTPUT: - pattern speed - HISTORY: - 2016-11-02 - Written - Bovy (UofT) - """ return self._omega def _wrap(self, attribute, *args, **kwargs): diff --git a/galpy/potential/SphericalPotential.py b/galpy/potential/SphericalPotential.py index 813367229..595d83f82 100644 --- a/galpy/potential/SphericalPotential.py +++ b/galpy/potential/SphericalPotential.py @@ -24,29 +24,22 @@ class SphericalPotential(Potential): def __init__(self, amp=1.0, ro=None, vo=None, amp_units=None): """ - NAME: + Initialize a spherical potential. - __init__ + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + amp_units : str, optional + Type of units that amp should have if it has units ('mass', 'velocity2', 'density'). - PURPOSE: - - initialize a spherical potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units that depend on the specific spherical potential - - amp_units - ('mass', 'velocity2', 'density') type of units that amp should have if it has units (passed to Potential.__init__) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2020-03-30 - Written - Bovy (UofT) + Notes + ----- + - 2020-03-30 - Written - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units=amp_units) @@ -57,78 +50,18 @@ def _rdens(self, r, t=0.0): return (self._r2deriv(r, t=t) - 2.0 * self._rforce(r, t=t) / r) / 4.0 / numpy.pi def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return self._revaluate(r, t=t) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return self._rforce(r, t=t) * R / r def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return self._rforce(r, t=t) * z / r def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return ( self._r2deriv(r, t=t) * R**2.0 / r**2.0 @@ -136,21 +69,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return ( self._r2deriv(r, t=t) * z**2.0 / r**2.0 @@ -158,21 +76,6 @@ def _z2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed radial, vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the mixed radial, vertical derivative - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return ( self._r2deriv(r, t=t) * R * z / r**2.0 @@ -180,39 +83,10 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2020-03-30 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return self._rdens(r, t=t) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-15 - Written - Bovy (UofT) - """ if z is not None: raise AttributeError # use general implementation R = numpy.float64(R) # Avoid indexing issues diff --git a/galpy/potential/SphericalShellPotential.py b/galpy/potential/SphericalShellPotential.py index 5b79bd5a3..96b144993 100644 --- a/galpy/potential/SphericalShellPotential.py +++ b/galpy/potential/SphericalShellPotential.py @@ -20,33 +20,25 @@ class SphericalShellPotential(SphericalPotential): def __init__(self, amp=1.0, a=0.75, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a spherical shell potential - - INPUT: - - amp - mass of the shell (default: 1); can be a Quantity with units of mass or Gxmass - - a= (0.75) radius of the shell (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1.; note that because the force is always zero at r < a, this does not work if a > 1 - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2018-08-04 - Written - Bovy (UofT) - - 2020-03-30 - Re-implemented using SphericalPotential - Bovy (UofT) + Initialize a spherical shell potential. + + Parameters + ---------- + amp : float or Quantity, optional + Mass of the shell (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Radius of the shell (default: 0.75). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1.; note that because the force is always zero at r < a, this does not work if a > 1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2018-08-04 - Written - Bovy (UofT) + - 2020-03-30 - Re-implemented using SphericalPotential - Bovy (UofT) """ SphericalPotential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") @@ -93,21 +85,6 @@ def _rdens(self, r, t=0.0): return numpy.infty def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2018-08-04 - Written - Bovy (UofT) - """ if R > self.a: return 0.0 h = numpy.sqrt(self.a2 - R**2) diff --git a/galpy/potential/SpiralArmsPotential.py b/galpy/potential/SpiralArmsPotential.py index 5280db360..236f1c4d4 100644 --- a/galpy/potential/SpiralArmsPotential.py +++ b/galpy/potential/SpiralArmsPotential.py @@ -56,31 +56,38 @@ def __init__( Cs=[1], ): """ - NAME: - __init__ - PURPOSE: - initialize a spiral arms potential - INPUT: - :amp: amplitude to be applied to the potential (default: 1); - can be a Quantity with units of density. (:math:`amp = 4 \\pi G \\rho_0`) - :ro: distance scales for translation into internal units (default from configuration file) - :vo: velocity scales for translation into internal units (default from configuration file) - :N: number of spiral arms - :alpha: pitch angle of the logarithmic spiral arms in radians (can be Quantity) - :r_ref: fiducial radius where :math:`\\rho = \\rho_0` (:math:`r_0` in the paper by Cox and Gomez) (can be Quantity) - :phi_ref: reference angle (:math:`\\phi_p(r_0)` in the paper by Cox and Gomez) (can be Quantity) - :Rs: radial scale length of the drop-off in density amplitude of the arms (can be Quantity) - :H: scale height of the stellar arm perturbation (can be Quantity) - :Cs: list of constants multiplying the :math:`\\cos(n \\gamma)` terms - :omega: rotational pattern speed of the spiral arms (can be Quantity) - OUTPUT: - (none) - HISTORY: - Started - 2017-05-12 Jack Hong (UBC) - - Completed - 2017-07-04 Jack Hong (UBC) + Initialize a spiral arms potential + + Parameters + ---------- + amp : float or Quantity, optional + amplitude to be applied to the potential (default: 1); can be a Quantity with units of density. (:math:`amp = 4 \\pi G \\rho_0`) + ro : float or Quantity, optional + distance scales for translation into internal units (default from configuration file) + vo : float or Quantity, optional + velocity scales for translation into internal units (default from configuration file) + N : int, optional + number of spiral arms. + alpha : float or Quantity, optional + pitch angle of the logarithmic spiral arms. + r_ref : float or Quantity, optional + fiducial radius where :math:`\\rho = \\rho_0` (:math:`r_0` in the paper by Cox and Gomez). + phi_ref : float or Quantity, optional + reference angle (:math:`\\phi_p(r_0)` in the paper by Cox and Gomez). + Rs : float or Quantity, optional + radial scale length of the drop-off in density amplitude of the arms. + H : float or Quantity, optional + scale height of the stellar arm perturbation. + Cs : list of floats, optional + constants multiplying the :math:`\\cos(n \\gamma)` terms. + omega : float or Quantity, optional + rotational pattern speed of the spiral arms. + + Notes + ----- + - 2017-05-12 - Started - Jack Hong (UBC) + - 2020-03-30 - Re-implemented using Potential - Bovy (UofT) """ - Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units=amp_units) alpha = conversion.parse_angle(alpha) r_ref = conversion.parse_length(r_ref, ro=self._ro) @@ -113,21 +120,6 @@ def __init__( self.hasC_dxdv = True # Potential has C implementation of second derivatives def _evaluate(self, R, z, phi=0, t=0): - """ - NAME: - _evaluate - PURPOSE: - Evaluate the potential at the given coordinates. (without the amp factor; handled by super class) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: Phi(R, z, phi, t) - HISTORY: - 2017-05-12 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -177,21 +169,6 @@ def _evaluate(self, R, z, phi=0, t=0): ) def _Rforce(self, R, z, phi=0, t=0): - """ - NAME: - _Rforce - PURPOSE: - Evaluate the radial force for this potential at the given coordinates. (-dPhi/dR) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the radial force - HISTORY: - 2017-05-12 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -263,21 +240,6 @@ def _Rforce(self, R, z, phi=0, t=0): ) def _zforce(self, R, z, phi=0, t=0): - """ - NAME: - _zforce - PURPOSE: - Evaluate the vertical force for this potential at the given coordinates. (-dPhi/dz) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the vertical force - HISTORY: - 2017-05-25 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -328,21 +290,6 @@ def _zforce(self, R, z, phi=0, t=0): ) def _phitorque(self, R, z, phi=0, t=0): - """ - NAME: - _phitorque - PURPOSE: - Evaluate the azimuthal torque in cylindrical coordinates. (-dPhi/dphi) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the azimuthal torque - HISTORY: - 2017-05-25 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -395,22 +342,6 @@ def _phitorque(self, R, z, phi=0, t=0): ) def _R2deriv(self, R, z, phi=0, t=0): - """ - NAME: - _R2deriv - PURPOSE: - Evaluate the second (cylindrical) radial derivative of the potential. - (d^2 potential / d R^2) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the second radial derivative - HISTORY: - 2017-05-31 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -634,22 +565,6 @@ def _R2deriv(self, R, z, phi=0, t=0): ) def _z2deriv(self, R, z, phi=0, t=0): - """ - NAME: - _z2deriv - PURPOSE: - Evaluate the second (cylindrical) vertical derivative of the potential. - (d^2 potential / d z^2) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the second vertical derivative - HISTORY: - 2017-05-26 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -703,22 +618,6 @@ def _z2deriv(self, R, z, phi=0, t=0): ) def _phi2deriv(self, R, z, phi=0, t=0): - """ - NAME: - _phi2deriv - PURPOSE: - Evaluate the second azimuthal derivative of the potential in cylindrical coordinates. - (d^2 potential / d phi^2) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: d^2 potential / d phi^2 - HISTORY: - 2017-05-29 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -771,22 +670,6 @@ def _phi2deriv(self, R, z, phi=0, t=0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - Evaluate the mixed (cylindrical) radial and vertical derivative of the potential - (d^2 potential / dR dz). - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: d^2 potential / dR dz - HISTORY: - 2017-05-12 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -872,22 +755,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _Rphideriv(self, R, z, phi=0, t=0): - """ - NAME: - _Rphideriv - PURPOSE: - Return the mixed radial and azimuthal derivative of the potential in cylindrical coordinates - (d^2 potential / dR dphi) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the mixed radial and azimuthal derivative - HISTORY: - 2017-06-09 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -963,21 +830,6 @@ def _Rphideriv(self, R, z, phi=0, t=0): ) def _phizderiv(self, R, z, phi=0, t=0): - """ - NAME: - _phizderiv - PURPOSE: - Evaluate the mixed azimuthal, vertical derivative for this potential at the given coordinates. (-dPhi/dz) - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: mixed azimuthal, vertical derivative - HISTORY: - 2021-04-30 - Jo Bovy (UofT) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -1030,22 +882,6 @@ def _phizderiv(self, R, z, phi=0, t=0): ) def _dens(self, R, z, phi=0, t=0): - """ - NAME: - _dens - PURPOSE: - Evaluate the density. If not given, the density is computed using the Poisson equation - from the first and second derivatives of the potential (if all are implemented). - INPUT: - :param R: galactocentric cylindrical radius - :param z: vertical height - :param phi: azimuth - :param t: time - OUTPUT: - :return: the density - HISTORY: - 2017-05-12 Jack Hong (UBC) - """ if isinstance(R, numpy.ndarray) or isinstance(z, numpy.ndarray): nR = len(R) if isinstance(R, numpy.ndarray) else len(z) self._Cs = numpy.transpose( @@ -1126,18 +962,6 @@ def _dens(self, R, z, phi=0, t=0): ) def OmegaP(self): - """ - NAME: - OmegaP - PURPOSE: - Return the pattern speed. (used to compute the Jacobi integral for orbits). - INPUT: - :param self - OUTPUT: - :return: the pattern speed - HISTORY: - 2017-06-09 Jack Hong (UBC) - """ return self._omega def _gamma(self, R, phi): diff --git a/galpy/potential/SteadyLogSpiralPotential.py b/galpy/potential/SteadyLogSpiralPotential.py index 369daf0ba..6f98c7459 100644 --- a/galpy/potential/SteadyLogSpiralPotential.py +++ b/galpy/potential/SteadyLogSpiralPotential.py @@ -36,45 +36,36 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a logarithmic spiral potential - - INPUT: - - amp - amplitude to be applied to the potential (default: - 1., A below) - - gamma - angle between sun-GC line and the line connecting the peak of the spiral pattern at the Solar radius (in rad; default=45 degree; or can be Quantity) - - A - amplitude (alpha*potential-amplitude; default=0.035; can be Quantity - - omegas= - pattern speed (default=0.65; can be Quantity) - - m= number of arms - - Either provide: - - a) alpha= - - b) p= pitch angle (rad; can be Quantity) - - tform - start of spiral growth / spiral period (default: -Infinity) - - tsteady - time from tform at which the spiral is fully grown / spiral period (default: 2 periods) - - OUTPUT: - - (none) - - HISTORY: - - 2011-03-27 - Started - Bovy (NYU) - + Initialize a steady-state logarithmic spiral potential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1., A below). + omegas : float or Quantity, optional + Pattern speed (default: 0.65). + A : float or Quantity, optional + Amplitude (alpha*potential-amplitude; default=0.035). + alpha : float, optional + Parameter that sets the strength of the spiral potential. + m : int, optional + Number of spiral arms. + gamma : float or Quantity, optional + Angle between sun-GC line and the line connecting the peak of the spiral pattern at the Solar radius (in rad; default=45 degree). + p : float or Quantity, optional + Pitch angle. + tform : float, optional + Start of spiral growth / spiral period (default: -Infinity). + tsteady : float, optional + Time from tform at which the spiral is fully grown / spiral period (default: 2 periods). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2011-03-27 - Started - Bovy (NYU) """ planarPotential.__init__(self, amp=amp, ro=ro, vo=vo) gamma = conversion.parse_angle(gamma) @@ -104,20 +95,6 @@ def __init__( self.hasC = True def _evaluate(self, R, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - Phi(R,phi,t) - HISTORY: - 2011-03-27 - Started - Bovy (NYU) - """ if not self._tform is None: if t < self._tform: smooth = 0.0 @@ -145,20 +122,6 @@ def _evaluate(self, R, phi=0.0, t=0.0): ) def _Rforce(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ if not self._tform is None: if t < self._tform: smooth = 0.0 @@ -186,20 +149,6 @@ def _Rforce(self, R, phi=0.0, t=0.0): ) def _phitorque(self, R, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ if not self._tform is None: if t < self._tform: smooth = 0.0 @@ -229,103 +178,55 @@ def _phitorque(self, R, phi=0.0, t=0.0): def wavenumber(self, R): """ - NAME: - - - wavenumber - - PURPOSE: - - return the wavenumber at radius R (d f(R)/ d R in Phi_a(R) = F(R) e^[i f(R)]; see Binney & Tremaine 2008) - - INPUT: - - R - Cylindrical radius + Return the wavenumber at radius R (d f(R)/ d R in Phi_a(R) = F(R) e^[i f(R)]; see Binney & Tremaine 2008) - OUTPUT: + Parameters + ---------- + R : float + Cylindrical radius - wavenumber at R + Returns + ------- + float + wavenumber at R - HISTORY: - - 2014-08-23 - Written - Bovy (IAS) + Notes + ----- + - 2014-08-23 - Written - Bovy (IAS) """ return self._alpha / R def OmegaP(self): - """ - NAME: - - - OmegaP - - PURPOSE: - - return the pattern speed - - INPUT: - - (none) - - OUTPUT: - - pattern speed - - HISTORY: - - 2011-10-10 - Written - Bovy (IAS) - - """ return self._omegas def m(self): """ - NAME: - + Return the number of arms. - m - - PURPOSE: - - return the number of arms - - INPUT: - - (none) - - OUTPUT: - - number of arms - - HISTORY: - - 2014-08-23 - Written - Bovy (IAS) + Returns + ------- + int + Number of arms. + Notes + ----- + - 2014-08-23 - Written - Bovy (IAS) """ return self._m def tform(self): # pragma: no cover """ - NAME: - - tform - - PURPOSE: - - return formation time of the bar - - INPUT: - - (none) - - OUTPUT: - - tform in normalized units + Return formation time of the bar. - HISTORY: + Returns + ------- + tform : float + Formation time of the bar in normalized units. - 2011-03-08 - Written - Bovy (NYU) + Notes + ----- + - 2011-03-08 - Written - Bovy (NYU) """ return self._tform diff --git a/galpy/potential/TimeDependentAmplitudeWrapperPotential.py b/galpy/potential/TimeDependentAmplitudeWrapperPotential.py index 180cc2b60..bb721f714 100644 --- a/galpy/potential/TimeDependentAmplitudeWrapperPotential.py +++ b/galpy/potential/TimeDependentAmplitudeWrapperPotential.py @@ -26,29 +26,24 @@ class TimeDependentAmplitudeWrapperPotential(parentWrapperPotential): def __init__(self, amp=1.0, A=None, pot=None, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a TimeDependentAmplitudeWrapperPotential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - A - function of time giving the time-dependence of the amplitude; should be able to be called with a single time and return a numbers.Number (that is, a number); input time is in internal units (see galpy.util.conversion.time_in_Gyr to convert) and output is a dimensionless amplitude modulation - - pot - Potential instance or list thereof; the amplitude of this will modified by this wrapper - - OUTPUT: - - (none) - - HISTORY: - - 2022-03-29 - Started - Bovy (UofT) + Initialize a TimeDependentAmplitudeWrapperPotential. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + A : function, optional + Function of time giving the time-dependence of the amplitude; should be able to be called with a single time and return a numbers.Number (that is, a number); input time is in internal units (see galpy.util.conversion.time_in_Gyr to convert) and output is a dimensionless amplitude modulation. + pot : Potential instance or list thereof + The amplitude of this will modified by this wrapper. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Started - 2022-03-29 - Bovy (UofT) """ if not callable(A): diff --git a/galpy/potential/TransientLogSpiralPotential.py b/galpy/potential/TransientLogSpiralPotential.py index 1dda98e20..a0f08b207 100644 --- a/galpy/potential/TransientLogSpiralPotential.py +++ b/galpy/potential/TransientLogSpiralPotential.py @@ -39,46 +39,35 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a transient logarithmic spiral potential localized - around to - - INPUT: - - amp - amplitude to be applied to the potential (default: - 1., A below) - - gamma - angle between sun-GC line and the line connecting the peak of the spiral pattern at the Solar radius (in rad; default=45 degree; can be Quantity) - - A - amplitude (alpha*potential-amplitude; default=0.035; can be Quantity) - - omegas= - pattern speed (default=0.65; can be Quantity) - - m= number of arms - - to= time at which the spiral peaks (can be Quantity) - - sigma= "spiral duration" (sigma in Gaussian amplitude; can be Quantity) - - Either provide: - - a) alpha= - - b) p= pitch angle (rad; can be Quantity) - - OUTPUT: - - (none) - - HISTORY: - - 2011-03-27 - Started - Bovy (NYU) - + Initialize a transient logarithmic spiral potential localized around to + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1). + omegas : float or Quantity, optional + Pattern speed (default: 0.65). + A : float or Quantity, optional + Amplitude (alpha*potential-amplitude; default: -0.035). + alpha : float, optional + Alpha parameter (default: -7.). + m : int, optional + Number of arms (default: 2). + gamma : float or Quantity, optional + Angle between sun-GC line and the line connecting the peak of the spiral pattern at the Solar radius (in rad; default: 45 degree). + p : float or Quantity, optional + Pitch angle. + sigma : float or Quantity, optional + "Spiral duration" (sigma in Gaussian amplitude; default: 1.). + to : float or Quantity, optional + Time at which the spiral peaks (default: 0.). + + Notes + ----- + - Either provide: + * alpha + * p + - 2011-03-27 - Started - Bovy (NYU) """ planarPotential.__init__(self, amp=amp, ro=ro, vo=vo) gamma = conversion.parse_angle(gamma) @@ -100,20 +89,6 @@ def __init__( self.hasC = True def _evaluate(self, R, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,phi,t - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - Phi(R,phi,t) - HISTORY: - 2011-03-27 - Started - Bovy (NYU) - """ return ( self._A * numpy.exp(-((t - self._to) ** 2.0) / 2.0 / self._sigma2) @@ -125,20 +100,6 @@ def _evaluate(self, R, phi=0.0, t=0.0): ) def _Rforce(self, R, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ return ( self._A * numpy.exp(-((t - self._to) ** 2.0) / 2.0 / self._sigma2) @@ -150,20 +111,6 @@ def _Rforce(self, R, phi=0.0, t=0.0): ) def _phitorque(self, R, phi=0.0, t=0.0): - """ - NAME: - _phitorque - PURPOSE: - evaluate the azimuthal torque for this potential - INPUT: - R - Galactocentric cylindrical radius - phi - azimuth - t - time - OUTPUT: - the azimuthal torque - HISTORY: - 2010-11-24 - Written - Bovy (NYU) - """ return ( -self._A * numpy.exp(-((t - self._to) ** 2.0) / 2.0 / self._sigma2) @@ -176,27 +123,4 @@ def _phitorque(self, R, phi=0.0, t=0.0): ) def OmegaP(self): - """ - NAME: - - - OmegaP - - PURPOSE: - - return the pattern speed - - INPUT: - - (none) - - OUTPUT: - - pattern speed - - HISTORY: - - 2011-10-10 - Written - Bovy (IAS) - - """ return self._omegas diff --git a/galpy/potential/TriaxialGaussianPotential.py b/galpy/potential/TriaxialGaussianPotential.py index 8aee20764..4a9e3e410 100644 --- a/galpy/potential/TriaxialGaussianPotential.py +++ b/galpy/potential/TriaxialGaussianPotential.py @@ -38,39 +38,34 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Gaussian potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - sigma - Gaussian dispersion scale (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2020-08-18 - Started - Bovy (UofT) + Initialize a triaxial Gaussian potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + sigma : float or Quantity, optional + Gaussian dispersion scale. + b : float, optional + y-to-x axis ratio of the density. + c : float, optional + z-to-x axis ratio of the density. + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis. + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + normalize : bool or float, optional + If True, normalize the potential (default: False). If a float, normalize the potential to this value. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2020-08-18 - Started - Bovy (UofT) """ EllipsoidalPotential.__init__( @@ -113,20 +108,6 @@ def _mdens_deriv(self, m): return -2.0 * m * numpy.exp(-(m**2) / self._twosigma2) / self._twosigma2 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-09 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( diff --git a/galpy/potential/TwoPowerSphericalPotential.py b/galpy/potential/TwoPowerSphericalPotential.py index 62209a3e7..b0032b494 100644 --- a/galpy/potential/TwoPowerSphericalPotential.py +++ b/galpy/potential/TwoPowerSphericalPotential.py @@ -32,36 +32,28 @@ def __init__( self, amp=1.0, a=5.0, alpha=1.5, beta=3.5, normalize=False, ro=None, vo=None ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a two-power-density potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - alpha - inner power - - beta - outer power - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Started - Bovy (NYU) - + Initialize a two-power-density potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius. + alpha : float, optional + Inner power. + beta : float, optional + Outer power. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Started - 2010-07-09 - Bovy (NYU) """ # Instantiate Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") @@ -96,21 +88,6 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-07-09 - Started - Bovy (NYU) - """ if self._specialSelf is not None: return self._specialSelf._evaluate(R, z, phi=phi, t=t) elif self.beta == 3.0: @@ -152,21 +129,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ if self._specialSelf is not None: return self._specialSelf._Rforce(R, z, phi=phi, t=t) else: @@ -185,21 +147,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ if self._specialSelf is not None: return self._specialSelf._zforce(R, z, phi=phi, t=t) else: @@ -218,21 +165,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2010-08-08 - Written - Bovy (NYU) - """ r = numpy.sqrt(R**2.0 + z**2.0) return ( (self.a / r) ** self.alpha @@ -243,19 +175,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _ddensdr(self, r, t=0.0): - """ - NAME: - _ddensdr - PURPOSE: - s evaluate the radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the density derivative - HISTORY: - 2021-02-05 - Written - Bovy (UofT) - """ return ( -self._amp * (self.a / r) ** (self.alpha - 1.0) @@ -268,19 +187,6 @@ def _ddensdr(self, r, t=0.0): ) def _d2densdr2(self, r, t=0.0): - """ - NAME: - _d2densdr2 - PURPOSE: - evaluate the second radial density derivative for this potential - INPUT: - r - spherical radius - t= time - OUTPUT: - the 2nd density derivative - HISTORY: - 2021-02-05 - Written - Bovy (UofT) - """ return ( self._amp * (self.a / r) ** (self.alpha - 2.0) @@ -298,17 +204,24 @@ def _d2densdr2(self, r, t=0.0): def _ddenstwobetadr(self, r, beta=0): """ - NAME: - _ddenstwobetadr - PURPOSE: - evaluate the radial density derivative x r^(2beta) for this potential - INPUT: - r - spherical radius - beta= (0) - OUTPUT: - d (rho x r^{2beta} ) / d r - HISTORY: - 2021-02-14 - Written - Bovy (UofT) + Evaluate the radial density derivative x r^(2beta) for this potential. + + Parameters + ---------- + r : float + Spherical radius. + beta : float, optional + Power of r in the density derivative. Default is 0. + + Returns + ------- + float + The derivative of the density times r^(2beta). + + Notes + ----- + - 2021-02-14 - Written - Bovy (UofT) + """ return ( self._amp @@ -322,21 +235,6 @@ def _ddenstwobetadr(self, r, beta=0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second cylindrically radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second cylindrically radial derivative - HISTORY: - 2020-11-23 - Written - Beane (CfA) - """ r = numpy.sqrt(R**2.0 + z**2.0) A = self.a ** (self.alpha - 3.0) / (3.0 - self.alpha) hyper = special.hyp2f1( @@ -360,21 +258,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): return term1 + term2 + term3 def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the mixed radial/vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the mixed radial/vertical derivative - HISTORY: - 2020-11-28 - Written - Beane (CfA) - """ r = numpy.sqrt(R**2.0 + z**2.0) A = self.a ** (self.alpha - 3.0) / (3.0 - self.alpha) hyper = special.hyp2f1( @@ -397,38 +280,9 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): return term1 + term2 def _z2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2012-07-26 - Written - Bovy (IAS@MPIA) - """ return self._R2deriv(numpy.fabs(z), R) # Spherical potential def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2014-04-01 - Written - Erkal (IoA) - """ if z is not None: raise AttributeError # use general implementation return ( @@ -450,34 +304,26 @@ class DehnenSphericalPotential(TwoPowerSphericalPotential): def __init__(self, amp=1.0, a=1.0, alpha=1.5, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a Dehnen Spherical Potential; note that the amplitude definition used here does NOT match that of Dehnen (1993) - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - alpha - inner power, restricted to [0, 3) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2019-10-07 - Started - Starkman (UofT) - + Initialize a Dehnen Spherical Potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius. + alpha : float, optional + Inner power, restricted to [0, 3). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Started - Starkman (UofT) - 2019-10-07 """ if (alpha < 0.0) or (alpha >= 3.0): raise OSError("DehnenSphericalPotential requires 0 <= alpha < 3") @@ -503,21 +349,6 @@ def __init__(self, amp=1.0, a=1.0, alpha=1.5, normalize=False, ro=None, vo=None) return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ if self._specialSelf is not None: return self._specialSelf._evaluate(R, z, phi=phi, t=t) else: # valid for alpha != 2, 3 @@ -527,21 +358,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): ) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ if self._specialSelf is not None: return self._specialSelf._Rforce(R, z, phi=phi, t=t) else: @@ -554,21 +370,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second radial derivative - HISTORY: - 2019-10-11 - Written - Starkman (UofT) - """ if self._specialSelf is not None: return self._specialSelf._R2deriv(R, z, phi=phi, t=t) a, alpha = self.a, self.alpha @@ -582,21 +383,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2019-11-21 - Written - Starkman (UofT) - """ if self._specialSelf is not None: return self._specialSelf._zforce(R, z, phi=phi, t=t) else: @@ -609,39 +395,9 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _z2deriv(self, R, z, phi=0.0, t=0.0): - r""" - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2019-10-20 - Written - Starkman (UofT) - """ return self._R2deriv(z, R, phi=phi, t=t) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2019-10-11 - Written - Starkman (UofT) - """ if self._specialSelf is not None: return self._specialSelf._Rzderiv(R, z, phi=phi, t=t) a, alpha = self.a, self.alpha @@ -655,21 +411,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) / (alpha - 3) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return ( (self.a / r) ** self.alpha @@ -680,20 +421,6 @@ def _dens(self, R, z, phi=0.0, t=0.0): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ if z is not None: raise AttributeError # use general implementation return ( @@ -711,34 +438,24 @@ class DehnenCoreSphericalPotential(DehnenSphericalPotential): def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - initialize a cored Dehnen Spherical Potential; note that the amplitude definition used here does NOT match that of Dehnen (1993) - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - alpha - inner power, restricted to [0, 3) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2019-10-07 - Started - Starkman (UofT) - + Initialize a cored Dehnen Spherical Potential; note that the amplitude definition used here does NOT match that of Dehnen (1993) + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass + a : float or Quantity, optional + Scale radius. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2019-10-07 - Started - Starkman (UofT) """ DehnenSphericalPotential.__init__( self, amp=amp, a=a, alpha=0, normalize=normalize, ro=ro, vo=vo @@ -750,74 +467,17 @@ def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return -(1.0 - 1.0 / (1.0 + self.a / r) ** 2.0) / (6.0 * self.a) def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ return -R / numpy.power(numpy.sqrt(R**2.0 + z**2.0) + self.a, 3.0) / 3.0 def _rforce_jax(self, r): - """ - NAME: - _rforce_jax - PURPOSE: - evaluate the spherical radial force for this potential using JAX - INPUT: - r - Galactocentric spherical radius - OUTPUT: - the radial force - HISTORY: - 2021-02-25 - Written - Bovy (UofT) - """ # No need for actual JAX! return -self._amp * r / (r + self.a) ** 3.0 / 3.0 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second radial derivative - HISTORY: - 2019-10-11 - Written - Starkman (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return -( ((2.0 * R**2.0 - z**2.0) - self.a * r) @@ -825,96 +485,22 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2019-11-21 - Written - Starkman (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return -z / numpy.power(self.a + r, 3.0) / 3.0 def _z2deriv(self, R, z, phi=0.0, t=0.0): - r""" - NAME: - _z2deriv - PURPOSE: - evaluate the second vertical derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second vertical derivative - HISTORY: - 2019-10-20 - Written - Starkman (UofT) - """ return self._R2deriv(z, R, phi=phi, t=t) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2019-10-11 - Written - Starkman (UofT) - """ a = self.a r = numpy.sqrt(R**2.0 + z**2.0) return -(R * z / r / numpy.power(a + r, 4.0)) def _dens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _dens - PURPOSE: - evaluate the density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the density - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) return 1.0 / (1.0 + r / self.a) ** 4.0 / 4.0 / numpy.pi / self.a**3.0 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2019-11-20 - Written - Starkman (UofT) - """ if z is not None: raise AttributeError # use general implementation return ( @@ -933,31 +519,24 @@ class HernquistPotential(DehnenSphericalPotential): def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a Hernquist potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass (note that amp is 2 x [total mass] for the chosen definition of the Hernquist potential) - - a - scale radius (can be Quantity) + Initialize a Two Power Spherical Potential. - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass (note that amp is 2 x [total mass] for the chosen definition of the Two Power Spherical potential). + a : float or Quantity, optional + Scale radius. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Written - Bovy (NYU) + Notes + ----- + - 2010-07-09 - Written - Bovy (NYU). """ DehnenSphericalPotential.__init__( @@ -971,92 +550,21 @@ def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-07-09 - Started - Bovy (NYU) - """ return -1.0 / (1.0 + numpy.sqrt(R**2.0 + z**2.0) / self.a) / 2.0 / self.a def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the radial force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return -R / self.a / sqrtRz / (1.0 + sqrtRz / self.a) ** 2.0 / 2.0 / self.a def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return -z / self.a / sqrtRz / (1.0 + sqrtRz / self.a) ** 2.0 / 2.0 / self.a def _rforce_jax(self, r): - """ - NAME: - _rforce_jax - PURPOSE: - evaluate the spherical radial force for this potential using JAX - INPUT: - r - Galactocentric spherical radius - OUTPUT: - the radial force - HISTORY: - 2021-02-14 - Written - Bovy (UofT) - """ # No need for actual JAX! return -self._amp / 2.0 / (r + self.a) ** 2.0 def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return ( (self.a * z**2.0 + (z**2.0 - 2.0 * R**2.0) * sqrtRz) @@ -1066,21 +574,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t- time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return ( -R @@ -1091,21 +584,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the surface density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) Rma = numpy.sqrt(R**2.0 - self.a**2.0 + 0j) if Rma == 0.0: @@ -1143,19 +621,6 @@ def _surfdens(self, R, z, phi=0.0, t=0.0): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - calculate the mass out to a given radius - INPUT: - R - radius at which to return the enclosed mass - z - (don't specify this) vertical height - OUTPUT: - mass in natural units - HISTORY: - 2014-01-29 - Written - Bovy (IAS) - """ if z is not None: raise AttributeError # use general implementation return ( @@ -1165,27 +630,23 @@ def _mass(self, R, z=None, t=0.0): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): """ - NAME: - - _nemo_accpars - - PURPOSE: + Return the accpars potential parameters for use of this potential with NEMO. - return the accpars potential parameters for use of this potential with NEMO + Parameters + ---------- + vo : float + Velocity unit in km/s. + ro : float + Length unit in kpc. - INPUT: + Returns + ------- + str + accpars string. - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: - - accpars string - - HISTORY: - - 2018-09-14 - Written - Bovy (UofT) + Notes + ----- + - 2018-09-14 - Written - Bovy (UofT) """ GM = self._amp * vo**2.0 * ro / 2.0 @@ -1203,32 +664,24 @@ class JaffePotential(DehnenSphericalPotential): def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a Jaffe potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Written - Bovy (NYU) - + Initialize a Jaffe Potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius (can be Quantity). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-07-09 - Written - Bovy (NYU) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") a = conversion.parse_length(a, ro=self._ro) @@ -1246,77 +699,17 @@ def __init__(self, amp=1.0, a=1.0, normalize=False, ro=None, vo=None): return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-07-09 - Started - Bovy (NYU) - """ return -numpy.log(1.0 + self.a / numpy.sqrt(R**2.0 + z**2.0)) / self.a def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return -R / sqrtRz**3.0 / (1.0 + self.a / sqrtRz) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return -z / sqrtRz**3.0 / (1.0 + self.a / sqrtRz) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return ( (self.a * (z**2.0 - R**2.0) + (z**2.0 - 2.0 * R**2.0) * sqrtRz) @@ -1325,21 +718,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ sqrtRz = numpy.sqrt(R**2.0 + z**2.0) return ( -R @@ -1350,21 +728,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the surface density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) Rma = numpy.sqrt(R**2.0 - self.a**2.0 + 0j) if Rma == 0.0: @@ -1397,19 +760,6 @@ def _surfdens(self, R, z, phi=0.0, t=0.0): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - calculate the mass out to a given radius - INPUT: - R - radius at which to return the enclosed mass - z - (don't specify this) vertical height - OUTPUT: - mass in natural units - HISTORY: - 2014-01-29 - Written - Bovy (IAS) - """ if z is not None: raise AttributeError # use general implementation return 1.0 / (1.0 + self.a / R) # written so it works for r=numpy.inf @@ -1441,60 +791,46 @@ def __init__( wrtcrit=False, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a NFW potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - - Alternatively, NFW potentials can be initialized in the following two manners: - - a) - - rmax= radius where the rotation curve peaks (can be a Quantity, otherwise assumed to be in internal units) - - vmax= maximum circular velocity (can be a Quantity, otherwise assumed to be in internal units) - - b) - - conc= concentration - - mvir= virial mass in 10^12 Msolar - - in which case you also need to supply the following keywords - - H= (default: 70) Hubble constant in km/s/Mpc - - Om= (default: 0.3) Omega matter - - overdens= (200) overdensity which defines the virial radius - - wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Written - Bovy (NYU) - - 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) - - 2020-04-29 - Initialization w/ rmax and vmax - Bovy (UofT) + Initialize a NFW Potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius (can be Quantity). + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + rmax : float or Quantity, optional + Radius where the rotation curve peak. + vmax : float or Quantity, optional + Maximum circular velocity. + conc : float, optional + Concentration. + mvir : float, optional + virial mass in 10^12 Msolar + H : float, optional + Hubble constant in km/s/Mpc. + Om : float, optional + Omega matter. + overdens : float, optional + Overdensity which defines the virial radius. + wrtcrit : bool, optional + If True, the overdensity is wrt the critical density rather than the mean matter density. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Initialize with one of: + * a and amp or normalize + * rmax and vmax + * conc, mvir, H, Om, overdens, wrtcrit + - 2010-07-09 - Written - Bovy (NYU) + - 2014-04-03 - Initialization w/ concentration and mass - Bovy (IAS) + - 2020-04-29 - Initialization w/ rmax and vmax - Bovy (UofT) """ Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units="mass") @@ -1538,21 +874,6 @@ def __init__( return None def _evaluate(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _evaluate - PURPOSE: - evaluate the potential at R,z - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - Phi(R,z) - HISTORY: - 2010-07-09 - Started - Bovy (NYU) - """ r = numpy.sqrt(R**2.0 + z**2.0) if isinstance(r, (float, int)) and r == 0: return -1.0 / self.a @@ -1564,21 +885,6 @@ def _evaluate(self, R, z, phi=0.0, t=0.0): return out def _Rforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rforce - PURPOSE: - evaluate the radial force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the radial force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ Rz = R**2.0 + z**2.0 sqrtRz = numpy.sqrt(Rz) return R * ( @@ -1587,21 +893,6 @@ def _Rforce(self, R, z, phi=0.0, t=0.0): ) def _zforce(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _zforce - PURPOSE: - evaluate the vertical force for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the vertical force - HISTORY: - 2010-07-09 - Written - Bovy (NYU) - """ Rz = R**2.0 + z**2.0 sqrtRz = numpy.sqrt(Rz) return z * ( @@ -1610,18 +901,6 @@ def _zforce(self, R, z, phi=0.0, t=0.0): ) def _rforce_jax(self, r): - """ - NAME: - _rforce_jax - PURPOSE: - evaluate the spherical radial force for this potential using JAX - INPUT: - r - Galactocentric spherical radius - OUTPUT: - the radial force - HISTORY: - 2021-02-14 - Written - Bovy (UofT) - """ if not _JAX_LOADED: # pragma: no cover raise ImportError( "Making use of _rforce_jax function requires the google/jax library" @@ -1631,21 +910,6 @@ def _rforce_jax(self, r): ) def _R2deriv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _R2deriv - PURPOSE: - evaluate the second radial derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the second radial derivative - HISTORY: - 2011-10-09 - Written - Bovy (IAS) - """ Rz = R**2.0 + z**2.0 sqrtRz = numpy.sqrt(Rz) return ( @@ -1662,21 +926,6 @@ def _R2deriv(self, R, z, phi=0.0, t=0.0): ) def _Rzderiv(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _Rzderiv - PURPOSE: - evaluate the mixed R,z derivative for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - d2phi/dR/dz - HISTORY: - 2013-08-28 - Written - Bovy (IAS) - """ Rz = R**2.0 + z**2.0 sqrtRz = numpy.sqrt(Rz) return ( @@ -1694,21 +943,6 @@ def _Rzderiv(self, R, z, phi=0.0, t=0.0): ) def _surfdens(self, R, z, phi=0.0, t=0.0): - """ - NAME: - _surfdens - PURPOSE: - evaluate the surface density for this potential - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - phi - azimuth - t - time - OUTPUT: - the surface density - HISTORY: - 2018-08-19 - Written - Bovy (UofT) - """ r = numpy.sqrt(R**2.0 + z**2.0) Rma = numpy.sqrt(R**2.0 - self.a**2.0 + 0j) if Rma == 0.0: @@ -1733,19 +967,6 @@ def _surfdens(self, R, z, phi=0.0, t=0.0): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - calculate the mass out to a given radius - INPUT: - R - radius at which to return the enclosed mass - z - (don't specify this) vertical height - OUTPUT: - mass in natural units - HISTORY: - 2014-01-29 - Written - Bovy (IAS) - """ if z is not None: raise AttributeError # use general implementation return numpy.log(1 + R / self.a) - R / self.a / (1.0 + R / self.a) @@ -1763,35 +984,33 @@ def rvir( use_physical=False, ): # use_physical necessary bc of pop=False, does nothing inside """ - NAME: - - rvir - - PURPOSE: - - calculate the virial radius for this density distribution - - INPUT: - - H= (default: 70) Hubble constant in km/s/Mpc - - Om= (default: 0.3) Omega matter - - overdens= (200) overdensity which defines the virial radius - - wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density - - ro= distance scale in kpc or as Quantity (default: object-wide, which if not set is 8 kpc)) - - vo= velocity scale in km/s or as Quantity (default: object-wide, which if not set is 220 km/s)) - - OUTPUT: - - virial radius - - HISTORY: - - 2014-01-29 - Written - Bovy (IAS) + Calculate the virial radius for this density distribution. + + Parameters + ---------- + H : float, optional + Hubble constant in km/s/Mpc. Default is 70.0. + Om : float, optional + Omega matter. Default is 0.3. + t : float, optional + Time. Default is 0.0. + overdens : float, optional + Overdensity which defines the virial radius. Default is 200.0. + wrtcrit : bool, optional + If True, the overdensity is wrt the critical density rather than the mean matter density. Default is False. + ro : float or Quantity, optional + Distance scale for translation into internal units (default is the object-wide value). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default is the object-wide value). + + Returns + ------- + float + Virial radius. + + Notes + ----- + - 2014-01-29 - Written - Bovy (IAS) """ if ro is None: @@ -1813,25 +1032,16 @@ def rvir( @conversion.physical_conversion("position", pop=True) def rmax(self): """ - NAME: - - rmax - - PURPOSE: - - calculate the radius at which the rotation curve peaks - - INPUT: - - (none) - - OUTPUT: - - Radius at which the rotation curve peaks + Calculate the radius at which the rotation curve peaks. - HISTORY: + Returns + ------- + float + Radius at which the rotation curve peaks. - 2020-02-05 - Written - Bovy (UofT) + Notes + ----- + - 2020-02-05 - Written - Bovy (UofT) """ # Magical number, solve(derivative (ln(1+x)-x/(1+x))/x wrt x=0,x) @@ -1840,25 +1050,16 @@ def rmax(self): @conversion.physical_conversion("velocity", pop=True) def vmax(self): """ - NAME: + Calculate the maximum rotation curve velocity. - vmax + Returns + ------- + float + Peak velocity in the rotation curve. - PURPOSE: - - calculate the maximum rotation curve velocity - - INPUT: - - (none) - - OUTPUT: - - Peak velocity in the rotation curve - - HISTORY: - - 2020-02-05 - Written - Bovy (UofT) + Notes + ----- + - 2020-02-05 - Written - Bovy (UofT) """ # 0.21621659550187311005 = (numpy.log(1.+rmax/a)-rmax/(a+rmax))*a/rmax @@ -1867,27 +1068,23 @@ def vmax(self): @kms_to_kpcGyrDecorator def _nemo_accpars(self, vo, ro): """ - NAME: - - _nemo_accpars - - PURPOSE: - - return the accpars potential parameters for use of this potential with NEMO - - INPUT: - - vo - velocity unit in km/s - - ro - length unit in kpc - - OUTPUT: + Return the accpars potential parameters for use of this potential with NEMO - accpars string + Parameters + ---------- + vo : float + Velocity unit in km/s + ro : float + Length unit in kpc - HISTORY: + Returns + ------- + str + accpars string - 2014-12-18 - Written - Bovy (IAS) + Notes + ----- + - 2014-12-18 - Written - Bovy (IAS) """ ampl = self._amp * vo**2.0 * ro diff --git a/galpy/potential/TwoPowerTriaxialPotential.py b/galpy/potential/TwoPowerTriaxialPotential.py index a7baa40c5..9efa1db05 100644 --- a/galpy/potential/TwoPowerTriaxialPotential.py +++ b/galpy/potential/TwoPowerTriaxialPotential.py @@ -52,47 +52,39 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - initialize a triaxial two-power-density potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - alpha - inner power (0 <= alpha < 3) - - beta - outer power ( beta > 2) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis (rad or Quantity) - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2016-05-30 - Started - Bovy (UofT) - - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) + Initialize a triaxial two-power-density potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius. + alpha : float, optional + Inner power (0 <= alpha < 3). + beta : float, optional + Outer power ( beta > 2). + b : float, optional + y-to-x axis ratio of the density. + c : float, optional + z-to-x axis ratio of the density. + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis. + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2016-05-30 - Started - Bovy (UofT) + - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) """ EllipsoidalPotential.__init__( @@ -176,20 +168,6 @@ def _mdens_deriv(self, m): ) def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-09 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( @@ -237,43 +215,36 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a triaxial Hernquist potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Written - Bovy (UofT) - - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) + Initialize a triaxial two-power-density potential. + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass. + a : float or Quantity, optional + Scale radius. + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + b : float, optional + y-to-x axis ratio of the density. + c : float, optional + z-to-x axis ratio of the density. + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis. + pa : float or Quantity, optional + If set, the position angle of the x axis. + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-07-09 - Written - Bovy (UofT) + + - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) """ EllipsoidalPotential.__init__( @@ -316,20 +287,6 @@ def _mdens_deriv(self, m): return -self.a4 * (self.a + 4.0 * m) / m**2 / (self.a + m) ** 4 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-16 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( @@ -375,43 +332,35 @@ def __init__( vo=None, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a Jaffe potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2010-07-09 - Written - Bovy (UofT) - - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) + Two-power-law triaxial potential + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass + a : float or Quantity, optional + Scale radius. + b : float, optional + y-to-x axis ratio of the density + c : float, optional + z-to-x axis ratio of the density + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis + pa : float or Quantity, optional + If set, the position angle of the x axis + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - 2010-07-09 - Written - Bovy (UofT) + - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) """ EllipsoidalPotential.__init__( @@ -458,20 +407,6 @@ def _mdens_deriv(self, m): return -2.0 * self.a2**2 * (self.a + 2.0 * m) / m**3 / (self.a + m) ** 3 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-16 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( @@ -516,61 +451,50 @@ def __init__( wrtcrit=False, ): """ - NAME: - - __init__ - - PURPOSE: - - Initialize a triaxial NFW potential - - INPUT: - - amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass - - a - scale radius (can be Quantity) - - b - y-to-x axis ratio of the density - - c - z-to-x axis ratio of the density - - zvec= (None) If set, a unit vector that corresponds to the z axis - - pa= (None) If set, the position angle of the x axis - - glorder= (50) if set, compute the relevant force and potential integrals with Gaussian quadrature of this order - - normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. - - - Alternatively, NFW potentials can be initialized using - - conc= concentration - - mvir= virial mass in 10^12 Msolar - - in which case you also need to supply the following keywords - - H= (default: 70) Hubble constant in km/s/Mpc - - Om= (default: 0.3) Omega matter - - overdens= (200) overdensity which defines the virial radius - - wrtcrit= (False) if True, the overdensity is wrt the critical density rather than the mean matter density - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - OUTPUT: - - (none) - - HISTORY: - - 2016-05-30 - Written - Bovy (UofT) - - 2018-08-06 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) - + Initialize a triaxial NFW potential + + Parameters + ---------- + amp : float or Quantity, optional + Amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass or Gxmass + a : float or Quantity, optional + Scale radius. + b : float, optional + y-to-x axis ratio of the density + c : float, optional + z-to-x axis ratio of the density + zvec : array_like, optional + If set, a unit vector that corresponds to the z axis + pa : float or Quantity, optional + If set, the position angle of the x axis + glorder : int, optional + If set, compute the relevant force and potential integrals with Gaussian quadrature of this order + normalize : bool or float, optional + If True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. + conc : float, optional + Concentration. + mvir : float, optional + Virial mass in 10^12 Msolar. + H : float, optional + Hubble constant in km/s/Mpc. + Om : float, optional + Omega matter. + overdens : float, optional + Overdensity which defines the virial radius. + wrtcrit : bool, optional + If True, the overdensity is wrt the critical density rather than the mean matter density. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + + Notes + ----- + - Initialize with one of: + * a and amp or normalize + * mvir, conc, H, Om, wrtcrit, overdens. + - 2010-07-09 - Written - Bovy (UofT) + - 2018-08-07 - Re-written using the general EllipsoidalPotential class - Bovy (UofT) """ EllipsoidalPotential.__init__( self, @@ -628,20 +552,6 @@ def _mdens_deriv(self, m): return -self.a3 * (self.a + 3.0 * m) / m**2 / (self.a + m) ** 3 def _mass(self, R, z=None, t=0.0): - """ - NAME: - _mass - PURPOSE: - evaluate the mass within R (and z) for this potential; if z=None, integrate to ellipsoidal boundary - INPUT: - R - Galactocentric cylindrical radius - z - vertical height - t - time - OUTPUT: - the mass enclosed - HISTORY: - 2021-03-16 - Written - Bovy (UofT) - """ if not z is None: raise AttributeError # Hack to fall back to general return ( diff --git a/galpy/potential/WrapperPotential.py b/galpy/potential/WrapperPotential.py index 3fe2f1944..0c474a959 100644 --- a/galpy/potential/WrapperPotential.py +++ b/galpy/potential/WrapperPotential.py @@ -64,27 +64,26 @@ def __new__(cls, *args, **kwargs): class WrapperPotential(Potential): def __init__(self, amp=1.0, pot=None, ro=None, vo=None, _init=None, **kwargs): """ - NAME: - - __init__ - - PURPOSE: - - initialize a WrapperPotential, a super-class for wrapper potentials - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof - - OUTPUT: - - (none) - - HISTORY: - - 2017-06-26 - Started - Bovy (UofT) + Initialize a WrapperPotential, a super-class for wrapper potentials. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + pot : Potential instance or list thereof + Potential instance or list thereof. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + _init : bool, optional + If True, run __init__ at the end of setup (default: True). + **kwargs + Any other keyword arguments are passed to the Potential superclass. + + Notes + ----- + - 2017-06-26 - Started - Bovy (UofT) """ if not _init: @@ -182,27 +181,26 @@ def _wrap_pot_func(self, attribute): class planarWrapperPotential(planarPotential): def __init__(self, amp=1.0, pot=None, ro=None, vo=None, _init=None, **kwargs): """ - NAME: - - __init__ - - PURPOSE: - - initialize a WrapperPotential, a super-class for wrapper potentials - - INPUT: - - amp - amplitude to be applied to the potential (default: 1.) - - pot - Potential instance or list thereof; the amplitude of this will be grown by this wrapper - - OUTPUT: - - (none) - - HISTORY: - - 2017-06-26 - Started - Bovy (UofT) + Initialize a WrapperPotential, a super-class for wrapper potentials. + + Parameters + ---------- + amp : float, optional + Amplitude to be applied to the potential (default: 1.). + pot : Potential instance or list thereof, optional + The potential instance or list thereof; the amplitude of this will be grown by this wrapper. + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + _init : bool, optional + If True, run __init__ at the end of setup. Default is None. + **kwargs + Any other keyword arguments are passed to the Potential class. + + Notes + ----- + - 2017-06-26 - Started - Bovy (UofT) """ if not _init: diff --git a/galpy/potential/amuse.py b/galpy/potential/amuse.py index 77e6baa24..192619f8e 100644 --- a/galpy/potential/amuse.py +++ b/galpy/potential/amuse.py @@ -18,33 +18,26 @@ class galpy_profile(LiteratureReferencesMixIn): def __init__(self, pot, t=0.0, tgalpy=0.0, ro=8, vo=220.0, reverse=False): """ - NAME: + Initialize a galpy potential for use with AMUSE. - __init__ + Parameters + ---------- + pot : Potential instance or list thereof, optional + Potential object(s) to be used with AMUSE. + t : float or Quantity, optional + Start time for AMUSE simulation (can be an AMUSE Quantity). + tgalpy : float or Quantity, optional + Start time for galpy potential, can be less than zero (can be Quantity). + ro : float or Quantity, optional + Distance scale for translation into internal units (default from configuration file). + vo : float or Quantity, optional + Velocity scale for translation into internal units (default from configuration file). + reverse : bool, optional + Set whether galpy potential evolves forwards or backwards in time (default: False). - PURPOSE: - - initialize a galpy potential for use with AMUSE - - INPUT: - - pot - galpy potential object or list of such objects - - t - start time for AMUSE simulation (can be an AMUSE Quantity) - - tgalpy - start time for galpy potential, can be less than zero (can be Quantity) - - ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) - - reverse - set whether galpy potential evolves forwards or backwards in time (default: False) - - OUTPUT: - - (none) - - HISTORY: - - 2019-08-12 - Written - Webb (UofT) + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) """ LiteratureReferencesMixIn.__init__(self) @@ -69,16 +62,21 @@ def __init__(self, pot, t=0.0, tgalpy=0.0, ro=8, vo=220.0, reverse=False): def evolve_model(self, time): """ - NAME: - evolve_model - PURPOSE: - evolve time parameters to t_end - INPUT: - time - time to evolve potential to - OUTPUT: - None - HISTORY: - 2019-08-12 - Written - Webb (UofT) + Evolve time parameters to t_end. + + Parameters + ---------- + time : float + End time for the potential evolution. + + Returns + ------- + None + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + """ dt = time - self.model_time self.model_time = time @@ -93,18 +91,25 @@ def evolve_model(self, time): def get_potential_at_point(self, eps, x, y, z): """ - NAME: - get_potential_at_point - PURPOSE: - Get potential at a given location in the potential - INPUT: - eps - softening length (necessary for AMUSE, but not used by galpy potential) - x,y,z - position in the potential - OUTPUT: - Phi(x,y,z) - HISTORY: - 2019-08-12 - Written - Webb (UofT) - 2019-11-06 - added physical compatibility - Starkman (UofT) + Get potential at a given location in the potential. + + Parameters + ---------- + eps : AMUSE Quantity + Softening length (necessary for AMUSE, but not used by galpy potential). + x,y,z : AMUSE Quantity + Position in the potential. + + Returns + ------- + AMUSE Quantity + Phi(x,y,z). + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + - 2019-11-06 - Added physical compatibility - Starkman (UofT). + """ R = numpy.sqrt(x.value_in(units.kpc) ** 2.0 + y.value_in(units.kpc) ** 2.0) zed = z.value_in(units.kpc) @@ -123,18 +128,29 @@ def get_potential_at_point(self, eps, x, y, z): def get_gravity_at_point(self, eps, x, y, z): """ - NAME: - get_gravity_at_point - PURPOSE: - Get acceleration due to potential at a given location in the potential - INPUT: - eps - softening length (necessary for AMUSE, but not used by galpy potential) - x,y,z - position in the potential - OUTPUT: - ax,ay,az - HISTORY: - 2019-08-12 - Written - Webb (UofT) - 2019-11-06 - added physical compatibility - Starkman (UofT) + Get acceleration due to potential at a given location in the potential. + + Parameters + ---------- + eps : AMUSE Quantity + Softening length (necessary for AMUSE, but not used by galpy potential). + x,y,z : AMUSE Quantity + Position in the potential. + + Returns + ------- + ax : AMUSE Quantity + Acceleration in the x-direction. + ay : AMUSE Quantity + Acceleration in the y-direction. + az : AMUSE Quantity + Acceleration in the z-direction. + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + - 2019-11-06 - Added physical compatibility - Starkman (UofT). + """ R = numpy.sqrt(x.value_in(units.kpc) ** 2.0 + y.value_in(units.kpc) ** 2.0) zed = z.value_in(units.kpc) @@ -180,18 +196,25 @@ def get_gravity_at_point(self, eps, x, y, z): def mass_density(self, x, y, z): """ - NAME: - mass_density - PURPOSE: - Get mass density at a given location in the potential - INPUT: - eps - softening length (necessary for AMUSE, but not used by galpy potential) - x,y,z - position in the potential - OUTPUT: - the density - HISTORY: - 2019-08-12 - Written - Webb (UofT) - 2019-11-06 - added physical compatibility - Starkman (UofT) + Get mass density at a given location in the potential + + Parameters + ---------- + eps : AMUSE Quantity + Softening length (necessary for AMUSE, but not used by galpy potential) + x,y,z : AMUSE Quantity + Position in the potential + + Returns + ------- + AMUSE Quantity + The density + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + - 2019-11-06 - added physical compatibility - Starkman (UofT) + """ R = numpy.sqrt(x.value_in(units.kpc) ** 2.0 + y.value_in(units.kpc) ** 2.0) zed = z.value_in(units.kpc) @@ -210,17 +233,23 @@ def mass_density(self, x, y, z): def circular_velocity(self, r): """ - NAME: - circular_velocity - PURPOSE: - Get circular velocity at a given radius in the potential - INPUT: - r - radius in the potential - OUTPUT: - the circular velocity - HISTORY: - 2019-08-12 - Written - Webb (UofT) - 2019-11-06 - added physical compatibility - Starkman (UofT) + Get circular velocity at a given radius in the potential + + Parameters + ---------- + r : AMUSE Quantity + Radius in the potential + + Returns + ------- + AMUSE Quantity + The circular velocity + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + - 2019-11-06 - added physical compatibility - Starkman (UofT) + """ res = potential.vcirc( self.pot, @@ -235,17 +264,23 @@ def circular_velocity(self, r): def enclosed_mass(self, r): """ - NAME: - enclosed_mass - PURPOSE: - Get mass enclosed within a given radius in the potential - INPUT: - r - radius in the potential - OUTPUT: - the mass enclosed - HISTORY: - 2019-08-12 - Written - Webb (UofT) - 2019-11-06 - added physical compatibility - Starkman (UofT) + Get mass enclosed within a given radius in the potential + + Parameters + ---------- + r : AMUSE Quantity + Radius in the potential + + Returns + ------- + AMUSE Quantity + The mass enclosed + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) + - 2019-11-06 - added physical compatibility - Starkman (UofT) + """ vc = ( potential.vcirc( @@ -263,15 +298,10 @@ def enclosed_mass(self, r): def stop(self): """ - NAME: - stop - PURPOSE: - Stop the potential model (necessary function for AMUSE) - INPUT: - None - OUTPUT: - None - HISTORY: - 2019-08-12 - Written - Webb (UofT) + Stop the potential model (necessary function for AMUSE) + + Notes + ----- + - 2019-08-12 - Written - Webb (UofT) """ pass diff --git a/galpy/potential/interpRZPotential.py b/galpy/potential/interpRZPotential.py index 921a4cbb7..44efacc36 100644 --- a/galpy/potential/interpRZPotential.py +++ b/galpy/potential/interpRZPotential.py @@ -111,45 +111,51 @@ def __init__( 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) + Initialize an interpRZPotential instance. + + Parameters + ---------- + RZPot : RZPotential or list of such instances + RZPotential to be interpolated. + rgrid : tuple, optional + R grid to be given to linspace as in rs= linspace(*rgrid). + zgrid : tuple, optional + z grid to be given to linspace as in zs= linspace(*zgrid). + logR : bool, optional + If True, rgrid is in the log of R so logrs= linspace(*rgrid). + interpPot : bool, optional + If True, interpolate the potential. + interpRforce : bool, optional + If True, interpolate the radial force. + interpzforce : bool, optional + If True, interpolate the vertical force. + interpDens : bool, optional + If True, interpolate the density. + interpvcirc : bool, optional + If True, interpolate the circular velocity. + interpdvcircdr : bool, optional + If True, interpolate the derivative of the circular velocity with respect to R. + interpepifreq : bool, optional + If True, interpolate the epicyclic frequency. + interpverticalfreq : bool, optional + If True, interpolate the vertical frequency. + ro : float, optional + Distance scale for translation into internal units (default from configuration file). + vo : float, optional + Velocity scale for translation into internal units (default from configuration file). + use_c : bool, optional + Use C to speed up the calculation of the grid. + enable_c : bool, optional + Enable use of C for interpolations. + zsym : bool, optional + If True (default), the potential is assumed to be symmetric around z=0 (so you can use, e.g., zgrid=(0.,1.,101)). + numcores : int, optional + If set to an integer, use this many cores (only used for vcirc, dvcircdR, epifreq, and verticalfreq; NOT NECESSARILY FASTER, TIME TO MAKE SURE). + + Notes + ----- + - 2010-07-21 - Written - Bovy (NYU) + - 2013-01-24 - Started with new implementation - Bovy (IAS) """ if isinstance(RZPot, interpRZPotential): @@ -605,20 +611,31 @@ def verticalfreq(self, R): def calc_potential_c(pot, R, z, rforce=False, zforce=False): """ - NAME: - calc_potential_c - PURPOSE: - Use C to calculate the potential on a grid - INPUT: - pot - Potential or list of such instances - R - grid in R - z - grid in z - rforce=, zforce= if either of these is True, calculate the radial or vertical force instead - OUTPUT: - potential on the grid (2D array) - HISTORY: - 2013-01-24 - Written - Bovy (IAS) - 2013-01-29 - Added forces - Bovy (IAS) + Calculate the potential on a grid. + + Parameters + ---------- + pot : Potential or list of such instances + Potential object(s) to calculate the potential from. + R : numpy.ndarray + Grid in R. + z : numpy.ndarray + Grid in z. + rforce : bool, optional + If True, calculate the radial force instead. Default is False. + zforce : bool, optional + If True, calculate the vertical force instead. Default is False. + + Returns + ------- + numpy.ndarray + Potential on the grid (2D array). + + Notes + ----- + - 2013-01-24 - Written - Bovy (IAS) + - 2013-01-29 - Added forces - Bovy (IAS) + """ from ..orbit.integrateFullOrbit import ( # here bc otherwise there is an infinite loop _parse_pot, @@ -685,16 +702,21 @@ def calc_potential_c(pot, R, z, rforce=False, zforce=False): def calc_2dsplinecoeffs_c(array2d): """ - NAME: - calc_2dsplinecoeffs_c - PURPOSE: - Use C to calculate spline coefficients for a 2D array - INPUT: - array2d - OUTPUT: - new array with spline coeffs - HISTORY: - 2013-01-24 - Written - Bovy (IAS) + Calculate spline coefficients for a 2D array. + + Parameters + ---------- + array2d : numpy.ndarray + 2D array to calculate spline coefficients for. + + Returns + ------- + ndarray + New array with spline coefficients. + + Notes + ----- + - 2013-01-24 - Written - Bovy (IAS) """ # Set up result arrays out = copy.copy(array2d) @@ -717,18 +739,25 @@ def calc_2dsplinecoeffs_c(array2d): def eval_potential_c(pot, R, z): """ - NAME: - eval_potential_c - PURPOSE: - Use C to evaluate the interpolated potential - INPUT: - pot - Potential or list of such instances - R - array - z - array - OUTPUT: - potential evaluated R and z - HISTORY: - 2013-01-24 - Written - Bovy (IAS) + Use C to evaluate the interpolated potential. + + Parameters + ---------- + pot : Potential or list of such instances + The potential + R : numpy.ndarray + Galactocentric cylindrical radius. + z : numpy.ndarray + Galactocentric height. + + Returns + ------- + numpy.ndarray + Potential evaluated at R and z. + + Notes + ----- + - 2013-01-24: Written - Bovy (IAS) """ from ..orbit.integrateFullOrbit import ( # here bc otherwise there is an infinite loop _parse_pot, @@ -788,19 +817,28 @@ def eval_potential_c(pot, R, z): def eval_force_c(pot, R, z, zforce=False): """ - NAME: - eval_force_c - PURPOSE: - Use C to evaluate the interpolated potential's forces - INPUT: - pot - Potential or list of such instances - R - array - z - array - zforce= if True, return the vertical force, otherwise return the radial force - OUTPUT: - force evaluated R and z - HISTORY: - 2013-01-29 - Written - Bovy (IAS) + Use C to evaluate the interpolated potential's forces + + Parameters + ---------- + pot : Potential or list of such instances + The potential + R : numpy.ndarray + Galactocentric cylindrical radius. + z : numpy.ndarray + Galactocentric height. + zforce : bool, optional + If True, return the vertical force, otherwise return the radial force. Default is False. + + Returns + ------- + numpy.ndarray + Force evaluated at R and z. + + Notes + ----- + - 2013-01-29: Written - Bovy (IAS) + """ from ..orbit.integrateFullOrbit import ( # here bc otherwise there is an infinite loop _parse_pot, diff --git a/galpy/potential/interpSphericalPotential.py b/galpy/potential/interpSphericalPotential.py index 9a7b40ab8..1cb0579d4 100644 --- a/galpy/potential/interpSphericalPotential.py +++ b/galpy/potential/interpSphericalPotential.py @@ -26,33 +26,25 @@ def __init__( ro=None, vo=None, ): - """__init__(self,rforce=None,rgrid=numpy.geomspace(0.01,20,101),Phi0=None,ro=None,vo=None) - - NAME: - - __init__ - - PURPOSE: - - initialize an interpolated, spherical potential - - INPUT: - - rforce= (None) Either a) function that gives the radial force (in internal units) as a function of r (in internal units) or b) a galpy Potential instance or list thereof - - rgrid= (numpy.geomspace(0.01,20,101)) radial grid in internal units on which to evaluate the potential for interpolation (note that beyond rgrid[-1], the potential is extrapolated as -GM(