Exemplo n.º 1
0
    def sigma_z2(self, R, Z, ilist=None) :
        """ Compute SigmaZ^2 : the second centred velocity moment from an MGE model

        :param R: input Radial coordinate
        :param Z: input Vertical coordinate
        :param ilist: indices for the Gaussians to take into account
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)

        R2 = R*R
        Z2 = Z*Z
        r2 = R2 + Z2
        r = sqrt(r2)
        r2soft = r2 + self.SoftarcMbh2
        rsoft = sqrt(r2soft)
        ## Compute the mass density for individual gaussians as well as the sum
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        sigz2 = np.sum(Wquad[i] * self._intsigma_z2(Xquad[i], R2, Z2, ilist) for i in xrange(self.Nquad))

        # Contribution from the BH
        if self.Mbh > 0. :
            for i in ilist :
                # facMbh in M arcsec2 pc-2 / 4PI G
                var = (r / self._pParam.dqSig3Darc[i]).astype(floatG)
                mask = (var < _Maximum_Value_forEXPERFC)
                lasterm = np.empty_like(var)
                # facMbh in M arcsec2 pc-2 / 4PI G
                lasterm[mask] = self._dParam.sqpi2s[i] * special.erfc(var[mask]) * np.exp(var[mask]**2)
                lasterm[~mask] = 2. / (r[~mask] + sqrt(r2[~mask] + self._dParam.qq2s2[i]))
                sigz2 += self.rho[i] * self.facMbh * (1. / rsoft - lasterm) # in rho * M arcsec pc-2 / 4 PI G

        return sigz2 * self.PIG / self.rhoT
Exemplo n.º 2
0
    def vtheta2(self, R, Z, ilist=None) :
        """
        Compute Vtheta**2 : the first velocity moment from an MGE model
        Input : R, Z as input coordinates
                ilist: indices of the Gaussians
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)

        R2 = R*R
        Z2 = Z*Z
        r2 = R2 + Z2
        r = sqrt(r2)
        r2soft = r2 + self.SoftarcMbh2
        rsoft = sqrt(r2soft)
        ## Compute the mass density for individual gaussians as well as the sum
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        # MU2
        VT2 = np.sum(Wquad[i] * self._intvtheta2(Xquad[i], R2, Z2, ilist=ilist) for i in xrange(self.Nquad))

        # Contribution from the BH
        if self.Mbh > 0. :
            for i in ilist :
                var = (r / self._pParam.dqSig3Darc[i]).astype(floatG)
                mask = (var < _Maximum_Value_forEXPERFC)
                lasterm = np.empty_like(var)
                # facMbh in M arcsec2 pc-2 / 4PI G
                lasterm[mask] = self._dParam.sqpi2s[i] * special.erfc(var[mask]) * np.exp(var[mask]**2)
                lasterm[~mask] = 2. / (r[~mask] + sqrt(r2[~mask] + self._dParam.qq2s2[i]))
                VT2 += (1. + self._dParam.e2q2Sig3Darc2[i] * R2) * self.rho[i] * self.facMbh \
                          * (1. / rsoft - lasterm)  # in rhoT * M arcsec pc-2 / 4 PI G

        return VT2 * self.PIG / self.rhoT
