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
LALSimIMRLackeyTidal2013.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Michael Puerrer, Prayush Kumar
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19
20#ifdef __GNUC__
21#define UNUSED __attribute__ ((unused))
22#else
23#define UNUSED
24#endif
25
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <math.h>
30#include <complex.h>
31
32#include <lal/Units.h>
33#include <lal/SeqFactories.h>
34#include <lal/LALConstants.h>
35#include <lal/XLALError.h>
36#include <lal/FrequencySeries.h>
37#include <lal/Sequence.h>
38#include <lal/LALSimIMR.h>
39
41
42
43/*************** Model coefficients ******************/
44
45// Amplitude correction factors for SEOBNRv2
46// Define constants as per Eq 33 of Lackey et al, arXiv:1303.6298.
47const double b0 = -1424.2;
48const double b1 = 6423.4;
49const double b2 = 0.84203;
50const double c0 = -9.7628;
51const double c1 = 33.939;
52const double c2 = 1.0971;
53// Phase correction factors
54const double g0 = -4.6339;
55const double g1 = 27.719;
56const double g2 = 10.268;
57const double g3 = -41.741;
58
59
60/********************* Definitions begin here ********************/
61
63 double *C,
64 const double eta,
65 const double chi_BH,
66 const double Lambda
67) {
68 // Coefficient in the amplitude factor, Eq 33 of Lackey et al
69 *C = exp(b0 + b1*eta + b2*chi_BH)
70 + Lambda * exp(c0 + c1*eta + c2*chi_BH);
71}
72
74 const double Mf,
75 const double C,
76 const double eta,
77 const double Lambda
78) {
79 const double MfA = 0.01; // amplitude transition frequency
80 if (Mf <= MfA)
81 return 1.0;
82 else {
83 // Generate the amplitude factor, Eq 33 of Lackey et al
84 double dMf = Mf - MfA;
85 double dMf2 = dMf*dMf;
86 double B = C * dMf*dMf2;
87 return exp(-eta * Lambda * B);
88 }
89}
90
91// precompute a0, a1 and G which do not depend on frequency
93 double *a0,
94 double *a1,
95 double *G,
96 const double eta,
97 const double chi_BH,
98 const double Lambda
99) {
100 // First compute the PN inspiral phasing correction
101 // see Eq. 7,8 of Lackey et al
102 double eta2 = eta*eta;
103 double eta3 = eta2*eta;
104 double SqrtOneMinus4Eta = sqrt(1.-4.*eta);
105
106 *a0 = -12 * Lambda * ((1 + 7.*eta - 31*eta2)
107 - SqrtOneMinus4Eta * (1 + 9.*eta - 11*eta2));
108 *a1 = -(585.*Lambda/28.)
109 * ((1. + 3775.*eta/234. - 389.*eta2/6. + 1376.*eta3/117.)
110 - SqrtOneMinus4Eta*(1 + 4243.*eta/234. - 6217*eta2/234. - 10.*eta3/9.));
111
112 *G = exp(g0 + g1*eta + g2*chi_BH + g3*eta*chi_BH); // Eq 35 of Lackey et al
113}
114
115static double tidalPNPhase(
116 const double Mf,
117 const double a0,
118 const double a1,
119 const double eta
120) {
121 // First compute the PN inspiral phasing correction
122 // see Eq. 7,8 of Lackey et al
123 double v = cbrt(LAL_PI * Mf);
124 double v2 = v*v;
125 double v5 = v2*v2*v;
126 double v7 = v5*v2;
127 return 3.*(a0*v5 + a1*v7) / (128.*eta);
128}
129
130static double tidalPNPhaseDeriv(
131 const double Mf,
132 const double a0,
133 const double a1,
134 const double eta
135) {
136 // First compute the PN inspiral phasing correction
137 // see Eq. 7,8 of Lackey et al
138 double v = cbrt(LAL_PI * Mf);
139 double v2 = v*v;
140 double v4 = v2*v2;
141 return LAL_PI * (5.*a0*v2 + 7.*a1*v4) / (128.*eta);
142}
143
144// Implements Eq. 34 of Lackey et al
146 const double Mf,
147 const double a0,
148 const double a1,
149 const double G,
150 const double eta,
151 const double Lambda
152)
153{
154 const double MfP = 0.02; // phase transition frequency
155
156 if (Mf <= MfP)
157 return tidalPNPhase(Mf, a0, a1, eta);
158
159 // Beyond the phase transition frequency we evaluate the tidal phase
160 // and its derivative at the transition frequency
161 double psiT = tidalPNPhase(MfP, a0, a1, eta);
162 double DpsiT= (Mf - MfP) * tidalPNPhaseDeriv(MfP, a0, a1, eta);
163 // Now compute the phenomenological term
164 double E = G * pow(Mf - MfP, 5./3.); // Eq 35 of Lackey et al
165 double psiFit = eta * Lambda * E;
166 return psiT + DpsiT - psiFit; // Eq 34 of Lackey et al
167}
168
170 struct tagCOMPLEX16FrequencySeries **hptilde, /**< Output: Frequency-domain waveform h+ */
171 struct tagCOMPLEX16FrequencySeries **hctilde, /**< Output: Frequency-domain waveform hx */
172 REAL8 phiRef, /**< Phase at reference time */
173 REAL8 fRef, /**< Reference frequency (Hz); 0 defaults to fLow */
174 REAL8 distance, /**< Distance of source (m) */
175 REAL8 inclination, /**< Inclination of source (rad) */
176 REAL8 mBH_SI, /**< Mass of black hole (kg) */
177 REAL8 mNS_SI, /**< Mass of neutron star (kg) */
178 REAL8 chi_BH, /**< Dimensionless aligned component spin of the BH */
179 REAL8 Lambda, /**< Dimensionless tidal deformability (Eq 1 of Lackey et al) */
180 const REAL8Sequence *freqs_in, /**< Frequency points at which to evaluate the waveform (Hz) */
181 REAL8 deltaF /**< Sampling frequency (Hz) */
182)
183{
184 /* Check output arrays */
185 if(!hptilde || !hctilde)
187 if(*hptilde || *hctilde) {
188 XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde));
190 }
191
192 if (!freqs_in) XLAL_ERROR(XLAL_EFAULT);
193 double fLow = freqs_in->data[0];
194 double fHigh = freqs_in->data[freqs_in->length - 1];
195 if(fRef == 0.0)
196 fRef = fLow;
197
198 double mBH = mBH_SI / LAL_MSUN_SI;
199 double mNS = mNS_SI / LAL_MSUN_SI;
200 double M = mBH + mNS;
201 double eta = mBH * mNS / (M*M); /* Symmetric mass-ratio */
202 double Mtot_sec = M * LAL_MTSUN_SI; /* Total mass in seconds */
203 double chi_NS = 0; // NS has zero spin
204
205 // Impose sanity checks and cutoffs on mass-ratio, and BH spins
206 if (mBH < mNS) XLAL_ERROR(XLAL_EDOM, "mBH = %g < mNS = %g ! ", mBH, mNS);
207 if ((eta < 5./36.) || (eta > 2./9.)) XLAL_ERROR(XLAL_EDOM,
208 "eta = %g is not in allowed range 5/36 < eta < 2/9 (5 < q < 2)!", eta);
209 if (chi_BH > 0.5) XLAL_ERROR(XLAL_EDOM, "BH spin = %g > 0.5!", chi_BH);
210 if (chi_BH < -0.5) XLAL_ERROR(XLAL_EDOM, "BH spin = %g < -0.5!", chi_BH);
211 if ((Lambda < 0) || (Lambda > 4382)) XLAL_ERROR(XLAL_EDOM,
212 "Dimensionless tidal deformability = %g is not in allowed range [0, 4382]!", Lambda);
213
214 // Call the high-resolution SEOBNRv2 ROM that can go to very low total mass
215 // We call either the FrequencySequence version or the regular LAL version depending on how we've been called.
216 int ret = XLAL_SUCCESS;
217 if (deltaF > 0)
219 hptilde, hctilde,
220 phiRef, deltaF, fLow, fHigh, fRef, distance, inclination,
221 mBH_SI, mNS_SI,
222 chi_BH, chi_NS,
223 -1);
224 else
226 hptilde, hctilde,
227 freqs_in,
228 phiRef, fRef, distance, inclination,
229 mBH_SI, mNS_SI,
230 chi_BH, chi_NS,
231 -1);
232 XLAL_CHECK(XLAL_SUCCESS == ret, ret, "XLALSimIMRSEOBNRv2ROMDoubleSpinHI() failed.");
233
234 UINT4 offset;
235 REAL8Sequence *freqs = NULL;
236 if (deltaF > 0) { // uniform frequencies
237 // Recreate freqs using only the lower and upper bounds
238 UINT4 iStart = (UINT4) ceil(fLow / deltaF);
239 UINT4 iStop = (*hptilde)->data->length - 1; // use the length calculated in the ROM function
240 freqs = XLALCreateREAL8Sequence(iStop - iStart);
241 if (!freqs) XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
242 double deltaF_geom = deltaF * Mtot_sec;
243 for (UINT4 i=iStart; i<iStop; i++)
244 freqs->data[i-iStart] = i*deltaF_geom;
245
246 offset = iStart;
247 }
248 else { // unequally spaced frequency sequence
249 freqs = XLALCreateREAL8Sequence(freqs_in->length);
250 if (!freqs) XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
251 for (UINT4 i=0; i<freqs_in->length; i++)
252 freqs->data[i] = freqs_in->data[i] * Mtot_sec; // just copy input and convert to geometric frequency
253 offset = 0;
254 }
255 COMPLEX16 *pdata=(*hptilde)->data->data;
256 COMPLEX16 *cdata=(*hctilde)->data->data;
257
258 // Precompute coefficients that do not depend on frequency
259 double C, a0, a1, G;
260 tidalPNAmplitudeCoefficient(&C, eta, chi_BH, Lambda);
261 tidalPNPhaseCoefficients(&a0, &a1, &G, eta, chi_BH, Lambda);
262
263 // Assemble waveform from aplitude and phase
264 for (size_t i=0; i<freqs->length; i++) { // loop over frequency points in sequence
265 double Mf = freqs->data[i];
266 int j = i + offset; // shift index for frequency series if needed
267 // Tidal corrections to be incorporated
268 double ampC = tidalCorrectionAmplitude(Mf, C, eta, Lambda);
269 double phsC = tidalCorrectionPhase(Mf, a0, a1, G, eta, Lambda);
270 COMPLEX16 Corr = ampC * cexp(-I*phsC);
271 pdata[j] *= Corr;
272 cdata[j] *= Corr;
273 }
274
276
277 return XLAL_SUCCESS;
278}
279
280/**
281 * @addtogroup LALSimIMRTidal_c
282 *
283 * @{
284 *
285 * @name Lackey et al (2013) tidal model based on SEOBNRv2_ROM
286 *
287 * @author Michael Puerrer, Prayush Kumar
288 *
289 * @brief C code for Lackey et al arXiv:1303.6298 tidal model.
290 *
291 * This is a frequency domain model that adds tidal modifications of amplitude and phasing
292 * to the SEOBNRv2 model. Instead of SEOBNRv2, we use the high resolution ROM.
293 *
294 * @note Parameter ranges:
295 * * 5/36 <= eta <= 2/9 (5 <= q <= 2)
296 * * -0.5 <= chi_BH <= 0.5 [calibration region]
297 * * Lambda_NS <= 4382
298 * * Mtot >= 2 Msun @ 10 Hz (inherited from the ROM)
299 *
300 * Aligned component spin on black hole chi_BH. The NS is assumed to be non-spinning.
301 * Symmetric mass-ratio eta = m1*m2/(m1+m2)^2.
302 * Total mass Mtot.
303 *
304 * @{
305 */
306
307
308/**
309 * Compute waveform in LAL format at specified frequencies for the Lackey et al (2013)
310 * tidal model based on SEOBNRv2_ROM_DoubleSpin_HI.
311 *
312 * XLALSimIMRLackeyTidal2013() returns the plus and cross polarizations as a complex
313 * frequency series with equal spacing deltaF and contains zeros from zero frequency
314 * to the starting frequency and zeros beyond the cutoff frequency in the ringdown.
315 *
316 * In contrast, XLALSimIMRLackeyTidal2013FrequencySequence() returns a
317 * complex frequency series with entries exactly at the frequencies specified in
318 * the sequence freqs (which can be unequally spaced). No zeros are added.
319 *
320 * If XLALSimIMRLackeyTidal2013FrequencySequence() is called with frequencies that
321 * are beyond the maxium allowed geometric frequency for the ROM, zero strain is returned.
322 * It is not assumed that the frequency sequence is ordered.
323 *
324 * This function is designed as an entry point for reduced order quadratures.
325 */
327 struct tagCOMPLEX16FrequencySeries **hptilde, /**< Output: Frequency-domain waveform h+ */
328 struct tagCOMPLEX16FrequencySeries **hctilde, /**< Output: Frequency-domain waveform hx */
329 const REAL8Sequence *freqs, /**< Frequency points at which to evaluate the waveform (Hz) */
330 REAL8 phiRef, /**< Phase at reference time */
331 REAL8 fRef, /**< Reference frequency (Hz); 0 defaults to fLow */
332 REAL8 distance, /**< Distance of source (m) */
333 REAL8 inclination, /**< Inclination of source (rad) */
334 REAL8 mBH_SI, /**< Mass of black hole (kg) */
335 REAL8 mNS_SI, /**< Mass of neutron star (kg) */
336 REAL8 chi_BH, /**< Dimensionless aligned component spin of the BH */
337 REAL8 Lambda) /**< Dimensionless tidal deformability (Eq 1 of Lackey et al) */
338{
339 if (!freqs) XLAL_ERROR(XLAL_EFAULT);
340
341 // Call the internal core function with deltaF = 0 to indicate that freqs is non-uniformly
342 // spaced and we want the strain only at these frequencies
343 int retcode = LackeyTidal2013SEOBNRv2ROMCore(hptilde, hctilde,
344 phiRef, fRef, distance, inclination, mBH_SI, mNS_SI, chi_BH, Lambda, freqs, 0);
345
346 return(retcode);
347}
348
349/**
350 * Compute waveform in LAL format for the Lackey et al (2013) tidal model based on
351 * SEOBNRv2_ROM_DoubleSpin_HI.
352 *
353 * Returns the plus and cross polarizations as a complex frequency series with
354 * equal spacing deltaF and contains zeros from zero frequency to the starting
355 * frequency fLow and zeros beyond the cutoff frequency in the ringdown.
356 */
358 struct tagCOMPLEX16FrequencySeries **hptilde, /**< Output: Frequency-domain waveform h+ */
359 struct tagCOMPLEX16FrequencySeries **hctilde, /**< Output: Frequency-domain waveform hx */
360 REAL8 phiRef, /**< Phase at reference time */
361 REAL8 deltaF, /**< Sampling frequency (Hz) */
362 REAL8 fLow, /**< Starting GW frequency (Hz) */
363 REAL8 fHigh, /**< End frequency; 0 defaults to Mf=0.14 */
364 REAL8 fRef, /**< Reference frequency (Hz); 0 defaults to fLow */
365 REAL8 distance, /**< Distance of source (m) */
366 REAL8 inclination, /**< Inclination of source (rad) */
367 REAL8 mBH_SI, /**< Mass of black hole (kg) */
368 REAL8 mNS_SI, /**< Mass of neutron star (kg) */
369 REAL8 chi_BH, /**< Dimensionless aligned component spin of the BH */
370 REAL8 Lambda /**< Dimensionless tidal deformability (Eq 1 of Lackey et al) */
371) {
372 // Use fLow, fHigh, deltaF to compute freqs sequence
373 // Instead of building a full sequence we only transfer the boundaries and let
374 // the internal core function do the rest (and properly take care of corner cases).
376 freqs->data[0] = fLow;
377 freqs->data[1] = fHigh;
378
379 int retcode = LackeyTidal2013SEOBNRv2ROMCore(hptilde, hctilde,
380 phiRef, fRef, distance, inclination, mBH_SI, mNS_SI, chi_BH, Lambda, freqs, deltaF);
381
383
384 return(retcode);
385}
386
387/** @} */
388/** @} */
const double b1
static void tidalPNPhaseCoefficients(double *a0, double *a1, double *G, const double eta, const double chi_BH, const double Lambda)
static double tidalCorrectionAmplitude(const double Mf, const double C, const double eta, const double Lambda)
static double tidalPNPhaseDeriv(const double Mf, const double a0, const double a1, const double eta)
static void tidalPNAmplitudeCoefficient(double *C, const double eta, const double chi_BH, const double Lambda)
const double c1
const double g3
const double b2
const double b0
const double g2
const double g0
const double g1
const double c2
static double tidalCorrectionPhase(const double Mf, const double a0, const double a1, const double G, const double eta, const double Lambda)
int LackeyTidal2013SEOBNRv2ROMCore(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 mBH_SI, REAL8 mNS_SI, REAL8 chi_BH, REAL8 Lambda, const REAL8Sequence *freqs_in, REAL8 deltaF)
const double c0
static double tidalPNPhase(const double Mf, const double a0, const double a1, const double eta)
#define G
REAL8 M
Definition: bh_qnmode.c:133
double i
Definition: bh_ringdown.c:118
const double Lambda
const double B
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_MTSUN_SI
double complex COMPLEX16
double REAL8
uint32_t UINT4
int XLALSimIMRSEOBNRv2ROMDoubleSpinHI(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, INT4 nk_max)
Compute waveform in LAL format for the SEOBNRv2_ROM_DoubleSpin_HI model.
int XLALSimIMRSEOBNRv2ROMDoubleSpinHIFrequencySequence(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs, REAL8 phiRef, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, INT4 nk_max)
Compute waveform in LAL format at specified frequencies for the SEOBNRv2_ROM_DoubleSpin_HI model.
int XLALSimIMRLackeyTidal2013(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 mBH_SI, REAL8 mNS_SI, REAL8 chi_BH, REAL8 Lambda)
Compute waveform in LAL format for the Lackey et al (2013) tidal model based on SEOBNRv2_ROM_DoubleSp...
int XLALSimIMRLackeyTidal2013FrequencySequence(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs, REAL8 phiRef, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 mBH_SI, REAL8 mNS_SI, REAL8 chi_BH, REAL8 Lambda)
Compute waveform in LAL format at specified frequencies for the Lackey et al (2013) tidal model based...
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EDOM
REAL8 * data