Skip to content

Commit 19fb509

Browse files
author
Niek Wielders
committed
added cnfw.py
1 parent 8748cc5 commit 19fb509

1 file changed

Lines changed: 114 additions & 0 deletions

File tree

  • autogalaxy/profiles/mass/dark
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import numpy as np
2+
3+
from typing import Tuple
4+
5+
import autoarray as aa
6+
7+
from autogalaxy.profiles.mass.abstract.abstract import MassProfile
8+
9+
class cNFW(MassProfile):
10+
def __init__(
11+
self,
12+
centre: Tuple[float, float] = (0.0, 0.0),
13+
kappa_s: float = 0.05,
14+
scale_radius: float = 1.0,
15+
core_radius: float = 0.5,
16+
):
17+
"""
18+
Represents a spherical cored NFW density distribution
19+
20+
Parameters
21+
----------
22+
centre
23+
The (y,x) arc-second coordinates of the profile centre.
24+
kappa_s
25+
The overall normalization of the dark matter halo \|
26+
(kappa_s = (rho_0 * scale_radius)/lensing_critical_density)
27+
scale_radius
28+
The cored NFW scale radius `theta_s`, as an angle on the sky in arcseconds.
29+
core_radius
30+
The cored NFW core radius `theta_c`, as an angle on the sky in arcseconds.
31+
"""
32+
33+
super().__init__(
34+
centre=centre,
35+
ell_comps=(0.0, 0.0))
36+
37+
self.kappa_s = kappa_s
38+
self.scale_radius = scale_radius
39+
self.core_radius = core_radius
40+
41+
42+
@aa.grid_dec.to_vector_yx
43+
@aa.grid_dec.transform
44+
def deflections_yx_2d_from(self, grid: aa.type.Grid2DLike, xp=np, **kwargs):
45+
"""
46+
Calculate the deflection angles on a grid of (y,x) arc-second coordinates.
47+
48+
The input grid of (y,x) coordinates are transformed to a coordinate system centred on the profile centre with
49+
and rotated based on the position angle defined from its `ell_comps` (this is described fully below).
50+
51+
The numerical backend can be selected via the ``xp`` argument, allowing this
52+
method to be used with both NumPy and JAX (e.g. inside ``jax.jit``-compiled
53+
code). This is described fully later in this example.
54+
55+
Parameters
56+
----------
57+
grid
58+
The grid of (y,x) arc-second coordinates the deflection angles are computed on.
59+
xp
60+
The numerical backend to use, either `numpy` or `jax.numpy`.
61+
"""
62+
theta = self.radial_grid_from(grid=grid, xp=xp, **kwargs).array
63+
64+
factor = (
65+
4.0
66+
* self.kappa_s
67+
* self.scale_radius**2
68+
)
69+
70+
deflection_r = (
71+
factor
72+
* (self.F_func(theta, self.scale_radius) - self.F_func(theta, self.core_radius)
73+
- (self.scale_radius - self.core_radius) * self.dev_F_func(theta, self.scale_radius)
74+
)
75+
/ (theta * (self.scale_radius - self.core_radius)**2)
76+
)
77+
78+
79+
return self._cartesian_grid_via_radial_from(
80+
grid=grid,
81+
radius=deflection_r,
82+
xp=xp,
83+
**kwargs,
84+
)
85+
86+
def F_func(self, theta, radius, xp=np):
87+
if theta == 0:
88+
F = 0
89+
elif theta < radius:
90+
F = (radius / 2 * xp.log(2 * radius / theta) - xp.sqrt(radius ** 2 - theta ** 2)
91+
* xp.arctanh(xp.sqrt((radius - theta) / (radius + theta)))
92+
)
93+
else:
94+
F = (radius / 2 * xp.log(2 * radius / theta) + xp.sqrt(theta ** 2 - radius ** 2)
95+
* xp.arctan(xp.sqrt((theta - radius) / (theta + radius)))
96+
)
97+
return 2 * radius * F
98+
99+
def dev_F_func(self, theta, radius, xp=np):
100+
if theta == 0:
101+
dev_F = 0
102+
elif theta < radius:
103+
dev_F = (radius * xp.log(2 * radius / theta)
104+
- (2 * radius ** 2 - theta ** 2) / xp.sqrt(radius ** 2 - theta ** 2)
105+
* xp.arctanh(xp.sqrt((radius - theta) / (radius + theta)))
106+
)
107+
elif theta == radius:
108+
dev_F = (radius * (xp.log(2) - 1 / 2))
109+
else:
110+
dev_F = (radius * xp.log(2 * radius / theta)
111+
+ (theta ** 2 - 2 * radius ** 2) / xp.sqrt(theta ** 2 - radius ** 2)
112+
* xp.arctan(xp.sqrt((theta - radius) / (theta + radius)))
113+
)
114+
return 2 * dev_F

0 commit comments

Comments
 (0)