Exemplo n.º 3
0
    def Potential(self, R, Z, ilist=None) :
        """
        Return, for a grid of R and Z the Gravitational potential in km^2.s^2
        R and Z should be in arcseconds

        :param R: cylindrical radius (float or array) in arcseconds
        :param Z: vertical height (float or array) in arcseconds
        :param ilist: list of indices for the Gaussians to consider (0 to Ngauss-1)

        :returns: Gravitational potential :math:`\Phi` in Units of km^2.s-2
        :rtype: float or array of float depending on input
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)
        ### First compute the gaussian quadrature points, and weights
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        R2 = R*R
        Z2 = Z*Z
        result = np.sum(Wquad[i] * self._IntPot(Xquad[i], R2, Z2, ilist) for i in xrange(self.Nquad))

        if (self.Mbh > 0.) :
            mask = (R2 + Z2 == 0.)
            result[~mask] += self.facMbh / sqrt(R2[~mask] + Z2[~mask] + self.SoftarcMbh2)

        return -4. * np.pi * self.G * result  # en km^2.s-2
Exemplo n.º 4
0
    def _sigma_z2_fromR2Z2(self, R2, Z2, ilist=None) :
        """
        Compute SigmaZ**2 : the second centred velocity moment from an MGE model

        WARNING: this function takes R2 and Z2 as input, not R and Z

        Input : R2 and Z2: squares of the R and Z coordinates
                ilist: indices for Gaussians to take into account
        """
        r2 = R2 + Z2
        r = sqrt(r2)
        r2soft = r2 + self.SoftarcMbh2
        rsoft = sqrt(r2soft)
        ## Compute the mass density for individual gaussians as well as the sum
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        sigz2 = np.sum(Wquad[i] * self._intsigma_z2(Xquad[i], R2, Z2, ilist) for i in xrange(self.Nquad))

        # Contribution from the BH
        if self.Mbh > 0. :
            for i in ilist:
                var = (r / self._pParam.dqSig3Darc[i]).astype(floatG)
                mask = (var < _Maximum_Value_forEXPERFC)
                lasterm = np.empty_like(var)
                # facMbh in M arcsec2 pc-2 / 4PI G
                lasterm[mask] = self._dParam.sqpi2s[i] * special.erfc(var[mask]) * np.exp(var[mask]**2)
                lasterm[~mask] = 2. / (r[~mask] + sqrt(r2[~mask] + self._dParam.qq2s2[i]))
                sigz2 += self.rho[i] * self.facMbh * (1. / rsoft - lasterm) # in rho * M arcsec pc-2 / 4 PI G

        return sigz2 * self.PIG / self.rhoT
Exemplo n.º 5
0
 def _d2Potd2R(self, R, Z, ilist=None) :
     ### First compute the gaussian quadrature points, and weights
     [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
     result = np.zeros_like(R)
     R2 = R*R
     Z2 = Z*Z
     for i in xrange(self.Nquad) :
         result += Wquad[i] * self._Intd2Potd2R(Xquad[i], R2, Z2, ilist)
     return self.PIG * result / (self.pc_per_arcsec*self/pc_per_arcsec)  # en km^2.s-2.pc-2
Exemplo n.º 6
0
    def _Mu1(self, X, Y, inclin=90., ilist=None) :
        X2 = X * X
        Y2 = Y * Y
        inclin_rad = inclin * np.pi / 180.
        sini = sin(inclin_rad)
        cosi = cos(inclin_rad)
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        rhop = self._rhoL2D_fromX2Y2(X2, Y2, ilist)

        result = np.zeros_like(X2)
        for i in xrange(shape(X2)[0]) :
            for j in xrange(shape(X2)[1]) :
                print "%f %f \n" %(X[i,j], Y[i,j])
                ### INTEGRAL between -infinity and infinity along the line of sight
                result[i,j] = float(scipy.integrate.quad(self._IntlosMu1, -inf, inf, epsabs=1.e-01, epsrel=1.e-01, args=(X2[i,j], Y[i,j], cosi, sini, Xquad, Wquad, ilist))[0])

        return sqrt(4. * np.pi * self.G) * result * sini * X / rhop
Exemplo n.º 7
0
    def sigmaz2_muTheta2(self, R, Z, ilist) :
        """
        Compute both Sigma_Z**2 and Mu_Z**2 the centred and non-centred
        second order velocity moments from an MGE model
        op can be "all" or "sigma" or "mu" depending on which quantity is needed

        Input : R and Z the coordinates
                ilist : Gaussian indices to take into account
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)

        R2 = R*R
        Z2 = Z*Z
        r2 = R2 + Z2
        r = sqrt(r2)
        r2soft = r2 + self.SoftarcMbh2
        rsoft = sqrt(r2soft)
        ## Compute the mass density for individual gaussians as well as the sum
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        sigz2 = np.zeros_like(R2)
        # sigmaz2
        for i in xrange(self.Nquad) :
            sigz2 += Wquad[i] * self._intsigma_z2(Xquad[i],  R2, Z2, ilist)

        # MU2
        muTheta2 = np.zeros_like(R2)
        for i in xrange(self.Nquad) :
            muTheta2 += Wquad[i] * self._intvtheta2(Xquad[i], R2, Z2, ilist)

        # Contribution from the BH
        if self.Mbh > 0. :
            for i in ilist :
                var = (r / self._pParam.dqSig3Darc[i]).astype(floatG)
                mask = (var < _Maximum_Value_forEXPERFC)
                lasterm = np.empty_like(var)
                # facMbh in M arcsec2 pc-2 / 4PI G
                lasterm[mask] = self._dParam.sqpi2s[i] * special.erfc(var[mask]) * np.exp(var[mask]**2)
                lasterm[~mask] = 2. / (r [~mask]+ sqrt(r2[~mask] + self._dParam.qq2s2[i]))
                sigz2 += self.rho[i] * self.facMbh * (1. / rsoft - lasterm) # in rho * M arcsec pc-2 / 4 PI G
                muTheta2 += (1. + self._dParam.e2q2Sig3Darc2[i] * R2) * self.rho[i] * self.facMbh \
                         * (1. / rsoft - lasterm)  # in rhoT * M arcsec pc-2 / 4 PI G

        sigz2 *= self.PIG / self.rhoT
        muTheta2 *= self.PIG / self.rhoT
        return sigz2, muTheta2
