Coverage for bilby/gw/eos/tov_solver.py: 100%
50 statements
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2025-05-06 04:57 +0000
1# Monica Rizzo, 2019
3import numpy as np
6class IntegrateTOV:
7 """Class that given an initial pressure a mass radius value and a k2-love number
8 """
10 def __init__(self, eos, eps_0):
11 self.eos = eos
12 # determine central values
13 pseudo_enthalpy0 = self.eos.pseudo_enthalpy_from_energy_density(eps_0)
15 # evolve first step analytically
16 self.pseudo_enthalpy = pseudo_enthalpy0 - 1e-3 * pseudo_enthalpy0
18 mass0, radius0 = self.__mass_radius_cent(pseudo_enthalpy0, self.pseudo_enthalpy)
20 # k2 integration starting vals
21 H0 = radius0 ** 2
22 B0 = 2. * radius0
24 self.y = np.array([mass0, radius0, H0, B0])
26 def __mass_radius_cent(self, pseudo_enthalpy0, pseudo_enthalpy):
27 """
28 Calculate approximate mass/radius central values (for starting integration)
30 Eqns 7 + 8 from http://www.ccom.ucsd.edu/~lindblom/Publications/50_1992ApJ...398..569L.pdf
31 """
33 eps_c = self.eos.energy_density_from_pseudo_enthalpy(pseudo_enthalpy0)
34 p_c = self.eos.pressure_from_pseudo_enthalpy(pseudo_enthalpy0)
35 depsdh_c = self.eos.dedh(pseudo_enthalpy0)
37 radius = ((3. * (pseudo_enthalpy0 - pseudo_enthalpy)) / (2. * np.pi * (eps_c + 3. * p_c))) ** 0.5 \
38 * (1. - 0.25 * (eps_c - 3. * p_c - (3. / 5.) * depsdh_c) *
39 ((pseudo_enthalpy0 - pseudo_enthalpy) / (eps_c + 3. * p_c)))
41 mass = (4. * np.pi) / 3. * eps_c * radius ** 3 * (1. - (3. / 5.) *
42 depsdh_c * (pseudo_enthalpy0 - pseudo_enthalpy) / eps_c)
44 return mass, radius
46 def __tov_eqns(self, h, y):
47 """
48 Taken from http://www.ccom.ucsd.edu/~lindblom/Publications/50_1992ApJ...398..569L.pdf
50 TOV equations in terms of pseudo-enthalpy; evolves in mass and radius
51 H and B equations taken from:
53 https://journals.aps.org/prd/pdf/10.1103/PhysRevD.81.123016
55 Transformed (hopefully to evolve in H(h) and B(h)
56 """
58 m = y[0]
59 r = y[1]
60 H = y[2]
61 B = y[3]
62 eps = self.eos.energy_density_from_pseudo_enthalpy(h, interp_type='CubicSpline')
63 p = self.eos.pressure_from_pseudo_enthalpy(h, interp_type='CubicSpline')
64 depsdp = self.eos.dedp(p, interp_type='CubicSpline')
66 dmdh = (- (4. * np.pi * eps * r ** 3 * (r - 2. * m)) /
67 (m + 4. * np.pi * r ** 3 * p))
69 drdh = -(r * (r - 2. * m)) / (m + 4. * np.pi * r ** 3 * p)
71 dHdh = B * drdh
73 # taken from Damour & Nagar
74 e_lam = (1. - 2. * m / r) ** (-1)
76 C1 = 2. / r + e_lam * (2. * m / r ** 2. + 4. * np.pi * r * (p - eps))
77 C0 = (e_lam * (- 6. / r ** 2. + 4. * np.pi * (eps + p) *
78 depsdp + 4. * np.pi * (5. * eps + 9. * p)) -
79 (2. * (m + 4. * np.pi * r ** 3. * p) /
80 (r ** 2. - 2. * m * r)) ** 2.)
82 dBdh = -(C1 * B + C0 * H) * drdh
84 y_dot = np.array([dmdh, drdh, dHdh, dBdh])
86 return y_dot
88 def __calc_k2(self, R, Beta, H, C):
89 """
90 Using evolved quantities, calculate the k2 love
92 https://journals.aps.org/prd/pdf/10.1103/PhysRevD.81.123016
94 https://journals.aps.org/prd/pdf/10.1103/PhysRevD.80.084035
95 """
97 y = (R * Beta) / H
99 num = ((8. / 5.) * (1. - 2. * C) ** 2 *
100 C ** 5 * (2. * C * (y - 1.) - y + 2.))
101 denom = (2. * C * (4. * (y + 1.) * C ** 4 + (6. * y - 4.) * C ** 3 +
102 (26. - 22. * y) * C ** 2 + 3. * (5. * y - 8.) *
103 C - 3. * y + 6.) - 3. * (1. - 2 * C) ** 2 *
104 (2. * C * (y - 1.) - y + 2.) *
105 np.log(1. / (1. - 2. * C)))
107 return num / denom
109 def integrate_TOV(self):
110 """
111 Evolves TOV+k2 equations and returns final quantities
112 """
113 from scipy.integrate import solve_ivp
115 # integration settings the same as in lalsimulation
116 rel_err = 1e-4
117 abs_err = 0.0
119 result = solve_ivp(self.__tov_eqns, (self.pseudo_enthalpy, 1e-16), self.y, rtol=rel_err,
120 atol=abs_err)
121 m_fin = result.y[0, -1]
122 r_fin = result.y[1, -1]
123 H_fin = result.y[2, -1]
124 B_fin = result.y[3, -1]
126 k_2 = self.__calc_k2(r_fin, B_fin, H_fin, m_fin / r_fin)
128 return m_fin, r_fin, k_2