53#include <lal/LALInspiral.h>
54#include <lal/LALEOBNRv2Waveform.h>
55#include <lal/LALAdaptiveRungeKuttaIntegrator.h>
56#include <lal/FindRoot.h>
57#include <lal/SeqFactories.h>
58#include <lal/NRWaveInject.h>
60#include <gsl/gsl_sf_gamma.h>
62#define ninty4by3etc 18.687902694437592603
66typedef struct tagrOfOmegaIn {
70typedef struct tagPr3In {
71 REAL8 eta, zeta2, omegaS, omega, vr,
r,
q;
97 const double values[],
110 const double values[],
116 const double values[],
177 REAL8 r,
pr,
pp, Omega, v2, vh, vh3, k, hathatk, eulerlogxabs;
178 REAL8 Hreal, Heff, Slm, deltalm, rholm, rholmPwrl;
181 gsl_sf_result lnr1, arg1, z2;
200 XLALPrintError(
"Eta seems to be > 0.25 - this isn't allowed!\n" );
203 else if ( eta == 0.25 &&
m % 2 )
211 pr = values->data[2];
212 pp = values->data[3];
215 Hreal = sqrt( 1.0 + 2.0 * eta * ( Heff - 1.0) );
226 vPhi =
r * cbrt(vPhi);
238 if ( ( (
l+
m)%2 ) == 0)
251 if (
status != GSL_SUCCESS)
257 if (
status != GSL_SUCCESS)
263 arg1.val + 2.0 * hathatk * log(4.0*k/sqrt(
LAL_E)) ) );
274 + vh*vh*(hCoeffs->delta22vh8 + hCoeffs->
delta22vh9*vh)))
288 rholm = 1. + v*(hCoeffs->
rho21v1
314 rholm = 1. + v*(hCoeffs->
rho32v
339 rholm = 1. + v2*(hCoeffs->
rho44v2
342 + hCoeffs->
rho44v6l*eulerlogxabs)*v))));
347 rholm = 1. + v*(hCoeffs->
rho43v
354 rholm = 1. + v2*(hCoeffs->
rho42v2
361 rholm = 1. + v*(hCoeffs->
rho41v
376 rholm = 1. + v2*( hCoeffs->
rho55v2
387 rholm = 1. + v2*(hCoeffs->
rho53v2
397 rholm = 1. + v2*(hCoeffs->
rho51v2
449 rholm = 1. + hCoeffs->
rho76v2 * v2;
457 rholm = 1. + hCoeffs->
rho74v2 * v2;
465 rholm = 1. + hCoeffs->
rho72v2 * v2;
481 rholm = 1. + hCoeffs->
rho88v2 * v2;
485 rholm = 1. + hCoeffs->
rho87v2 * v2;
489 rholm = 1. + hCoeffs->
rho86v2 * v2;
493 rholm = 1. + hCoeffs->
rho85v2 * v2;
497 rholm = 1. + hCoeffs->
rho84v2 * v2;
501 rholm = 1. + hCoeffs->
rho83v2 * v2;
505 rholm = 1. + hCoeffs->
rho82v2 * v2;
509 rholm = 1. + hCoeffs->
rho81v2 * v2;
529 *hlm = Tlm *
cpolar( 1.0, deltalm) * Slm*rholmPwrl;
530 *hlm = *hlm * hNewton;
538 return - 5.82827 - 143.486 * eta + 447.045 * eta * eta;
571 coeffs->
n4 = -64. + 12.*
a4 + 4.*a5 + a6 + 64.*eta - 4.*eta2;
572 coeffs->
n5 = 32. -4.*
a4 - a5 - 24.*eta;
573 coeffs->
d0 = 4.*
a4*
a4 + 4.*
a4*a5 + a5*a5 -
a4*a6 + 16.*a6
574 + (32.*
a4 + 16.*a5 - 8.*a6) * eta + 4.*
a4*eta2 + 32.*eta3;
575 coeffs->
d1 = 4.*
a4*
a4 +
a4*a5 + 16.*a5 + 8.*a6 + (32.*
a4 - 2.*a6)*eta + 32.*eta2 + 8.*eta3;
576 coeffs->
d2 = 16.*
a4 + 8.*a5 + 4.*a6 + (8.*
a4 + 2.*a5)*eta + 32.*eta2;
577 coeffs->
d3 = 8.*
a4 + 4.*a5 + 2.*a6 + 32.*eta - 8.*eta2;
578 coeffs->
d4 = 4.*
a4 + 2.*a5 + a6 + 16.*eta - 4.*eta2;
579 coeffs->
d5 = 32. - 4.*
a4 - a5 - 24. * eta;
623 REAL8 NA, DA, dNA, dDA, dA;
640 dNA = 4. * coeffs->n4 * r3
641 + 5. * coeffs->n5 * r4;
644 + 2. * coeffs->d2 *
r
645 + 3. * coeffs->d3 *
r2
646 + 4. * coeffs->d4 * r3
647 + 5. * coeffs->d5 * r4;
649 dA = dNA * DA - dDA * NA;
664 return 1./(1.+6.*eta*
u2+2.*eta*(26.-3.*eta)*
u3);
690 z3 = 2. * ( 4. - 3. * eta ) * eta;
691 return sqrt( pr2 + eoba * ( 1. +
pp2/
r2 + z3*pr2*pr2/
r2 ) );
714 return sqrt(-dA/(2.*
u*A +
u2 * dA));
727 REAL8 onebyD, AbyD, Heff, HReal, etahH;
745 z3 = 2. * (4. - 3. * eta) * eta;
751 Heff = sqrt(A*(1. + AbyD * p2 +
q*
q *
u2 + z3 * p4 *
u2));
752 HReal = sqrt(1. + 2.*eta*(Heff - 1.)) / eta;
753 etahH = eta*Heff*HReal;
757 pr = -vr + A*(AbyD*
p + 2. * z3 *
u2 * p3)/etahH;
786 omega = sqrt(
u3) * sqrt ( -0.5 * dA /(1. + 2.*eta * (A/sqrt(A+0.5 *
u*dA)-1.)));
797 REAL8 r = values->data[0];
798 REAL8 pphi = values->data[3];
803 return 2. * (1. + 2. * eta * ( -1. + sqrt( (1. + pphi*pphi/(
r*
r)) * A ) ) )
823 omega1 = pr3in->
omega;
825 return ( -omega1 + omega2 );
833 const REAL8 values[],
861 memcpy( &(valuesVec.
data), &(values),
sizeof(
REAL8 *) );
865 z3 = 2. * ( 4. - 3. * eta ) * eta;
889 Hreal = sqrt( 1. + 2.*eta*(Heff - 1.) );
891 HeffHreal = Heff *
Hreal;
894 dvalues[0] = AoverSqrtD *
u2 *
p * (
r2 + 2. * p2 * z3 * A ) / HeffHreal;
897 dvalues[1] = omega =
q * A *
u2 / HeffHreal;
904 dvalues[2] = 0.5 * AoverSqrtD *
u3 * ( 2.0 * ( q2 + p4 * z3) * A
905 -
r * ( q2 +
r2 + p4 * z3 ) * dAdr ) / HeffHreal
906 - (
p /
q) * (flux / (eta * omega));
909 dvalues[3] = - flux / (eta * omega);
912 if ( isnan( dvalues[0] ) || isnan( dvalues[1] ) || isnan( dvalues[2] ) || isnan( dvalues[3] ) )
933 Hreal = sqrt( 1. + 2.*eta*(Heff - 1.) );
935 HeffHreal = Heff *
Hreal;
936 return pPhi * A / (HeffHreal*
r*
r);
945 const double UNUSED values[],
952 double omega = dvalues[1];
954 if ( omega < params->omega )
969 const double values[],
971 void UNUSED *funcParams
978 rstop = 1.25 -
params->eta;
982 rstop = 2.1 - 10.0 *
params->eta;
985 if ( values[0] <= rstop || isnan(dvalues[3]) || isnan(dvalues[2]) || isnan(dvalues[1]) || isnan(dvalues[0]) )
997 REAL8 A, dAdr, d2Adr2, dA, d2A, NA, DA, dDA, dNA, d2DA, d2NA;
1000 REAL8 twoUAPlusu2dA;
1014 NA = r4 * aCoeffs->
n4
1024 dNA = 4. * aCoeffs->
n4 * r3
1025 + 5. * aCoeffs->
n5 * r4;
1028 + 2. * aCoeffs->
d2 *
r
1029 + 3. * aCoeffs->
d3 *
r2
1030 + 4. * aCoeffs->
d4 * r3
1031 + 5. * aCoeffs->
d5 * r4;
1033 d2NA = 12. * aCoeffs->
n4 *
r2
1034 + 20. * aCoeffs->
n5 * r3;
1036 d2DA = 2. * aCoeffs->
d2
1037 + 6. * aCoeffs->
d3 *
r
1038 + 12. * aCoeffs->
d4 *
r2
1039 + 20. * aCoeffs->
d5 * r3;
1042 dAdr = ( dNA * DA - dDA * NA ) / (DA*DA);
1043 d2Adr2 = (d2NA*DA - d2DA*NA - 2.*dDA*DA*dAdr)/(DA*DA);
1048 d2A = r4 * d2Adr2 + 2.*r3 * dAdr;
1051 FDIS = -
params->in3copy.flux(v,
params->in3copy.coeffs)/(eta*omega);
1053 twoUAPlusu2dA = 2.*
u * A +
u2 * dA;
1054 x1 = -
r2 * sqrt (-dA * twoUAPlusu2dA * twoUAPlusu2dA * twoUAPlusu2dA )
1055 / (2.*
u * dA * dA + A*dA -
u * A * d2A);
1130 XLALPrintWarning(
"WARNING: The lalinspiral version of EOBNRv2 and EOBNRv2HM are not reviewed or maintained and will be removed in the future. The lalsimulation versions of these waveforms should be used.\n" );
1139 if ( !signalvec->
data )
1152 if (
params->fLower <= 0. )
1157 if (
params->tSampling <= 0. )
1162 if (
params->totalMass <= 0. )
1211 if ( !signalvec1->
data )
1215 if ( !signalvec2->
data )
1228 if (
params->fLower <= 0. )
1233 if (
params->tSampling <= 0. )
1238 if (
params->totalMass <= 0. )
1298 XLALPrintError(
"Pointer for waveform->a exists. Was expecting NULL.\n" );
1303 XLALPrintError(
"Pointer for waveform->h exists. Was expecting NULL.\n" );
1308 XLALPrintError(
"Pointer for waveform->f exists. Was expecting NULL.\n" );
1311 if ( waveform->
phi )
1313 XLALPrintError(
"Pointer for waveform->phi exists. Was expecting NULL.\n" );
1316 if ( waveform->
shift )
1318 XLALPrintError(
"Pointer for waveform->shift exists. Was expecting NULL.\n" );
1331 if (paramsInit.
nbins==0)
1342 phiC = ppnParams->
phi;
1359 if (h->
data[
i] != 0.0)
break;
1391 waveform->
psi = ppnParams->
psi;
1393 snprintf( waveform->
h->
name,
1401 ppnParams->
tc = (double)(count-1) /
params->tSampling ;
1402 ppnParams->
length = count;
1431 UINT4 count, nn=4, length = 0, hiSRndx=0;
1435 REAL8Vector rVecHi, phiVecHi, prVecHi, pPhiVecHi, tVecHi;
1437 REAL8 eta,
m,
r,
s,
p,
q,
dt, t, v, omega, f, ampl0;
1480 REAL8 y_1, y_2, z_1, z_2;
1487 REAL8 resampEstimate;
1496 const REAL8 xacc = 1.0e-12;
1499 const REAL8 EPS_ABS = 1.0e-12;
1500 const REAL8 EPS_REL = 1.0e-10;
1535 ak = paramsInit->
ak;
1536 func = paramsInit->
func;
1541 XLALPrintError(
"Order must be LAL_PNORDER_PSEUDO_FOUR for approximant EOBNRv2.\n" );
1546 if (signalvec1) length = signalvec1->
length;
else if (h) length = h->
length / 2;
1552 if ( !values || !dvalues )
1574 ampl0 =
params->signalAmplitude;
1613 "Increase sample rate or consider using EOB approximant.\n" );
1619 nStepBack = ceil( tStepBack *
params->tSampling );
1622 memset( &eobParams, 0,
sizeof(eobParams) );
1623 eobParams.
eta = eta;
1662 if ( resampEstimate > 1 )
1664 resampPwr = (
UINT4)ceil(log2(resampEstimate));
1665 while ( resampPwr-- )
1673 lengthHiSR = ( nStepBack + (
UINT4)(20.0 / cimagf(modefreqs->
data[0]) /
dt) ) * resampFac;
1692 rootIn3.
xacc = xacc;
1693 rootIn2.
xmax = 1000.;
1696 pr3in.omegaS =
params->OmegaS;
1697 pr3in.zeta2 =
params->Zeta2;
1704 pr3in.
omega = omega;
1712 funcParams = (
void *) &pr3in;
1714 rootIn2.
xmax, xacc, funcParams);
1724 r = (
r<rmin) ? rmin :
r;
1728 pr3in.in3copy = in3;
1735 pr3in.
omega = omega;
1739 funcParams = (
void *) &pr3in;
1752 values->
data[0] =
r;
1753 values->
data[1] =
s;
1754 values->
data[2] =
p;
1755 values->
data[3] =
q;
1762 if ( !sig1 || !sig2 || !freq )
1792 if ( !sig1Hi || !sig2Hi || !freqHi || !phseHi )
1829 if (h || signalvec2)
1832 count =
params->nStartPad;
1839 hiSRndx = retLen - nStepBack;
1844 phiVec.
data = dynamics->
data+2*retLen;
1845 prVec.
data = dynamics->
data+3*retLen;
1846 pPhiVec.
data = dynamics->
data+4*retLen;
1853 sSub = phiVec.
data[retLen - 1] - (*phiC)/2.;
1857 values->
data[0] = rVec.
data[hiSRndx];
1858 values->
data[1] = phiVec.
data[hiSRndx];
1859 values->
data[2] = prVec.
data[hiSRndx];
1860 values->
data[3] = pPhiVec.
data[hiSRndx];
1866 0, (lengthHiSR-1)*
dt/
m,
dt/
m, &dynamicsHi );
1869 rVecHi.
data = dynamicsHi->
data+retLen;
1870 phiVecHi.
data = dynamicsHi->
data+2*retLen;
1871 prVecHi.
data = dynamicsHi->
data+3*retLen;
1872 pPhiVecHi.
data = dynamicsHi->
data+4*retLen;
1888 for ( currentMode = 0; currentMode <
nModes; currentMode++ )
1890 count =
params->nStartPad;
1892 modeL =
lmModes[currentMode][0];
1893 modeM =
lmModes[currentMode][1];
1896 if ( eta == 0.25 && modeM % 2 )
1902 for (
i=0;
i < (
UINT4)retLen;
i++ )
1905 omegaHi->
data[
i] = omega;
1908 values->
data[1] =
s = phiVecHi.
data[
i] - sSub;
1916 ampNQC->
data[
i] = cabs( hLM );
1917 sig1Hi->
data[
i] = (
REAL4) ampl0 * creal(hLM);
1918 sig2Hi->
data[
i] = (
REAL4) ampl0 * cimag(hLM);
1928 p1->
data[
i] =
p / (
r*omega );
1931 if ( omega <= omegaOld && !peakIdx )
1937 finalIdx = retLen - 1;
1940 gsl_spline *spline = NULL;
1941 gsl_interp_accel *acc = NULL;
1944 REAL8 timePeak, omegaDerivMid;
1946 spline = gsl_spline_alloc( gsl_interp_cspline, retLen );
1947 acc = gsl_interp_accel_alloc();
1949 time1 = dynamicsHi->
data[peakIdx];
1951 gsl_spline_init( spline, dynamicsHi->
data, omegaHi->
data, retLen );
1952 omegaDeriv1 = gsl_spline_eval_deriv( spline, time1, acc );
1953 if ( omegaDeriv1 > 0. )
1955 time2 = dynamicsHi->
data[peakIdx+1];
1960 time1 = dynamicsHi->
data[peakIdx-1];
1962 omegaDeriv1 = gsl_spline_eval_deriv( spline, time1, acc );
1967 timePeak = ( time1 + time2 ) / 2.;
1968 omegaDerivMid = gsl_spline_eval_deriv( spline, timePeak, acc );
1970 if ( omegaDerivMid * omegaDeriv1 < 0.0 )
1976 omegaDeriv1 = omegaDerivMid;
1980 while ( time2 - time1 > 1.0e-5 );
1982 gsl_spline_free( spline );
1983 gsl_interp_accel_free( acc );
1985 XLALPrintInfo(
"Estimation of the peak is now at time %e\n", timePeak );
1988 XLALCalculateNQCCoefficients( ampNQC, phseHi, q1,q2,q3,p1,p2, modeL, modeM, timePeak,
dt/
m, eta, &nqcCoeffs );
1996 while (
i < hiSRndx )
1999 if ( omega > lfCut || fabs( omega - lfCut ) < 1.0e-5 )
2008 XLALPrintError(
"We don't seem to have crossed the low frequency cut-off\n" );
2015 t =
m * (dynamics->
data[hiSRndx] + dynamicsHi->
data[peakIdx] - dynamics->
data[startIdx]);
2018 while (
i < hiSRndx )
2034 sig1->
data[count] = (
REAL4) ampl0 * creal(hLM);
2035 sig2->
data[count] = (
REAL4) ampl0 * cimag(hLM);
2042 for (
i = 0;
i <= finalIdx;
i++ )
2048 values->
data[1] =
s = phiVecHi.
data[
i] - sSub;
2066 if (signalvec1 && !signalvec2)
params->tC = t;
2076 params->tSampling *= resampFac;
2081 if ( ceil( tStepBack *
params->tSampling / 2.0 ) > peakIdx )
2083 XLALPrintError(
"Invalid index for first ringdown matching point.\n" );
2090 if ( combSize > timePeak )
2094 rdMatchPoint->
data[0] = combSize < timePeak + nrPeakDeltaT ? timePeak + nrPeakDeltaT - combSize : 0;
2095 rdMatchPoint->
data[1] = timePeak + nrPeakDeltaT;
2096 rdMatchPoint->
data[2] = dynamicsHi->
data[finalIdx];
2099 modeL, modeM, &tVecHi, rdMatchPoint,
params);
2108 params->tSampling = tmpSamplingRate;
2110 for(j=0; j<sig1Hi->
length; j+=resampFac)
2112 sig1->
data[count] = sig1Hi->
data[j];
2113 sig2->
data[count] = sig2Hi->
data[j];
2114 freq->
data[count] = freqHi->
data[j];
2115 if (sig1->
data[count] == 0)
2136 xlalStatus =
XLALSphHarm( &MultSphHarmP, modeL, modeM, inclination, coa_phase );
2146 xlalStatus =
XLALSphHarm( &MultSphHarmM, modeL, modeM, inclination, coa_phase );
2157 MultSphHarmM = - MultSphHarmM;
2159 y_1 = creal(MultSphHarmP) + creal(MultSphHarmM);
2160 y_2 = cimag(MultSphHarmM) - cimag(MultSphHarmP);
2161 z_1 = - cimag(MultSphHarmM) - cimag(MultSphHarmP);
2162 z_2 = creal(MultSphHarmM) - creal(MultSphHarmP);
2167 freq->
data[
i] /= unitHz;
2170 sig1->
data[
i] = (x1 * y_1) + (x2 * y_2);
2171 sig2->
data[
i] = (x1 * z_1) + (x2 * z_2);
2180 for(
i = 0;
i < length;
i++)
2194 for (
i = 0;
i < length;
i++ )
2201 for (
i = 0;
i < length;
i++ )
int XLALCalculateNQCCoefficients(REAL8Vector *restrict amplitude, REAL8Vector *restrict phase, REAL8Vector *restrict q1, REAL8Vector *restrict q2, REAL8Vector *restrict q3, REAL8Vector *restrict p1, REAL8Vector *restrict p2, INT4 l, INT4 m, REAL8 timePeak, REAL8 deltaT, REAL8 eta, EOBNonQCCoeffs *restrict coeffs)
int XLALEOBNonQCCorrection(COMPLEX16 *restrict nqc, REAL8Vector *restrict values, const REAL8 omega, EOBNonQCCoeffs *restrict coeffs)
INT4 XLALGenerateQNMFreqV2(COMPLEX8Vector *modefreqs, InspiralTemplate *params, UINT4 l, UINT4 m, UINT4 nmodes)
As with the above function, this generates the quasinormal mode frequencies for a black hole ringdown...
int XLALInspiralSetup(expnCoeffs *ak, InspiralTemplate *params)
int XLALInspiralInit(InspiralTemplate *params, InspiralInit *paramsInit)
int XLALInspiralChooseModel(expnFunc *func, expnCoeffs *ak, InspiralTemplate *params)
INT4 XLALInspiralHybridAttachRingdownWave(REAL4Vector *signalvec1, REAL4Vector *signalvec2, INT4 l, INT4 m, REAL8Vector *timeVec, REAL8Vector *matchrange, InspiralTemplate *params)
const UINT4 lmModes[NMODES][2]
#define XLAL_CALLGSL(statement)
void XLALDestroyREAL8Array(REAL8Array *)
REAL4VectorSequence * XLALCreateREAL4VectorSequence(UINT4 length, UINT4 veclen)
REAL8 XLALDBisectionFindRoot(REAL8(*y)(REAL8, void *), REAL8 xmin, REAL8 xmax, REAL8 xacc, void *params)
#define GENERATEPPNINSPIRALH_EFSTOP
Reached requested termination frequency.
int XLALAdaptiveRungeKutta4(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend, REAL8 deltat, REAL8Array **yout)
void XLALAdaptiveRungeKuttaFree(LALAdaptiveRungeKuttaIntegrator *integrator)
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)
INT4 XLALSphHarm(COMPLEX16 *out, UINT4 L, INT4 M, REAL4 theta, REAL4 phi)
const LALUnit lalStrainUnit
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
COMPLEX8Vector * XLALCreateCOMPLEX8Vector(UINT4 length)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
void XLALDestroyCOMPLEX8Vector(COMPLEX8Vector *vector)
#define XLAL_ERROR_REAL8(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
#define XLAL_IS_REAL8_FAIL_NAN(val)
REAL4TimeVectorSeries * a
REAL4TimeVectorSeries * h
EOBNonQCCoeffs * nqcCoeffs
FacWaveformCoeffs * hCoeffs
NewtonMultipolePrefixes * prefixes
EOBACoefficients * aCoeffs
Structure used as an input to compute the derivatives needed in solving the phasing formula when the ...
EOBNonQCCoeffs * nqcCoeffs
The inspiral waveform parameter structure containing information about the waveform to be generated.
int(* stop)(double t, const double y[], double dydt[], void *params)
This structure stores the parameters for constructing a restricted post-Newtonian waveform.
const CHAR * termDescription
The termination code description (above)
INT4 termCode
The termination condition (above) that stopped computation of the waveform.
REAL4 phi
The phase at coalescence (or arbitrary reference phase for a post -Newtonian approximation),...
REAL4 psi
polarization angle (radians)
REAL4 fStart
The actual starting frequency of the waveform, in Hz (normally close but not identical to fStartIn)
SkyPosition position
location of source on sky
UINT4 length
The length of the generated waveform.
REAL4 fStop
The frequency at the termination of the waveform, in Hz.
REAL8 tc
The time from the start of the waveform to coalescence (in the point-mass approximation),...
REAL4 fStartIn
The requested starting frequency of the waveform, in Hz.
REAL4VectorSequence * data
This structure contains various post-Newtonian and P-approximant expansion coefficients; the meanings...
Structure to hold the pointers to the generic functions defined above.
EOBACoefficients * aCoeffs