Exemplo n.º 8
0
    def _Mu2(self, X, Y, inclin=90., ilist=None) :
        ilist = self._set_ilist(ilist)
        ### First compute the gaussian quadrature points, and weights
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        X2 = X * X
        Y2 = Y * Y
        self.rhop = np.sum(self.Imax2D[ilist] * exp(- (X2[...,np.newaxis] + Y2[...,np.newaxis] / self.Q2D2[ilist]) / self.dSig2Darc2[ilist]))

        inclin_rad = inclin * np.pi / 180.
        sini = sin(inclin_rad)
        cosi = cos(inclin_rad)
        sini2 = sini * sini
        cosi2 = cosi * cosi

        result = np.zeros_like(X)
        for i in xrange(self.Nquad) :
            result += Wquad[i] * self._IntMu2(Xquad[i], X2, Y2, cosi2, sini2, ilist)
        return 4. * np.pi**1.5 * self.G * result / self.rhop # en km^2.s-2
Exemplo n.º 9
0
    def kappa(self, R, ilist=None) :
        """
        Return :math:`\kappa`, the epicycle radial frequency for an MGE model

        :param R: cylindrical radius (float or array) in arcseconds
        :param Z: vertical height (float or array) in arcseconds

        :returns: :math:`\kappa` Radial Epicycle frequency [km.s-1.pc-1]
        :rtype: float or array of float depending on input
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)
        ### First compute the gaussian quadrature points, and weights
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        result = np.zeros_like(R)
        R2 = R*R
        for i in xrange(self.Nquad) :
            result += Wquad[i] * self._Intkappa(Xquad[i], R2, ilist)
        return sqrt(self.PIG * result) / self.pc_per_arcsec  # en km.s-1.pc-1
Exemplo n.º 10
0
    def Omega(self, R, ilist=None) :
        """ Returns :math:`\Omega`, the circular frequency, for a grid of R.
        R should be in arcseconds

        :param R: cylindrical radius (float or array) in arcseconds
        :param Z: vertical height (float or array) in arcseconds

        :returns: :math:`\Omega` Circular frequency [km.s-1.pc-1]
        :rtype: float or array of float depending on input

        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)
        ### First compute the gaussian quadrature points, and weights
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        R2 = R*R
        result = np.sum(Wquad[i] * self._IntVc(Xquad[i], R2, ilist) for i in xrange(self.Nquad))

        if (self.Mbh > 0.) :
            mask = (R == 0.)
            result[mask] += self.facMbh / np.maximum(1.e-4, self.SoftarcMbh**3)
            result[~mask] += self.facMbh / (R2[~mask] + self.SoftarcMbh2)**(3.0/2.0)

        return sqrt(self.PIG * result) / self.pc_per_arcsec  # en km.s-1.pc-1
Exemplo n.º 11
0
    def Vcirc(self, R, ilist=None) :
        """
        Derive the circular velocity for the MGE model taking into account
        Only the Gaussians from the indice list (ilist) - counting from 0
        A softening can be included (eps in pc)

        :param R: cylindrical radius (float or array) in arcseconds
        :param ilist: list of indices of Gaussians to count

        :returns: float/array -- Circular velocity [km.s-1]
        """
        ### Set the list of indices
        ilist = self._set_ilist(ilist)
        ### First compute the gaussian quadrature points, and weights
        [Xquad, Wquad] = quadrat_ps_roots(self.Nquad)
        R2 = R*R
        result = R2 * np.sum(Wquad[i] * self._IntVc(Xquad[i], R2, ilist) for i in xrange(self.Nquad))

        if (self.Mbh > 0.) :
            mask = (R == 0.)
            result[mask] += self.facMbh / np.maximum(1.e-2, self.SoftarcMbh)
            result[~mask] += self.facMbh / sqrt(R2[~mask] + self.SoftarcMbh2)

        return sqrt(result * self.PIG)  # en km.s-1