Source code for caustics.lenses.func.tnfw

from ...backend_obj import backend
from ...constants import arcsec_to_rad, G_over_c2, rad_to_arcsec
from ...utils import translate_rotate


[docs] def concentration_tnfw(mass, Rs, critical_density, d_l, DELTA=200.0): """ Compute the concentration parameter "c" for a TNFW profile. Parameters ---------- mass: ArrayLike The mass of the lens. *Unit: Msun* Rs: ArrayLike The scale radius of the TNFW lens. *Unit: arcsec* critical_density: ArrayLike The critical density of the universe. *Unit: Msun / Mpc^3* d_l: ArrayLike The angular diameter distance to the lens. *Unit: Mpc* DELTA: float The overdensity parameter. *Unit: unitless* Returns ------- ArrayLike The concentration parameter "c" for a TNFW profile. *Unit: unitless* """ r_delta = (3 * mass / (4 * backend.pi * DELTA * critical_density)) ** (1 / 3) # fmt: skip return r_delta / (Rs * d_l * arcsec_to_rad) # fmt: skip
def _F_tnfw(x): """ Compute the function F(x) for a TNFW profile. Helper method from Baltz et al. 2009 equation A.5 """ x_gt1 = backend.clamp(x, min=1 + 1e-3) x_lt1 = backend.clamp(x, max=1 - 1e-3) return backend.where( x < 1 - 1e-2, backend.arccosh(1 / x_lt1) / backend.sqrt(1.0 - x_lt1**2), backend.where( x > 1 + 1e-2, backend.arccos(1 / x_gt1) / backend.sqrt(x_gt1**2 - 1.0), 1 - 2 * (x - 1) / 3 + 7 * (x - 1) ** 2 / 15, # where: x == 1 ), ) def _L_tnfw(x, tau): """ Helper method from Baltz et al. 2009 equation A.6 """ return backend.log(x / (tau + backend.sqrt(tau**2 + x**2))) # fmt: skip
[docs] def scale_density_tnfw(c, critical_density, DELTA=200.0): return DELTA / 3 * critical_density * c**3 / (backend.log(1 + c) - c / (1 + c)) # fmt: skip
[docs] def M0_totmass_tnfw(mass, tau): """ Rearranged from Baltz et al. 2009 equation A.4 """ return mass * (tau**2 + 1) ** 2 / (tau**2 * ((tau**2 - 1) * backend.log(tau) + backend.pi * tau - (tau**2 + 1))) # fmt: skip
[docs] def M0_scalemass_tnfw(Rs, c, critical_density, d_l, DELTA=200.0): """What M0 would be for an NFW Parameters ---------- Rs: ArrayLike The scale radius of the TNFW lens. *Unit: arcsec* c: ArrayLike The concentration parameter of an NFW lens with the same parameters. *Unit: unitless* critical_density: ArrayLike The critical density of the universe. *Unit: Msun / Mpc^3* d_l: ArrayLike The angular diameter distance to the lens. *Unit: Mpc* DELTA: float The overdensity parameter. *Unit: unitless* """ return 4 * backend.pi * (Rs * d_l * arcsec_to_rad) ** 3 * scale_density_tnfw(c, critical_density, DELTA) # fmt: skip
[docs] def mass_enclosed_2d_tnfw( r, Rs, tau, M0, ): """ Total projected mass (Msun) within a radius r (arcsec). Given in Baltz et al. 2009 equation A.11 Parameters ---------- r: ArrayLike Radius at which to compute the enclosed mass. *Unit: arcsec* mass: ArrayLike Mass of the lens. *Unit: Msun* Rs: ArrayLike Scale radius of the TNFW lens. *Unit: arcsec* tau: ArrayLike Truncation scale. Ratio of truncation radius to scale radius. *Unit: unitless* Returns ------- ArrayLike Integrated mass projected in infinite cylinder within radius r. *Unit: Msun* """ g = r / Rs t2 = tau**2 F = _F_tnfw(g) L = _L_tnfw(g, tau) a1 = t2 / (t2 + 1) ** 2 a2 = (t2 + 1 + 2 * (g**2 - 1)) * F a3 = tau * backend.pi a4 = (t2 - 1) * backend.log(tau) a5 = backend.sqrt(t2 + g**2) * (-backend.pi + (t2 - 1) * L / tau) # fmt: skip return M0 * a1 * (a2 + a3 + a4 + a5)
[docs] def physical_deflection_angle_tnfw( x0, y0, Rs, tau, x, y, M0, d_l, s=0.0, ): """ Compute the physical deflection angle for a TNFW profile. Converted from Baltz et al. 2009 equation A.18 Parameters ---------- x0: ArrayLike The x-coordinate of the lens center. *Unit: arcsec* y0: ArrayLike The y-coordinate of the lens center. *Unit: arcsec* Rs: ArrayLike The scale radius of the TNFW lens. *Unit: arcsec* tau: ArrayLike The truncation scale. Ratio of truncation radius to scale radius. *Unit: unitless* x: ArrayLike The x-coordinate in the lens plane. *Unit: arcsec* y: ArrayLike The y-coordinate in the lens plane. *Unit: arcsec* M0: ArrayLike The mass normalization constant. See `M0_totmass_tnfw` and `M0_scalemass_tnfw`. *Unit: Msun* d_l: ArrayLike The angular diameter distance to the lens. *Unit: Mpc* s: float Softening parameter to prevent numerical instabilities. *Unit: arcsec* """ x, y = translate_rotate(x, y, x0, y0) r = backend.sqrt(x**2 + y**2) + s theta = backend.arctan2(y, x) # The below actually equally comes from eq 2.13 in Meneghetti notes dr = mass_enclosed_2d_tnfw(r, Rs, tau, M0) / ( r * d_l * arcsec_to_rad ) # note dpsi(u)/du = 2x*dpsi(x)/dx when u = x^2 # fmt: skip S = 4 * G_over_c2 * rad_to_arcsec return S * dr * backend.cos(theta), S * dr * backend.sin(theta)
[docs] def convergence_tnfw( x0, y0, Rs, tau, x, y, critical_density, M0, d_l, s=0.0, ): """ Compute the dimensionless convergence for the TNFW. See Baltz et al. 2009 equation A.8 Parameters ---------- x0: ArrayLike The x-coordinate of the lens center. *Unit: arcsec* y0: ArrayLike The y-coordinate of the lens center. *Unit: arcsec* Rs: ArrayLike The scale radius of the TNFW lens. *Unit: arcsec* tau: ArrayLike The truncation scale. Ratio of truncation radius to scale radius. *Unit: unitless* x: ArrayLike The x-coordinate in the lens plane. *Unit: arcsec* y: ArrayLike The y-coordinate in the lens plane. *Unit: arcsec* M0: ArrayLike The mass normalization constant. See `M0_totmass_tnfw` and `M0_scalemass_tnfw`. *Unit: Msun* d_l: ArrayLike The angular diameter distance to the lens. *Unit: Mpc* s: float Softening parameter to prevent numerical instabilities. *Unit: arcsec* """ x, y = translate_rotate(x, y, x0, y0) r = backend.sqrt(x**2 + y**2) + s g = r / Rs F = _F_tnfw(g) L = _L_tnfw(g, tau) S = M0 / (2 * backend.pi * (Rs * d_l * arcsec_to_rad) ** 2) # fmt: skip t2 = tau**2 a1 = t2 / (t2 + 1) ** 2 a2 = backend.where(g == 1, (t2 + 1) / 3.0, (t2 + 1) * (1 - F) / (g**2 - 1)) # fmt: skip a3 = 2 * F a4 = -backend.pi / backend.sqrt(t2 + g**2) a5 = (t2 - 1) * L / (tau * backend.sqrt(t2 + g**2)) return a1 * (a2 + a3 + a4 + a5) * S / critical_density # fmt: skip
def _P_tnfw(x): """ Compute the function F(x) for a TNFW profile. Helper method from Baltz et al. 2009 equation A.5 """ x_gt1 = backend.clamp(x, min=1 + 1e-4) x_lt1 = backend.clamp(x, max=1 - 1e-4) return backend.where( x < 1 - 1e-3, -backend.arccosh(1 / x_lt1) ** 2, backend.where( x > 1 + 1e-3, backend.arccos(1 / x_gt1) ** 2, (2 * (x - 1) - 5 * (x - 1) ** 2 / 3), # where: x == 1 # fixme ), )
[docs] def potential_tnfw( x0, y0, Rs, tau, x, y, M0, d_l, d_s, d_ls, s=0.0, ): """ Compute the lensing potential for a TNFW profile. See Baltz et al. 2009 equation A.14 Parameters ---------- x0: ArrayLike The x-coordinate of the lens center. *Unit: arcsec* y0: ArrayLike The y-coordinate of the lens center. *Unit: arcsec* Rs: ArrayLike The scale radius of the TNFW lens. *Unit: arcsec* tau: ArrayLike The truncation scale. Ratio of truncation radius to scale radius. *Unit: unitless* x: ArrayLike The x-coordinate in the lens plane. *Unit: arcsec* y: ArrayLike The y-coordinate in the lens plane. *Unit: arcsec* M0: ArrayLike The mass normalization constant. See `M0_totmass_tnfw` and `M0_scalemass_tnfw`. *Unit: Msun* d_l: ArrayLike The angular diameter distance to the lens. *Unit: Mpc* d_s: ArrayLike The angular diameter distance to the source. *Unit: Mpc* d_ls: ArrayLike The angular diameter distance between the lens and the source. *Unit: Mpc* s: float Softening parameter to prevent numerical instabilities. *Unit: arcsec* """ x, y = translate_rotate(x, y, x0, y0) r = backend.sqrt(x**2 + y**2) + s g = r / Rs t2 = tau**2 u = g**2 F = _F_tnfw(g) L = _L_tnfw(g, tau) # fmt: off S = 2 * M0 * G_over_c2 * (d_ls / d_s) / (d_l * arcsec_to_rad**2) a1 = 1 / (t2 + 1) ** 2 a2 = 2 * backend.pi * t2 * (tau - backend.sqrt(t2 + u) + tau * backend.log(tau + backend.sqrt(t2 + u))) a3 = 2 * (t2 - 1) * tau * backend.sqrt(t2 + u) * L a4 = t2 * (t2 - 1) * L**2 a5 = 4 * t2 * (u - 1) * F a6 = t2 * (t2 - 1) * _P_tnfw(g) a7 = t2 * ((t2 - 1) * backend.log(tau) - t2 - 1) * backend.log(u) a8 = t2 * ((t2 - 1) * backend.log(tau) * backend.log(4 * tau) + 2 * backend.log(tau / 2) - 2 * tau * (tau - backend.pi) * backend.log(2 * tau)) return S * a1 * (a2 + a3 + a4 + a5 + a6 + a7 - a8)