pybhpt 0.9.10__cp312-cp312-macosx_15_0_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
Binary file
pybhpt/__init__.py ADDED
File without changes
pybhpt/flux.py ADDED
@@ -0,0 +1,164 @@
1
+ """
2
+ Docstring for pybhpt.flux
3
+
4
+ Module containing classes and functions for computing fluxes of energy, angular momentum, and Carter constant in Kerr spacetime.
5
+ """
6
+
7
+ from cybhpt_full import flux as _FluxCython
8
+ from cybhpt_full import _ELQdot_to_pexdot_wrapper, _ELQdot_to_pexdot_array_wrapper
9
+ import numpy as np
10
+
11
+ class FluxList:
12
+ """A class for storing fluxes of energy, angular momentum, and Carter constant.
13
+
14
+ Parameters
15
+ ----------
16
+ fluxes : list of dicts, optional
17
+ A list containing three dictionaries, each with keys "I" and "H" representing the fluxes at infinity and on the horizon, respectively.
18
+ If not provided, initializes with zero fluxes for all three components.
19
+
20
+ Attributes
21
+ ----------
22
+ fluxes : list of dicts
23
+ A list containing three dictionaries, each with keys "I" and "H" representing the fluxes at infinity and on the horizon, respectively.
24
+ The first dictionary corresponds to energy flux,
25
+ the second to angular momentum flux, and the third to Carter constant flux.
26
+
27
+ Methods
28
+ -------
29
+ __call__():
30
+ Returns the list of fluxes.
31
+ """
32
+ def __init__(self, fluxes=None):
33
+ if fluxes is None:
34
+ self.fluxes = [{"I": 0., "H": 0.}, {"I": 0., "H": 0.}, {"I": 0., "H": 0.}]
35
+ elif len(fluxes) != 3:
36
+ self.fluxes = [{"I": 0., "H": 0.}, {"I": 0., "H": 0.}, {"I": 0., "H": 0.}]
37
+ else:
38
+ self.fluxes = fluxes
39
+
40
+ @property
41
+ def energy(self):
42
+ return self.fluxes[0]
43
+
44
+ @property
45
+ def angularmomentum(self):
46
+ return self.fluxes[1]
47
+
48
+ @property
49
+ def carterconstant(self):
50
+ return self.fluxes[2]
51
+
52
+ def __call__(self):
53
+ return self.fluxes
54
+
55
+
56
+ class FluxMode:
57
+ """A class for computing fluxes of energy, angular momentum, and Carter constant for a given Teukolsky mode.
58
+
59
+ Parameters
60
+ ----------
61
+ geo : KerrGeodesic class instance
62
+ KerrGeodesic object containing the background motion of the point-particle source.
63
+
64
+ teuk : TeukolskyMode object
65
+ TeukolskyMode object containing mode solutions to the point-particle-sourced Teukolsky equation.
66
+
67
+ Attributes
68
+ ----------
69
+ energy : dict
70
+ A dictionary containing the energy flux at infinity and on the horizon.
71
+ The keys are "I" for infinity and "H" for the horizon.
72
+ angularmomentum : dict
73
+ A dictionary containing the angular momentum flux at infinity and on the horizon.
74
+ The keys are "I" for infinity and "H" for the horizon.
75
+ carterconstant : dict
76
+ A dictionary containing the Carter constant flux at infinity and on the horizon.
77
+ The keys are "I" for infinity and "H" for the horizon.
78
+ fluxes : FluxList
79
+ A FluxList object containing the energy, angular momentum, and Carter constant fluxes.
80
+ horizonfluxes : list
81
+ A list containing the energy, angular momentum, and Carter constant fluxes on the horizon.
82
+ infinityfluxes : list
83
+ A list containing the energy, angular momentum, and Carter constant fluxes at infinity.
84
+ totalfluxes : list
85
+ A list containing the total fluxes, which are the sum of the horizon and infinity fluxes.
86
+ """
87
+ def __init__(self, geo, teuk):
88
+ self.base = _FluxCython(teuk.spinweight, geo.base, teuk.base)
89
+ self.apex = np.array([geo.a, geo.p, geo.e, geo.x])
90
+
91
+ @property
92
+ def energy(self):
93
+ return self.base.energy
94
+
95
+ @property
96
+ def angularmomentum(self):
97
+ return self.base.angularmomentum
98
+
99
+ @property
100
+ def carterconstant(self):
101
+ return self.base.carterconstant
102
+
103
+ @property
104
+ def Edot(self):
105
+ return self.energy
106
+ @property
107
+ def Ldot(self):
108
+ return self.angularmomentum
109
+ @property
110
+ def Qdot(self):
111
+ return self.carterconstant
112
+
113
+ @property
114
+ def fluxes(self):
115
+ return FluxList([self.energy, self.angularmomentum, self.carterconstant])
116
+
117
+ @property
118
+ def horizonfluxes(self):
119
+ return [self.energy["H"], self.angularmomentum["H"], self.carterconstant["H"]]
120
+
121
+ @property
122
+ def infinityfluxes(self):
123
+ return [self.energy["I"], self.angularmomentum["I"], self.carterconstant["I"]]
124
+
125
+ @property
126
+ def totalfluxes(self):
127
+ return [self.energy["I"] + self.energy["H"], self.angularmomentum["I"] + self.angularmomentum["H"], self.carterconstant["I"] + self.carterconstant["H"]]
128
+
129
+ def transform_ELQ_fluxes_to_pex(a, p, e, x, Edot, Lzdot, Qdot):
130
+ """Transform fluxes of energy, angular momentum, and Carter constant to fluxes of semi-latus rectum, eccentricity, and inclination.
131
+
132
+ Parameters
133
+ ----------
134
+ a : float or np.ndarray
135
+ Spin parameter of the Kerr black hole.
136
+ p : float or np.ndarray
137
+ Semi-latus rectum of the orbit.
138
+ e : float or np.ndarray
139
+ Eccentricity of the orbit.
140
+ x : float or np.ndarray
141
+ Cosine of the inclination angle of the orbit.
142
+ Edot : float or np.ndarray
143
+ Flux of energy.
144
+ Lzdot : float or np.ndarray
145
+ Flux of angular momentum.
146
+ Qdot : float or np.ndarray
147
+ Flux of Carter constant.
148
+
149
+ Returns
150
+ -------
151
+ tuple of (float or np.ndarray, float or np.ndarray, float or np.ndarray)
152
+ A tuple ``(pdot, edot, xdot)`` where:
153
+ - pdot: Flux of semi-latus rectum.
154
+ - edot: Flux of eccentricity.
155
+ - xdot: Flux of inclination.
156
+ """
157
+ if isinstance(p, np.ndarray):
158
+ assert isinstance(e, np.ndarray) and isinstance(x, np.ndarray) and isinstance(Edot, np.ndarray) and isinstance(Lzdot, np.ndarray) and isinstance(Qdot, np.ndarray), "If p is an array, e, x, Edot, Lzdot, and Qdot must also be arrays of the same shape."
159
+ assert p.shape == e.shape == x.shape == Edot.shape == Lzdot.shape == Qdot.shape, "p, e, x, Edot, Lzdot, and Qdot must have the same shape."
160
+ if not isinstance(a, np.ndarray):
161
+ a = np.full_like(p, a)
162
+ return _ELQdot_to_pexdot_array_wrapper(a, p, e, x, Edot, Lzdot, Qdot)
163
+ else:
164
+ return _ELQdot_to_pexdot_wrapper(a, p, e, x, Edot, Lzdot, Qdot)