Source code for lenstronomy.LensModel.Profiles.nfw_vir_trunc

__author__ = "sibirrer"

# this file contains a class to compute the Navaro-Frank-White function in mass/kappa space
# the potential therefore is its integral

import numpy as np
from lenstronomy.Util import constants as const
from lenstronomy.LensModel.Profiles.base_profile import LensProfileBase
from lenstronomy.Cosmo.lens_cosmo import LensCosmo

__all__ = ["NFWVirTrunc"]


[docs] class NFWVirTrunc(LensProfileBase): """ this class contains functions concerning the NFW profile that is sharply truncated at the virial radius https://arxiv.org/pdf/astro-ph/0304034.pdf relation are: R_200 = c * Rs """
[docs] def __init__(self, z_lens, z_source, cosmo=None): """ :param z_lens: redshift of lens :param z_source: redshift of source :param cosmo: astropy cosmology instance """ if cosmo is None: from astropy.cosmology import FlatLambdaCDM cosmo = FlatLambdaCDM(H0=70, Om0=0.3, Ob0=0.05) self._lens_cosmo = LensCosmo(z_lens=z_lens, z_source=z_source, cosmo=cosmo) super(NFWVirTrunc, self).__init__()
[docs] def kappa(self, theta, logM, c): """Projected surface brightness. :param theta: radial angle from the center of the profile :param logM: log_10 halo mass in physical units of M_sun :param c: concentration of the halo; r_200 = c * r_s :return: convergence at theta """ M = 10.0**logM theta_r200 = self._lens_cosmo.nfw_M_theta_r200(M) # r_vir = theta_vir * self._lens_cosmo.D_d * const.arcsec # physical Mpc # print(r_vir, 'r_vir') x = c * theta / theta_r200 f = self._f(c) return ( M / self._lens_cosmo.sigma_crit_angle * c**2 * f / (2 * np.pi * theta_r200**2) * self._G(x, c) )
def _G(self, x, c): """ # G(x) https://arxiv.org/pdf/astro-ph/0209167.pdf equation 27 :param x: scaled projected radius with c * theta / theta_r200 :param c: oncentration of the halo; r_200 = c * r_s :return: G(x) """ s = 0.000001 if isinstance(x, int) or isinstance(x, float): if x < 1: x = max(s, x) a = -np.sqrt(c**2 - x**2) / (1 - x**2) / (1 + c) + 1 / ( 1 - x**2 ) ** (3.0 / 2) * np.arccosh((x**2 + c) / (x * (1 + c))) elif x == 1: a = np.sqrt(c**2 - 1) / (3 * (1 + c)) * (1 + 1 / (c + 1.0)) elif x <= c: # X > 1: a = -np.sqrt(c**2 - x**2) / (1 - x**2) / (1 + c) - 1 / ( x**2 - 1 ) ** (3.0 / 2) * np.arccos((x**2 + c) / (x * (1 + c))) else: a = 0 else: a = np.zeros_like(x) x[x <= s] = s x_ = x[x < 1] a[x < 1] = -np.sqrt(c**2 - x_**2) / ((1 - x_**2) * (1 + c)) + 1 / ( 1 - x_**2 ) ** (3.0 / 2) * np.arccosh((x_**2 + c) / (x_ * (1 + c))) a[x == 1] = np.sqrt(c**2 - 1) / (3 * (1 + c)) * (1 + 1 / (c + 1.0)) x_ = x[(x > 1) & (x <= c)] a[(x > 1) & (x <= c)] = -np.sqrt(c**2 - x_**2) / (1 - x_**2) / ( 1 + c ) - 1 / (x_**2 - 1) ** (3.0 / 2) * np.arccos( (x_**2 + c) / (x_ * (1 + c)) ) # a[x > c] = 0 return a def _f(self, c): """ :param c: concentration :return: dimensionless normalization of Halo mass """ return 1.0 / (np.log(1 + c) - c / (1 + c))
# https://arxiv.org/pdf/astro-ph/0304034.pdf equation 17 for shear