20 #ifndef _LALSIMIMRSPINPRECEOBv4P_C
21 #define _LALSIMIMRSPINPRECEOBv4P_C
35 #include <gsl/gsl_deriv.h>
37 #include <lal/LALSimInspiral.h>
38 #include <lal/LALSimIMR.h>
40 #include <lal/TimeSeries.h>
41 #include <lal/LALAdaptiveRungeKuttaIntegrator.h>
42 #include <lal/SphericalHarmonics.h>
43 #include <gsl/gsl_integration.h>
44 #include <gsl/gsl_sf_gamma.h>
45 #include <lal/Units.h>
46 #include <lal/VectorOps.h>
82 #define UNUSED __attribute__ ((unused))
90 #define _SEOB_MODES_LMAX 5
105 #define v4PdynamicsVariables 26
108 if (ICvalues != NULL) \
109 XLALDestroyREAL8Vector(ICvalues); \
110 if (dynamicsAdaS != NULL) \
111 XLALDestroyREAL8Array(dynamicsAdaS); \
112 if (seobdynamicsAdaS != NULL) \
113 SEOBdynamics_Destroy(seobdynamicsAdaS); \
114 if (seobvalues_tstartHiS != NULL) \
115 XLALDestroyREAL8Vector(seobvalues_tstartHiS); \
116 if (ICvaluesHiS != NULL) \
117 XLALDestroyREAL8Vector(ICvaluesHiS); \
118 if (dynamicsHiS != NULL) \
119 XLALDestroyREAL8Array(dynamicsHiS); \
120 if (chi1L_tPeakOmega != NULL) \
121 XLALDestroyREAL8Vector(chi1L_tPeakOmega); \
122 if (chi2L_tPeakOmega != NULL) \
123 XLALDestroyREAL8Vector(chi2L_tPeakOmega); \
124 if (seobdynamicsHiS != NULL) \
125 SEOBdynamics_Destroy(seobdynamicsHiS); \
126 if (seobvalues_tPeakOmega != NULL) \
127 XLALDestroyREAL8Vector(seobvalues_tPeakOmega); \
128 if (Jfinal != NULL) \
129 XLALDestroyREAL8Vector(Jfinal); \
130 if (listhPlm_HiS != NULL) \
131 SphHarmListCAmpPhaseSequence_Destroy(listhPlm_HiS); \
132 if (listhPlm_HiSRDpatch != NULL) \
133 SphHarmListCAmpPhaseSequence_Destroy(listhPlm_HiSRDpatch); \
134 if (listhPlm_AdaS != NULL) \
135 SphHarmListCAmpPhaseSequence_Destroy(listhPlm_AdaS); \
136 if (*tVecPmodes != NULL) \
137 XLALDestroyREAL8Vector(*tVecPmodes); \
138 if (seobdynamicsAdaSHiS != NULL) \
139 SEOBdynamics_Destroy(seobdynamicsAdaSHiS); \
140 if (listhPlm != NULL) \
141 SphHarmListCAmpPhaseSequence_Destroy(listhPlm); \
142 if (*hP22_amp != NULL) \
143 XLALDestroyREAL8Vector(*hP22_amp); \
144 if (*hP22_phase != NULL) \
145 XLALDestroyREAL8Vector(*hP22_phase); \
146 if (*hP21_amp != NULL) \
147 XLALDestroyREAL8Vector(*hP21_amp); \
148 if (*hP21_phase != NULL) \
149 XLALDestroyREAL8Vector(*hP21_phase); \
150 if (*alphaJ2P != NULL) \
151 XLALDestroyREAL8Vector(*alphaJ2P); \
152 if (*betaJ2P != NULL) \
153 XLALDestroyREAL8Vector(*betaJ2P); \
154 if (*gammaJ2P != NULL) \
155 XLALDestroyREAL8Vector(*gammaJ2P); \
157 XLALDestroySphHarmTimeSeries(*hJlm); \
159 XLALDestroySphHarmTimeSeries(*hIlm); \
160 if (hplusTS != NULL) \
161 XLALDestroyREAL8TimeSeries(hplusTS); \
162 if (hcrossTS != NULL) \
163 XLALDestroyREAL8TimeSeries(hcrossTS); \
164 if (*mergerParams != NULL) \
165 XLALDestroyREAL8Vector(*mergerParams); \
166 if (*seobdynamicsAdaSVector != NULL) \
167 XLALDestroyREAL8Vector(*seobdynamicsAdaSVector); \
168 if (*seobdynamicsHiSVector != NULL) \
169 XLALDestroyREAL8Vector(*seobdynamicsHiSVector); \
170 if (*seobdynamicsAdaSHiSVector != NULL) \
171 XLALDestroyREAL8Vector(*seobdynamicsAdaSHiSVector);
172 #define PRINT_ALL_PARAMS \
175 "--approximant SEOBNRv4P --f-min %.16e --m1 %.16e --m2 %.16e " \
176 "--spin1x %.16e --spin1y %.16e --spin1z %.16e --spin2x %.16e " \
177 "--spin2y %.16e --spin2z %.16e --inclination %.16e --distance %.16e " \
178 "--phiRef %.16e --sample-rate %.16e\n", \
179 fMin, m1SI / LAL_MSUN_SI, m2SI / LAL_MSUN_SI, chi1x, chi1y, chi1z, \
180 chi2x, chi2y, chi2z, inc, r / (1e6 * LAL_PC_SI), phi, 1. / INdeltaT); \
193 *freqMinRad = pow(10.5, -1.5) / (
LAL_PI * mTScaled);
202 if (vec->
data[
i] > max) {
213 UINT4 size = hi - lo;
215 for (
UINT4 jj = 0; jj < size; jj++) {
216 slice->
data[jj] = vec->
data[lo + jj];
229 UINT4 window_width) {
232 UINT4 local_argmax = 0;
233 UINT4 idx_global = 0;
237 UNUSED
REAL8 global_max = quantVec->
data[global_arg_max];
240 for (
UINT4 kk = vlen - window_width - 1; kk > window_width; kk--) {
241 lo = kk - window_width;
242 hi = kk + window_width +
245 local_argmax =
argmax(sl);
246 if (sl->
data[local_argmax] > sl->
data[0] &&
250 if (sl->
data[local_argmax] > curr_max) {
251 curr_max = sl->
data[local_argmax];
252 idx_global = lo + local_argmax;
264 if (idx_global == 0 ||
265 ((quantVec->
data[global_arg_max] - quantVec->
data[idx_global]) /
266 quantVec->
data[idx_global] >
268 (idx_global > tVec->
length - 4)) {
277 gsl_spline *spline = NULL;
278 gsl_interp_accel *acc = NULL;
279 spline = gsl_spline_alloc(gsl_interp_cspline, quantVec->
length);
280 acc = gsl_interp_accel_alloc();
282 REAL8 time1 = tVec->
data[idx_global - 3];
283 REAL8 time2 = tVec->
data[idx_global + 3];
285 REAL8 omegaDerivMid = 0;
286 gsl_spline_init(spline, tVec->
data, quantVec->
data, quantVec->
length);
287 REAL8 omegaDeriv1 = gsl_spline_eval_deriv(spline, time1, acc);
289 timePeak = (time1 + time2) / 2.;
290 omegaDerivMid = gsl_spline_eval_deriv(spline, timePeak, acc);
292 if (omegaDerivMid * omegaDeriv1 < 0.0) {
295 omegaDeriv1 = omegaDerivMid;
298 }
while (time2 - time1 > 1.0e-8);
299 *tPeakQuant = timePeak;
300 gsl_spline_free(spline);
301 gsl_interp_accel_free(acc);
310 const double values[],
312 void UNUSED *funcParams) {
318 REAL8 p[3],
r[3], pdotVec[3], rdotVec[3];
319 REAL8 omega, omega_xyz[3];
321 memcpy(
r, values, 3 *
sizeof(
REAL8));
322 memcpy(
p, values + 3, 3 *
sizeof(
REAL8));
323 memcpy(rdotVec, dvalues, 3 *
sizeof(
REAL8));
324 memcpy(pdotVec, dvalues + 3, 3 *
sizeof(
REAL8));
329 counter =
params->eobParams->omegaPeaked;
330 if (
r2 < 36. && omega < params->eobParams->omega) {
331 params->eobParams->omegaPeaked = counter + 1;
334 if (
params->eobParams->omegaPeaked == 5) {
337 for (
i = 0;
i < 12;
i++) {
338 if (isnan(dvalues[
i]) || isnan(values[
i])) {
339 params->termination_reason = -1;
343 params->eobParams->omega = omega;
353 void UNUSED *funcParams) {
355 int debugPKverbose = 0;
360 REAL8 p[3],
r[3], pdotVec[3], rdotVec[3];
361 REAL8 omega, omega_xyz[3], L[3], dLdt1[3], dLdt2[3];
363 memcpy(
r, values, 3 *
sizeof(
REAL8));
364 memcpy(
p, values + 3, 3 *
sizeof(
REAL8));
365 memcpy(rdotVec, dvalues, 3 *
sizeof(
REAL8));
366 memcpy(pdotVec, dvalues + 3, 3 *
sizeof(
REAL8));
378 "XLALEOBSpinPrecStopConditionBasedOnPR:: values = %e %e %e %e %e %e\n",
379 values[6], values[7], values[8], values[9], values[10], values[11]);
383 "XLALEOBSpinPrecStopConditionBasedOnPR:: dvalues = %e %e %e %e %e %e\n",
384 dvalues[6], dvalues[7], dvalues[8], dvalues[9], dvalues[10],
421 for (
i = 0;
i < 12;
i++) {
422 if (isnan(dvalues[
i]) || isnan(values[
i])) {
427 XLALPrintError(
"XLAL Error - %s: nan reached at r2 = %f \n", __func__,
430 params->termination_reason = -1;
440 if (r2 < 16 && pDotr >= 0) {
443 "\n Integration stopping, p_r pointing outwards -- out-spiraling!\n");
446 params->termination_reason = 0;
452 if (r2 < 16 && rdot >= 0) {
454 XLAL_PRINT_INFO(
"\n Integration stopping, dr/dt>0 -- out-spiraling!\n");
457 params->termination_reason = 1;
464 if (r2 < 4. && prDot > 0.) {
470 params->termination_reason = 2;
475 if (
r2 < 16. && (sqrt(values[3] * values[3] + values[4] * values[4] +
476 values[5] * values[5]) > 10.)) {
480 params->termination_reason = 3;
485 if (
r2 < 16. && (sqrt(values[3] * values[3] + values[4] * values[4] +
486 values[5] * values[5]) < 1.e-10)) {
490 params->termination_reason = 4;
499 if (
r2 < 16. && omega < params->eobParams->omega)
500 params->eobParams->omegaPeaked = 1;
503 if (r2 < 4. && params->eobParams->omegaPeaked == 1 &&
504 omega >
params->eobParams->omega) {
507 "\n Integration stopping, omega reached second extremum\n");
510 params->termination_reason = 5;
517 if ((
r2 < 16. && omega < 0.04) ||
518 (
r2 < 4. && omega < 0.14 && params->eobParams->omegaPeaked == 1)) {
521 "omega=%f at r = %f\n",
525 params->termination_reason = 6;
530 if (r2 < 16. && omega > 1.) {
535 params->termination_reason = 7;
539 params->eobParams->omega = omega;
546 if (
r2 < 25 && (fabs(dvalues[3]) > 10 || fabs(dvalues[4]) > 10 ||
547 fabs(dvalues[5]) > 10)) {
552 params->termination_reason = 8;
558 if (
r2 < 16. && values[5] > 10) {
563 params->termination_reason = 9;
568 if (r2 < 9. && rdot >
params->prev_dr) {
574 params->termination_reason = 10;
585 if (debugPKverbose &&
r2 < 16.) {
586 XLAL_PRINT_INFO(
"%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f\n", t,
587 values[0], values[1], values[2], values[3], values[4],
588 values[5], values[6], values[7], values[8], values[9],
589 values[10], values[11], values[12], values[13], omega);
605 const double values[],
619 if (
r < 6. && omega < params->eobParams->omega) {
623 params->eobParams->omega = omega;
632 const double UNUSED values[],
634 void UNUSED *funcParams
642 counter =
params->eobParams->omegaPeaked;
644 if (
r < 6. && omega < params->eobParams->omega) {
646 params->eobParams->omegaPeaked = counter + 1;
648 if (dvalues[2] >= 0. ||
params->eobParams->omegaPeaked == 5 ||
649 isnan(dvalues[3]) || isnan(dvalues[2]) || isnan(dvalues[1]) ||
654 params->eobParams->omega = omega;
664 UINT4 PrecEOBversion) {
695 UINT4 PrecEOBversion) {
700 const UINT4 lmModes[5][2] = {{2, 2}, {2, 1}, {3, 3}, {4, 4}, {5, 5}};
713 for (
INT4 EMM = -ELL; EMM < 0; EMM++) {
716 In mode array you should specify (l,|m|). The code will automatically return +- m modes\n",
728 for (
UINT4 EMM = 0; EMM <= ELL; EMM++) {
733 if ((modeL == ELL) && (modeM == EMM)) {
741 XLALPrintError(
"Mode (%d,%d) is not available for the model %s.\n",
746 XLALPrintError(
"Mode (%d,%d) is not available for the model %s.\n",
773 const REAL8 INspin1[],
774 const REAL8 INspin2[],
809 if (modearray == NULL) {
828 INT4 NumericalOrAnalyticalHamiltonianDerivative =
832 if ((NumericalOrAnalyticalHamiltonianDerivative != 0) &&
833 (NumericalOrAnalyticalHamiltonianDerivative != 1)) {
834 XLALPrintError(
"XLAL Error - %s: Unknown value for the derivative of the "
835 "Hamiltonian flag. \nAt present only "
836 "1 (numerical derivative) or 0 (analytical derivative) are "
841 if (NumericalOrAnalyticalHamiltonianDerivative ==
847 NumericalOrAnalyticalHamiltonianDerivative);
861 INT4 ellMaxForNyquistCheck = 2;
863 ellMaxForNyquistCheck =
869 hplus, hcross, &hIlm, &hJlm, &dyn_Low, &dyn_Hi, &dyn_all,
870 &t_vec_modes, &hP22_amp, &hP22_phase, &hP21_amp, &hP21_phase,
871 &hP33_amp, &hP33_phase, &hP44_amp, &hP44_phase, &hP55_amp,
872 &hP55_phase, &alphaJ2P, &betaJ2P, &gammaJ2P, &AttachPars, phiC,
873 deltaT, m1SI, m2SI, fMin,
r, inc, INspin1[0], INspin1[1],
874 INspin1[2], INspin2[0], INspin2[1], INspin2[2], modearray,
964 for (
INT4 l = 2;
l <= lmax;
l++) {
973 "XLAL Warning - %s: mode (l,m)=(%d,%d) present in mode array -- "
974 "in our conventions, we only consider m>0. Mode ignored for "
994 const REAL8 INspin1[],
995 const REAL8 INspin2[],
1032 if (modearray == NULL) {
1051 INT4 NumericalOrAnalyticalHamiltonianDerivative =
1055 if ((NumericalOrAnalyticalHamiltonianDerivative != 0) &&
1056 (NumericalOrAnalyticalHamiltonianDerivative != 1)) {
1057 XLALPrintError(
"XLAL Error - %s: Unknown value for the derivative of the "
1058 "Hamiltonian flag. \nAt present only "
1059 "1 (numerical derivative) or 0 (analytical derivative) are "
1064 if (NumericalOrAnalyticalHamiltonianDerivative ==
1070 NumericalOrAnalyticalHamiltonianDerivative);
1082 INT4 ellMaxForNyquistCheck = 2;
1084 ellMaxForNyquistCheck =
1090 &hplus, &hcross, &hIlm, &hJlm, &dyn_Low, &dyn_Hi, &dyn_all,
1091 &t_vec_modes, &hP22_amp, &hP22_phase, &hP21_amp, &hP21_phase,
1092 &hP33_amp, &hP33_phase, &hP44_amp, &hP44_phase, &hP55_amp,
1093 &hP55_phase, &alphaJ2P, &betaJ2P, &gammaJ2P, &AttachPars, 0.,
1094 deltaT, m1SI, m2SI, fMin,
r, 0., INspin1[0], INspin1[1],
1095 INspin1[2], INspin2[0], INspin2[1], INspin2[2], modearray,
1152 REAL8 mTotal = m1 + m2;
1157 char mode_string[32];
1165 for (
INT4 l = 2;
l <= modes_lmax;
l++) {
1261 return hIlm_dimfull;
1270 XLALPrintError(
"XLAL Error - %s: input double pointer is NULL.\n",
1275 XLALPrintError(
"XLAL Error - %s: input pointer is not NULL.\n", __func__);
1284 XLALPrintError(
"XLAL Error - %s: failed to create REAL8Vector xdata.\n",
1289 XLALPrintError(
"XLAL Error - %s: failed to create REAL8Vector camp_real.\n",
1294 XLALPrintError(
"XLAL Error - %s: failed to create REAL8Vector camp_imag.\n",
1299 XLALPrintError(
"XLAL Error - %s: failed to create REAL8Vector phase.\n",
1303 memset((*campphase)->xdata->data, 0, size *
sizeof(
REAL8));
1304 memset((*campphase)->camp_real->data, 0, size *
sizeof(
REAL8));
1305 memset((*campphase)->camp_imag->data, 0, size *
sizeof(
REAL8));
1306 memset((*campphase)->phase->data, 0, size *
sizeof(
REAL8));
1316 XLALPrintError(
"XLAL Error - %s: data is a NULL pointer.\n", __func__);
1319 if (campphase->
xdata)
1325 if (campphase->
phase)
1336 while ((pop = list)) {
1361 list = *list_prepended;
1363 if (
l == list->
l &&
m == list->
m) {
1370 XLALPrintError(
"XLAL Error - %s: tried to add an already existing mode to "
1371 "a SphHarmListCAmpPhaseSequence.\n",
1384 if (*list_prepended) {
1385 list->
next = *list_prepended;
1389 *list_prepended = list;
1404 while (itr->
l !=
l || itr->
m !=
m) {
1417 while ((pop = list)) {
1421 "XLAL Error - %s: failure in CAmpPhaseSequence_Destroy.\n",
1447 list = *list_prepended;
1449 if (
l == list->
l &&
m == list->
m) {
1456 XLALPrintError(
"XLAL Error - %s: tried to add an already existing mode to "
1457 "a SphHarmListCAmpPhaseSequence.\n",
1470 if (*list_prepended) {
1471 list->
next = *list_prepended;
1475 *list_prepended = list;
1490 while (itr->
l !=
l || itr->
m !=
m) {
1511 if (!seobdynamics) {
1512 XLALPrintError(
"XLAL Error - %s: seobdynamics is a NULL double pointer.\n",
1518 if ((*seobdynamics)) {
1524 XLALPrintError(
"XLAL Error - %s: failed to allocate struct SEOBdynamics.\n",
1530 (*seobdynamics)->length = retLen;
1533 if (!((*seobdynamics)->array =
1536 "XLAL Error - %s: failed to allocate REAL8Array seobdynamics->array.\n",
1543 (*seobdynamics)->tVec = (*seobdynamics)->array->data;
1544 (*seobdynamics)->posVecx = (*seobdynamics)->array->data + 1 * retLen;
1545 (*seobdynamics)->posVecy = (*seobdynamics)->array->data + 2 * retLen;
1546 (*seobdynamics)->posVecz = (*seobdynamics)->array->data + 3 * retLen;
1547 (*seobdynamics)->momVecx = (*seobdynamics)->array->data + 4 * retLen;
1548 (*seobdynamics)->momVecy = (*seobdynamics)->array->data + 5 * retLen;
1549 (*seobdynamics)->momVecz = (*seobdynamics)->array->data + 6 * retLen;
1550 (*seobdynamics)->s1Vecx = (*seobdynamics)->array->data + 7 * retLen;
1551 (*seobdynamics)->s1Vecy = (*seobdynamics)->array->data + 8 * retLen;
1552 (*seobdynamics)->s1Vecz = (*seobdynamics)->array->data + 9 * retLen;
1553 (*seobdynamics)->s2Vecx = (*seobdynamics)->array->data + 10 * retLen;
1554 (*seobdynamics)->s2Vecy = (*seobdynamics)->array->data + 11 * retLen;
1555 (*seobdynamics)->s2Vecz = (*seobdynamics)->array->data + 12 * retLen;
1556 (*seobdynamics)->phiDMod = (*seobdynamics)->array->data + 13 * retLen;
1557 (*seobdynamics)->phiMod = (*seobdynamics)->array->data + 14 * retLen;
1558 (*seobdynamics)->velVecx = (*seobdynamics)->array->data + 15 * retLen;
1559 (*seobdynamics)->velVecy = (*seobdynamics)->array->data + 16 * retLen;
1560 (*seobdynamics)->velVecz = (*seobdynamics)->array->data + 17 * retLen;
1561 (*seobdynamics)->polarrVec = (*seobdynamics)->array->data + 18 * retLen;
1562 (*seobdynamics)->polarphiVec = (*seobdynamics)->array->data + 19 * retLen;
1563 (*seobdynamics)->polarprVec = (*seobdynamics)->array->data + 20 * retLen;
1564 (*seobdynamics)->polarpphiVec = (*seobdynamics)->array->data + 21 * retLen;
1565 (*seobdynamics)->omegaVec = (*seobdynamics)->array->data + 22 * retLen;
1566 (*seobdynamics)->s1dotZVec = (*seobdynamics)->array->data + 23 * retLen;
1567 (*seobdynamics)->s2dotZVec = (*seobdynamics)->array->data + 24 * retLen;
1568 (*seobdynamics)->hamVec = (*seobdynamics)->array->data + 25 * retLen;
1578 return 0.5 * (chi1dotZ + chi2dotZ);
1581 return 0.5 * (chi1dotZ - chi2dotZ);
1589 REAL8 chi2dotZ,
INT4 SpinAlignedEOBversion) {
1590 REAL8 chiS, chiA, tplspin;
1594 switch (SpinAlignedEOBversion) {
1602 tplspin = (1. - 2. * eta) * chiS + (m1 - m2) / (m1 + m2) * chiA;
1605 XLALPrintError(
"XLAL Error - %s: Unknown SEOBNR version!\nAt present only "
1606 "v1, v2 and v4 are available.\n",
1647 sigmaStar->
data[
i] =
1648 (mass2 / mass1 * s1->
data[
i] + mass1 / mass2 * s2->
data[
i]);
1668 flagHamiltonianDerivative,
1679 REAL8 rvec[3] = {0, 0, 0};
1680 REAL8 pvec[3] = {0, 0, 0};
1681 REAL8 spin1vec[3] = {0, 0, 0};
1682 REAL8 spin2vec[3] = {0, 0, 0};
1683 REAL8 rdotvec[3] = {0, 0, 0};
1684 REAL8 rcrossrdot[3] = {0, 0, 0};
1685 REAL8 rcrossp[3] = {0, 0, 0};
1686 REAL8 LNhat[3] = {0, 0, 0};
1687 REAL8 Lhat[3] = {0, 0, 0};
1688 REAL8 polarr, polarphi, polarpr, polarpphi, omega, s1dotZ, s2dotZ, ham;
1696 "XLAL Error - %s: failed to allocate REAL8Vector values, dvalues.\n",
1717 memset(sigmaStar->
data, 0, 3 *
sizeof(
REAL8));
1718 memset(sigmaKerr->data, 0, 3 *
sizeof(
REAL8));
1722 for (
i = 0;
i < retLen;
i++) {
1725 for (j = 0; j < 14; j++) {
1726 values->
data[j] = dynamics->
data[
i + (j + 1) * retLen];
1730 if (flagHamiltonianDerivative ==
1733 (
void *)seobParams) ==
1736 "XLALSpinPrecHcapRvecDerivative_exact.\n",
1740 }
else if (flagHamiltonianDerivative ==
1745 "XLAL Error - %s: failure in XLALSpinPrecHcapRvecDerivative.\n",
1751 "XLAL Error - %s: flagHamiltonianDerivative not recognized.\n",
1757 for (j = 0; j < 3; j++) {
1758 rvec[j] = values->
data[j];
1759 pvec[j] = values->
data[3 + j];
1760 spin1vec[j] = values->
data[6 + j];
1761 spin2vec[j] = values->
data[9 + j];
1762 rdotvec[j] = dvalues->
data[j];
1767 for (j = 0; j < 3; j++) {
1768 LNhat[j] = rcrossrdot[j] / rcrossrdotNorm;
1774 polarphi = values->
data[12] + values->
data[13];
1776 for (j = 0; j < 3; j++) {
1777 Lhat[j] = rcrossp[j] / magL;
1782 omega = rcrossrdotNorm / (polarr * polarr);
1793 XLALPrintError(
"XLAL Error - %s: flagZframe not recognized.\n", __func__);
1801 cartPosVec.
data = rvec;
1802 cartMomVec.
data = pvec;
1803 s1Vec.
data = spin1vec;
1804 s2Vec.
data = spin2vec;
1813 REAL8 S1_perp[3] = {0, 0, 0};
1814 REAL8 S2_perp[3] = {0, 0, 0};
1815 for (
UINT4 jj = 0; jj < 3; jj++) {
1816 S1_perp[jj] = spin1vec[jj] - tempS1_p * Lhat[jj];
1817 S2_perp[jj] = spin2vec[jj] - tempS2_p * Lhat[jj];
1819 UNUSED
REAL8 sKerr_norm =
1822 if (sKerr_norm > 1
e-6) {
1823 S_con = sigmaKerr->data[0] * Lhat[0] + sigmaKerr->data[1] * Lhat[1] +
1824 sigmaKerr->data[2] * Lhat[2];
1825 S_con /= (1 - 2 * eta);
1828 sKerr_norm / (1 - 2 * eta) / 2.;
1833 seobCoeffs, eta,
a, S_con, SpinAlignedEOBversion) ==
XLAL_FAILURE) {
1835 "XLALSimIMRCalculateSpinPrecEOBHCoeffs_v2 in step %d of "
1841 &s1Vec, &s2Vec, sigmaKerr, sigmaStar,
1879 flagHamiltonianDerivative
1887 "XLAL Error - %s: pointer to REAL8Vector ICvalues is NULL.\n",
1895 "XLAL Error - %s: failed to allocate REAL8Vector ICvalues.\n",
1899 memset((*ICvalues)->data, 0, ((*ICvalues)->length) *
sizeof(
REAL8));
1902 REAL8 eta = m1 * m2 / (m1 + m2) / (m1 + m2);
1914 INT4 use_optimized = 0;
1915 if (flagHamiltonianDerivative ==
1918 else if (flagHamiltonianDerivative ==
1923 "XLAL Error - %s: flagHamiltonianDerivative not recognized.\n",
1930 REAL8 mSpin1data[3] = {0., 0., 0.};
1931 REAL8 mSpin2data[3] = {0., 0., 0.};
1933 if (SpinsAlmostAligned) {
1941 SpinAlignedEOBversion);
1944 chiS, chiA, SpinAlignedEOBversion) ==
1949 "XLALSimIMREOBCalcSpinFacWaveformCoefficients.\n",
1953 mSpin1data[2] = chi1->
data[2] * m1 * m1;
1954 mSpin2data[2] = chi2->
data[2] * m2 * m2;
1956 mSpin1data, mSpin2data, seobParams,
1962 "XLAL Error - %s: failure in XLALSimIMRSpinEOBInitialConditions.\n",
1967 for (j = 0; j < 3; j++) {
1968 mSpin1data[j] = chi1->
data[j] * m1 * m1;
1969 mSpin2data[j] = chi2->
data[j] * m2 * m2;
1974 *ICvalues, m1, m2, fMin, inc, mSpin1data, mSpin2data, seobParams,
1977 "XLALSimIMRSpinEOBInitialConditionsPrec.\n",
1984 (*ICvalues)->data[12] = 0.;
1985 (*ICvalues)->data[13] = 0.;
2011 REAL8 mTotal = m1 + m2;
2020 tVec.
data = dynamics_spinaligned->
data;
2021 rVec.
data = dynamics_spinaligned->
data + retLen;
2022 phiVec.
data = dynamics_spinaligned->
data + 2 * retLen;
2023 prVec.
data = dynamics_spinaligned->
data + 3 * retLen;
2024 pPhiVec.
data = dynamics_spinaligned->
data + 4 * retLen;
2025 for (
i = 0;
i < retLen;
i++) {
2026 (*dynamics)->data[
i] = tVec.
data[
i];
2027 (*dynamics)->data[retLen +
i] = rVec.
data[
i] * cos(phiVec.
data[
i]);
2028 (*dynamics)->data[2 * retLen +
i] = rVec.
data[
i] * sin(phiVec.
data[
i]);
2029 (*dynamics)->data[3 * retLen +
i] = 0.;
2030 (*dynamics)->data[4 * retLen +
i] =
2033 (*dynamics)->data[5 * retLen +
i] =
2036 (*dynamics)->data[6 * retLen +
i] = 0.;
2037 (*dynamics)->data[7 * retLen +
i] = 0.;
2038 (*dynamics)->data[8 * retLen +
i] = 0.;
2039 (*dynamics)->data[9 * retLen +
i] = chi1 * (m1 * m1 / mTotal / mTotal);
2040 (*dynamics)->data[10 * retLen +
i] = 0.;
2041 (*dynamics)->data[11 * retLen +
i] = 0.;
2042 (*dynamics)->data[12 * retLen +
i] = chi2 * (m2 * m2 / mTotal / mTotal);
2043 (*dynamics)->data[13 * retLen +
i] = phiVec.
data[
i];
2044 (*dynamics)->data[14 * retLen +
i] = 0.;
2080 UINT4 flagConstantSampling,
2084 flagHamiltonianDerivative
2096 UINT4 nb_Hamiltonian_variables = 14;
2097 UINT4 nb_Hamiltonian_variables_spinsaligned = 4;
2105 XLALPrintError(
"XLAL Error - %s: failed to create REAL8Vector values.\n",
2113 if (!(values_spinaligned =
2116 "XLAL Error - %s: failed to create REAL8Vector values_spinaligned.\n",
2120 memset(values_spinaligned->
data, 0,
2124 if (SpinsAlmostAligned) {
2130 ICvalues->
data[1] * ICvalues->
data[1] +
2131 ICvalues->
data[2] * ICvalues->
data[2]);
2134 values_spinaligned->
data[0] = temp_r;
2135 values_spinaligned->
data[1] = temp_phi;
2136 values_spinaligned->
data[2] = ICvalues->
data[3] * cos(temp_phi) +
2137 ICvalues->
data[4] * sin(temp_phi);
2138 values_spinaligned->
data[3] =
2139 temp_r * (ICvalues->
data[4] * cos(temp_phi) -
2140 ICvalues->
data[3] * sin(temp_phi));
2159 if (flagHamiltonianDerivative ==
2164 }
else if (flagHamiltonianDerivative ==
2178 "XLAL Error - %s: flagHamiltonianDerivative not recognized.\n",
2185 "XLAL Error - %s: failure in the initialization of the integrator.\n",
2197 INT4 EOBversion = 2;
2200 if (SpinsAlmostAligned) {
2202 if (!flagConstantSampling) {
2204 integrator, seobParams, values_spinaligned->
data, 0., tend -
tstart,
2205 deltaT, deltaT_min, &dynamics_spinaligned, EOBversion);
2208 integrator, seobParams, values_spinaligned->
data, 0., tend -
tstart,
2209 deltaT, &dynamics_spinaligned);
2212 XLALPrintError(
"XLAL Error - %s: failure in the integration of the "
2213 "spin-aligned dynamics.\n",
2220 dynamics, dynamics_spinaligned, retLen, seobParams->
chi1,
2223 "SEOBConvertSpinAlignedDynamicsToGenericSpins.\n",
2228 if (!flagConstantSampling) {
2231 deltaT_min, dynamics, EOBversion);
2237 XLALPrintError(
"XLAL Error - %s: failure in the integration of the "
2238 "generic-spin dynamics.\n",
2248 (*dynamics)->data[
i] +=
tstart;
2251 *retLenOut = retLen;
2254 if (dynamics_spinaligned)
2285 "XLAL Error - %s: pointer to CAmpPhaseSequence hlm is NULL.\n",
2295 REAL8 mtot = m1 + m2;
2297 UINT4 SpinAlignedEOBversionWaveform;
2306 XLALPrintError(
"XLAL Error - %s: failure in CAmpPhaseSequence_Init.\n",
2313 REAL8 valuesdata[14] = {0.};
2314 REAL8 polarDynamicsdata[4] = {0.};
2316 polarDynamics.
length = 4;
2317 values.
data = valuesdata;
2318 polarDynamics.
data = polarDynamicsdata;
2322 if (includeNQC == 0) {
2323 if (((
l == 2) && (
m == 1)) || ((
l == 5) && (
m == 5))) {
2325 seobParams,
l,
m, seobdynamics,
2326 tPeakOmega - seobdynamics->
tVec[0], m1, m2,
2329 "XLALSimIMREOBCalcCalibCoefficientHigherModesPrec.\n",
2337 REAL8 s1dotZ, s2dotZ, chiS, chiA, tplspin, t, omega, ham, v;
2339 for (
i = 0;
i < retLen;
i++) {
2341 t = seobdynamics->
tVec[
i];
2343 ham = seobdynamics->
hamVec[
i];
2346 REAL8 chi1dotZ = s1dotZ * mtot * mtot / (m1 * m1);
2347 REAL8 chi2dotZ = s2dotZ * mtot * mtot / (m2 * m2);
2352 SpinAlignedEOBversion);
2353 if (SpinAlignedEOBversion == 4) {
2354 SpinAlignedEOBversionWaveform =
v4Pwave;
2356 SpinAlignedEOBversionWaveform = SpinAlignedEOBversion;
2363 "XLALSimIMREOBCalcSpinPrecFacWaveformCoefficients at step "
2364 "%d of the loop.\n",
2372 for (j = 0; j < 14; j++) {
2373 values.
data[j] = seobdynamics->
array->
data[
i + (j + 1) * retLen];
2382 &hlm_val, &polarDynamics, &values, v, ham,
l,
m, seobParams) ==
2385 "XLALSimIMRSpinEOBGetPrecSpinFactorizedWaveform at step "
2386 "%d of the loop.\n",
2396 "XLAL Error - %s: failure in XLALSimIMRSpinEOBNonQCCorrection at "
2397 "step %d of the loop.\n",
2404 COMPLEX16 hlmNQC = hlm_val * factor_nqc;
2405 (*hlm)->xdata->data[
i] = t;
2406 (*hlm)->camp_real->data[
i] = cabs(hlmNQC);
2407 (*hlm)->camp_imag->data[
i] = 0.;
2408 (*hlm)->phase->data[
i] = carg(hlmNQC);
2436 UINT4 includeNQC = 0;
2439 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
2441 INT4 l = modes[nmode][0];
2442 INT4 m = modes[nmode][1];
2444 if ((!(
l == 2 &&
m == 2)) && (SpinAlignedEOBversion == 3)) {
2448 includeNQC = flagNQC;
2472 INT4 *foundPeakOmega,
2479 flagHamiltonianDerivative
2487 omegaVec.
length = retLen;
2490 *foundPeakOmega = 1;
2554 "XLAL Error - %s: failed to allocate COMPLEX16Vector hmode.\n",
2558 for (
UINT4 i = 0;
i < retLen;
i++) {
2590 XLALPrintError(
"XLAL Error - %s: failed to allocate REAL8Vector "
2591 "seobdynamics_values.\n",
2595 memset((*seobdynamics_values)->data, 0,
2596 ((*seobdynamics_values)->length) *
sizeof(
REAL8));
2601 if ((t < tVec[0]) || (t > tVec[retLen - 1])) {
2603 "XLAL Error - %s: time for interpolation is out of range of "
2604 "the SEOBdynamics data. t = %.17f, tVec[0]=%.17f, tVec[-1]=%.17f\n",
2605 __func__, t, tVec[0], tVec[retLen - 1]);
2612 while ((indext < retLen - 1) && (tVec[indext + 1] <= t))
2614 INT4 indexstart = indext - 20 > 0 ? indext - 20 : 0;
2615 INT4 indexend = indext + 20 < retLen - 1 ? indext + 20 : retLen - 1;
2616 INT4 interp_length = indexend - indexstart + 1;
2617 if (interp_length <= 0) {
2618 XLALPrintError(
"XLAL Error - %s: not finding a strictly positive number of "
2619 "samples for interpolation.\n",
2625 gsl_spline *spline = gsl_spline_alloc(gsl_interp_cspline, interp_length);
2626 gsl_interp_accel *acc = gsl_interp_accel_alloc();
2629 (*seobdynamics_values)->data[0] = t;
2631 gsl_spline_init(spline, &(tVec[indexstart]),
2632 &(seobdynamics->
array->
data[j * retLen + indexstart]),
2634 (*seobdynamics_values)->data[j] = gsl_spline_eval(spline, t, acc);
2638 gsl_spline_free(spline);
2639 gsl_interp_accel_free(acc);
2654 if ((!S1) || (!S2) || (!seobvalues)) {
2658 REAL8 mTotal = m1 + m2;
2660 REAL8 m1_sc = m1 / mTotal;
2661 REAL8 m2_sc = m2 / mTotal;
2664 XLALPrintError(
"XLAL Error: failed to allocate REAL8Vector S1.\n");
2669 XLALPrintError(
"XLAL Error failed to allocate REAL8Vector S2.\n");
2672 memset((*S1)->data, 0, 3 *
sizeof(
REAL8));
2673 memset((*S2)->data, 0, 3 *
sizeof(
REAL8));
2676 REAL8 rvec[3] = {0, 0, 0};
2677 REAL8 drvec[3] = {0, 0, 0};
2678 REAL8 pvec[3] = {0, 0, 0};
2679 REAL8 spin1vec[3] = {0, 0, 0};
2680 REAL8 spin2vec[3] = {0, 0, 0};
2681 REAL8 crossp[3] = {0, 0, 0};
2682 REAL8 L_hat[3] = {0, 0, 0};
2683 REAL8 n_hat[3] = {0, 0, 0};
2684 REAL8 lambda_hat[3] = {0, 0, 0};
2686 for (
int j = 0; j < 3; j++) {
2687 rvec[j] = seobvalues->
data[1 + j];
2688 drvec[j] = seobvalues->
data[15 + j];
2689 pvec[j] = seobvalues->
data[4 + j];
2690 spin1vec[j] = seobvalues->
data[7 + j] / m1_sc / m1_sc;
2691 spin2vec[j] = seobvalues->
data[10 + j] / m2_sc / m2_sc;
2703 for (
int jj = 0; jj < 3; jj++) {
2704 L_hat[jj] = crossp[jj] / Lmag;
2705 n_hat[jj] = rvec[jj] / sep;
2730 if ((!J) || (!seobvalues) || (!seobParams)) {
2731 XLALPrintError(
"Some pointers passed to SEOBJfromDynamics were null\n");
2736 XLALPrintError(
"XLAL Error failed to allocate REAL8Vector J.\n");
2739 memset((*J)->data, 0, 3 *
sizeof(
REAL8));
2745 REAL8 rvec[3] = {0, 0, 0};
2746 REAL8 pvec[3] = {0, 0, 0};
2747 REAL8 spin1vec[3] = {0, 0, 0};
2748 REAL8 spin2vec[3] = {0, 0, 0};
2749 REAL8 rcrossp[3] = {0, 0, 0};
2752 for (j = 0; j < 3; j++) {
2753 rvec[j] = seobvalues->
data[1 + j];
2754 pvec[j] = seobvalues->
data[4 + j];
2755 spin1vec[j] = seobvalues->
data[7 + j];
2756 spin2vec[j] = seobvalues->
data[10 + j];
2762 for (j = 0; j < 3; j++) {
2763 (*J)->data[j] = eta * rcrossp[j] + spin1vec[j] + spin2vec[j];
2780 if ((!L) || (!seobvalues) || (!seobParams))
2782 XLALPrintError(
"Some pointers passed to SEOBLfromDynamics were null\n");
2788 XLALPrintError(
"XLAL Error failed to allocate REAL8Vector L.\n");
2791 memset((*L)->data, 0, 3 *
sizeof(
REAL8));
2794 REAL8 rvec[3] = {0, 0, 0};
2795 REAL8 drvec[3] = {0, 0, 0};
2796 REAL8 pvec[3] = {0, 0, 0};
2797 REAL8 crossp[3] = {0, 0, 0};
2800 for (
int j = 0; j < 3; j++)
2802 rvec[j] = seobvalues->
data[1 + j];
2803 drvec[j] = seobvalues->
data[15 + j];
2804 pvec[j] = seobvalues->
data[4 + j];
2818 for (
int jj = 0; jj < 3; jj++)
2820 (*L)->data[jj] = crossp[jj] / Lmag;
2842 if ((!e1J) || (!e2J) || (!e3J) || (!JVec)) {
2843 XLALPrintError(
"XLAL Error: at least one input pointer is NULL.\n");
2848 "XLAL Error: at least one input vector is not of length 3.\n");
2854 for (j = 0; j < 3; j++) {
2855 e3J->
data[j] = JVec->
data[j] / Jnorm;
2866 REAL8 normfacx = 0.;
2867 REAL8 normfacy = 0.;
2870 REAL8 e1Jblendednorm = 0.;
2871 REAL8 exvec[3] = {1, 0, 0};
2872 REAL8 eyvec[3] = {0, 1, 0};
2875 REAL8 lambda = 1. - fabs(exdote3J);
2876 if ((lambda < 0.) || (lambda > 1.)) {
2877 XLALPrintError(
"Problem: lambda=1-|e3J.ex|=%g, should be in [0,1]", lambda);
2880 if (lambda > 1
e-4) {
2881 normfacx = 1. / sqrt(1. - exdote3J * exdote3J);
2882 for (j = 0; j < 3; j++) {
2883 e1J->
data[j] = (exvec[j] - exdote3J * e3J->
data[j]) / normfacx;
2885 }
else if (lambda < 1
e-5) {
2886 normfacy = 1. / sqrt(1. - eydote3J * eydote3J);
2887 for (j = 0; j < 3; j++) {
2888 e1J->
data[j] = (eyvec[j] - eydote3J * e3J->
data[j]) / normfacy;
2891 weightx = (lambda - 1
e-5) / (1
e-4 - 1
e-5);
2892 weighty = 1. - weightx;
2893 normfacx = 1. / sqrt(1. - exdote3J * exdote3J);
2894 normfacy = 1. / sqrt(1. - eydote3J * eydote3J);
2895 for (j = 0; j < 3; j++) {
2896 e1J->
data[j] = weightx * (exvec[j] - exdote3J * e3J->
data[j]) / normfacx +
2897 weighty * (eyvec[j] - eydote3J * e3J->
data[j]) / normfacy;
2900 for (j = 0; j < 3; j++) {
2901 e1J->
data[j] /= e1Jblendednorm;
2913 for (j = 0; j < 3; j++) {
2914 e1J->
data[j] /= e1Jnorm;
2915 e2J->
data[j] /= e2Jnorm;
2916 e3J->
data[j] /= e3Jnorm;
2984 r.length =
pr.length = omega.
length = retLen;
3018 REAL8 chi1dotZfinal = chi1_omegaPeak->
data[2];
3019 REAL8 chi2dotZfinal = chi2_omegaPeak->
data[2];
3025 REAL8 tPeakOmegaFromStartDyn = tPeakOmega - seobdynamics->
tVec[0];
3033 UINT4 includeNQC = 0;
3035 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3037 INT4 l = modes[nmode][0];
3038 INT4 m = modes[nmode][1];
3043 if (
q<1.005 && (
m % 2 != 0) && (fabs(chiAfinal) < 0.15)) {
3047 nqcCoeffs->
a3S = 0.;
3068 "XLAL Error - %s: failed to allocate REAL8Vector hlm_amp.\n",
3074 "XLAL Error - %s: failed to allocate REAL8Vector hlm_phase.\n",
3085 hlm_amp, hlm_phase, &
r, &
pr, &omega,
l,
m, tPeakOmegaFromStartDyn,
3086 deltaT, m1, m2, chiAfinal, chiSfinal,
3089 "XLAL Error - %s: failure for the mode (l,m) = (%d, %d).\n",
3123 while ((index < length - 1) && (
data[index + 1] <= value))
3127 if (index < length - 1) {
3128 if (fabs(
data[index] - value) > fabs(
data[index + 1] - value))
3144 return vec->
data[index];
3172 XLALPrintError(
"XLAL Error - %s: failure in SEOBLFrameVectors.\n",
3182 "XLAL Error - %s: failure in XLALSimIMREOBFinalMassSpinPrec.\n",
3200 *listhPlm_RDattached,
3213 UINT4 retLenRDPatch,
3226 if (!(*listhPlm_RDattached == NULL)) {
3228 "hPlm_RDattached is not NULL.\n",
3232 if (!(*sigmaQNMlm0 == NULL)) {
3233 XLALPrintError(
"XLAL Error - %s: output pointer for the vector sigmaQNMlm0 "
3240 UINT4 retLen_RDattached = retLen + retLenRDPatch;
3241 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3243 INT4 l = modes[nmode][0];
3244 INT4 m = modes[nmode][1];
3249 XLALPrintError(
"XLAL Error - %s: failed to allocate CAmpPhaseSequence "
3250 "hlm for mode (l,m) = (%d,%d).\n",
3263 REAL8 mTotal = m1 + m2;
3271 REAL8 finalM, finalS = 0;
3289 if (finalS < -0.9996)
3291 if (finalS > 0.9996)
3295 XLAL_PRINT_INFO(
"In RD attachment: final mass = %e, final spin = %e, "
3296 "total_mass = %e \n",
3297 finalM, finalS, mTotal);
3306 sigmaQNMlm0physicalVec.
length = 1;
3308 sigmaQNMlm0physicalVec.
data = &sigmaQNMlm0physicalval;
3309 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3311 INT4 l = modes[nmode][0];
3312 INT4 m = modes[nmode][1];
3317 m2, finalM, finalS,
l,
m,
3320 "XLALSimIMREOBGenerateQNMFreqV2FromFinalPrec for mode "
3321 "(l,m) = (%d,%d).\n",
3326 (*sigmaQNMlm0)->data[nmode] = mTScaled * sigmaQNMlm0physicalVec.
data[0];
3330 m, creal((*sigmaQNMlm0)->data[nmode]),
3331 cimag((*sigmaQNMlm0)->data[nmode]));
3339 REAL8 timeNeartAttach55 =
3345 REAL8 rdMatchPointdata[4] = {0.};
3347 rdMatchPoint.
data = rdMatchPointdata;
3348 rdMatchPoint.
data[0] = 0.;
3349 rdMatchPoint.
data[1] =
3351 rdMatchPoint.
data[2] = 0.;
3352 rdMatchPoint.
data[3] = timeNeartAttach55;
3358 XLALPrintError(
"XLAL Error - %s: failed to allocate REAL8Vector hPlmRe.\n",
3363 XLALPrintError(
"XLAL Error - %s: failed to allocate REAL8Vector hPlmIm.\n",
3372 UINT4 indAmpMax = 0;
3375 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3377 INT4 l = modes[nmode][0];
3378 INT4 m = modes[nmode][1];
3388 for (
UINT4 i = 0;
i < retLen;
i++) {
3391 hPlmRe->
data[
i] = creal(hPlm_val);
3392 hPlmIm->
data[
i] = cimag(hPlm_val);
3398 hPlmRe, hPlmIm,
l,
m, deltaTseconds, m1, m2, chi1Lx, chi1Ly, chi1Lz,
3399 chi2Lx, chi2Ly, chi2Lz, finalM, finalS, &timeVec, &rdMatchPoint,
3401 XLALPrintError(
"XLAL Error - %s: XLALSimIMREOBAttachFitRingdown failed "
3402 "for mode (l,m) = (%d,%d).\n",
3408 for (
UINT4 i = 0;
i < retLen;
i++) {
3411 for (
UINT4 i = 0;
i < retLen_RDattached - retLen;
i++) {
3417 for (
UINT4 i = 0;
i < retLen_RDattached;
i++) {
3418 hPlm_val = hPlmRe->
data[
i] + I * hPlmIm->
data[
i];
3421 hPlm_RDattached->
phase->
data[
i] = carg(hPlm_val);
3444 UINT4 *retLenPmodes,
3447 UINT4 *indexJoinHiS,
3449 UINT4 *indexJoinAttach,
3450 UINT4 retLenHiSRDpatch,
3468 while ((iJoinHiS < lenAdaS - 1) && (tAdaS[iJoinHiS] < tstartHiS))
3472 INT4 lenPmodes = iJoinHiS + lenHiS + retLenHiSRDpatch;
3475 "XLAL Error - %s: failed to allocate REAL8Vector tVecPmodes.\n",
3479 *retLenPmodes = lenPmodes;
3482 memcpy(&((*tVecPmodes)->data[0]), tAdaS, iJoinHiS *
sizeof(
REAL8));
3483 memcpy(&((*tVecPmodes)->data[iJoinHiS]), tHiS, lenHiS *
sizeof(
REAL8));
3486 for (
UINT4 i = 0;
i < retLenHiSRDpatch;
i++) {
3487 (*tVecPmodes)->data[iJoinHiS + lenHiS +
i] =
3488 tHiS[lenHiS - 1] + (
i + 1) * deltaTHiS;
3492 INT4 iJoinAttach = lenPmodes - 1;
3493 while ((iJoinAttach > 0) && ((*tVecPmodes)->data[iJoinAttach] > tAttach))
3497 *indexJoinHiS = iJoinHiS;
3498 *tJoinHiS = (*tVecPmodes)->data[iJoinHiS];
3499 *indexJoinAttach = iJoinAttach;
3500 *tJoinAttach = (*tVecPmodes)->data[iJoinAttach];
3514 *seobdynamicsJoined,
3524 INT4 lenJoined = indexEnd2;
3525 INT4 lendyn1Joined = indexJoin12;
3526 INT4 lendyn2Joined = indexEnd2 - indexJoin12;
3535 memcpy(&((*seobdynamicsJoined)->array->data[j * lenJoined]),
3536 &(seobdynamics1->
array->
data[j * lendyn1]),
3537 lendyn1Joined *
sizeof(
REAL8));
3542 memcpy(&((*seobdynamicsJoined)->array->data[j * lenJoined + lendyn1Joined]),
3543 &(seobdynamics2->
array->
data[j * lendyn2]),
3544 lendyn2Joined *
sizeof(
REAL8));
3567 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3569 INT4 l = modes[nmode][0];
3570 INT4 m = modes[nmode][1];
3580 INT4 lenJoined1 = indexJoin12;
3581 INT4 lenJoined = lenJoined1 + len2;
3586 XLALPrintError(
"XLAL Error - %s: failed to allocate CAmpPhaseSequence "
3587 "hlm_joined for mode (l,m) = (%d,%d).\n",
3594 lenJoined1 *
sizeof(
REAL8));
3596 lenJoined1 *
sizeof(
REAL8));
3598 lenJoined1 *
sizeof(
REAL8));
3600 lenJoined1 *
sizeof(
REAL8));
3603 len2 *
sizeof(
REAL8));
3605 len2 *
sizeof(
REAL8));
3607 len2 *
sizeof(
REAL8));
3609 len2 *
sizeof(
REAL8));
3617 hlm_joined->
phase->
data[lenJoined1 +
i] += shift_2kpi;
3644 UINT4 found22 = 0, found21 = 0;
3645 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
3646 if (modes[nmode][0] == 2 && modes[nmode][1] == 2)
3648 if (modes[nmode][0] == 2 && modes[nmode][1] == 1)
3652 XLALPrintError(
"XLAL Error - %s: mode 22 not found.\n", __func__);
3666 XLALPrintError(
"XLAL Error - %s: lengths of input amplitude and time "
3667 "REAL8Vector do not match.\n",
3674 REAL8 AsquareMax = 0.;
3675 REAL8 A22_real = 0., A22_imag = 0., A21_real = 0., A21_imag = 0.,
3677 for (
UINT4 i = 0;
i < length;
i++) {
3680 Asquare = A22_real * A22_real + A22_imag * A22_imag;
3684 Asquare += A21_real * A21_real + A21_imag * A21_imag;
3686 if (Asquare > AsquareMax) {
3687 AsquareMax = Asquare;
3693 *indexPeak = indexMax;
3694 *tPeak = tVec->
data[indexMax];
3729 UINT4 retLenDyn = indexStop;
3731 if (!((retLenDyn <= dynlength) && (dynlength <= retLen))) {
3732 XLALPrintError(
"XLAL Error - %s: incompatible lengths.\n", __func__);
3739 "XLAL Error - %s: failed to allocate REAL8Vector alphaJ2P.\n",
3744 XLALPrintError(
"XLAL Error - %s: failed to allocate REAL8Vector betaJ2P.\n",
3750 "XLAL Error - %s: failed to allocate REAL8Vector gammaJ2P.\n",
3754 memset((*alphaJ2P)->data, 0, retLen *
sizeof(
REAL8));
3755 memset((*betaJ2P)->data, 0, retLen *
sizeof(
REAL8));
3756 memset((*gammaJ2P)->data, 0, retLen *
sizeof(
REAL8));
3758 if (!SpinsAlmostAligned)
3765 REAL8 rvec[3] = {0, 0, 0};
3766 REAL8 pvec[3] = {0, 0, 0};
3767 REAL8 rdotvec[3] = {0, 0, 0};
3768 REAL8 Lhat[3] = {0, 0, 0};
3769 REAL8 LNhat[3] = {0, 0, 0};
3770 REAL8 Zframe[3] = {0, 0, 0};
3771 REAL8 e1PiniIbasis[3] = {0, 0, 0};
3772 REAL8 e2PiniIbasis[3] = {0, 0, 0};
3773 REAL8 e3PiniIbasis[3] = {0, 0, 0};
3774 REAL8 e1PiniJbasis[3] = {0, 0, 0};
3775 REAL8 e2PiniJbasis[3] = {0, 0, 0};
3779 for (
i = 0;
i < retLenDyn;
i++) {
3782 for (j = 0; j < 3; j++) {
3783 rvec[j] = seobdynamics->
array->
data[(1 + j) * dynlength +
i];
3784 pvec[j] = seobdynamics->
array->
data[(4 + j) * dynlength +
i];
3785 rdotvec[j] = seobdynamics->
array->
data[(15 + j) * dynlength +
i];
3793 for (j = 0; j < 3; j++) {
3794 Lhat[j] /= Lhatnorm;
3796 memcpy(Zframe, Lhat, 3 *
sizeof(
REAL8));
3801 for (j = 0; j < 3; j++) {
3802 LNhat[j] /= LNhatnorm;
3804 memcpy(Zframe, LNhat, 3 *
sizeof(
REAL8));
3817 (*alphaJ2P)->data[
i] = atan2(Ze2J, Ze1J);
3818 (*betaJ2P)->data[
i] = acos(Ze3J);
3825 memcpy(e3PiniIbasis, Zframe, 3 *
sizeof(
REAL8));
3827 memcpy(e1PiniIbasis, rvec, 3 *
sizeof(
REAL8));
3828 REAL8 e1PiniIbasisnorm =
3830 for (j = 0; j < 3; j++) {
3831 e1PiniIbasis[j] /= e1PiniIbasisnorm;
3851 REAL8 InitialGamma = atan2(e2PiniJbasis[2], -e1PiniJbasis[2]);
3860 REAL8 precEulerresult = 0, precEulererror = 0;
3861 gsl_integration_workspace *precEulerw =
3862 gsl_integration_workspace_alloc(1000);
3863 gsl_function precEulerF;
3865 gsl_spline *x_spline = gsl_spline_alloc(gsl_interp_cspline, retLenDyn);
3866 gsl_spline *y_spline = gsl_spline_alloc(gsl_interp_cspline, retLenDyn);
3867 gsl_interp_accel *x_acc = gsl_interp_accel_alloc();
3868 gsl_interp_accel *y_acc = gsl_interp_accel_alloc();
3869 gsl_spline_init(x_spline, seobdynamics->
tVec, (*alphaJ2P)->data, retLenDyn);
3870 gsl_spline_init(y_spline, seobdynamics->
tVec, (*betaJ2P)->data, retLenDyn);
3878 precEulerF.params = &precEulerparams;
3880 for (
i = 0;
i < retLenDyn;
i++) {
3882 (*gammaJ2P)->data[
i] = InitialGamma;
3884 gsl_integration_qags(&precEulerF, tVec[
i - 1], tVec[
i], 1
e-9, 1
e-9,
3885 1000, precEulerw, &precEulerresult,
3887 (*gammaJ2P)->data[
i] = (*gammaJ2P)->data[
i - 1] + precEulerresult;
3890 gsl_integration_workspace_free(precEulerw);
3891 gsl_spline_free(x_spline);
3892 gsl_spline_free(y_spline);
3893 gsl_interp_accel_free(x_acc);
3894 gsl_interp_accel_free(y_acc);
3939 if (!SpinsAlmostAligned) {
3942 REAL8 timeAttach = tVec->
data[indexStart - 1];
3943 REAL8 alphaAttach = alphaJ2P->
data[indexStart - 1];
3944 REAL8 betaAttach = betaJ2P->
data[indexStart - 1];
3945 REAL8 gammaAttach = gammaJ2P->
data[indexStart - 1];
3949 REAL8 omegaQNM220 = creal(sigmaQNM220);
3950 REAL8 omegaQNM210 = creal(sigmaQNM210);
3951 REAL8 precRate = omegaQNM220 - omegaQNM210;
3956 REAL8 cosbetaAttach = cos(betaAttach);
3957 for (
i = indexStart;
i < retLen;
i++) {
3959 alphaAttach + (tVec->
data[
i] - timeAttach) * precRate;
3960 betaJ2P->
data[
i] = betaAttach;
3961 gammaJ2P->
data[
i] = gammaAttach - cosbetaAttach *
3962 (tVec->
data[
i] - timeAttach) *
3968 for (
i = indexStart;
i < retLen;
i++) {
3969 alphaJ2P->
data[
i] = alphaAttach;
3970 betaJ2P->
data[
i] = betaAttach;
3971 gammaJ2P->
data[
i] = gammaAttach;
3976 XLALPrintError(
"XLAL Error - %s: flagEulerextension not recognized.\n",
3985 memset(&(alphaJ2P->
data[indexStart]), 0,
3986 (retLen - indexStart) *
sizeof(
REAL8));
3987 memset(&(betaJ2P->
data[indexStart]), 0,
3988 (retLen - indexStart) *
sizeof(
REAL8));
3989 memset(&(gammaJ2P->
data[indexStart]), 0,
3990 (retLen - indexStart) *
sizeof(
REAL8));
4047 UINT4 flagSymmetrizehPlminusm
4053 REAL8 t = 0., camp_real = 0., camp_imag = 0., phase = 0.,
alpha = 0.,
4060 for (
i = 0;
i < retLenTS;
i++) {
4067 char mode_string[32];
4068 for (
l = 2;
l <= modes_lmax;
l++) {
4069 for (
m = -
l;
m <=
l;
m++) {
4070 sprintf(mode_string,
"H_%d%d",
l,
m);
4093 memset(Dlmminusmp_amp->
data, 0, (Dlmminusmp_amp->
length) *
sizeof(
REAL8));
4094 memset(Dlmminusmp_phase->
data, 0, (Dlmminusmp_phase->
length) *
sizeof(
REAL8));
4097 gsl_spline *spline_Dlmmp_amp = gsl_spline_alloc(gsl_interp_cspline, retLenP);
4098 gsl_spline *spline_Dlmmp_phase =
4099 gsl_spline_alloc(gsl_interp_cspline, retLenP);
4100 gsl_spline *spline_Dlmminusmp_amp =
4101 gsl_spline_alloc(gsl_interp_cspline, retLenP);
4102 gsl_spline *spline_Dlmminusmp_phase =
4103 gsl_spline_alloc(gsl_interp_cspline, retLenP);
4104 gsl_interp_accel *accel_Dlmmp_amp = gsl_interp_accel_alloc();
4105 gsl_interp_accel *accel_Dlmmp_phase = gsl_interp_accel_alloc();
4106 gsl_interp_accel *accel_Dlmminusmp_amp = gsl_interp_accel_alloc();
4107 gsl_interp_accel *accel_Dlmminusmp_phase = gsl_interp_accel_alloc();
4110 gsl_spline *spline_camp_real = gsl_spline_alloc(gsl_interp_cspline, retLenP);
4111 gsl_spline *spline_camp_imag = gsl_spline_alloc(gsl_interp_cspline, retLenP);
4112 gsl_spline *spline_phase = gsl_spline_alloc(gsl_interp_cspline, retLenP);
4113 gsl_interp_accel *accel_camp_real = gsl_interp_accel_alloc();
4114 gsl_interp_accel *accel_camp_imag = gsl_interp_accel_alloc();
4115 gsl_interp_accel *accel_phase = gsl_interp_accel_alloc();
4121 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
4123 l = modes[nmode][0];
4124 m = modes[nmode][1];
4131 XLALPrintError(
"XLAL Error - %s: failure in CAmpPhaseSequence_Init for "
4132 "mode (l,m) = (%d,%d).\n",
4141 gsl_spline_init(spline_phase, tVecPmodes->
data, hPlm->
phase->
data, retLenP);
4148 for (
i = 0;
i < retLenTS;
i++) {
4152 camp_real = gsl_spline_eval(spline_camp_real, t, accel_camp_real);
4153 camp_imag = gsl_spline_eval(spline_camp_imag, t, accel_camp_imag);
4154 phase = gsl_spline_eval(spline_phase, t, accel_phase);
4155 hPlm_val = (camp_real + I * camp_imag) * cexp(I * phase);
4158 hPlmTS_tdata[
i] = t;
4159 hPlmTS_camprealdata[
i] = creal(hPlm_val);
4160 hPlmTS_campimagdata[
i] = cimag(hPlm_val);
4161 hPlmTS_phasedata[
i] = 0.;
4170 REAL8 *Dlmmp_amp_data = Dlmmp_amp->
data;
4171 REAL8 *Dlmmp_phase_data = Dlmmp_phase->
data;
4172 REAL8 *Dlmminusmp_amp_data = Dlmminusmp_amp->
data;
4173 REAL8 *Dlmminusmp_phase_data = Dlmminusmp_phase->
data;
4179 REAL8 *hPlmp_campreal_data;
4180 REAL8 *hPlmp_campimag_data;
4182 COMPLEX16 Dlmmp_amp_val, Dlmmp_phase_val, Dlmmp_val;
4183 COMPLEX16 Dlmminusmp_amp_val, Dlmminusmp_phase_val, Dlmminusmp_val;
4186 for (
l = 2;
l <= modes_lmax;
l++) {
4189 for (
m = -
l;
m <=
l;
m++) {
4193 hJlmmode_data = hJlmmode->
data->
data;
4196 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
4199 if (modes[nmode][0] !=
l)
4202 mp = modes[nmode][1];
4208 "allowed as mp<=0.\n",
4221 for (
i = 0;
i < retLenP;
i++) {
4227 if (flagSymmetrizehPlminusm) {
4235 gsl_spline_init(spline_Dlmmp_amp, tVecPmodes->
data, Dlmmp_amp->
data,
4237 gsl_spline_init(spline_Dlmmp_phase, tVecPmodes->
data, Dlmmp_phase->
data,
4239 if (flagSymmetrizehPlminusm) {
4240 gsl_spline_init(spline_Dlmminusmp_amp, tVecPmodes->
data,
4241 Dlmminusmp_amp->
data, retLenP);
4242 gsl_spline_init(spline_Dlmminusmp_phase, tVecPmodes->
data,
4243 Dlmminusmp_phase->
data, retLenP);
4245 for (
i = 0;
i < retLenTS;
i++) {
4247 Dlmmp_amp_val = gsl_spline_eval(spline_Dlmmp_amp, t, accel_Dlmmp_amp);
4249 gsl_spline_eval(spline_Dlmmp_phase, t, accel_Dlmmp_phase);
4252 cexp(-I * Dlmmp_phase_val);
4253 hPlmp_val = hPlmp_campreal_data[
i] + I * hPlmp_campimag_data[
i];
4254 hJlmmode_data[
i] += Dlmmp_val * hPlmp_val;
4255 if (flagSymmetrizehPlminusm) {
4256 Dlmminusmp_amp_val =
4257 gsl_spline_eval(spline_Dlmminusmp_amp, t, accel_Dlmminusmp_amp);
4258 Dlmminusmp_phase_val = gsl_spline_eval(spline_Dlmminusmp_phase, t,
4259 accel_Dlmminusmp_phase);
4261 Dlmminusmp_amp_val *
4262 cexp(-I * Dlmminusmp_phase_val);
4264 hJlmmode_data[
i] += Dlmminusmp_val * pow(-1,
l) * conj(hPlmp_val);
4273 gsl_spline_free(spline_camp_real);
4274 gsl_spline_free(spline_camp_imag);
4275 gsl_spline_free(spline_phase);
4276 gsl_interp_accel_free(accel_camp_real);
4277 gsl_interp_accel_free(accel_camp_imag);
4278 gsl_interp_accel_free(accel_phase);
4279 gsl_spline_free(spline_Dlmmp_amp);
4280 gsl_spline_free(spline_Dlmmp_phase);
4281 gsl_spline_free(spline_Dlmminusmp_amp);
4282 gsl_spline_free(spline_Dlmminusmp_phase);
4283 gsl_interp_accel_free(accel_Dlmmp_amp);
4284 gsl_interp_accel_free(accel_Dlmmp_phase);
4285 gsl_interp_accel_free(accel_Dlmminusmp_amp);
4286 gsl_interp_accel_free(accel_Dlmminusmp_phase);
4317 REAL8 amp_wigner = 0., phase_wigner = 0.;
4324 memcpy(tI->
data, tJdata, retLen *
sizeof(
REAL8));
4329 char mode_string[32];
4330 for (
l = 2;
l <= modes_lmax;
l++) {
4331 for (
m = -
l;
m <=
l;
m++) {
4332 sprintf(mode_string,
"H_%d%d",
l,
m);
4357 for (
l = 2;
l <= modes_lmax;
l++) {
4360 for (
m = -
l;
m <=
l;
m++) {
4364 hIlmmode_data = hIlmmode->
data->
data;
4367 for (mp = -
l; mp <=
l; mp++) {
4371 hJlmpmode_data = hJlmpmode->
data->
data;
4376 D_wigner = amp_wigner *
4377 cexp(-I * phase_wigner);
4380 for (
i = 0;
i < retLen;
i++) {
4381 hIlmmode_data[
i] += D_wigner * hJlmpmode_data[
i];
4418 for (
l = 2;
l <= modes_lmax;
l++) {
4419 for (
m = -
l;
m <=
l;
m++) {
4430 hpc_contrib = sYlm * hIlm_data[
i];
4431 hplusdata[
i] += amp0 * creal(hpc_contrib);
4432 hcrossdata[
i] += -amp0 * cimag(hpc_contrib);
4446 LALValue *modearray,
4451 for (
INT4 l = 2;
l <= lmax;
l++) {
4458 "XLAL Warning - %s: mode (l,m)=(%d,%d) present in mode array -- "
4459 "in our conventions, we only consider m>0. Mode ignored.\n",
4475 LALValue *modearray,
4481 for (
INT4 l = 2;
l <= lmax;
l++) {
4485 modes[nmode][0] =
l;
4486 modes[nmode][1] =
m;
4490 "XLAL Warning - %s: mode (l,m)=(%d,%d) present in mode array -- "
4491 "in our conventions, we only consider m>0. Mode ignored.\n",
4506 UINT4 mode_highest_freqL = ell_max;
4507 UINT4 mode_highest_freqM = ell_max;
4512 modefreqVec.
data = &modeFreq;
4515 mode_highest_freqL, mode_highest_freqM,
4522 "frequency!\nAt present this situation is not supported.\n",
4602 const REAL8 INdeltaT,
4620 LALValue *modearray,
4628 XLALPrintError(
"XLAL Error - %s: pointer to LALDict seobflags is NULL.\n",
4635 INT4 SpinAlignedEOBversion = 0;
4637 SpinAlignedEOBversion = 4;
4639 SpinAlignedEOBversion =
4644 INT4 flagSymmetrizehPlminusm = 0;
4646 flagSymmetrizehPlminusm = 1;
4648 flagSymmetrizehPlminusm =
4653 INT4 flagHamiltonianDerivative = 0;
4657 flagHamiltonianDerivative =
4662 INT4 flagEulerextension = 0;
4666 flagEulerextension =
4670 INT4 flagZframe = 0;
4684 printf(
"************************************\n");
4685 printf(
"XLALSimIMRSpinPrecEOBWaveformAll\n");
4686 printf(
"************************************\n");
4687 printf(
"phi = %.16e\n", phi);
4688 printf(
"INdeltaT = %.16e\n", INdeltaT);
4689 printf(
"m1SI = %.16e\n", m1SI);
4690 printf(
"m2SI = %.16e\n", m2SI);
4691 printf(
"fMin = %.16e\n", fMin);
4692 printf(
"r = %.16e\n",
r);
4693 printf(
"inc = %.16e\n", inc);
4694 printf(
"chi1x = %.16e\n", chi1x);
4695 printf(
"chi1y = %.16e\n", chi1y);
4696 printf(
"chi1z = %.16e\n", chi1z);
4697 printf(
"chi2x = %.16e\n", chi2x);
4698 printf(
"chi2y = %.16e\n", chi2y);
4699 printf(
"chi2z = %.16e\n", chi2z);
4700 printf(
"flagHamiltonianDerivative = %d\n", flagHamiltonianDerivative);
4701 printf(
"flagEulerextension = %d\n", flagEulerextension);
4702 printf(
"flagZframe = %d\n", flagZframe);
4711 printf(
"STEP 0) Allocate memory, prepare parameters and pre-compute "
4712 "coeffs for EOB Hamiltonian, flux and waveform\n");
4715 if (!((SpinAlignedEOBversion == 2) || (SpinAlignedEOBversion == 4))) {
4716 XLALPrintError(
"XLAL Error - %s: unauthorized SpinAlignedEOBversion %d.\n",
4717 __func__, SpinAlignedEOBversion);
4725 REAL8 mTotal = m1 + m2;
4727 REAL8 eta = m1 * m2 / (mTotal * mTotal);
4739 REAL8 INchi1data[3] = {chi1x, chi1y, chi1z};
4740 REAL8 INchi2data[3] = {chi2x, chi2y, chi2z};
4742 INchi1.
data = INchi1data;
4743 INchi2.
data = INchi2data;
4747 UINT4 ellMaxForNyquistCheck = 2;
4754 ellMaxForNyquistCheck = ell_max;
4759 if (ellMaxForNyquistCheck<2){
4760 XLALPrintError(
"Custom value of ell < 2 was passed to Nyquist check. This is not supported!");
4763 if(ellMaxForNyquistCheck < ell_max){
4764 XLALPrintError(
"WARNING: Using ell=%d for Nyqusit check of srate, even though max ell of waveforms produced is %d\n",ellMaxForNyquistCheck,ell_max);
4767 ellMaxForNyquistCheck,
SEOBNRv4P, INdeltaT),
4773 if (sqrt(chi1x * chi1x + chi1y * chi1y + chi1z * chi1z) > 1 ||
4774 sqrt(chi2x * chi2x + chi2y * chi2y + chi2z * chi2z) > 1) {
4775 XLALPrintError(
"XLAL Error - %s: Spins have magnitude > 1 !\n", __func__);
4779 if (m1 < 0 || m2 < 0) {
4780 XLALPrintError(
"XLAL Error - %s: One of the masses is < 0 !\n", __func__);
4785 printf(
"Warning: you are attempting to generate waveforms for BHs with "
4786 "total mass < 2 M_Sun. This may take a *very* long time\n");
4788 if (m1 / m2 > 100 || m1 / m2 < 1 / 100) {
4789 XLALPrintError(
"XLAL Error - %s: Mass ratio is > 100 !\n", __func__);
4795 REAL8 EPS_ALIGN = 1.0e-4;
4802 REAL8 freqMinRad = 0;
4805 if (fMin > freqMinRad) {
4806 XLALPrintError(
"XLAL Error - %s: Intitial frequency is too high, the limit "
4808 __func__, freqMinRad);
4816 REAL8 EPS_ABS = 1.0e-8;
4817 REAL8 EPS_REL = 1.0e-8;
4821 REAL8 deltaT_min = 8.0e-5;
4828 REAL8 tStepBack = 150.;
4835 UINT4 flagConstantSampling = 0;
4865 *mergerParams = NULL;
4866 *seobdynamicsAdaSVector = NULL;
4867 *seobdynamicsHiSVector = NULL;
4868 *seobdynamicsAdaSHiSVector = NULL;
4938 memset(&seobParams, 0,
sizeof(seobParams));
4939 memset(&seobCoeffs, 0,
sizeof(seobCoeffs));
4940 memset(&seobCoeffConsts, 0,
sizeof(seobCoeffConsts));
4941 memset(&eobParams, 0,
sizeof(eobParams));
4942 memset(&nqcCoeffs, 0,
sizeof(nqcCoeffs));
4943 memset(&hCoeffs, 0,
sizeof(hCoeffs));
4944 memset(&prefixes, 0,
sizeof(prefixes));
4950 XLALPrintError(
"XLAL Error - %s: dominant harmonic (2,2) not present in "
4951 "input ModeArray -- will be needed internally.\n",
4958 INT4 modes[nmodes][2];
4959 memset(modes, 0, 2 * nmodes *
sizeof(
INT4));
4962 printf(
"P-frame modes :\n");
4963 for (
UINT4 nmode = 0; nmode < nmodes; nmode++)
4964 printf(
"(%d, %d)\n", modes[nmode][0], modes[nmode][1]);
4969 REAL8 s1Vecdata[3] = {0.};
4970 REAL8 s2Vecdata[3] = {0.};
4971 REAL8 sigmaStardata[3] = {0.};
4972 REAL8 sigmaKerrdata[3] = {0.};
4974 s1Vec.
data = s1Vecdata;
4975 s2Vec.
data = s2Vecdata;
4976 sigmaStar.
data = sigmaStardata;
4977 sigmaKerr.
data = sigmaKerrdata;
4979 for (
UINT4 j = 0; j < 3; j++) {
4980 s1Vec.
data[j] = INchi1.
data[j] * m1 * m1 / mTotal / mTotal;
4981 s2Vec.
data[j] = INchi2.
data[j] * m2 * m2 / mTotal / mTotal;
4992 seobParams.
s1Vec = &s1Vec;
4993 seobParams.
s2Vec = &s2Vec;
5005 seobParams.
chi1 = chi1z;
5006 seobParams.
chi2 = chi2z;
5013 eobParams.
eta = eta;
5016 tidal1.
mByM = m1SI / (m1SI + m2SI);
5023 tidal2.
mByM = m2SI / (m1SI + m2SI);
5030 seobCoeffs.
tidal1 = &tidal1;
5031 seobCoeffs.
tidal2 = &tidal2;
5033 hCoeffs.
tidal1 = &tidal1;
5034 hCoeffs.
tidal2 = &tidal2;
5039 REAL8 Lhat[3] = {0.0, 0.0, 1.0};
5042 REAL8 S1_perp[3] = {0, 0, 0};
5043 REAL8 S2_perp[3] = {0, 0, 0};
5044 for (
UINT4 jj = 0; jj < 3; jj++) {
5045 S1_perp[jj] = s1Vec.
data[jj] - tempS1_p * Lhat[jj];
5046 S2_perp[jj] = s2Vec.
data[jj] - tempS2_p * Lhat[jj];
5050 if (sKerr_norm > 1
e-6) {
5051 S_con = sigmaKerr.
data[0] * Lhat[0] + sigmaKerr.
data[1] * Lhat[1] +
5052 sigmaKerr.
data[2] * Lhat[2];
5053 S_con /= (1 - 2 * eta);
5056 sKerr_norm / (1 - 2 * eta) / 2.;
5061 &seobCoeffs, eta,
a, S_con, SpinAlignedEOBversion) ==
XLAL_FAILURE) {
5064 "XLAL Error: XLALSimIMRCalculateSpinPrecEOBHCoeffs_v2 failed.\n");
5075 "XLALSimIMREOBComputeNewtonMultipolePrefixes failed.\n",
5086 printf(
"STEP 1) Solve for initial conditions\n");
5088 flagConstantSampling = 0;
5090 REAL8 MfMin = mTScaled * fMin;
5093 UINT4 SpinsAlmostAligned = 0;
5094 if ((sqrt(chi1x * chi1x + chi1y * chi1y) < EPS_ALIGN) &&
5095 (sqrt(chi2x * chi2x + chi2y * chi2y) < EPS_ALIGN)) {
5096 SpinsAlmostAligned = 1;
5097 INchi1.
data[0] = 0.;
5098 INchi1.
data[1] = 0.;
5099 INchi2.
data[0] = 0.;
5100 INchi2.
data[1] = 0.;
5104 flagConstantSampling = 1;
5106 SpinsAlmostAligned = 0;
5115 XLALPrintError(
"XLAL Error - %s: SEOBInitialConditions failed.\n",
5126 printf(
"STEP 2) Evolve EOB trajectory with adaptive sampling (AdaS)\n");
5128 UINT4 retLenAdaS = 0;
5132 REAL8 tstartAdaS = 0.;
5136 EPS_REL,
deltaT, deltaT_min, tstartAdaS, tendAdaS,
5137 &seobParams, flagConstantSampling,
5141 "XLAL Error - %s: SEOBIntegrateDynamicsAdaptiveSampling failed.\n",
5149 &seobdynamicsAdaS, dynamicsAdaS, retLenAdaS, &seobParams,
5150 flagHamiltonianDerivative, flagZframe) ==
XLAL_FAILURE) {
5152 XLALPrintError(
"XLAL Error - %s: SEOBComputeExtendedSEOBdynamics failed.\n",
5163 printf(
"STEP 3) Step back and evolve EOB trajectory at high sampling rate "
5167 if (!SpinsAlmostAligned){
5175 REAL8 deltaTHiS = 1. / 50;
5182 REAL8 tstartHiSTarget = seobdynamicsAdaS->
tVec[retLenAdaS - 1] - tStepBack;
5183 INT4 indexstartHiS = retLenAdaS - 1;
5184 while ((indexstartHiS > 0) &&
5185 (seobdynamicsAdaS->
tVec[indexstartHiS] > tstartHiSTarget))
5187 REAL8 tstartHiS = seobdynamicsAdaS->
tVec[indexstartHiS];
5196 XLALPrintError(
"XLAL Error - %s: SEOBInterpolateDynamicsAtTime failed.\n",
5203 "XLAL Error - %s: failed to allocate REAL8Vector ICvaluesHiS.\n",
5207 memcpy(ICvaluesHiS->
data, &(seobvalues_tstartHiS->
data[1]),
5208 14 *
sizeof(
REAL8));
5216 UINT4 retLenHiS = 0;
5218 tstartHiS + tStepBack;
5220 flagConstantSampling = 1;
5223 EPS_REL, deltaTHiS, 0., tstartHiS, tendHiS,
5224 &seobParams, flagConstantSampling,
5228 "XLAL Error - %s: SEOBIntegrateDynamicsConstantSampling failed.\n",
5236 &seobParams, flagHamiltonianDerivative,
5239 XLALPrintError(
"XLAL Error - %s: SEOBComputeExtendedSEOBdynamics failed.\n",
5245 INT4 foundPeakOmega = 0;
5246 REAL8 tPeakOmega = 0.;
5248 seobdynamicsHiS, retLenHiS, &seobParams,
5249 flagHamiltonianDerivative);
5257 printf(
"STEP 4) Get final J/L/spins from HiS dynamics at peak of Omega, "
5258 "compute constant angles EulerI2J\n");
5266 XLALPrintError(
"XLAL Error - %s: SEOBInterpolateDynamicsAtTime failed at "
5275 timeVec.
length = retLenAdaS;
5276 timeVec.
data = seobdynamicsAdaS->
tVec;
5278 for (
UINT4 jj = 0; jj < retLenAdaS; jj++) {
5295 REAL8 time_10M = timeVec.
data[index_10M];
5300 "XLAL Error - %s: SEOBInterpolateDynamicsAtTime failed at time_10M.\n",
5307 m1, m2, flagZframe);
5309 2, 2, m1, m2, chi1L_tPeakOmega->
data[2], chi2L_tPeakOmega->
data[2]);
5312 REAL8 tAttach = tPeakOmega - Deltat22;
5328 REAL8 e1Jdata[3] = {0.};
5329 REAL8 e2Jdata[3] = {0.};
5330 REAL8 e3Jdata[3] = {0.};
5339 REAL8 alphaI2J = 0., betaI2J = 0., gammaI2J = 0.;
5340 if (!SpinsAlmostAligned) {
5351 printf(
"STEP 5) Compute P-frame of modes amp/phase on HiS and compute NQC "
5355 &nqcCoeffsList, modes, nmodes, tPeakOmega, seobdynamicsHiS,
5356 &seobParams, chi1L_tPeakOmega, chi2L_tPeakOmega) ==
XLAL_FAILURE) {
5358 XLALPrintError(
"XLAL Error - %s: NQC computation failed.\n", __func__);
5369 printf(
"STEP 6) Compute P-frame amp/phase on HiS, now including NQC\n");
5377 seobdynamicsHiS, nqcCoeffsList,
5378 &seobParams, flagNQC);
5385 printf(
"STEP 7) Attach RD to the P-frame waveform\n");
5388 REAL8 finalMass = 0., finalSpin = 0.;
5392 XLALPrintError(
"XLAL Error - %s: SEOBGetFinalSpinMass failed.\n", __func__);
5406 if (finalSpin < -0.9996)
5407 finalSpin = -0.9996;
5408 if (finalSpin > 0.9996)
5412 XLAL_PRINT_INFO(
"final mass = %e, final spin = %e\n", finalMass, finalSpin);
5420 COMPLEX16 sigmaQNM220estimatephysical = 0.;
5421 sigmaQNM220estimatephysicalVec.
length = 1;
5422 sigmaQNM220estimatephysicalVec.
data = &sigmaQNM220estimatephysical;
5424 m2, finalMass, finalSpin, 2,
5428 "XLAL Error - %s: failure in "
5429 "XLALSimIMREOBGenerateQNMFreqV2FromFinalPrec for mode (l,m) = (2,2).\n",
5433 COMPLEX16 sigmaQNM220estimate = mTScaled * sigmaQNM220estimatephysical;
5436 UINT4 retLenRDPatch =
5437 (
UINT4)ceil(40 / (cimag(sigmaQNM220estimate) * deltaTHiS));
5447 &listhPlm_HiSRDpatch, &sigmaQNMlm0, modes, nmodes, finalMass, finalSpin,
5448 listhPlm_HiS, deltaTHiS, retLenHiS, retLenRDPatch, tAttach,
5449 seobvalues_tPeakOmega, seobdynamicsHiS, &seobParams, flagZframe, debug);
5457 printf(
"STEP 8) Build the joined dynamics AdaS+HiS up to attachment, "
5458 "joined P-modes AdaS+HiS+RDpatch\n");
5464 seobdynamicsAdaS, nqcCoeffsList,
5465 &seobParams, flagNQC);
5469 UINT4 retLenPmodes = 0;
5471 UINT4 indexJoinHiS = 0;
5472 REAL8 tJoinHiS = 0.;
5474 UINT4 indexJoinAttach = 0;
5475 REAL8 tJoinAttach = 0.;
5479 &tJoinAttach, &indexJoinAttach, retLenRDPatch, deltaTHiS,
5480 tstartHiS, tAttach, seobdynamicsAdaS, seobdynamicsHiS);
5488 indexJoinHiS, indexJoinAttach);
5493 nmodes, indexstartHiS);
5497 UINT4 indexPeak = 0;
5508 printf(
"STEP 9) Compute Euler angles J2P from AdaS and HiS dynamics up to "
5514 retLenPmodes, indexJoinAttach,
5515 seobdynamicsAdaSHiS, &seobParams,
5518 XLALPrintError(
"XLAL Error - %s: SEOBEulerJ2PFromDynamics failed.\n",
5529 printf(
"STEP 10) Compute Euler angles J2P extension after attachment\n");
5536 COMPLEX16 sigmaQNM220 = 0., sigmaQNM210 = 0.;
5538 sigmaQNM220physicalVec.
length = 1;
5539 sigmaQNM210physicalVec.
length = 1;
5542 sigmaQNM220physicalVec.
data = &sigmaQNM220physicalval;
5543 sigmaQNM210physicalVec.
data = &sigmaQNM210physicalval;
5547 m2, finalMass, finalSpin, 2,
5551 "XLAL Error - %s: failure in "
5552 "XLALSimIMREOBGenerateQNMFreqV2FromFinalPrec for mode (l,m) = (2,2).\n",
5557 m2, finalMass, finalSpin, 2,
5561 "XLAL Error - %s: failure in "
5562 "XLALSimIMREOBGenerateQNMFreqV2FromFinalPrec for mode (l,m) = (2,1).\n",
5566 sigmaQNM220 = mTScaled * sigmaQNM220physicalVec.
data[0];
5567 sigmaQNM210 = mTScaled * sigmaQNM210physicalVec.
data[0];
5573 *alphaJ2P, *betaJ2P, *gammaJ2P, sigmaQNM220, sigmaQNM210, *tVecPmodes,
5574 retLenPmodes, indexJoinAttach, &seobParams, flagEulerextension, flip);
5582 printf(
"STEP 11) Compute modes hJlm on the output time series by rotating "
5583 "and interpolating the modes hPlm\n");
5587 floor(((*tVecPmodes)->data[retLenPmodes - 1] - (*tVecPmodes)->data[0]) /
5592 hJlm, modes, nmodes, modes_lmax,
deltaT, retLenTS, *tVecPmodes,
5593 listhPlm, *alphaJ2P, *betaJ2P, *gammaJ2P,
5597 "XLAL Error - %s: failure in "
5598 "SEOBRotateInterpolatehJlmReImFromSphHarmListhPlmAmpPhase.\n",
5609 printf(
"STEP 12) Rotate waveform from J-frame to the output I-frame on "
5610 "timeseries-sampling (constant Wigner coeffs)\n");
5622 printf(
"STEP 13) Compute hplus, hcross from I-frame waveform on timeseries "
5648 printf(
"STEP -1) Output and cleanup\n");
5659 "XLAL Error - %s: failed to allocate REAL8Vector mergerParams.\n",
5663 (*mergerParams)->data[0] = tPeakOmega;
5664 (*mergerParams)->data[1] = tAttach;
5665 (*mergerParams)->data[2] = tPeak;
5666 (*mergerParams)->data[3] = Jfinal->
data[0];
5667 (*mergerParams)->data[4] = Jfinal->
data[1];
5668 (*mergerParams)->data[5] = Jfinal->
data[2];
5669 (*mergerParams)->data[6] = finalMass;
5670 (*mergerParams)->data[7] = finalSpin;
5672 for (
UINT4 nmode = 0; nmode < nmodes; nmode++) {
5673 (*mergerParams)->data[9 + 2 * nmode] = creal(sigmaQNMlm0->
data[nmode]);
5674 (*mergerParams)->data[9 + 2 * nmode + 1] = cimag(sigmaQNMlm0->
data[nmode]);
5679 (*hcross) = hcrossTS;
5685 *seobdynamicsAdaSVector =
5687 *seobdynamicsHiSVector =
5689 *seobdynamicsAdaSHiSVector =
5691 memcpy((*seobdynamicsAdaSVector)->data, seobdynamicsAdaS->
array->
data,
5693 memcpy((*seobdynamicsHiSVector)->data, seobdynamicsHiS->
array->
data,
5695 memcpy((*seobdynamicsAdaSHiSVector)->data, seobdynamicsAdaSHiS->
array->
data,
5707 memset((*hP22_amp)->data, 0, retLenPmodes *
sizeof(
REAL8));
5708 memset((*hP22_phase)->data, 0, retLenPmodes *
sizeof(
REAL8));
5711 retLenPmodes *
sizeof(
REAL8));
5713 retLenPmodes *
sizeof(
REAL8));
5721 memset((*hP21_amp)->data, 0, retLenPmodes *
sizeof(
REAL8));
5722 memset((*hP21_phase)->data, 0, retLenPmodes *
sizeof(
REAL8));
5725 retLenPmodes *
sizeof(
REAL8));
5727 retLenPmodes *
sizeof(
REAL8));
5735 memset((*hP33_amp)->data, 0, retLenPmodes *
sizeof(
REAL8));
5736 memset((*hP33_phase)->data, 0, retLenPmodes *
sizeof(
REAL8));
5739 retLenPmodes *
sizeof(
REAL8));
5741 retLenPmodes *
sizeof(
REAL8));
5749 memset((*hP44_amp)->data, 0, retLenPmodes *
sizeof(
REAL8));
5750 memset((*hP44_phase)->data, 0, retLenPmodes *
sizeof(
REAL8));
5753 retLenPmodes *
sizeof(
REAL8));
5755 retLenPmodes *
sizeof(
REAL8));
5763 memset((*hP55_amp)->data, 0, retLenPmodes *
sizeof(
REAL8));
5764 memset((*hP55_phase)->data, 0, retLenPmodes *
sizeof(
REAL8));
5767 retLenPmodes *
sizeof(
REAL8));
5769 retLenPmodes *
sizeof(
REAL8));
5773 if (ICvalues != NULL)
5775 if (dynamicsAdaS != NULL)
5779 if (seobdynamicsAdaS != NULL)
5781 if (seobvalues_tstartHiS != NULL)
5783 if (ICvaluesHiS != NULL)
5785 if (dynamicsHiS != NULL)
5787 if (seobdynamicsHiS != NULL)
5789 if (seobvalues_tPeakOmega != NULL)
5791 if (seobvalues_test != NULL)
5795 if (Lhatfinal != NULL)
5797 if (nqcCoeffsList != NULL)
5799 if (listhPlm_HiS != NULL)
5801 if (listhPlm_HiSRDpatch != NULL)
5803 if (listhPlm_AdaS != NULL)
5805 if (seobdynamicsAdaSHiS != NULL)
5807 if (listhPlm != NULL)
5809 if (chi1L_tPeakOmega != NULL)
5811 if (chi2L_tPeakOmega != NULL)
5813 if (sigmaQNMlm0 != NULL)
5818 #undef PRINT_ALL_PARAMS
int XLALDictContains(const LALDict *dict, const char *key)
void XLALDestroyDict(LALDict *dict)
LALDict * XLALCreateDict(void)
INT4 XLALDictLookupINT4Value(LALDict *dict, const char *key)
int XLALDictInsertINT4Value(LALDict *dict, const char *key, INT4 value)
INT4 XLALSimIMREOBFinalMassSpinPrec(REAL8 *finalMass, REAL8 *finalSpin, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], Approximant approximant)
Computes the final mass and spin of the black hole resulting from merger.
INT4 XLALSimIMREOBGenerateQNMFreqV2FromFinalPrec(COMPLEX16Vector *modefreqs, const REAL8 mass1, const REAL8 mass2, const REAL8 finalMass, REAL8 finalSpin, UINT4 l, INT4 m, UINT4 nmodes)
This function generates the quasinormal mode frequencies for a black hole ringdown.
INT4 XLALSimIMREOBGenerateQNMFreqV2Prec(COMPLEX16Vector *modefreqs, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], UINT4 l, INT4 m, UINT4 nmodes, Approximant approximant)
This function generates the quasinormal mode frequencies for a black hole ringdown.
double XLALSimLocateMaxAmplTime(REAL8Vector *timeHi, COMPLEX16Vector *hP22, int *found)
flagSEOBNRv4P_euler_extension
@ FLAG_SEOBNRv4P_EULEREXT_QNM_SIMPLE_PRECESSION
QNM-based simple precession prescription post-merger.
@ FLAG_SEOBNRv4P_EULEREXT_CONSTANT
Euler angles set to constants post-merger.
@ FLAG_SEOBNRv4P_ZFRAME_L
set Z axis of the P-frame along L
@ FLAG_SEOBNRv4P_ZFRAME_LN
set Z axis of the P-frame along LN
flagSEOBNRv4P_hamiltonian_derivative
@ FLAG_SEOBNRv4P_HAMILTONIAN_DERIVATIVE_ANALYTICAL
use analytical derivatives (opt)
@ FLAG_SEOBNRv4P_HAMILTONIAN_DERIVATIVE_NUMERICAL
use numerical derivatives (pre-opt)
static int XLALSimIMRCalculateSpinPrecEOBHCoeffs_v2(SpinEOBHCoeffs *coeffs, const REAL8 eta, REAL8 a, REAL8 chi, const UINT4 SpinAlignedEOBversion)
This function is used to calculate some coefficients which will be used in the spinning EOB Hamiltoni...
static UNUSED INT4 XLALSimIMREOBAttachFitRingdown(REAL8Vector *signal1, REAL8Vector *signal2, const INT4 l, const INT4 m, const REAL8 dt, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1x, const REAL8 spin1y, const REAL8 spin1z, const REAL8 spin2x, const REAL8 spin2y, const REAL8 spin2z, const REAL8 domega220, const REAL8 dtau220, const REAL8 domega210, const REAL8 dtau210, const REAL8 domega330, const REAL8 dtau330, const REAL8 domega440, const REAL8 dtau440, const REAL8 domega550, const REAL8 dtau550, const UINT2 TGRflag, REAL8Vector *timeVec, REAL8Vector *matchrange, Approximant approximant, UINT4 *indAmpMax)
The main function for performing the ringdown attachment for SEOBNRv4 (and beyond) This is the functi...
static UNUSED int XLALSimIMRSpinEOBNonQCCorrection(COMPLEX16 *restrict nqc, REAL8Vector *restrict values, const REAL8 omega, EOBNonQCCoeffs *restrict coeffs)
This function calculates the non-quasicircular correction to apply to the waveform.
static UNUSED REAL8 XLALSimIMREOBGetNRSpinPeakDeltaTv4(INT4 UNUSED l, INT4 UNUSED m, REAL8 UNUSED m1, REAL8 UNUSED m2, REAL8 UNUSED chi1, REAL8 UNUSED chi2)
The time difference between the orbital peak and the peak amplitude of the mode in question (currentl...
static UNUSED int XLALSimIMRSpinEOBCalculateNQCCoefficientsV4(REAL8Vector *restrict amplitude, REAL8Vector *restrict phase, REAL8Vector *restrict rVec, REAL8Vector *restrict prVec, REAL8Vector *restrict orbOmegaVec, INT4 modeL, INT4 modeM, REAL8 timePeak, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 chiA, REAL8 chiS, EOBNonQCCoeffs *restrict coeffs)
This function computes the coefficients a3s, a4, etc.
static UNUSED int XLALSimIMREOBComputeNewtonMultipolePrefixes(NewtonMultipolePrefixes *prefix, const REAL8 m1, const REAL8 m2)
Function which computes the various coefficients in the Newtonian multipole.
static double f_alphadotcosi(double x, void *inparams)
const UINT4 lmModes[NMODES][2]
static int XLALSpinAlignedHcapDerivative(double t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
SEOBHCoeffConstants XLALEOBSpinPrecCalcSEOBHCoeffConstants(REAL8 eta)
Optimized routine for calculating coefficients for the v3 Hamiltonian.
static REAL8 XLALSimIMRSpinPrecEOBHamiltonian(const REAL8 eta, REAL8Vector *restrict x, REAL8Vector *restrict p, REAL8Vector *restrict s1Vec, REAL8Vector *restrict s2Vec, REAL8Vector *restrict sigmaKerr, REAL8Vector *restrict sigmaStar, int tortoise, SpinEOBHCoeffs *coeffs)
static REAL8 * cross_product(const REAL8 values1[], const REAL8 values2[], REAL8 result[])
static int XLALSpinPrecHcapRvecDerivative(double UNUSED t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
Function to calculate numerical derivatives of the spin EOB Hamiltonian, to get , as decribed in Eqs.
static REAL8 inner_product(const REAL8 values1[], const REAL8 values2[])
Functions to compute the inner product and cross products between vectors.
static int XLALSpinPrecHcapExactDerivative(double UNUSED t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
Function to calculate numerical derivatives of the spin EOB Hamiltonian, which correspond to time der...
static int XLALSpinPrecHcapNumericalDerivative(double UNUSED t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
Function to calculate numerical derivatives of the spin EOB Hamiltonian, which correspond to time der...
static int XLALSimIMRSpinEOBInitialConditions(REAL8Vector *initConds, const REAL8 mass1, const REAL8 mass2, const REAL8 fMin, const REAL8 inc, const REAL8 spin1[], const REAL8 spin2[], SpinEOBParams *params, INT4 use_optimized_v2)
Main function for calculating the spinning EOB initial conditions, following the quasi-spherical init...
static int XLALSimIMRSpinEOBInitialConditionsPrec(REAL8Vector *initConds, const REAL8 mass1, const REAL8 mass2, const REAL8 fMin, const REAL8 inc, const REAL8 spin1[], const REAL8 spin2[], SpinEOBParams *params, INT4 use_optimized)
Main function for calculating the spinning EOB initial conditions, following the quasi-spherical init...
static UNUSED int RotationMatrixActiveFromBasisVectors(REAL8Array *R, const REAL8 e1p[], const REAL8 e2p[], const REAL8 e3p[])
Active rotation matrix from orthonormal basis (e1, e2, e3) to (e1', e2', e3') Input are e1',...
static UNUSED int EulerAnglesZYZFromRotationMatrixActive(REAL8 *alpha, REAL8 *beta, REAL8 *gamma, REAL8Array *R)
Computes the Euler angles in the (z,y,z) convention corresponding to a given 3*3 active rotation matr...
static int SEOBConvertSpinAlignedDynamicsToGenericSpins(REAL8Array **dynamics, REAL8Array *dynamics_spinaligned, UINT4 retLen, REAL8 chi1, REAL8 chi2, SpinEOBParams *seobParams)
This function converts a spin-aligned dynamics as output by the Runge-Kutta integrator to a generic-s...
static int SEOBLhatfromDynamics(REAL8Vector **L, REAL8Vector *seobvalues, SpinEOBParams *seobParams, const flagSEOBNRv4P_Zframe flagZframe)
This function computes the L-hat vector.
static UNUSED int XLALEOBFindRobustPeak(REAL8 *tPeakQuant, REAL8Vector *tVec, REAL8Vector *quantVec, UINT4 window_width)
static int SEOBGetLMaxInModeArray(LALValue *modearray, int lmax)
This function returns the maximum ell in the mode array.
SphHarmTimeSeries * XLALSimIMRSpinPrecEOBModes(const REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fMin, const REAL8 r, const REAL8 INspin1[], const REAL8 INspin2[], UNUSED const UINT4 PrecEOBversion, LALDict *LALParams)
Standard interface for SEOBNRv4P modes generator: calls XLALSimIMRSpinPrecEOBWaveformAll.
static UINT4 FindClosestIndex(REAL8Vector *vec, REAL8 value)
This function finds the index in a vector such that the value at the index closest to an input value.
static REAL8 SEOBWignerDPhase(INT4 m, INT4 mp, REAL8 alpha, REAL8 gamma)
static int SEOBInterpolateDynamicsAtTime(REAL8Vector **seobdynamics_values, REAL8 t, SEOBdynamics *seobdynamics)
This function computes all extended dynamics values at a given time by interpolating the dynamics arr...
static int SEOBLocateTimePeakOmega(REAL8 *tPeakOmega, INT4 *foundPeakOmega, UNUSED REAL8Array *dynamics, SEOBdynamics *seobdynamics, UINT4 retLen, UNUSED SpinEOBParams *seobParams, UNUSED flagSEOBNRv4P_hamiltonian_derivative flagHamiltonianDerivative)
This function finds the peak of omega.
static UNUSED int SEOBLocateTimePeakModeAmp(REAL8 *tPeakAmp, INT4 *foundPeakAmp, CAmpPhaseSequence *hlm, SEOBdynamics *seobdynamics, UINT4 retLen)
This function looks for the peak of a mode amplitude.
static int SEOBdynamics_Destroy(SEOBdynamics *seobdynamics)
static int SEOBIntegrateDynamics(REAL8Array **dynamics, UINT4 *retLenOut, REAL8Vector *ICvalues, REAL8 EPS_ABS, REAL8 EPS_REL, REAL8 deltaT, REAL8 deltaT_min, REAL8 tstart, REAL8 tend, SpinEOBParams *seobParams, UINT4 flagConstantSampling, flagSEOBNRv4P_hamiltonian_derivative flagHamiltonianDerivative)
This function integrates the SEOBNRv4P dynamics.
static int CAmpPhaseSequence_Destroy(CAmpPhaseSequence *campphase)
static INT4 XLALCheck_EOB_mode_array_structure(LALValue *ModeArray, UINT4 PrecEOBversion)
ModeArray is a structure which allows to select the the co-precessing frame modes to include in the w...
static INT4 XLALSetup_EOB__std_mode_array_structure(LALValue *ModeArray, UINT4 PrecEOBversion)
ModeArray is a structure which allows to select the the co-precessing frame modes to include in the w...
static SphHarmListCAmpPhaseSequence * SphHarmListCAmpPhaseSequence_GetMode(SphHarmListCAmpPhaseSequence *list, UINT4 l, INT4 m)
static int SEOBJoinTimeVector(REAL8Vector **tVecPmodes, UINT4 *retLenPmodes, REAL8 *tJoinHiS, UINT4 *indexJoinHiS, REAL8 *tJoinAttach, UINT4 *indexJoinAttach, UINT4 retLenHiSRDpatch, REAL8 deltaTHiS, REAL8 tstartHiS, REAL8 tAttach, SEOBdynamics *seobdynamicsAdaS, SEOBdynamics *seobdynamicsHiS)
This function constructs the joined vector of times (AdaS+HiS+RDpatch) and keeps the jonction indices...
static int SEOBAttachRDToSphHarmListhPlm(SphHarmListCAmpPhaseSequence **listhPlm_RDattached, COMPLEX16Vector **sigmaQNMlm0, INT4 modes[][2], UINT4 nmodes, REAL8 finalMass, REAL8 finalSpin, SphHarmListCAmpPhaseSequence *listhPlm, REAL8 deltaT, UINT4 retLen, UINT4 retLenRDPatch, REAL8 tAttach, REAL8Vector *seobvalues, SEOBdynamics *seobdynamics, SpinEOBParams *seobParams, const flagSEOBNRv4P_Zframe flagZframe, const INT4 debug)
This function attaches the ringdown to the P-frame modes hlm.
static REAL8 SEOBCalculateChiA(REAL8 chi1dotZ, REAL8 chi2dotZ)
static SphHarmListEOBNonQCCoeffs * SphHarmListEOBNonQCCoeffs_GetMode(SphHarmListEOBNonQCCoeffs *list, UINT4 l, INT4 m)
static UNUSED REAL8Vector * get_slice(REAL8Vector *vec, UINT4 lo, UINT4 hi)
static int SEOBRotatehIlmFromhJlm(SphHarmTimeSeries **hIlm, SphHarmTimeSeries *hJlm, INT4 modes_lmax, REAL8 alphaI2J, REAL8 betaI2J, REAL8 gammaI2J, REAL8 deltaT)
This function computes the hIlm Re/Im timeseries (fixed sampling) from hJlm Re/Im timeseries (same sa...
static REAL8 SEOBWignerDAmp(UINT4 l, INT4 m, INT4 mp, REAL8 beta)
These functions compute the amplitude and phase of a Wigner coefficient Dlmmp, given Euler angles of ...
static int SEOBJoinDynamics(SEOBdynamics **seobdynamicsJoined, SEOBdynamics *seobdynamics1, SEOBdynamics *seobdynamics2, UINT4 indexJoin12, UINT4 indexEnd2)
This function copies dynamics from AdaS<HiS and HiS<tAttach to form joined dynamics,...
static REAL8 SEOBCalculateChiS(REAL8 chi1dotZ, REAL8 chi2dotZ)
Functions to calculate symmetrized and antisymmetrized combinations of the dimensionless spins projec...
static int SphHarmListCAmpPhaseSequence_AddMode(SphHarmListCAmpPhaseSequence **list_prepended, CAmpPhaseSequence *campphase, UINT4 l, INT4 m)
int XLALSimIMRSpinPrecEOBWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiC, const REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fMin, const REAL8 r, const REAL8 inc, const REAL8 INspin1[], const REAL8 INspin2[], UNUSED const UINT4 PrecEOBversion, LALDict *LALParams)
Standard interface for SEOBNRv4P waveform generator: calls XLALSimIMRSpinPrecEOBWaveformAll.
static UNUSED int XLALEOBSpinPrecStopConditionBasedOnPR(double UNUSED t, const double values[], double dvalues[], void UNUSED *funcParams)
Stopping conditions for dynamics integration for SEOBNRv4P.
static int XLALSpinPrecAlignedHiSRStopCondition(double UNUSED t, const double UNUSED values[], double dvalues[], void UNUSED *funcParams)
Stopping condition for the high resolution SEOBNRv4.
static int XLALEOBSpinPrecAlignedStopCondition(double UNUSED t, const double values[], double dvalues[], void *funcParams)
Stopping condition for the regular resolution SEOBNRv1/2 orbital evolution – stop when reaching max o...
static int SEOBJfromDynamics(REAL8Vector **J, REAL8Vector *seobvalues, SpinEOBParams *seobParams)
This function computes the J vector.
static int SEOBRotateInterpolatehJlmReImFromSphHarmListhPlmAmpPhase(SphHarmTimeSeries **hJlm, INT4 modes[][2], UINT4 nmodes, INT4 modes_lmax, REAL8 deltaT, UINT4 retLenTS, REAL8Vector *tVecPmodes, SphHarmListCAmpPhaseSequence *listhPlm, REAL8Vector *alphaJ2P, REAL8Vector *betaJ2P, REAL8Vector *gammaJ2P, UINT4 flagSymmetrizehPlminusm)
This function computes the hJlm Re/Im timeseries (fixed sampling) from hPlm amp/phase modes and Euler...
static int SEOBCalculateSigmaStar(REAL8Vector *sigmaStar, REAL8 mass1, REAL8 mass2, REAL8Vector *s1, REAL8Vector *s2)
Function to calculate normalized spin of the test particle in SEOBNRv1.
static int SEOBEulerJ2PFromDynamics(REAL8Vector **alphaJ2P, REAL8Vector **betaJ2P, REAL8Vector **gammaJ2P, REAL8Vector *e1J, REAL8Vector *e2J, REAL8Vector *e3J, UINT4 retLen, UINT4 indexStop, SEOBdynamics *seobdynamics, SpinEOBParams *seobParams, flagSEOBNRv4P_Zframe flagZframe)
This function computes the Euler angles from J-frame to P-frame given the dynamics and basis vectors ...
static UNUSED UINT4 argmax(REAL8Vector *vec)
static UINT4 SEOBGetNumberOfModesInModeArray(LALValue *modearray, int lmax)
This function gets the number of modes present in a mode array, ignoring modes l>lmax (and l<2) Note ...
static int CAmpPhaseSequence_Init(CAmpPhaseSequence **campphase, int size)
static UNUSED int XLALEOBSpinPrecStopCondition_v4(double UNUSED t, const double values[], double dvalues[], void UNUSED *funcParams)
static int SEOBCalculateSphHarmListNQCCoefficientsV4(SphHarmListEOBNonQCCoeffs **nqcCoeffsList, INT4 modes[][2], UINT4 nmodes, REAL8 tPeakOmega, SEOBdynamics *seobdynamics, SpinEOBParams *seobParams, REAL8Vector *chi1_omegaPeak, REAL8Vector *chi2_omegaPeak)
This function computes the NQC coefficients for a list of mode contributions.
static int SEOBLFrameVectors(REAL8Vector **S1, REAL8Vector **S2, REAL8Vector *seobvalues, REAL8 m1, REAL8 m2, const flagSEOBNRv4P_Zframe flagZframe)
static int SphHarmListEOBNonQCCoeffs_AddMode(SphHarmListEOBNonQCCoeffs **list_prepended, EOBNonQCCoeffs *nqcCoeffs, UINT4 l, INT4 m)
static int SEOBComputehplushcrossFromhIlm(REAL8TimeSeries *hplusTS, REAL8TimeSeries *hcrossTS, INT4 modes_lmax, SphHarmTimeSeries *hIlm, REAL8 amp0, REAL8 inc, REAL8 phi)
This function combines the modes hIlm timeseries with the sYlm to produce the polarizations hplus,...
static REAL8 FindClosestValueInIncreasingVector(REAL8Vector *vec, REAL8 value)
This function finds the value in a vector that is closest to an input value.
static int SEOBJoinSphHarmListhlm(SphHarmListCAmpPhaseSequence **listhlm_joined, SphHarmListCAmpPhaseSequence *listhlm_1, SphHarmListCAmpPhaseSequence *listhlm_2, INT4 modes[][2], UINT4 nmodes, UINT4 indexJoin12)
This function copies dynamics from AdaS<HiS and HiS<tAttach to form joined dynamics,...
static int SEOBCalculateSphHarmListhlmAmpPhase(SphHarmListCAmpPhaseSequence **listhlm, INT4 modes[][2], UINT4 nmodes, SEOBdynamics *seobdynamics, SphHarmListEOBNonQCCoeffs *listnqcCoeffs, SpinEOBParams *seobParams, UINT4 flagNQC)
This function generates all waveform modes as a list for a given SEOB dynamics.
#define v4PdynamicsVariables
int XLALSimIMRSpinPrecEOBWaveformAll(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, SphHarmTimeSeries **hIlm, SphHarmTimeSeries **hJlm, REAL8Vector **seobdynamicsAdaSVector, REAL8Vector **seobdynamicsHiSVector, REAL8Vector **seobdynamicsAdaSHiSVector, REAL8Vector **tVecPmodes, REAL8Vector **hP22_amp, REAL8Vector **hP22_phase, REAL8Vector **hP21_amp, REAL8Vector **hP21_phase, REAL8Vector **hP33_amp, REAL8Vector **hP33_phase, REAL8Vector **hP44_amp, REAL8Vector **hP44_phase, REAL8Vector **hP55_amp, REAL8Vector **hP55_phase, REAL8Vector **alphaJ2P, REAL8Vector **betaJ2P, REAL8Vector **gammaJ2P, REAL8Vector **mergerParams, const REAL8 phi, const REAL8 INdeltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fMin, const REAL8 r, const REAL8 inc, const REAL8 chi1x, const REAL8 chi1y, const REAL8 chi1z, const REAL8 chi2x, const REAL8 chi2y, const REAL8 chi2z, LALValue *modearray, LALDict *seobflags)
This function is the master function generating precessing spinning SEOBNRv4P waveforms h+ and hx.
int XLALEOBHighestInitialFreq(REAL8 *freqMinRad, REAL8 mTotal)
static int SEOBGetModeNumbersFromModeArray(INT4 modes[][2], LALValue *modearray, int lmax)
This function populates a dynamically allocated INT4 array to with the modes active in a ModeArray Po...
static int SEOBBuildJframeVectors(REAL8Vector *e1J, REAL8Vector *e2J, REAL8Vector *e3J, REAL8Vector *JVec)
This function computes the Jframe unit vectors, with e3J along Jhat.
int XLALEOBCheckNyquistFrequency(REAL8 m1, REAL8 m2, REAL8 spin1[3], REAL8 spin2[3], UINT4 ell_max, Approximant approx, REAL8 deltaT)
static int SEOBCalculateSigmaKerr(REAL8Vector *sigmaKerr, REAL8Vector *s1, REAL8Vector *s2)
Function to calculate normalized spin of the deformed-Kerr background in SEOBNRv1.
static int SEOBCalculatehlmAmpPhase(CAmpPhaseSequence **hlm, INT4 l, INT4 m, SEOBdynamics *seobdynamics, EOBNonQCCoeffs *nqcCoeffs, SpinEOBParams *seobParams, UINT4 includeNQC)
This function generates a waveform mode for a given SEOB dynamics.
static int SphHarmListEOBNonQCCoeffs_Destroy(SphHarmListEOBNonQCCoeffs *list)
static int SEOBEulerI2JFromJframeVectors(REAL8 *alphaI2J, REAL8 *betaI2J, REAL8 *gammaI2J, REAL8Vector *e1J, REAL8Vector *e2J, REAL8Vector *e3J)
This function computes Euler angles I2J given the unit vectors of the Jframe.
static REAL8 SEOBCalculatetplspin(REAL8 m1, REAL8 m2, REAL8 eta, REAL8 chi1dotZ, REAL8 chi2dotZ, INT4 SpinAlignedEOBversion)
Function to calculate tplspin See discussion below Eq.
static int SEOBComputeExtendedSEOBdynamics(SEOBdynamics **seobdynamics, REAL8Array *dynamics, UINT4 retLen, SpinEOBParams *seobParams, flagSEOBNRv4P_hamiltonian_derivative flagHamiltonianDerivative, flagSEOBNRv4P_Zframe flagZframe)
This function computes quantities (polardynamics, omega, s1dotZ, s2dotZ, hamiltonian) derived from th...
static int SEOBGetFinalSpinMass(REAL8 *finalMass, REAL8 *finalSpin, REAL8Vector *seobvalues, SpinEOBParams *seobParams, const flagSEOBNRv4P_Zframe flagZframe)
static int SphHarmListCAmpPhaseSequence_Destroy(SphHarmListCAmpPhaseSequence *list)
static int SEOBEulerJ2PPostMergerExtension(REAL8Vector *alphaJ2P, REAL8Vector *betaJ2P, REAL8Vector *gammaJ2P, COMPLEX16 sigmaQNM220, COMPLEX16 sigmaQNM210, REAL8Vector *tVec, UINT4 retLen, UINT4 indexStart, SpinEOBParams *seobParams, flagSEOBNRv4P_euler_extension flagEulerextension, INT4 flip)
This function extends Euler angles J2P according to the prescription flagEulerextension after attachm...
static int SEOBAmplitudePeakFromAmp22Amp21(REAL8 *tPeak, UINT4 *indexPeak, SphHarmListCAmpPhaseSequence *listhPlm, INT4 modes[][2], UINT4 nmodes, REAL8Vector *tVec)
This function finds the (first) index and time with the largest sum-of-squares amplitude - discrete,...
static int SEOBdynamics_Init(SEOBdynamics **seobdynamics, UINT4 retLen)
static int SEOBInitialConditions(REAL8Vector **ICvalues, REAL8 MfMin, REAL8 m1, REAL8 m2, REAL8Vector *chi1, REAL8Vector *chi2, SpinEOBParams *seobParams, flagSEOBNRv4P_hamiltonian_derivative flagHamiltonianDerivative)
This function computes initial conditions for SEOBNRv4P.
static double beta(const double a, const double b, const sysq *system)
Internal function that computes the spin-orbit couplings.
Module containing the energy and flux functions for waveform generation.
static int XLALSpinPrecHcapRvecDerivative_exact(double UNUSED t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
Function to calculate exact derivatives of the spin EOB Hamiltonian, to get , as decribed in Eqs.
void XLALDestroyValue(LALValue *value)
REAL8Array * XLALCreateREAL8ArrayL(UINT4,...)
void XLALDestroyREAL8Array(REAL8Array *)
int XLALAdaptiveRungeKutta4(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend, REAL8 deltat, REAL8Array **yout)
void XLALAdaptiveRungeKuttaFree(LALAdaptiveRungeKuttaIntegrator *integrator)
int XLALAdaptiveRungeKutta4NoInterpolate(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend, REAL8 deltat_or_h0, REAL8 min_deltat_or_h0, REAL8Array **t_and_yout, INT4 EOBversion)
LALAdaptiveRungeKuttaIntegrator * XLALAdaptiveRungeKutta4Init(int dim, int(*dydt)(double t, const double y[], double dydt[], void *params), int(*stop)(double t, const double y[], double dydt[], void *params), double eps_abs, double eps_rel)
void * XLALMalloc(size_t n)
Approximant
Enum that specifies the PN approximant to be used in computing the waveform.
@ SEOBNRv4P
Spin precessing EOBNR model based on SEOBNRv4.
SphHarmTimeSeries * XLALSphHarmTimeSeriesAddMode(SphHarmTimeSeries *appended, const COMPLEX16TimeSeries *inmode, UINT4 l, INT4 m)
Prepend a node to a linked list of SphHarmTimeSeries, or create a new head.
COMPLEX16TimeSeries * XLALSphHarmTimeSeriesGetMode(SphHarmTimeSeries *ts, UINT4 l, INT4 m)
Get the time series of a waveform's (l,m) spherical harmonic mode from a SphHarmTimeSeries linked lis...
void XLALSphHarmTimeSeriesSetTData(SphHarmTimeSeries *ts, REAL8Sequence *tdata)
Set the tdata member for all nodes in the list.
void XLALDestroySphHarmTimeSeries(SphHarmTimeSeries *ts)
Delete list from current pointer to the end of the list.
double XLALWignerdMatrix(int l, int mp, int m, double beta)
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series)
COMPLEX16TimeSeries * XLALCreateCOMPLEX16TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
void XLALDestroyCOMPLEX16Vector(COMPLEX16Vector *vector)
int XLALREAL8VectorUnwrapAngle(REAL8Vector *out, const REAL8Vector *in)
#define XLAL_PRINT_INFO(...)
#define XLAL_ERROR_NULL(...)
#define XLAL_PRINT_WARNING(...)
#define XLAL_TRY(statement, errnum)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_PRINT_ERROR(...)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
Structure to represent a data piece (e.g.
REAL8Vector * xdata
Sequence of times or frequencies on which data is given.
REAL8Vector * phase
Sequence for the phase.
REAL8Vector * camp_imag
Sequence for the imag part of the complex amplitude (enveloppe).
REAL8Vector * camp_real
Sequence for the real part of the complex amplitude (enveloppe).
The coefficients which are used in calculating the non-quasicircular correction to the EOBNRv2 model.
Structure containing all the parameters needed for the EOB waveform.
FacWaveformCoeffs * hCoeffs
NewtonMultipolePrefixes * prefixes
Structure containing all the terms of the Newtonian multipole which are constant over the course of t...
gsl_spline * alpha_spline
gsl_interp_accel * alpha_acc
gsl_interp_accel * beta_acc
Structure the EOB dynamics for precessing waveforms.
Structure to represent linked list of modes with complex amplitude (enveloppe) and phase.
struct tagSphHarmListCAmpPhaseSequence * next
Pointer to next element in the list.
CAmpPhaseSequence * campphase
Data for this mode.
Structure to represent linked list of modes with complex amplitude (enveloppe) and phase.
EOBNonQCCoeffs * nqcCoeffs
NQC coefficients for this mode.
struct tagSphHarmListEOBNonQCCoeffs * next
Pointer to next element in the list.
Structure to carry a collection of spherical harmonic modes in COMPLEX16 time series.
REAL8Sequence * tdata
Timestamp values.
Parameters for the spinning EOB model, used in calculating the Hamiltonian.
UINT4 SpinAlignedEOBversion
Parameters for the spinning EOB model.
SpinEOBHCoeffs * seobCoeffs
EOBNonQCCoeffs * nqcCoeffs
SEOBHCoeffConstants * seobCoeffConsts
Approximant seobApproximant
Tidal parameters for EOB model of NS: mByM - dimensionless ratio m_{NS}/M lambda2Tidal - dimensionles...