Ejemplo n.º 1
0
    def __init__(self,
                 amp=1.,
                 hr=1. / 3.,
                 hz=1. / 16.,
                 maxiter=_MAXITER,
                 tol=0.001,
                 normalize=False,
                 ro=None,
                 vo=None,
                 new=True,
                 kmaxFac=2.,
                 glorder=10):
        """
        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)

           tol - relative accuracy of potential-evaluations

           maxiter - scipy.integrate keyword

           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:

           DoubleExponentialDiskPotential object

        HISTORY:

           2010-04-16 - Written - Bovy (NYU)

           2013-01-01 - Re-implemented using faster integration techniques - Bovy (IAS)

        """
        Potential.__init__(self, amp=amp, ro=ro, vo=vo, amp_units='density')
        if _APY_LOADED and isinstance(hr, units.Quantity):
            hr = hr.to(units.kpc).value / self._ro
        if _APY_LOADED and isinstance(hz, units.Quantity):
            hz = hz.to(units.kpc).value / self._ro
        self.hasC = True
        self._kmaxFac = kmaxFac
        self._glorder = glorder
        self._hr = hr
        self._scale = self._hr
        self._hz = hz
        self._alpha = 1. / self._hr
        self._beta = 1. / self._hz
        self._gamma = self._alpha / self._beta
        self._maxiter = maxiter
        self._tol = tol
        self._zforceNotSetUp = True  #We have not calculated a typical Kz yet
        #Setup j0 zeros etc.
        self._glx, self._glw = nu.polynomial.legendre.leggauss(self._glorder)
        self._nzeros = 100
        #j0 for potential and z
        self._j0zeros = nu.zeros(self._nzeros + 1)
        self._j0zeros[1:self._nzeros + 1] = special.jn_zeros(0, self._nzeros)
        self._dj0zeros = self._j0zeros - nu.roll(self._j0zeros, 1)
        self._dj0zeros[0] = self._j0zeros[0]
        #j1 for R
        self._j1zeros = nu.zeros(self._nzeros + 1)
        self._j1zeros[1:self._nzeros + 1] = special.jn_zeros(1, self._nzeros)
        self._dj1zeros = self._j1zeros - nu.roll(self._j1zeros, 1)
        self._dj1zeros[0] = self._j1zeros[0]
        #j2 for R2deriv
        self._j2zeros = nu.zeros(self._nzeros + 1)
        self._j2zeros[1:self._nzeros + 1] = special.jn_zeros(2, self._nzeros)
        self._dj2zeros = self._j2zeros - nu.roll(self._j2zeros, 1)
        self._dj2zeros[0] = self._j2zeros[0]
        if normalize or \
                (isinstance(normalize,(int,float)) \
                     and not isinstance(normalize,bool)): #pragma: no cover
            self.normalize(normalize)
        #Load Kepler potential for large R
        self._kp = KeplerPotential(normalize=4. * nu.pi / self._alpha**2. /
                                   self._beta)