1+ import numpy as np
2+
3+ def PN_charges (m , ν ):
4+ """
5+ Determine a tuple of callables for passing to
6+ com_transformation_map_to_superrest_frame function for a specific input of
7+ mass (m) and symmetric mass ratio (ν).
8+
9+ Parameters
10+ ----------
11+ m: float, real
12+ Total mass of the binary.
13+ ν: float, real
14+ Symmetric mass ratio of the binary.
15+
16+ Returns
17+ -------
18+ (energy_pn, angular_momentum_pn, com_charge_pn, phase): tuple of callables
19+ energy_pn is the PN series of energy up to 2PN order.
20+ angular_momentum_pn is the PN series of angular momentum up to 3PN order.
21+ com_charge_pn is the PN series of CoM charge up to leading order.
22+ orbital_phase is the phase obtained from the (2,1) mode of the strain.
23+
24+ Our conventions for defining the orbital phase differ from the standard
25+ conventions used in PN theory. This stems from the fact that SpEC uses
26+ h_{ab} to define the metric perturbation while PN theory uses h^{ab} for
27+ the metric perturbation, which results in h^{NR}_{lm} = − h^{PN}_{lm}.
28+ Also, the π/2 phase difference is due to the leading order complex phase
29+ of h_{21} mode from PN theory.
30+
31+ All of the callables accept abd object as a parameter.
32+ """
33+
34+ def compute_x (abd ):
35+ """Helper function to extract PN parameter x."""
36+ h = abd .h
37+ ω_mag = np .linalg .norm (h .angular_velocity (), axis = 1 )
38+ x = (m * ω_mag ) ** (2. / 3. )
39+
40+ return x
41+
42+ def energy_pn (abd ):
43+ x = compute_x (abd )
44+ E = m - (m * ν * x )/ 2 * (1 + (- 3 / 4 - ν / 12 )* x + (- 27 / 8 + 19 / 8 * ν - ν ** 2 / 24 ) * x ** 2 )
45+ return E
46+
47+ def angular_momentum_pn (abd ):
48+ x = compute_x (abd )
49+ J_mag = (m ** 2 * ν * x ** (- 1 / 2 )) * (1 + (3 / 2 + ν / 6 )* x + (- 27 / 8 + 19 / 8 * ν - ν ** 2 / 24 ) * x ** 2
50+ + (135 / 16 + (- 6889 / 144 + 41 / 24 * np .pi ** 2 )* ν + 31 / 24 * ν ** 2 + 7 / 1296 * ν ** 3 ) * x ** 3 )
51+ return J_mag
52+
53+ def G_mag_pn (abd ):
54+ x = compute_x (abd )
55+ G_mag = - (1142 / 105 ) * x ** (5 / 2 ) * m ** 2 * np .sqrt (1 - 4 * ν ) * ν ** 2
56+ return G_mag
57+
58+ def orbital_phase (abd ):
59+ h = abd .h
60+ h_21 = h .data [:, h .index (2 ,1 )]
61+ ψ = (- 1 )* np .unwrap (np .angle (- h_21 ) - np .pi / 2 )
62+ return ψ
63+
64+ return energy_pn , angular_momentum_pn , G_mag_pn , orbital_phase
65+
66+
67+ def analytical_CoM_func (θ , t , E , J_mag , G_mag , ψ ):
68+ """
69+ Computes the boosted center-of-mass-charge using PN expressions of other charges.
70+
71+ Parameters
72+ ----------
73+ θ: list[floats]
74+ Parameters of the model.
75+ θ[0:3] are the components of boost_velocity, θ[3:6] are components of
76+ the spatial translation (l=1 supertranslation), and there can be any
77+ extra fit parameters desired (but their fitted values are ignored).
78+ t: ndarray, real
79+ Time array corresponding to the size of the center-of-mass charge.
80+ E: ndarray, real
81+ Array corresponding to the energy.
82+ J_mag: ndarray, real
83+ Array corresponding to the magnitude of angular momentum.
84+ G_mag: ndarray, real
85+ Array corresponding to the magnitude of the center-of-mass charge.
86+ ψ: ndarray, real
87+ Orbital phase obtained from the (2,1) mode of the strain.
88+
89+ Returns
90+ -------
91+ G: ndarray, real, shape(..., 3)
92+ Model timeseries of the boosted center-of-mass charge.
93+ """
94+ β = θ [0 :3 ][None ]
95+ X = θ [3 :6 ][None ]
96+ α1 , α2 = θ [6 :]
97+
98+ # Get the orbital direction vectors, and the angular momentum vector.
99+ cosψ , sinψ = np .cos (ψ ), np .sin (ψ )
100+ nvec = np .stack ((cosψ , sinψ , 0 * ψ ),axis = 1 )
101+ λvec = np .stack ((- sinψ , cosψ ,0 * ψ ),axis = 1 )
102+ J = np .array ([0 * t ,0 * t ,J_mag ]).T
103+
104+ G = α1 * (G_mag / E )[:, None ] * λvec + α2 * (G_mag / E )[:, None ] * nvec - np .cross ( β , J / E [:,None ]) - t [:,None ] @ β + X
105+
106+ return G
0 commit comments