forked from SWIFTSIM/SOAP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecently_heated_gas_filter.py
91 lines (74 loc) · 3.11 KB
/
recently_heated_gas_filter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/bin/env python
import numpy as np
import unyt
from astropy.cosmology import w0waCDM, z_at_value
import astropy.constants as const
import astropy.units as astropy_units
class RecentlyHeatedGasFilter:
"""
Filter used to determine whether gas particles should be considered to be
"recently heated".
This corresponds to the lightcone map filter used in SWIFT itself, which
filters out gas particles for which LastAGNFeedbackScaleFactors is less
than 15 Myr ago, and within some temperature bracket.
Since the conversion from a time difference to a scale factor is not
trivial, we compute the corresponding scale factor limit only once using
the correct astropy.cosmology.
"""
def __init__(
self,
cellgrid,
delta_time=15.0 * unyt.Myr,
delta_logT_min=-1.0,
delta_logT_max=0.3,
AGN_delta_T=8.80144197177e7 * unyt.K,
):
H0 = unyt.unyt_quantity(
cellgrid.cosmology["H0 [internal units]"],
units="1/snap_time",
registry=cellgrid.snap_unit_registry,
).to("1/s")
Omega_b = cellgrid.cosmology["Omega_b"]
Omega_lambda = cellgrid.cosmology["Omega_lambda"]
Omega_r = cellgrid.cosmology["Omega_r"]
Omega_m = cellgrid.cosmology["Omega_m"]
w_0 = cellgrid.cosmology["w_0"]
w_a = cellgrid.cosmology["w_a"]
z_now = cellgrid.cosmology["Redshift"]
# expressions taken directly from astropy, since they do no longer
# allow access to these attributes (since version 5.1+)
critdens_const = (3.0 / (8.0 * np.pi * const.G)).cgs.value
a_B_c2 = (4.0 * const.sigma_sb / const.c**3).cgs.value
# SWIFT provides Omega_r, but we need a consistent Tcmb0 for astropy.
# This is an exact inversion of the procedure performed in astropy.
critical_density_0 = astropy_units.Quantity(
critdens_const * H0.to("1/s").value ** 2,
astropy_units.g / astropy_units.cm**3,
)
Tcmb0 = (Omega_r * critical_density_0.value / a_B_c2) ** (1.0 / 4.0)
cosmology = w0waCDM(
H0=H0.to_astropy(),
Om0=Omega_m,
Ode0=Omega_lambda,
w0=w_0,
wa=w_a,
Tcmb0=Tcmb0,
Ob0=Omega_b,
)
lookback_time_now = cosmology.lookback_time(z_now)
lookback_time_limit = lookback_time_now + delta_time.to_astropy()
z_limit = z_at_value(cosmology.lookback_time, lookback_time_limit)
# for some reason, the return type of z_at_value has changed between
# astropy versions. We make sure it is not some astropy quantity
# before using it.
if hasattr(z_limit, "value"):
z_limit = z_limit.value
self.a_limit = 1.0 / (1.0 + z_limit) * unyt.dimensionless
self.Tmin = AGN_delta_T * 10.0**delta_logT_min
self.Tmax = AGN_delta_T * 10.0**delta_logT_max
def is_recently_heated(self, lastAGNfeedback, temperature):
return (
(lastAGNfeedback >= self.a_limit)
& (temperature >= self.Tmin)
& (temperature <= self.Tmax)
)