Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALSimNRTunedTides.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2017 Tim Dietrich, Sebastiano Bernuzzi, Nathan Johnson-McDaniel,
3 * Shasvath J Kapadia, Francesco Pannarale and Sebastian Khan, Michael Puerrer, Adrian Abac.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with with program; see the file COPYING. If not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301 USA
19 */
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <math.h>
25#include <complex.h>
26#include <lal/LALStdlib.h>
27#include <lal/LALConstants.h>
28#include <lal/Date.h>
29#include <lal/Units.h>
30#include <lal/LALSimIMR.h>
31
32#include "LALSimNRTunedTides.h"
34
35#ifdef __GNUC__
36#define UNUSED __attribute__ ((unused))
37#else
38#define UNUSED
39#endif
40
41/**
42 * Planck taper window
43 */
44static REAL8 PlanckTaper(const REAL8 t, const REAL8 t1, const REAL8 t2) {
45 REAL8 taper;
46 if (t <= t1)
47 taper = 0.;
48 else if (t >= t2)
49 taper = 1.;
50 else
51 taper = 1. / (exp((t2 - t1)/(t - t1) + (t2 - t1)/(t - t2)) + 1.);
52
53 return taper;
54}
55
56/**
57 * function to swap masses and lambda to enforce m1 >= m2
58 */
59static int EnforcePrimaryMassIsm1(REAL8 *m1, REAL8 *m2, REAL8 *lambda1, REAL8 *lambda2){
60 if ((*m1 == *m2) && (*lambda1 != *lambda2))
61 XLALPrintWarning("m1 == m2 (%g), but lambda1 != lambda2 (%g, %g).\n", *m1, *lambda1, *lambda2);
62
63 REAL8 lambda1_tmp, lambda2_tmp, m1_tmp, m2_tmp;
64 if (*m1>=*m2) {
65 lambda1_tmp = *lambda1;
66 lambda2_tmp = *lambda2;
67 m1_tmp = *m1;
68 m2_tmp = *m2;
69 } else {
70 lambda1_tmp = *lambda2;
71 lambda2_tmp = *lambda1;
72 m1_tmp = *m2;
73 m2_tmp = *m1;
74 }
75 *m1 = m1_tmp;
76 *m2 = m2_tmp;
77 *lambda1 = lambda1_tmp;
78 *lambda2 = lambda2_tmp;
79
80 if (*m1 < *m2)
81 XLAL_ERROR(XLAL_EDOM, "XLAL_ERROR in EnforcePrimaryMassIsm1. When trying\
82 to enfore that m1 should be the larger mass.\
83 After trying to enforce this m1 = %f and m2 = %f\n", *m1, *m2);
84
85 return XLAL_SUCCESS;
86}
87
88/**
89 * function to swap masses, spins, and lambda to enforce m1 >= m2, This is mainly for NRTidalv3,
90 * which has a merger frequency fit that is dependent on the aligned spin component. See Eq. (41)
91 * in https://arxiv.org/pdf/2311.07456.pdf.
92 */
93static int EnforcePrimaryMassIsm1_v3(REAL8 *m1, REAL8 *m2, REAL8 *lambda1, REAL8 *lambda2, REAL8 *chi1_AS, REAL8 *chi2_AS){
94 if ((*m1 == *m2) && (*lambda1 != *lambda2))
95 XLALPrintWarning("m1 == m2 (%g), but lambda1 != lambda2 (%g, %g).\n", *m1, *lambda1, *lambda2);
96
97 REAL8 lambda1_tmp, lambda2_tmp, m1_tmp, m2_tmp, chi1_tmp, chi2_tmp;
98 if (*m1>=*m2) {
99 lambda1_tmp = *lambda1;
100 lambda2_tmp = *lambda2;
101 m1_tmp = *m1;
102 m2_tmp = *m2;
103 chi1_tmp = *chi1_AS;
104 chi2_tmp = *chi2_AS;
105 } else { /* swap spins, dimensionless tidal deformabilities, and masses */
106 lambda1_tmp = *lambda2;
107 lambda2_tmp = *lambda1;
108 m1_tmp = *m2;
109 m2_tmp = *m1;
110 chi1_tmp = *chi2_AS;
111 chi2_tmp = *chi1_AS;
112 }
113 *m1 = m1_tmp;
114 *m2 = m2_tmp;
115 *lambda1 = lambda1_tmp;
116 *lambda2 = lambda2_tmp;
117 *chi1_AS = chi1_tmp;
118 *chi2_AS = chi2_tmp;
119
120 if (*m1 < *m2)
121 XLAL_ERROR(XLAL_EDOM, "XLAL_ERROR in EnforcePrimaryMassIsm1. When trying\
122 to enfore that m1 should be the larger mass.\
123 After trying to enforce this m1 = %f and m2 = %f\n", *m1, *m2);
124
125 return XLAL_SUCCESS;
126}
127
128
129/**
130 * convenient function to compute tidal coupling constant. Eq. 2 in arXiv:1706.02969
131 * given masses and lambda numbers
132 */
134 REAL8 m1_SI, /**< Mass of companion 1 (kg) */
135 REAL8 m2_SI, /**< Mass of companion 2 (kg) */
136 REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
137 REAL8 lambda2 /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
138 )
139{
140 int errcode = EnforcePrimaryMassIsm1(&m1_SI, &m2_SI, &lambda1, &lambda2);
141 XLAL_CHECK(XLAL_SUCCESS == errcode, errcode, "EnforcePrimaryMassIsm1 failed");
142
143 const REAL8 m1 = m1_SI / LAL_MSUN_SI;
144 const REAL8 m2 = m2_SI / LAL_MSUN_SI;
145 const REAL8 mtot = m1 + m2;
146
147 /* Xa and Xb are the masses normalised for a total mass = 1 */
148 /* not the masses appear symmetrically so we don't need to switch them. */
149 const REAL8 Xa = m1 / mtot;
150 const REAL8 Xb = m2 / mtot;
151
152 /* tidal coupling constant. This is the
153 kappa^T_eff = 2/13 [ (1 + 12 X_B/X_A) (X_A/C_A)^5 k^A_2 + [A <- -> B] ]
154 from Tim Dietrich */
155
156 /* Note that 2*k_2^A/c_A^5 = 3*lambda1 */
157 const REAL8 term1 = ( 1.0 + 12.0*Xb/Xa ) * pow(Xa, 5.0) * lambda1;
158 const REAL8 term2 = ( 1.0 + 12.0*Xa/Xb ) * pow(Xb, 5.0) * lambda2;
159 const REAL8 kappa2T = (3.0/13.0) * ( term1 + term2 );
160
161 return kappa2T;
162}
163
164/**
165 * compute the merger frequency of a BNS system.
166 * Tim's new fit that incorporates mass-ratio and asymptotes to zero for large kappa2T.
167 */
169 const REAL8 mtot_MSUN, /**< total mass of system (solar masses) */
170 const REAL8 kappa2T, /**< tidal coupling constant. Eq. 2 in arXiv:1706.02969 */
171 const REAL8 q /**< mass-ratio q >= 1 */
172 )
173{
174 if (q < 1.0) {
175 XLALPrintError("XLAL Error - %s: q (%f) should be greater or equal to unity!\n",
176 __func__, q);
178 }
179
180 const REAL8 a_0 = 0.3586;
181 const REAL8 n_1 = 3.35411203e-2;
182 const REAL8 n_2 = 4.31460284e-5;
183 const REAL8 d_1 = 7.54224145e-2;
184 const REAL8 d_2 = 2.23626859e-4;
185
186 const REAL8 kappa2T2 = kappa2T * kappa2T;
187
188 const REAL8 num = 1.0 + n_1*kappa2T + n_2*kappa2T2;
189 const REAL8 den = 1.0 + d_1*kappa2T + d_2*kappa2T2;
190 const REAL8 Q_0 = a_0 / sqrt(q);
191
192 /* dimensionless angular frequency of merger */
193 const REAL8 Momega_merger = Q_0 * (num / den);
194
195 /* convert from angular frequency to frequency (divide by 2*pi)
196 * and then convert from
197 * dimensionless frequency to Hz (divide by mtot * LAL_MTSUN_SI)
198 */
199 const REAL8 fHz_merger = Momega_merger / (LAL_TWOPI) / (mtot_MSUN * LAL_MTSUN_SI);
200
201 return fHz_merger;
202}
203
204
205/**
206 * compute the merger frequency of a BNS system for NRTidalv3 (https://arxiv.org/pdf/2311.07456.pdf).
207 * This uses a new fit from Gonzalez, et. al (2022); Eq. (23) of https://arxiv.org/abs/2210.16366.
208 */
210 const REAL8 mtot_MSUN, /**< total mass of system (solar masses) */
211 REAL8 lambda1, /**<dimensionless tidal deformability of star 1 */
212 REAL8 lambda2, /**<dimensionless tidal deformability of star 2 */
213 const REAL8 q, /**<mass ratio q>=1 */
214 REAL8 chi1_AS, /**<aligned spin component of star 1 */
215 REAL8 chi2_AS /**<aligned spin component of star 2 */
216 )
217{
218 if (q < 1.0) {
219 XLALPrintError("XLAL Error - %s: q (%f) should be greater or equal to unity!\n",
220 __func__, q);
222 }
223
224 REAL8 Xa = q/(1.0+q);
225 REAL8 Xb = 1.0 - Xa;
226
227 REAL8 m1 = Xa*mtot_MSUN;
228 REAL8 m2 = Xb*mtot_MSUN;
229
230 int errcode = EnforcePrimaryMassIsm1_v3(&m1, &m2, &lambda1, &lambda2, &chi1_AS, &chi2_AS);
231 XLAL_CHECK(XLAL_SUCCESS == errcode, errcode, "EnforcePrimaryMassIsm1_v3 failed");
232
233 REAL8 nu = Xa*Xb;
234
235 REAL8 Xa_2 = Xa*Xa;
236 REAL8 Xa_3 = Xa_2*Xa;
237 REAL8 Xb_2 = Xb*Xb;
238 REAL8 Xb_3 = Xb_2*Xb;
239
240 REAL8 kappa2eff = 3.0*nu*(Xa_3*lambda1 + Xb_3*lambda2);
241
242 const REAL8 a_0 = 0.22;
243
244 const REAL8 a_1M = 0.80;
245 const REAL8 a_1S = 0.25;
246 const REAL8 b_1S = -1.99; /**< This was not written in 2311.07456, but can be found in Table 2 of 2210.16366.*/
247
248 const REAL8 a_1T = 0.0485;
249 const REAL8 a_2T = 0.00000586;
250 const REAL8 a_3T = 0.10;
251 const REAL8 a_4T = 0.000186;
252
253 const REAL8 b_1T = 1.80;
254 const REAL8 b_2T = 599.99;
255 const REAL8 b_3T = 7.80;
256 const REAL8 b_4T = 84.76;
257
258 const REAL8 Xval = 1.0 - 4.0*nu;
259
260 const REAL8 p_1S = a_1S*(1.0 + b_1S*Xval);
261 const REAL8 p_1T = a_1T*(1.0 + b_1T*Xval);
262 const REAL8 p_2T = a_2T*(1.0 + b_2T*Xval);
263 const REAL8 p_3T = a_3T*(1.0 + b_3T*Xval);
264 const REAL8 p_4T = a_4T*(1.0 + b_4T*Xval);
265
266 const REAL8 kappa2eff2 = kappa2eff*kappa2eff;
267
268 const REAL8 Sval = Xa_2*chi1_AS + Xb_2*chi2_AS;
269
270 const REAL8 QM = 1.0 + a_1M*Xval;
271 const REAL8 QS = 1.0 + p_1S*Sval;
272
273 const REAL8 num = 1.0 + p_1T*kappa2eff + p_2T*kappa2eff2;
274 const REAL8 den = 1.0 + p_3T*kappa2eff + p_4T*kappa2eff2;
275 const REAL8 QT = num / den;
276
277 /* dimensionless angular frequency of merger */
278
279 const REAL8 Qfit = a_0*QM*QS*QT;
280
281 const REAL8 Momega_merger = nu*Qfit*(LAL_TWOPI);
282
283
284 /* convert from angular frequency to frequency (divide by 2*pi)
285 * and then convert from
286 * dimensionless frequency to Hz (divide by mtot * LAL_MTSUN_SI)
287 */
288 const REAL8 fHz_merger = Momega_merger / (LAL_TWOPI) / (mtot_MSUN * LAL_MTSUN_SI);
289
290 return fHz_merger;
291}
292
293
294/**
295 * Internal function only.
296 * Function to call the frequency domain tidal correction.
297 * Equation (7) in arXiv:1706.02969
298 */
300 const REAL8 fHz, /**< Gravitational wave frequency (Hz) */
301 const REAL8 Xa, /**< Mass of companion 1 divided by total mass */
302 const REAL8 Xb, /**< Mass of companion 2 divided by total mass */
303 const REAL8 mtot, /**< total mass (Msun) */
304 const REAL8 kappa2T /**< tidal coupling constant. Eq. 2 in arXiv:1706.02969 */
305 )
306{
307 /* NRTunedTidesFDTidalPhase is Eq 7 in arXiv:1706.02969
308 * and is a function of x = angular_orb_freq^(2/3)
309 */
310 REAL8 M_omega = LAL_PI * fHz * (mtot * LAL_MTSUN_SI); //dimensionless angular GW frequency
311
312 REAL8 PN_x = pow(M_omega, 2.0/3.0);
313 REAL8 PN_x_2 = PN_x * PN_x;
314 REAL8 PN_x_3over2 = pow(PN_x, 3.0/2.0);
315 REAL8 PN_x_5over2 = pow(PN_x, 5.0/2.0);
316
317 /* model parameters */
318 const REAL8 c_Newt = 2.4375; /* 39.0 / 16.0 */
319
320 const REAL8 n_1 = -17.428;
321 const REAL8 n_3over2 = 31.867;
322 const REAL8 n_2 = -26.414;
323 const REAL8 n_5over2 = 62.362;
324
325 const REAL8 d_1 = n_1 - 2.496; /* 3115.0/1248.0 */
326 const REAL8 d_3over2 = 36.089;
327
328 REAL8 tidal_phase = - kappa2T * c_Newt / (Xa * Xb) * PN_x_5over2;
329
330 REAL8 num = 1.0 + (n_1 * PN_x) + (n_3over2 * PN_x_3over2) + (n_2 * PN_x_2) + (n_5over2 * PN_x_5over2) ;
331 REAL8 den = 1.0 + (d_1 * PN_x) + (d_3over2 * PN_x_3over2) ;
332
333 REAL8 ratio = num / den;
334
335 tidal_phase *= ratio;
336
337 return tidal_phase;
338}
339
340/**
341 * Tidal amplitude corrections; only available for NRTidalv2;
342 * Eq 24 of arxiv:1905.06011
343 */
345 const REAL8 fHz, /**< Gravitational wave frequency (Hz) */
346 const REAL8 mtot, /**< Total mass in solar masses */
347 const REAL8 kappa2T /**< tidal coupling constant. Eq. 2 in arXiv:1706.02969 */
348 )
349{
350 const REAL8 M_sec = (mtot * LAL_MTSUN_SI);
351
352 REAL8 prefac = 0.0;
353 prefac = 9.0*kappa2T;
354
355 REAL8 x = pow(LAL_PI*M_sec*fHz, 2.0/3.0);
356 REAL8 ampT = 0.0;
357 REAL8 poly = 1.0;
358 const REAL8 n1 = 4.157407407407407;
359 const REAL8 n289 = 2519.111111111111;
360 const REAL8 d = 13477.8073677;
361
362 poly = (1.0 + n1*x + n289*pow(x, 2.89))/(1+d*pow(x,4.));
363 ampT = - prefac*pow(x,3.25)*poly;
364
365 return ampT;
366}
367
368/**
369 * Set the NRTidalv2 phase coefficients in an array for use here and in the IMRPhenomX*_NRTidalv2 implementation
370 */
372{
373 NRTidalv2_coeffs[0] = 2.4375; // c_Newt
374 NRTidalv2_coeffs[1] = -12.615214237993088; // n_1
375 NRTidalv2_coeffs[2] = 19.0537346970349; // n_3over2
376 NRTidalv2_coeffs[3] = -21.166863146081035; // n_2
377 NRTidalv2_coeffs[4] = 90.55082156324926; // n_5over2
378 NRTidalv2_coeffs[5] = -60.25357801943598; // n_3
379 NRTidalv2_coeffs[6] = -15.111207827736678; // d_1
380 NRTidalv2_coeffs[7] = 22.195327350624694; // d_3over2
381 NRTidalv2_coeffs[8] = 8.064109635305156; // d_2
382
383 return XLAL_SUCCESS;
384}
385
386/**
387 * NRTunedTidesFDTidalPhase is Eq 22 of https://arxiv.org/abs/1905.06011
388 * and is a function of x = angular_orb_freq^(2/3)
389 */
391 const REAL8 fHz, /**< Gravitational wave frequency (Hz) */
392 const REAL8 Xa, /**< Mass of companion 1 divided by total mass */
393 const REAL8 Xb, /**< Mass of companion 2 divided by total mass */
394 const REAL8 mtot, /**< total mass (Msun) */
395 const REAL8 kappa2T /**< tidal coupling constant. Eq. 2 in arXiv:1706.02969 */
396 )
397{
398
399 REAL8 M_omega = LAL_PI * fHz * (mtot * LAL_MTSUN_SI); //dimensionless angular GW frequency
400 REAL8 PN_x = pow(M_omega, 2.0/3.0);
401 REAL8 PN_x_2 = PN_x * PN_x;
402 REAL8 PN_x_3 = PN_x * PN_x_2;
403 REAL8 PN_x_3over2 = pow(PN_x, 3.0/2.0);
404 REAL8 PN_x_5over2 = pow(PN_x, 5.0/2.0);
405 /* model parameters */
406 REAL8 NRTidalv2_coeffs[9];
407
408 int errcode;
409 errcode = XLALSimNRTunedTidesSetFDTidalPhase_v2_Coeffs(NRTidalv2_coeffs);
410 XLAL_CHECK(XLAL_SUCCESS == errcode, errcode, "Setting NRTidalv2 coefficients failed.\n");
411
412 const REAL8 c_Newt = NRTidalv2_coeffs[0];
413 const REAL8 n_1 = NRTidalv2_coeffs[1];
414 const REAL8 n_3over2 = NRTidalv2_coeffs[2];
415 const REAL8 n_2 = NRTidalv2_coeffs[3];
416 const REAL8 n_5over2 = NRTidalv2_coeffs[4];
417 const REAL8 n_3 = NRTidalv2_coeffs[5];
418 const REAL8 d_1 = NRTidalv2_coeffs[6];
419 const REAL8 d_3over2 = NRTidalv2_coeffs[7];
420 const REAL8 d_2 = NRTidalv2_coeffs[8];
421 REAL8 tidal_phase = - kappa2T * c_Newt / (Xa * Xb) * PN_x_5over2;
422 REAL8 num = 1.0 + (n_1 * PN_x) + (n_3over2 * PN_x_3over2) + (n_2 * PN_x_2) + (n_5over2 * PN_x_5over2) + (n_3 * PN_x_3);
423 REAL8 den = 1.0 + (d_1 * PN_x) + (d_3over2 * PN_x_3over2) + (d_2 * PN_x_2) ;
424 REAL8 ratio = num / den;
425 tidal_phase *= ratio;
426 return tidal_phase;
427}
428
429/**
430 * Coefficients or the PN tidal phase correction, at 7.5PN, to connect with NRTidalv3 Phase post-merger,
431 * see Eq. (45) of https://arxiv.org/pdf/2311.07456.pdf
432 */
433int XLALSimNRTunedTidesSetFDTidalPhase_PN_Coeffs(REAL8 *PN_coeffs,/**<PN coefficients*/
434 const REAL8 Xa /**< Mass of companion 1 divided by total mass*/)
435{
436 /* Powers of Xa and Xb */
437 REAL8 Xb = 1.0 - Xa; //secondary mass divided by total mass
438 REAL8 Xa_2 = Xa*Xa;
439 REAL8 Xa_3 = Xa_2*Xa;
440 REAL8 Xa_4 = Xa_3*Xa;
441 REAL8 Xa_5 = Xa_4*Xa;
442
443 REAL8 Xb_2 = Xb*Xb;
444 REAL8 Xb_3 = Xb_2*Xb;
445 REAL8 Xb_4 = Xb_3*Xb;
446 REAL8 Xb_5 = Xb_4*Xb;
447
448 REAL8 den_a = 11.0*Xa-12.0;
449 REAL8 den_b = 11.0*Xb-12.0;
450
451 /* 7.5PN Coefficients */
452 PN_coeffs[0] = -3.0*den_a/(16*Xa*Xb_2);//(3.0)*(12.0 -11.0*Xa)/(16*Xa*Xb_2);
453 PN_coeffs[1] = (-1300.0*Xa_3 + 11430.0*Xa_2 + 4595.0*Xa -15895.0)/(672.0*den_a);//-5.0*(260.0*Xa_3 - 2286.0*Xa_2 - 919.0*Xa + 3179.0)/(672.0*(11.0*Xa-12.0));
454 PN_coeffs[2] = -LAL_PI;
455 PN_coeffs[3] = (22861440.0*Xa_5 - 102135600.0*Xa_4 + 791891100.0*Xa_3 + 874828080.0*Xa_2 + 216234195.0*Xa -1939869350.0)/(27433728.0*den_a);//(5.0*(4572288.0*Xa_5 - 20427120.0*Xa_4 + 158378220.0*Xa_3 +174965616.0*Xa_2 + 43246839.0*Xa -387973870.0))/(27433728.0*(11.0*Xa - 12.0));
456 PN_coeffs[4] = -LAL_PI*(10520.0*Xa_3 -7598.0*Xa_2 +22415.0*Xa - 27719.0)/(672.0*den_a);
457
458 PN_coeffs[5] = -3.0*den_b/(16*Xb*Xa_2);//(3.0)*(12.0 -11.0*Xb)/(16*Xb*Xa_2);
459 PN_coeffs[6] = (-1300.0*Xb_3 + 11430.0*Xb_2 + 4595.0*Xb -15895.0)/(672.0*den_b);//-5.0*(260.0*Xb_3 - 2286.0*Xb_2 - 919.0*Xb + 3179.0)/(672.0*(11.0*Xb-12.0));
460 PN_coeffs[7] = -LAL_PI;
461 PN_coeffs[8] = (22861440.0*Xb_5 - 102135600.0*Xb_4 + 791891100.0*Xb_3 + 874828080.0*Xb_2 + 216234195.0*Xb -1939869350.0)/(27433728.0*den_b);//(5.0*(4572288.0*Xb_5 - 20427120.0*Xb_4 + 158378220.0*Xb_3 +174965616.0*Xb_2 + 43246839.0*Xb -387973870.0))/(27433728.0*(11.0*Xb - 12.0));
462 PN_coeffs[9] = -LAL_PI*(10520.0*Xb_3 -7598.0*Xb_2 +22415.0*Xb - 27719.0)/(672.0*den_b);
463
464 return XLAL_SUCCESS;
465}
466
467/**
468 * Set the NRTidalv3 effective love number and phase coefficients in an array for use here and in the IMRPhenomX*_NRTidalv3 implementation
469 */
470int XLALSimNRTunedTidesSetFDTidalPhase_v3_Coeffs(REAL8 *NRTidalv3_coeffs, /**< output of NRTidalv3 parameters to be used in computing the tidal phase corrections*/
471 const REAL8 Xa, /**< Mass of companion 1 divided by total mass*/
472 const REAL8 mtot, /**< total mass (Msun) */
473 const REAL8 lambda1, /**< dimensionless tidal deformability of companion 1*/
474 const REAL8 lambda2, /**< dimensionless tidal deformability of companion 2*/
475 const REAL8 PN_coeffs[10] /**< 7.5 PN coefficients to be used for constraints*/
476 )
477{
478 REAL8 Xb = 1.0 - Xa; //secondary mass divided by total mass
479 REAL8 q = Xa/Xb;
480
481 //Coefficients for the effective enhancement factor:
482 const REAL8 s10 = 1.273000423; //s10
483 const REAL8 s11 = 3.64169971e-03; //s11
484 const REAL8 s12 = 1.76144380e-03; //s12
485
486 const REAL8 s20 = 2.78793291e+01; //s20
487 const REAL8 s21 = 1.18175396e-02; //s21
488 const REAL8 s22 = -5.39996790e-03; //s22
489
490 const REAL8 s30 = 1.42449682e-01; //s30
491 const REAL8 s31 = -1.70505852e-05; //s31
492 const REAL8 s32 = 3.38040594e-05; //s32
493
494 REAL8 m1_SI = Xa * mtot * LAL_MSUN_SI;
495 REAL8 m2_SI = Xb * mtot * LAL_MSUN_SI;
496
497 REAL8 kappa2T = XLALSimNRTunedTidesComputeKappa2T(m1_SI, m2_SI, lambda1, lambda2);
498
499 NRTidalv3_coeffs[0] = s10 + s11*kappa2T + s12*q*kappa2T; // s1
500 NRTidalv3_coeffs[1] = s20 + s21*kappa2T + s22*q*kappa2T; // s2
501 NRTidalv3_coeffs[2] = s30 + s31*kappa2T + s32*q*kappa2T; // s3
502
503 REAL8 s2s3 = NRTidalv3_coeffs[1]*NRTidalv3_coeffs[2];
504 NRTidalv3_coeffs[3] = cosh(s2s3) + sinh(s2s3);
505
506 NRTidalv3_coeffs[4] = 3.0*Xb*Xa*Xa*Xa*Xa*lambda1; //kappaA
507 NRTidalv3_coeffs[5] = 3.0*Xa*Xb*Xb*Xb*Xb*lambda2; //kappaB
508
509//Exponent parameters:
510 const REAL8 alpha = -8.08155404e-03; //alpha
511 const REAL8 beta = -1.13695919e+00; //beta
512
513 REAL8 kappaA_alpha = pow(NRTidalv3_coeffs[4] + 1, alpha); //kappaA_alpha
514 REAL8 kappaB_alpha = pow(NRTidalv3_coeffs[5] + 1, alpha); //kappaB_alpha
515
516 REAL8 Xa_beta = pow(Xa, beta); //Xa_beta
517 REAL8 Xb_beta = pow(Xb, beta); //Xb_beta
518
519//Pade approximant coefficients:
520 const REAL8 n_5over20 = -9.40654388e+02; //n_5over20
521 const REAL8 n_5over21 = 6.26517157e+02; //n_5over21
522 const REAL8 n_5over22 = 5.53629706e+02; //n_5over22
523 const REAL8 n_5over23 = 8.84823087e+01; //n_5over23
524
525 const REAL8 n_30 = 4.05483848e+02; //n_30
526 const REAL8 n_31 = -4.25525054e+02; //n_31
527 const REAL8 n_32 = -1.92004957e+02; //n_32
528 const REAL8 n_33 = -5.10967553e+01; //n_33
529
530 const REAL8 d_10 = 3.80343306e+00; //d_10
531 const REAL8 d_11 = -2.52026996e+01; //d_11
532 const REAL8 d_12 = -3.08054443e+00; //d_12
533
534 NRTidalv3_coeffs[6] = n_5over20 + n_5over21*Xa + n_5over22*kappaA_alpha + n_5over23*Xa_beta; //n_5over2A
535 NRTidalv3_coeffs[7] = n_30 + n_31*Xa + n_32*kappaA_alpha + n_33*Xa_beta; //n_3A
536 NRTidalv3_coeffs[8] = d_10 + d_11*Xa + d_12*Xa_beta; //d_1A
537
538 NRTidalv3_coeffs[9] = n_5over20 + n_5over21*Xb + n_5over22*kappaB_alpha + n_5over23*Xb_beta; //n_5over2B
539 NRTidalv3_coeffs[10] = n_30 + n_31*Xb + n_32*kappaB_alpha + n_33*Xb_beta; //n_3B
540 NRTidalv3_coeffs[11] = d_10 + d_11*Xb + d_12*Xb_beta; //d_1B
541
542 /* 7.5PN Coefficients */
543 REAL8 c_1A = PN_coeffs[1];
544 REAL8 c_3over2A = PN_coeffs[2];
545 REAL8 c_2A = PN_coeffs[3];
546 REAL8 c_5over2A = PN_coeffs[4];
547
548 REAL8 c_1B = PN_coeffs[6];
549 REAL8 c_3over2B = PN_coeffs[7];
550 REAL8 c_2B = PN_coeffs[8];
551 REAL8 c_5over2B = PN_coeffs[9];
552
553 /* Pade Coefficients constrained with PN */
554 REAL8 inv_c1_A = 1.0/c_1A;
555 NRTidalv3_coeffs[12] = c_1A + NRTidalv3_coeffs[8]; //n_1A
556 NRTidalv3_coeffs[13] = ((c_1A*c_3over2A) - c_5over2A - (c_3over2A)*NRTidalv3_coeffs[8] + NRTidalv3_coeffs[6])*inv_c1_A; //n_3over2A
557 NRTidalv3_coeffs[14] = c_2A + c_1A*NRTidalv3_coeffs[8];// + d_2A; //n_2A
558 NRTidalv3_coeffs[15] = -(c_5over2A + c_3over2A*NRTidalv3_coeffs[8] - NRTidalv3_coeffs[6])*inv_c1_A; //d_3over2A
559
560 REAL8 inv_c1_B = 1.0/c_1B;
561 NRTidalv3_coeffs[16] = c_1B + NRTidalv3_coeffs[11];//n_1B
562 NRTidalv3_coeffs[17] = ((c_1B*c_3over2B) - c_5over2B - (c_3over2B)*NRTidalv3_coeffs[11] + NRTidalv3_coeffs[9])*inv_c1_B; //n_3over2B
563 NRTidalv3_coeffs[18] = c_2B + c_1B*NRTidalv3_coeffs[11];// + d_2B; //n_2B
564 NRTidalv3_coeffs[19] = -(c_5over2B + c_3over2B*NRTidalv3_coeffs[11] - NRTidalv3_coeffs[9])*inv_c1_B; //d_3over2B
565
566 return XLAL_SUCCESS;
567}
568
569/**
570 * Tidal phase correction for NRTidalv3, Eq. (27,30), from Abac, et. al. (2023) (https://arxiv.org/pdf/2311.07456.pdf)
571 * and is a function of x = angular_orb_freq^(2./3.)
572 */
574 const REAL8 fHz, /**< Gravitational wave frequency (Hz) */
575 const REAL8 mtot, /**< total mass (Msun) */
576 const REAL8 NRTidalv3_coeffs[20], /**< NRTidalv3 coefficients */
577 const REAL8 PN_coeffs[10] /**< 7.5 PN coefficients to be used as constraints*/
578 )
579{
580 REAL8 M_omega = LAL_PI * fHz * (mtot * LAL_MTSUN_SI); //dimensionless angular GW frequency
581
582 REAL8 s1 = NRTidalv3_coeffs[0];
583 REAL8 s2 = NRTidalv3_coeffs[1];
584
585 REAL8 exps2s3 = NRTidalv3_coeffs[3];
586
587 REAL8 s2Mom = -s2*M_omega*2.0;
588 REAL8 exps2Mom = cosh(s2Mom) + sinh(s2Mom);
589
590 /* expression for the effective love number enhancement factor, see Eq. (27) of https://arxiv.org/pdf/2311.07456.pdf.*/
591 REAL8 dynk2bar = 1.0 + ((s1) - 1)*(1.0/(1.0 + exps2Mom*exps2s3)) - ((s1-1.0)/(1.0 + exps2s3)) - 2.0*M_omega*((s1) - 1)*s2*exps2s3/((1.0 + exps2s3)*(1.0 + exps2s3));
592
593 REAL8 PN_x = M_omega / cbrt(M_omega); // pow(M_omega, 2.0/3.0)
594 REAL8 PN_x_2 = PN_x * PN_x; // pow(PN_x, 2)
595 REAL8 PN_x_3 = PN_x * PN_x_2;
596 REAL8 PN_x_3over2 = PN_x * sqrt(PN_x); // pow(PN_x, 3.0/2.0)
597 REAL8 PN_x_5over2 = PN_x_3over2 * PN_x; // pow(PN_x, 5.0/2.0)
598
599 REAL8 kappaA = NRTidalv3_coeffs[4];
600 REAL8 kappaB = NRTidalv3_coeffs[5];
601
602 REAL8 dynkappaA = kappaA*dynk2bar;
603 REAL8 dynkappaB = kappaB*dynk2bar;
604
605 /* Pade Coefficients */
606 REAL8 n_5over2A = NRTidalv3_coeffs[6];
607 REAL8 n_3A = NRTidalv3_coeffs[7];
608 REAL8 d_1A = NRTidalv3_coeffs[8];
609
610 REAL8 n_5over2B = NRTidalv3_coeffs[9];
611 REAL8 n_3B = NRTidalv3_coeffs[10];
612 REAL8 d_1B = NRTidalv3_coeffs[11];
613
614 /* 7.5PN Coefficients */
615 REAL8 c_NewtA = PN_coeffs[0];
616 REAL8 c_NewtB = PN_coeffs[5];
617
618 /* Pade Coefficients constrained with PN */
619 REAL8 n_1A = NRTidalv3_coeffs[12];
620 REAL8 n_3over2A = NRTidalv3_coeffs[13];
621 REAL8 n_2A = NRTidalv3_coeffs[14];
622 REAL8 d_3over2A = NRTidalv3_coeffs[15];
623
624 REAL8 n_1B = NRTidalv3_coeffs[16];
625 REAL8 n_3over2B = NRTidalv3_coeffs[17];
626 REAL8 n_2B = NRTidalv3_coeffs[18];
627 REAL8 d_3over2B = NRTidalv3_coeffs[19];
628
629 REAL8 factorA = -c_NewtA*PN_x_5over2*dynkappaA;
630 REAL8 factorB = -c_NewtB*PN_x_5over2*dynkappaB;
631
632 /* Pade approximant, see Eq. (32) of https://arxiv.org/pdf/2311.07456.pdf. */
633 REAL8 numA = 1.0 + (n_1A*PN_x) + (n_3over2A*PN_x_3over2) + (n_2A*PN_x_2) + (n_5over2A*PN_x_5over2) + (n_3A*PN_x_3);
634 REAL8 denA = 1.0 + (d_1A*PN_x) + (d_3over2A*PN_x_3over2);// + (d_2A*PN_x_2);
635
636 REAL8 numB = 1.0 + (n_1B*PN_x) + (n_3over2B*PN_x_3over2) + (n_2B*PN_x_2) + (n_5over2B*PN_x_5over2) + (n_3B*PN_x_3);
637 REAL8 denB = 1.0 + (d_1B*PN_x) + (d_3over2B*PN_x_3over2);// + (d_2B*PN_x_2);
638
639 REAL8 ratioA = numA/denA;
640 REAL8 ratioB = numB/denB;
641
642 REAL8 tidal_phaseA = factorA*ratioA;
643 REAL8 tidal_phaseB = factorB*ratioB;
644
645 REAL8 tidal_phase = tidal_phaseA + tidal_phaseB;
646
647 return tidal_phase;
648}
649
650/**
651 * PN tidal phase correction, at 7.5PN, to connect with NRTidalv3 Phase post-merger,
652 * see Eq. (22) and (45) of https://arxiv.org/pdf/2311.07456.pdf
653 * and is a function of x = angular_orb_freq^(2./3.)
654 */
656 const REAL8 fHz, /**< Gravitational wave frequency (Hz) */
657 const REAL8 Xa, /**< Mass of companion 1 divided by total mass */
658 const REAL8 mtot, /**< total mass (Msun) */
659 const REAL8 lambda1, /**< dimensionless tidal deformability of companion 1*/
660 const REAL8 lambda2, /**< dimensionless tidal deformability of companion 2*/
661 const REAL8 PN_coeffs[10] /**< 7.5 PN coefficients*/
662 )
663{
664 REAL8 M_omega = LAL_PI * fHz * (mtot * LAL_MTSUN_SI); //dimensionless angular GW frequency
665
666 REAL8 Xb = 1.0 - Xa;
667
668 REAL8 PN_x = M_omega / cbrt(M_omega); // pow(M_omega, 2.0/3.0)
669 REAL8 PN_x_2 = PN_x * PN_x; // pow(PN_x, 2)
670 REAL8 PN_x_3over2 = PN_x * sqrt(PN_x); // pow(PN_x, 3.0/2.0)
671 REAL8 PN_x_5over2 = PN_x_3over2 * PN_x; // pow(PN_x, 5.0/2.0)
672
673 REAL8 kappaA = 3.0*Xb*Xa*Xa*Xa*Xa*lambda1;
674 REAL8 kappaB = 3.0*Xa*Xb*Xb*Xb*Xb*lambda2;
675
676 /* 7.5PN Coefficients */
677 REAL8 c_NewtA = PN_coeffs[0];
678 REAL8 c_1A = PN_coeffs[1];
679 REAL8 c_3over2A = PN_coeffs[2];
680 REAL8 c_2A = PN_coeffs[3];
681 REAL8 c_5over2A = PN_coeffs[4];
682
683 REAL8 c_NewtB = PN_coeffs[5];
684 REAL8 c_1B = PN_coeffs[6];
685 REAL8 c_3over2B = PN_coeffs[7];
686 REAL8 c_2B = PN_coeffs[8];
687 REAL8 c_5over2B = PN_coeffs[9];
688
689 REAL8 factorA = -c_NewtA*PN_x_5over2*kappaA;
690 REAL8 factorB = -c_NewtB*PN_x_5over2*kappaB;
691
692 REAL8 tidal_phasePNA = factorA*(1.0 + (c_1A*PN_x) + (c_3over2A*PN_x_3over2) + (c_2A*PN_x_2) + (c_5over2A*PN_x_5over2));
693 REAL8 tidal_phasePNB = factorB*(1.0 + (c_1B*PN_x) + (c_3over2B*PN_x_3over2) + (c_2B*PN_x_2) + (c_5over2B*PN_x_5over2));
694
695 REAL8 tidal_phasePN = tidal_phasePNA + tidal_phasePNB;
696
697 return tidal_phasePN;
698}
699
700/** Function to call amplitude tidal series only;
701 * done for convenience to use for PhenomD_NRTidalv2 and
702 * SEOBNRv4_ROM_NRTidalv2
703 */
704
706 const REAL8Sequence *amp_tidal, /**< [out] tidal amplitude frequency series */
707 const REAL8Sequence *fHz, /**< list of input Gravitational wave Frequency [Hz or dimensionless] */
708 REAL8 m1, /**< Mass of companion 1 in solar masses */
709 REAL8 m2, /**< Mass of companion 2 in solar masses */
710 REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
711 REAL8 lambda2 /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
712 )
713{
714 REAL8 m1_SI = m1 * LAL_MSUN_SI;
715 REAL8 m2_SI = m2 * LAL_MSUN_SI;
716 REAL8 f_dim_to_Hz;
717 int errcode = EnforcePrimaryMassIsm1(&m1_SI, &m2_SI, &lambda1, &lambda2);
718 XLAL_CHECK(XLAL_SUCCESS == errcode, errcode, "EnforcePrimaryMassIsm1 failed");
719
720 if( lambda1 < 0 || lambda2 < 0 )
721 XLAL_ERROR(XLAL_EFUNC, "lambda1 = %f, lambda2 = %f. Both should be greater than zero for NRTidal models", lambda1, lambda2);
722
723
724 const REAL8 mtot = m1 + m2;
725 /* SEOBNRv4ROM_NRTidalv2 and IMRPhenomD_NRTidalv2 deal with dimensionless freqs and freq in Hz;
726 * If the value corresponding to the last index is above 1, we are safe to assume a frequency given in Hz,
727 * otherwise a dimensionless frequency
728 */
729
730 if ((*fHz).data[(*fHz).length - 1] > 1.)
731 f_dim_to_Hz = 1.;
732 else
733 f_dim_to_Hz = mtot*LAL_MTSUN_SI;
734
735 /* tidal coupling constant.*/
736 const REAL8 kappa2T = XLALSimNRTunedTidesComputeKappa2T(m1_SI, m2_SI, lambda1, lambda2);
737
738 for(UINT4 i = 0; i < (*fHz).length; i++)
739 (*amp_tidal).data[i] = SimNRTunedTidesFDTidalAmplitude((*fHz).data[i]/f_dim_to_Hz, mtot, kappa2T);
740
741 return XLAL_SUCCESS;
742}
743
744/**
745 * Function to call the frequency domain tidal correction
746 * over an array of input frequencies. This is
747 * Equation (7) in arXiv:1706.02969 when NRTidal_version is NRTidal_V,
748 * or Equations (17)-(21) (for phasing) and Equation (24) (for amplitude)
749 * in arXiv:1905.06011 when NRTidal_version is NRTidalv2_V,
750 * or Equations (17)-(21) in arXiv:1905.06011 when NRTidal_version is NRTidalv2NoAmpCorr_V.
751 * NoNRT_V specifies NO tidal phasing or amplitude is being added.
752 * Note internally we use m1>=m2 - this is enforced in the code.
753 * So any can be supplied
754 *
755 * The model for the tidal phase correction in NRTidal_V/NRTidalv2_V was calibrated
756 * up to mass-ratio q=1.5 and kappa2T in [40, 5000].
757 * The upper kappa2T limit is reached roughly for a
758 * 1.4+1.4 BNS with lambda = 2700 on both NSs.
759 * In the high mass-ratio limit, the BNS merger frequency defined in
760 * XLALSimNRTunedTidesMergerFrequency() asymptotes to zero. The waveform
761 * amplitude should be tapered away starting at this frequency.
762 * Therefore, no explicit limits are enforced.
763 *
764 * We also include here NRTidalv3_V, which was calibrated
765 * up to mass ratio q = 2.0 and kappa2T in [40, 5000].
766 * The NRTidalv3 tidal phase is connected to the 7.5PN tidal phase to minimize the presence of asymptotes post-merger.
767 *
768 */
769
771 const REAL8Sequence *phi_tidal, /**< [out] tidal phase frequency series */
772 const REAL8Sequence *amp_tidal, /**< [out] tidal amplitude frequency series */
773 const REAL8Sequence *planck_taper, /**< [out] planck tapering to be applied on overall signal */
774 const REAL8Sequence *fHz, /**< list of input Gravitational wave Frequency in Hz to evaluate */
775 REAL8 m1_SI, /**< Mass of companion 1 (kg) */
776 REAL8 m2_SI, /**< Mass of companion 2 (kg) */
777 REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
778 REAL8 lambda2, /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
779 REAL8 chi1_AS, /**< aligned-spin component of mass 1*/
780 REAL8 chi2_AS, /**< aligned-spin component of mass 2*/
781 NRTidal_version_type NRTidal_version /** < one of NRTidal_V, NRTidalv2_V, NRTidalv3_V, NRTidalv3NoAmpCorr_V, NRTidalv2NoAmpCorr_V or NoNRT_V */
782 )
783{
784 /* NOTE: internally m1 >= m2
785 * This is enforced in the code below and we swap the lambda's
786 * accordingly. For NRTidalv3, we also swap the aligned spin components chi1_AS and chi2_AS, on which the new merger frequency fit is dependent.
787 */
788
789
790 int errcode = EnforcePrimaryMassIsm1_v3(&m1_SI, &m2_SI, &lambda1, &lambda2, &chi1_AS, &chi2_AS);
791 XLAL_CHECK(XLAL_SUCCESS == errcode, errcode, "EnforcePrimaryMassIsm1_v3 failed");
792
793 if( lambda1 < 0 || lambda2 < 0 )
794 XLAL_ERROR(XLAL_EFUNC, "lambda1 = %f, lambda2 = %f. Both should be greater than zero for NRTidal models", lambda1, lambda2);
795
796 const REAL8 m1 = m1_SI / LAL_MSUN_SI;
797 const REAL8 m2 = m2_SI / LAL_MSUN_SI;
798 const REAL8 mtot = m1 + m2;
799 const REAL8 q = m1 / m2;
800
801 /* Xa and Xb are the masses normalised for a total mass = 1 */
802 const REAL8 Xa = m1 / mtot;
803 const REAL8 Xb = m2 / mtot;
804
805 /* tidal coupling constant.*/
806 const REAL8 kappa2T = XLALSimNRTunedTidesComputeKappa2T(m1_SI, m2_SI, lambda1, lambda2);
807
808 /* Prepare tapering of amplitude beyond merger frequency */
809 const REAL8 fHz_mrg = XLALSimNRTunedTidesMergerFrequency(mtot, kappa2T, q);
810 const REAL8 fHz_mrg_v3 = XLALSimNRTunedTidesMergerFrequency_v3(mtot, lambda1, lambda2, q, chi1_AS, chi2_AS); //for NRTidalv3
811 const REAL8 fHz_end_taper = 1.2*fHz_mrg;
812 const REAL8 fHz_end_taper_v3 = 1.2*fHz_mrg_v3; //for NRTidalv3
813
814 if (NRTidal_version == NRTidal_V) {
815 for(UINT4 i = 0; i < (*fHz).length; i++){
816 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase((*fHz).data[i], Xa, Xb, mtot, kappa2T);
817 (*planck_taper).data[i] = 1.0 - PlanckTaper((*fHz).data[i], fHz_mrg, fHz_end_taper);
818 }
819 }
820 else if (NRTidal_version == NRTidalv2_V) {
821 for(UINT4 i = 0; i < (*fHz).length; i++) {
822 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase_v2((*fHz).data[i], Xa, Xb, mtot, kappa2T);
823 (*amp_tidal).data[i] = SimNRTunedTidesFDTidalAmplitude((*fHz).data[i], mtot, kappa2T);
824 (*planck_taper).data[i] = 1.0 - PlanckTaper((*fHz).data[i], fHz_mrg, fHz_end_taper);
825 }
826 }
827 else if (NRTidal_version == NRTidalv3_V) {
828 int indexmin = -1; //initiate an invalid index where one first finds a minimum
829 REAL8 PN_coeffs[10];
831 REAL8 NRTidalv3_coeffs[20];
832 XLALSimNRTunedTidesSetFDTidalPhase_v3_Coeffs(NRTidalv3_coeffs, Xa, mtot, lambda1, lambda2, PN_coeffs);
833 REAL8 fHzmrgcheck = 0.9 * fHz_mrg_v3; // start checking of minimum;
834 for (UINT4 i = 0; i < (*fHz).length; i++) {
835 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase_v3((*fHz).data[i], mtot, NRTidalv3_coeffs, PN_coeffs);
836 if ((*fHz).data[i] >= fHzmrgcheck && (*phi_tidal).data[i] >= (*phi_tidal).data[i-1]) {
837 indexmin = i - 1;
838 break;
839 }
840 }
841 if (indexmin != -1) { //If a minimum is found, the tidal phase will be constant at that minimum value
842 REAL8 tidal_min_value = (*phi_tidal).data[indexmin];
843 for (UINT4 i = indexmin + 1; i < (*fHz).length; i++) {
844 (*phi_tidal).data[i] = tidal_min_value;
845 }
846 }
847 for(UINT4 i = 0; i < (*fHz).length; i++) {
848 REAL8 planck_func = PlanckTaper((*fHz).data[i], 1.15*fHz_mrg_v3, 1.35*fHz_mrg_v3);
849 /* We employ here the smooth connection between NRTidal and PN post-merger, Eq. (45) of https://arxiv.org/pdf/2311.07456.pdf*/
850 (*phi_tidal).data[i] = (*phi_tidal).data[i]*(1.0 - planck_func) + SimNRTunedTidesFDTidalPhase_PN((*fHz).data[i], Xa, mtot, lambda1, lambda2, PN_coeffs)*planck_func;
851 (*amp_tidal).data[i] = SimNRTunedTidesFDTidalAmplitude((*fHz).data[i], mtot, kappa2T);
852 (*planck_taper).data[i] = 1.0 - PlanckTaper((*fHz).data[i], fHz_mrg_v3, fHz_end_taper_v3);
853 }
854 }
855 else if (NRTidal_version == NRTidalv2NSBH_V) {
856 for(UINT4 i = 0; i < (*fHz).length; i++) {
857 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase_v2((*fHz).data[i], Xa, Xb, mtot, kappa2T);
858 (*planck_taper).data[i] = 1.0;
859 }
860 }
861 else if (NRTidal_version == NRTidalv2NoAmpCorr_V) {
862 for(UINT4 i = 0; i < (*fHz).length; i++) {
863 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase_v2((*fHz).data[i], Xa, Xb, mtot, kappa2T);
864 (*planck_taper).data[i] = 1.0 - PlanckTaper((*fHz).data[i], fHz_mrg, fHz_end_taper);
865 }
866 }
867 else if (NRTidal_version == NRTidalv3NoAmpCorr_V) {
868 int indexmin = -1; //initiate an invalid index where one first finds a minimum
869 REAL8 PN_coeffs[10];
871 REAL8 NRTidalv3_coeffs[20];
872 XLALSimNRTunedTidesSetFDTidalPhase_v3_Coeffs(NRTidalv3_coeffs, Xa, mtot, lambda1, lambda2, PN_coeffs);
873 REAL8 fHzmrgcheck = 0.9 * fHz_mrg_v3; // start checking of minimum; if a minimum is found, the tidal phase will be constant at that minimum value
874 for (UINT4 i = 0; i < (*fHz).length; i++) {
875 (*phi_tidal).data[i] = SimNRTunedTidesFDTidalPhase_v3((*fHz).data[i], mtot, NRTidalv3_coeffs, PN_coeffs);
876 if ((*fHz).data[i] >= fHzmrgcheck && (*phi_tidal).data[i] >= (*phi_tidal).data[i-1]) {
877 indexmin = i - 1;
878 break;
879 }
880 }
881 if (indexmin != -1) { //If a minimum is found, the tidal phase will be constant at that minimum value
882 REAL8 tidal_min_value = (*phi_tidal).data[indexmin];
883 for (UINT4 i = indexmin + 1; i < (*fHz).length; i++) {
884 (*phi_tidal).data[i] = tidal_min_value;
885 }
886 }
887 for(UINT4 i = 0; i < (*fHz).length; i++) {
888 REAL8 planck_func = PlanckTaper((*fHz).data[i], 1.15*fHz_mrg_v3, 1.35*fHz_mrg_v3);
889 /* We employ here the smooth connection between NRTidal and PN post-merger, Eq. (45) of https://arxiv.org/pdf/2311.07456.pdf*/
890 (*phi_tidal).data[i] = (*phi_tidal).data[i]*(1.0 - planck_func) + SimNRTunedTidesFDTidalPhase_PN((*fHz).data[i], Xa, mtot, lambda1, lambda2, PN_coeffs)*planck_func;
891 (*planck_taper).data[i] = 1.0 - PlanckTaper((*fHz).data[i], fHz_mrg_v3, fHz_end_taper_v3);
892 }
893 }
894 else if (NRTidal_version == NoNRT_V)
895 XLAL_ERROR( XLAL_EINVAL, "Trying to add NRTides to a BBH waveform!" );
896 else
897 XLAL_ERROR( XLAL_EINVAL, "Unknown version of NRTidal being used! At present, NRTidal_V, NRTidalv2_V, NRTidalv2NSBH_V, NRTidalv2NoAmpCorr_V and NoNRT_V are the only known ones!" );
898
899 return XLAL_SUCCESS;
900}
901
902/**
903 * Function to add 3.5PN spin-squared and 3.5PN spin-cubed terms.
904 * The spin-squared terms occur with the spin-induced quadrupole moment terms
905 * while the spin-cubed terms occur with both spin-induced quadrupole as well as
906 * octupole moments. The terms are computed in arXiv:1806.01772 and are
907 * explicitly written out in Eq 27 of arXiv:1905.06011. The following terms
908 * are specifically meant for BNS systems, and are added to the NRTidalv2
909 * extensions of the approximants IMRPhenomPv2, IMRPhenomD and SEOBNRv4_ROM.
910 */
911
913 REAL8 *SS_3p5PN, /**< 3.5PN spin-spin tail term containing spin-induced quadrupole moment */
914 REAL8 *SSS_3p5PN, /**< 3.5 PN spin cubed term containing spin-induced octupole moment */
915 REAL8 X_A, /**< Mass fraction m_1/M for first component of binary */
916 REAL8 X_B, /**< Mass fraction m_2/M for second component of binary */
917 REAL8 chi1, /**< Aligned component of spin vector of first component of binary */
918 REAL8 chi2, /**< Aligned component of spin vector of second component of binary */
919 REAL8 quadparam1, /**< Spin-induced quadrupole moment parameter for component 1 */
920 REAL8 quadparam2 /**< Spin-induced quadrupole moment parameter for component 2 */
921 )
922{
923 REAL8 chi1_sq = 0., chi2_sq = 0.;
924 REAL8 X_Asq = 0., X_Bsq = 0.;
925 REAL8 octparam1 = 0, octparam2 = 0.;
926
927 X_Asq = X_A*X_A;
928 X_Bsq = X_B*X_B;
929
930 chi1_sq = chi1*chi1;
931 chi2_sq = chi2*chi2;
932
933 /* Remove -1 to account for BBH baseline*/
936
937 *SS_3p5PN = - 400.*LAL_PI*(quadparam1-1.)*chi1_sq*X_Asq - 400.*LAL_PI*(quadparam2-1.)*chi2_sq*X_Bsq;
938 *SSS_3p5PN = 10.*((X_Asq+308./3.*X_A)*chi1+(X_Bsq-89./3.*X_B)*chi2)*(quadparam1-1.)*X_Asq*chi1_sq
939 + 10.*((X_Bsq+308./3.*X_B)*chi2+(X_Asq-89./3.*X_A)*chi1)*(quadparam2-1.)*X_Bsq*chi2_sq
940 - 440.*octparam1*X_A*X_Asq*chi1_sq*chi1 - 440.*octparam2*X_B*X_Bsq*chi2_sq*chi2;
941}
double cosh(double)
static vector d(const double L_norm, const double J_norm, const vector roots)
Internal function that returns the coefficients "d_0", "d_2" and "d_4" from 1703.03967 corresponding ...
static double beta(const double a, const double b, const sysq *system)
Internal function that computes the spin-orbit couplings.
void XLALSimInspiralGetHOSpinTerms(REAL8 *SS_3p5PN, REAL8 *SSS_3p5PN, REAL8 X_A, REAL8 X_B, REAL8 chi1, REAL8 chi2, REAL8 quadparam1, REAL8 quadparam2)
Function to add 3.5PN spin-squared and 3.5PN spin-cubed terms.
static int EnforcePrimaryMassIsm1_v3(REAL8 *m1, REAL8 *m2, REAL8 *lambda1, REAL8 *lambda2, REAL8 *chi1_AS, REAL8 *chi2_AS)
function to swap masses, spins, and lambda to enforce m1 >= m2, This is mainly for NRTidalv3,...
static double SimNRTunedTidesFDTidalPhase_v3(const REAL8 fHz, const REAL8 mtot, const REAL8 NRTidalv3_coeffs[20], const REAL8 PN_coeffs[10])
Tidal phase correction for NRTidalv3, Eq.
static double SimNRTunedTidesFDTidalPhase_PN(const REAL8 fHz, const REAL8 Xa, const REAL8 mtot, const REAL8 lambda1, const REAL8 lambda2, const REAL8 PN_coeffs[10])
PN tidal phase correction, at 7.5PN, to connect with NRTidalv3 Phase post-merger, see Eq.
static REAL8 SimNRTunedTidesFDTidalAmplitude(const REAL8 fHz, const REAL8 mtot, const REAL8 kappa2T)
Tidal amplitude corrections; only available for NRTidalv2; Eq 24 of arxiv:1905.06011.
static REAL8 PlanckTaper(const REAL8 t, const REAL8 t1, const REAL8 t2)
Planck taper window.
static double SimNRTunedTidesFDTidalPhase_v2(const REAL8 fHz, const REAL8 Xa, const REAL8 Xb, const REAL8 mtot, const REAL8 kappa2T)
NRTunedTidesFDTidalPhase is Eq 22 of https://arxiv.org/abs/1905.06011 and is a function of x = angula...
static int EnforcePrimaryMassIsm1(REAL8 *m1, REAL8 *m2, REAL8 *lambda1, REAL8 *lambda2)
function to swap masses and lambda to enforce m1 >= m2
int XLALSimNRTunedTidesSetFDTidalPhase_PN_Coeffs(REAL8 *PN_coeffs, const REAL8 Xa)
Coefficients or the PN tidal phase correction, at 7.5PN, to connect with NRTidalv3 Phase post-merger,...
int XLALSimNRTunedTidesFDTidalPhaseFrequencySeries(const REAL8Sequence *phi_tidal, const REAL8Sequence *amp_tidal, const REAL8Sequence *planck_taper, const REAL8Sequence *fHz, REAL8 m1_SI, REAL8 m2_SI, REAL8 lambda1, REAL8 lambda2, REAL8 chi1_AS, REAL8 chi2_AS, NRTidal_version_type NRTidal_version)
Function to call the frequency domain tidal correction over an array of input frequencies.
double XLALSimNRTunedTidesMergerFrequency_v3(const REAL8 mtot_MSUN, REAL8 lambda1, REAL8 lambda2, const REAL8 q, REAL8 chi1_AS, REAL8 chi2_AS)
compute the merger frequency of a BNS system for NRTidalv3 (https://arxiv.org/pdf/2311....
int XLALSimNRTunedTidesSetFDTidalPhase_v2_Coeffs(REAL8 *NRTidalv2_coeffs)
Set the NRTidalv2 phase coefficients in an array for use here and in the IMRPhenomX*_NRTidalv2 implem...
double XLALSimNRTunedTidesMergerFrequency(const REAL8 mtot_MSUN, const REAL8 kappa2T, const REAL8 q)
compute the merger frequency of a BNS system.
static double SimNRTunedTidesFDTidalPhase(const REAL8 fHz, const REAL8 Xa, const REAL8 Xb, const REAL8 mtot, const REAL8 kappa2T)
Internal function only.
int XLALSimNRTunedTidesFDTidalAmplitudeFrequencySeries(const REAL8Sequence *amp_tidal, const REAL8Sequence *fHz, REAL8 m1, REAL8 m2, REAL8 lambda1, REAL8 lambda2)
Function to call amplitude tidal series only; done for convenience to use for PhenomD_NRTidalv2 and S...
double XLALSimNRTunedTidesComputeKappa2T(REAL8 m1_SI, REAL8 m2_SI, REAL8 lambda1, REAL8 lambda2)
convenient function to compute tidal coupling constant.
int XLALSimNRTunedTidesSetFDTidalPhase_v3_Coeffs(REAL8 *NRTidalv3_coeffs, const REAL8 Xa, const REAL8 mtot, const REAL8 lambda1, const REAL8 lambda2, const REAL8 PN_coeffs[10])
Set the NRTidalv3 effective love number and phase coefficients in an array for use here and in the IM...
REAL8 XLALSimUniversalRelationSpinInducedOctupoleVSSpinInducedQuadrupole(REAL8 qm_def)
double i
Definition: bh_ringdown.c:118
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_TWOPI
#define LAL_MTSUN_SI
double REAL8
uint32_t UINT4
NRTidal_version_type
Definition: LALSimIMR.h:80
@ NRTidalv2NoAmpCorr_V
version NRTidalv2, without amplitude corrections
Definition: LALSimIMR.h:84
@ NRTidalv3_V
version NRTidalv3
Definition: LALSimIMR.h:83
@ NRTidal_V
version NRTidal: based on https://arxiv.org/pdf/1706.02969.pdf
Definition: LALSimIMR.h:81
@ NoNRT_V
special case for PhenomPv2 BBH baseline
Definition: LALSimIMR.h:87
@ NRTidalv3NoAmpCorr_V
version NRTidalv3, without amplitude corrections
Definition: LALSimIMR.h:85
@ NRTidalv2NSBH_V
version NRTidalv2: https://arxiv.org/abs/1905.06011 with amplitude corrections for NSBH (used for SEO...
Definition: LALSimIMR.h:86
@ NRTidalv2_V
version NRTidalv2: https://arxiv.org/abs/1905.06011
Definition: LALSimIMR.h:82
static const INT4 q
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFUNC
XLAL_EDOM
XLAL_EINVAL
x
double alpha
Definition: sgwb.c:106