21 #include <lal/Units.h>
22 #include <lal/LALConstants.h>
23 #include <lal/LALAdaptiveRungeKuttaIntegrator.h>
24 #include <lal/TimeSeries.h>
25 #include <lal/LALSimInspiral.h>
26 #include <lal/VectorOps.h>
28 #define LAL_PISQR 9.869604401089358
30 #define UNUSED(expr) do { (void)(expr); } while (0)
33 #define LALSIMINSPIRAL_ST5_TEST_ENERGY 1025
34 #define LALSIMINSPIRAL_ST5_TEST_VDOT 1026
35 #define LALSIMINSPIRAL_ST5_TEST_COORDINATE 1027
36 #define LALSIMINSPIRAL_ST5_TEST_VNAN 1028
37 #define LALSIMINSPIRAL_ST5_TEST_FREQBOUND 1029
38 #define LALSIMINSPIRAL_ST5_DERIVATIVE_OMEGANONPOS 1030
41 #define LAL_MAX_PN_ORDER 8
43 #define LAL_NUM_ST5_VARIABLES 10
45 #define LAL_ST5_ABSOLUTE_TOLERANCE 1.e-12
46 #define LAL_ST5_RELATIVE_TOLERANCE 1.e-12
57 typedef struct SpinTaylorT5StructParams {
154 static double dotProduct(
double a[3],
double b[3]);
156 static void rotateVector(
double a[3],
double b[3],
double phi,
double theta,
double psi);
187 UINT4 i, intStatus, lenReturn;
189 REAL8TimeSeries *orbPhase=NULL, *
V=NULL, *LNhxVec=NULL, *LNhyVec=NULL, *LNhzVec=NULL;
190 REAL8TimeSeries *S1xVec=NULL, *S1yVec=NULL, *S1zVec=NULL, *S2xVec=NULL, *S2yVec=NULL, *S2zVec=NULL;
194 REAL8 LNh[3], S1[3], S2[3], J[3], Jh[3], Lmag, Jmag, v;
196 mParams = &SpinTaylorParameters;
202 XLALPrintError(
"XLAL Error - %s: Unable to initialize the mParams structure.\n", __func__);
217 S1[0] = s1x*mParams->
m1Sqr;
218 S1[1] = s1y*mParams->
m1Sqr;
219 S1[2] = s1z*mParams->
m1Sqr;
220 S2[0] = s2x*mParams->
m2Sqr;
221 S2[1] = s2y*mParams->
m2Sqr;
222 S2[2] = s2z*mParams->
m2Sqr;
225 Lmag = (mParams->
eta*mParams->
mSqr/mParams->
v0)*(1. + (1.5+mParams->
eta/6.)*mParams->
v0*mParams->
v0);
227 for (
i=0;
i<3;
i++) J[
i] = Lmag*LNh[
i] + S1[
i] + S2[
i];
228 Jmag = sqrt(J[0]*J[0] + J[1]*J[1] + J[2]*J[2]);
229 for (
i=0;
i<3;
i++) Jh[
i] = J[
i]/Jmag;
232 REAL8 JIniTheta = -acos(Jh[2]);
233 REAL8 JIniPhi = -atan2(Jh[1], Jh[0]);
242 if (JIniTheta == 0) {
244 incAngle = incAngle+JIniTheta;
253 yinit[0] = v = mParams->
v0;
271 XLALPrintError(
"XLAL Error - %s: Cannot allocate integrator\n", __func__);
286 XLALPrintError(
"XLAL Error - %s: integration failed with errorcode %d.\n", __func__, intStatus);
293 XLALPrintWarning(
"XLAL Warning - %s: integration terminated with code %d.\n \
294 Waveform parameters were m1 = %e, m2 = %e, S1 = [%e,%e,%e], S2 = [%e,%e,%e], LNh = [%e,%e,%e]\n",
296 S2[1], S2[2], LNh[0], LNh[1], LNh[2]);
313 memset(
V->data->data, 0, lenReturn*
sizeof(
REAL8));
315 memset(LNhxVec->data->data, 0, lenReturn*
sizeof(
REAL8));
316 memset(LNhyVec->data->data, 0, lenReturn*
sizeof(
REAL8));
317 memset(LNhzVec->data->data, 0, lenReturn*
sizeof(
REAL8));
319 memset(S1yVec->data->data, 0, lenReturn*
sizeof(
REAL8));
320 memset(S1zVec->data->data, 0, lenReturn*
sizeof(
REAL8));
321 memset(S2xVec->data->data, 0, lenReturn*
sizeof(
REAL8));
322 memset(S2yVec->data->data, 0, lenReturn*
sizeof(
REAL8));
323 memset(S2zVec->data->data, 0, lenReturn*
sizeof(
REAL8));
327 for (
i = 0;
i<lenReturn;
i++) {
328 V->data->data[
i] = yout->
data[lenReturn+
i];
329 LNhxVec->data->data[
i] = yout->
data[2*lenReturn+
i];
330 LNhyVec->data->data[
i] = yout->
data[3*lenReturn+
i];
331 LNhzVec->data->data[
i] = yout->
data[4*lenReturn+
i];
333 S1yVec->data->data[
i] = yout->
data[6*lenReturn+
i];
334 S1zVec->data->data[
i] = yout->
data[7*lenReturn+
i];
335 S2xVec->data->data[
i] = yout->
data[8*lenReturn+
i];
336 S2yVec->data->data[
i] = yout->
data[9*lenReturn+
i];
337 S2zVec->data->data[
i] = yout->
data[10*lenReturn+
i];
345 XLALPrintError(
"XLAL Error - %s: Unable to compute the orbital phase .\n", __func__);
350 switch (amplitudeO) {
354 XLALPrintError(
"XLAL Error - %s: Unable to project the waveforms into radiation frame.\n", __func__);
359 XLALPrintError(
"XLAL Error - %s: Polarizations are currently computed only in amplitudeO = 0\n", __func__);
391 REAL8 LNh[3], S1[3], S2[3], chi1[3], chi2[3], Omega1[3], Omega2[3];
392 REAL8 dS1byDt[3], dS2byDt[3], dLNhByDt[3];
393 REAL8 m, eta,
q,
delta, v, dEbyF, om0, v2, S1dotLNh, S2dotLNh, Lmag;
394 UINT4 phaseO,
i, onePFpnFlag = 1, onePNFlag = 1;
418 chi1[0] = S1[0]/
params->m1Sqr;
419 chi1[1] = S1[1]/
params->m1Sqr;
420 chi1[2] = S1[2]/
params->m1Sqr;
421 chi2[0] = S2[0]/
params->m2Sqr;
422 chi2[1] = S2[1]/
params->m2Sqr;
423 chi2[2] = S2[2]/
params->m2Sqr;
435 if (phaseO < 6) onePFpnFlag = 0;
436 if (phaseO < 5) onePNFlag = 0;
437 if (phaseO < 3) om0 = 0;
439 for (
i=0;
i<3;
i++) {
440 Omega1[
i] = om0*((0.75 + eta/2. - 0.75*
delta) * LNh[
i]
441 + onePNFlag * v *(-3.*(S2dotLNh + S1dotLNh*
q) * LNh[
i] + S2[
i])/(2.*
params->mSqr)
442 + onePFpnFlag * v2 *(0.5625 + 1.25*eta -
params->etaSqr/24. - 0.5625*
delta
443 + 0.625*
params->deltaEta)*LNh[
i]);
445 Omega2[
i] = om0*((0.75 + eta/2. + 0.75*
delta) * LNh[
i]
446 + onePNFlag * v *(-3.*(S1dotLNh + S2dotLNh/
q) * LNh[
i] + S1[
i])/(2.*
params->mSqr)
447 + onePFpnFlag * v2 *(0.5625 + 1.25*eta -
params->etaSqr/24. + 0.5625*
delta
448 - 0.625*
params->deltaEta)*LNh[
i]);
455 Lmag = (eta*
params->mSqr/v)*(1. + (1.5+eta/6.)*v2);
456 dLNhByDt[0] = -(dS1byDt[0] + dS2byDt[0])/Lmag;
457 dLNhByDt[1] = -(dS1byDt[1] + dS2byDt[1])/Lmag;
458 dLNhByDt[2] = -(dS1byDt[2] + dS2byDt[2])/Lmag;
461 dydt[0] = -1./(dEbyF*
m);
462 dydt[1] = dLNhByDt[0];
463 dydt[2] = dLNhByDt[1];
464 dydt[3] = dLNhByDt[2];
465 dydt[4] = dS1byDt[0];
466 dydt[5] = dS1byDt[1];
467 dydt[6] = dS1byDt[2];
468 dydt[7] = dS2byDt[0];
469 dydt[8] = dS2byDt[1];
470 dydt[9] = dS2byDt[2];
491 REAL8 chi_s[3], chi_a[3];
492 REAL8 chisDotLNh, chiaDotLNh, chisDotChia, chisSqr, chiaSqr;
493 REAL8 dEbF0 = 0., dEbF1 = 0., dEbF2 = 0., dEbF3 = 0., dEbF4 = 0., dEbF5 = 0., dEbF6 = 0.;
494 REAL8 dEbF6L = 0., dEbF7 = 0.;
495 REAL8 v2, v3, v4, v5, v6, v7, v9;
500 REAL8 eta_p2 = eta*eta;
503 chi_s[0] = 0.5*(chi1[0]+chi2[0]);
504 chi_s[1] = 0.5*(chi1[1]+chi2[1]);
505 chi_s[2] = 0.5*(chi1[2]+chi2[2]);
506 chi_a[0] = 0.5*(chi1[0]-chi2[0]);
507 chi_a[1] = 0.5*(chi1[1]-chi2[1]);
508 chi_a[2] = 0.5*(chi1[2]-chi2[2]);
521 dEbF7 =
params->dEbF7NonSpin;
522 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
526 dEbF6 =
params->dEbF6NonSpin;
527 dEbF6L =
params->dEbF6LogNonSpin;
528 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
532 dEbF5 =
params->dEbF5NonSpin
533 + chiaDotLNh*
delta*(72.71676587301587 + (7*eta)/2.)
534 + chisDotLNh*(72.71676587301587 - (1213*eta)/18. - (17*eta_p2)/2.);
535 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
539 dEbF4 =
params->dEbF4NonSpin
540 + (233*chisDotChia*
delta)/48. - (719*chiaDotLNh*chisDotLNh*
delta)/48.
541 + chiaSqr*(2.4270833333333335 - 10*eta) + chisDotLNh*chisDotLNh*(-7.489583333333333 - eta/24.)
542 + chisSqr*(2.4270833333333335 + (7*eta)/24.) + chiaDotLNh*chiaDotLNh*(-7.489583333333333 + 30*eta);
543 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
547 dEbF3 =
params->dEbF3NonSpin
548 + (113*chiaDotLNh*
delta)/12. + chisDotLNh*(9.416666666666666 - (19*eta)/3.);
549 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
553 dEbF2 =
params->dEbF2NonSpin;
554 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
558 dEbF1 =
params->dEbF1NonSpin;
559 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
563 dEbF0 =
params->dEbF0NonSpin;
566 XLALPrintError(
"XLAL Error - %s: Invalid phase. PN order %d\n", __func__, phaseO);
571 v2 = v*v; v3 = v2*v; v4 = v2*v2; v5 = v4*v; v6 = v3*v3; v7 = v6*v; v9 = v7*v2;
574 return (dEbF0/v9)*(1. + dEbF1*v + dEbF2*v2 + dEbF3*v3 + dEbF4*v4 + dEbF5*v5
575 + (dEbF6 + dEbF6L*log(v))*v6 + dEbF7*v7);
596 REAL8 deltaPhi, twoPhiS, alphaDot;
597 REAL8 LNx, LNy, LNz, v2, LNx_p2, LNy_p2, LNz_p2, LN_xz;
600 REAL8 cos_TwoPhiS, sin_TwoPhiS;
602 UINT4 dataLength =
V->data->length;
605 REAL8 eta = m1*m2/(m1+m2)/(m1+m2);
612 memset(iVec->data, 0, iVec->length *
sizeof(
REAL8 ));
616 for (
i=0;
i<dataLength;
i++) {
617 if (
V->data->data[
i]) {
635 memset((*hplus)->data->data, 0, (*hplus)->data->length*
sizeof(*(*hplus)->data->data));
636 memset((*hcross)->data->data, 0, (*hcross)->data->length*
sizeof(*(*hcross)->data->data));
638 REAL8 cos_Theta = cos(Theta);
639 REAL8 cos_TwoTheta = cos(2.*Theta);
640 REAL8 sin_Theta = sin(Theta);
641 REAL8 sin_TwoTheta = sin(2.*Theta);
643 for (
i=0;
i<dataLength;
i++) {
645 if (
V->data->data[
i]) {
650 v2 =
V->data->data[
i]*
V->data->data[
i];
658 if (
i == dataLength-1) alphaDot = (alphaVec->
data[
i] - alphaVec->
data[
i-1])/
deltaT;
662 deltaPhi += LNz*alphaDot*
deltaT;
665 twoPhiS = 2.*(Phi->
data->
data[
i] - deltaPhi);
667 cos_TwoPhiS = cos(twoPhiS);
668 sin_TwoPhiS = sin(twoPhiS);
672 (*hplus)->data->data[
i] = -(0.5*amp*v2*(cos_TwoPhiS*(-LNx_p2 + LNy_p2*LNz_p2 + ((LNy
673 + LN_xz)*cos_Theta + sin_Theta
674 - LNz_p2*sin_Theta)*((LNy - LN_xz)*cos_Theta + (-1. + LNz_p2)*sin_Theta))
675 + LNy*sin_TwoPhiS*(LN_xz*(3. + cos_TwoTheta) - (-1. + LNz_p2)*sin_TwoTheta)))/(-1. + LNz_p2);
677 (*hcross)->data->data[
i] = -(amp*v2*(cos_Theta*(-(LNx*LNy*(1 + LNz_p2)*cos_TwoPhiS)
678 + (-LNx_p2 + LNy_p2)*LNz*sin_TwoPhiS)
679 + (-1. + LNz_p2)*(LNy*LNz*cos_TwoPhiS + LNx*sin_TwoPhiS)*sin_Theta))/(-1. + LNz_p2);
710 REAL8 chi_s[3], chi_a[3], LNh[3];
711 REAL8 chisDotLNh, chiaDotLNh, chisDotChia, chisSqr, chiaSqr;
712 REAL8 v, v2, v3, v4, v5, v6, v7;
713 REAL8 phi0 = 0., phi1 = 0., phi2 = 0., phi3 = 0., phi4 = 0., phi5 = 0.;
714 REAL8 phi6 = 0., phi6L = 0., phi7 = 0.;
720 REAL8 eta_p2 = eta*eta;
722 for (
i = 0;
i<
V->data->length;
i++) {
724 if (
V->data->data[
i]) {
745 v =
V->data->data[
i];
751 phi7 =
params->phiOrb7NonSpin;
752 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
756 phi6 =
params->phiOrb6NonSpin;
757 phi6L =
params->phiOrb6LogNonSpin;
758 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
762 phi5 =
params->phiOrb5LogNonSpin
763 + chiaDotLNh*((-732985*
delta)/2016. - (35*
delta*eta)/2.)
764 + chisDotLNh*(-363.58382936507934 + (6065*eta)/18. + (85*eta_p2)/2.);
765 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
769 phi4 =
params->phiOrb4NonSpin
770 + (1165*chisDotChia*
delta)/48. - (3595*chiaDotLNh*chisDotLNh*
delta)/48.
771 + chiaSqr*(12.135416666666666 - 50*eta) + chisDotLNh*chisDotLNh*(-37.447916666666664 - (5*eta)/24.)
772 + chisSqr*(12.135416666666666 + (35*eta)/24.) + chiaDotLNh*chiaDotLNh*(-37.447916666666664 + 150*eta);
773 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
777 phi3 =
params->phiOrb3NonSpin
778 + (565*chiaDotLNh*
delta)/24. + chisDotLNh*(23.541666666666668 - (95*eta)/6.);
779 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
783 phi2 =
params->phiOrb2NonSpin;
784 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
788 phi1 =
params->phiOrb1NonSpin;
789 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
793 phi0 =
params->phiOrb0NonSpin;
796 XLALPrintError(
"XLAL Error - %s: Invalid phase. PN order %d\n", __func__, phaseO);
801 v2 = v*v; v3 = v2*v; v4 = v2*v2; v5 = v4*v; v6 = v3*v3; v7 = v6*v;
804 orbPhase->
data->
data[
i] = (phi0/v5)*(1. + phi1*v + phi2*v2 + phi3*v3 + phi4*v4 + phi5*log(v)*v5
805 + (phi6 + phi6L*log(v))*v6 + phi7*v7);
853 mParams->
dEbF6NonSpin = -115.2253249962622 + (3147553127*mParams->
eta)/1.2192768e7 - (15211*mParams->
etaSqr)/6912.
855 - (451*mParams->
eta*
LAL_PISQR)/48. + (1712*log(4))/105.;
867 mParams->
phiOrb6NonSpin = 657.6504345051205 - (15737765635*mParams->
eta)/1.2192768e7
868 + (76055*mParams->
etaSqr)/6912. - (127825*mParams->
etaSqr*mParams->
eta)/5184.
893 REAL8 LNh[3], S1[3], S2[3], chi1[3], chi2[3], v, dEbyF;
908 chi1[0] = S1[0]/
params->m1Sqr;
909 chi1[1] = S1[1]/
params->m1Sqr;
910 chi1[2] = S1[2]/
params->m1Sqr;
911 chi2[0] = S2[0]/
params->m2Sqr;
912 chi2[1] = S2[1]/
params->m2Sqr;
913 chi2[2] = S2[2]/
params->m2Sqr;
920 else if (dy[0] < 0.0)
922 else if (isnan(v) || isinf(v))
924 else if ((v < params->v0) || (v >
params->vMax) || (v < 0.) || (v >=
PN_V_MAX))
932 return a[0]*b[0] +
a[1]*b[1] +
a[2]*b[2];
937 c[0] =
a[1]*b[2] -
a[2]*b[1];
938 c[1] =
a[2]*b[0] -
a[0]*b[2];
939 c[2] =
a[0]*b[1] -
a[1]*b[0];
953 b[1] = -(z*cos(
theta)*sin(psi)) +
x*(cos(psi)*sin(phi)
954 + cos(phi)*sin(psi)*sin(
theta))
955 +
y*(cos(phi)*cos(psi) - sin(phi)*sin(psi)*sin(
theta));
957 b[2] = z*cos(psi)*cos(
theta) +
x*(sin(phi)*sin(psi)
958 - cos(phi)*cos(psi)*sin(
theta))
959 +
y*(cos(phi)*sin(psi) + cos(psi)*sin(phi)*sin(
theta));
static double double delta
#define LALSIMINSPIRAL_ST5_TEST_VNAN
static int polarizationsInRadiationFrame(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *LNhxVec, REAL8TimeSeries *LNhyVec, REAL8TimeSeries *LNhzVec, REAL8 m1, REAL8 m2, REAL8 r, REAL8 Theta)
#define LALSIMINSPIRAL_ST5_TEST_VDOT
static int spinTaylorT5Init(REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 deltaT, REAL8 phiRef, UINT4 phaseO, SpinTaylorT5Params *mParams)
Initialize the non-dynamical variables required for the SpinTaylorT5 evolution.
static REAL8 XLALdEnergyByFluxSpinPrec(double v, double *chi1, double *chi2, double *LNh, SpinTaylorT5Params *params)
#define LAL_ST5_ABSOLUTE_TOLERANCE
#define LALSIMINSPIRAL_ST5_TEST_ENERGY
#define LAL_NUM_ST5_VARIABLES
#define LALSIMINSPIRAL_ST5_TEST_FREQBOUND
static int computeOrbitalPhase(SpinTaylorT5Params *params, REAL8TimeSeries *V, REAL8TimeSeries *LNhxVec, REAL8TimeSeries *LNhyVec, REAL8TimeSeries *LNhzVec, REAL8TimeSeries *S1xVec, REAL8TimeSeries *S1yVec, REAL8TimeSeries *S1zVec, REAL8TimeSeries *S2xVec, REAL8TimeSeries *S2yVec, REAL8TimeSeries *S2zVec, REAL8TimeSeries *orbPhase)
static void crossProduct(double a[3], double b[3], double c[3])
static double dotProduct(double a[3], double b[3])
#define LAL_ST5_RELATIVE_TOLERANCE
static int XLALSimInspiralSpinTaylorT5StoppingTest(double t, const double y[], double dy[], void *mParams)
static int XLALSimInspiralSpinTaylorT5Derivatives(double t, const double y[], double dy[], void *mParams)
static void rotateVector(double a[3], double b[3], double phi, double theta, double psi)
void XLALDestroyREAL8Array(REAL8Array *)
void XLALAdaptiveRungeKuttaFree(LALAdaptiveRungeKuttaIntegrator *integrator)
int XLALAdaptiveRungeKutta4Hermite(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend_in, REAL8 deltat, REAL8Array **yout)
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)
int XLALSimInspiralSpinTaylorT5duplicate(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 incAngle, int phaseO, int amplitudeO)
Generate time-domain generic spinning PN waveforms in the SpinTaylorT5 approximaton.
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
const LALUnit lalStrainUnit
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
int XLALREAL8VectorUnwrapAngle(REAL8Vector *out, const REAL8Vector *in)
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)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
Structure containing the non-dynamical coefficients needed to evolve a spinning, precessing binary an...