static int test_tidal_F2( const REAL8 m2M ) { REAL8 m1M = 1.L-m2M; REAL8 eta = m1M*m2M; REAL8 energy2 = XLALSimInspiralPNEnergy_2PNCoeff(eta); REAL8 flux2 = XLALSimInspiralPNFlux_2PNCoeff(eta); REAL8 energy10 = XLALSimInspiralPNEnergy_10PNTidalCoeff(m2M); REAL8 flux10 = XLALSimInspiralPNFlux_10PNTidalCoeff(m2M); REAL8 energy12 = XLALSimInspiralPNEnergy_12PNTidalCoeff(m2M); REAL8 flux12 = XLALSimInspiralPNFlux_12PNTidalCoeff(m2M); REAL8 dtdv2 = 2.L*energy2 - flux2; REAL8 dtdv10 = 6.L*energy10 - flux10; REAL8 dtdv12 = (7.L*energy12 - flux12) - flux2*dtdv10 - flux10*dtdv2; REAL8 calc_phasing10 = 4.L*dtdv10; REAL8 calc_phasing12 = (10.L/7.L)*dtdv12; REAL8 phasing10 = XLALSimInspiralTaylorF2Phasing_10PNTidalCoeff(m2M); REAL8 phasing12 = XLALSimInspiralTaylorF2Phasing_12PNTidalCoeff(m2M); int ret = 0; ret += compare(calc_phasing10, phasing10, 10, 0); ret += compare(calc_phasing12, phasing12, 12, 0); return ret; }
int XLALSimInspiralTaylorF2Core( COMPLEX16FrequencySeries **htilde_out, /**< FD waveform */ const REAL8Sequence *freqs, /**< frequency points at which to evaluate the waveform (Hz) */ const REAL8 phi_ref, /**< reference orbital phase (rad) */ const REAL8 m1_SI, /**< mass of companion 1 (kg) */ const REAL8 m2_SI, /**< mass of companion 2 (kg) */ const REAL8 S1z, /**< z component of the spin of companion 1 */ const REAL8 S2z, /**< z component of the spin of companion 2 */ const REAL8 f_ref, /**< Reference GW frequency (Hz) - if 0 reference point is coalescence */ const REAL8 shft, /**< time shift to be applied to frequency-domain phase (sec)*/ const REAL8 r, /**< distance of source (m) */ LALDict *p /**< Linked list containing the extra testing GR parameters >**/ ) { if (!htilde_out) XLAL_ERROR(XLAL_EFAULT); if (!freqs) XLAL_ERROR(XLAL_EFAULT); /* external: SI; internal: solar masses */ const REAL8 m1 = m1_SI / LAL_MSUN_SI; const REAL8 m2 = m2_SI / LAL_MSUN_SI; const REAL8 m = m1 + m2; const REAL8 m_sec = m * LAL_MTSUN_SI; /* total mass in seconds */ const REAL8 eta = m1 * m2 / (m * m); const REAL8 piM = LAL_PI * m_sec; const REAL8 m1OverM = m1 / m; const REAL8 m2OverM = m2 / m; REAL8 amp0; size_t i; COMPLEX16 *data = NULL; LIGOTimeGPS tC = {0, 0}; INT4 iStart = 0; COMPLEX16FrequencySeries *htilde = NULL; if (*htilde_out) { //case when htilde_out has been allocated in XLALSimInspiralTaylorF2 htilde = *htilde_out; iStart = htilde->data->length - freqs->length; //index shift to fill pre-allocated data if(iStart < 0) XLAL_ERROR(XLAL_EFAULT); } else { //otherwise allocate memory here htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &tC, freqs->data[0], 0., &lalStrainUnit, freqs->length); if (!htilde) XLAL_ERROR(XLAL_EFUNC); XLALUnitMultiply(&htilde->sampleUnits, &htilde->sampleUnits, &lalSecondUnit); } /* phasing coefficients */ PNPhasingSeries pfa; XLALSimInspiralPNPhasing_F2(&pfa, m1, m2, S1z, S2z, S1z*S1z, S2z*S2z, S1z*S2z, p); REAL8 pfaN = 0.; REAL8 pfa1 = 0.; REAL8 pfa2 = 0.; REAL8 pfa3 = 0.; REAL8 pfa4 = 0.; REAL8 pfa5 = 0.; REAL8 pfl5 = 0.; REAL8 pfa6 = 0.; REAL8 pfl6 = 0.; REAL8 pfa7 = 0.; INT4 phaseO=XLALSimInspiralWaveformParamsLookupPNPhaseOrder(p); switch (phaseO) { case -1: case 7: pfa7 = pfa.v[7]; case 6: pfa6 = pfa.v[6]; pfl6 = pfa.vlogv[6]; case 5: pfa5 = pfa.v[5]; pfl5 = pfa.vlogv[5]; case 4: pfa4 = pfa.v[4]; case 3: pfa3 = pfa.v[3]; case 2: pfa2 = pfa.v[2]; case 1: pfa1 = pfa.v[1]; case 0: pfaN = pfa.v[0]; break; default: XLAL_ERROR(XLAL_ETYPE, "Invalid phase PN order %d", phaseO); } /* Validate expansion order arguments. * This must be done here instead of in the OpenMP parallel loop * because when OpenMP parallelization is turned on, early exits * from loops (via return or break statements) are not permitted. */ /* Validate amplitude PN order. */ INT4 amplitudeO=XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(p); switch (amplitudeO) { case -1: case 7: case 6: case 5: case 4: case 3: case 2: case 0: break; default: XLAL_ERROR(XLAL_ETYPE, "Invalid amplitude PN order %d", amplitudeO); } /* Generate tidal terms separately. * Enums specifying tidal order are in LALSimInspiralWaveformFlags.h */ REAL8 pft10 = 0.; REAL8 pft12 = 0.; REAL8 lambda1=XLALSimInspiralWaveformParamsLookupTidalLambda1(p); REAL8 lambda2=XLALSimInspiralWaveformParamsLookupTidalLambda2(p); switch( XLALSimInspiralWaveformParamsLookupPNTidalOrder(p) ) { case LAL_SIM_INSPIRAL_TIDAL_ORDER_ALL: case LAL_SIM_INSPIRAL_TIDAL_ORDER_6PN: pft12 = pfaN * (lambda1*XLALSimInspiralTaylorF2Phasing_12PNTidalCoeff(m1OverM) + lambda2*XLALSimInspiralTaylorF2Phasing_12PNTidalCoeff(m2OverM) ); case LAL_SIM_INSPIRAL_TIDAL_ORDER_5PN: pft10 = pfaN * ( lambda1*XLALSimInspiralTaylorF2Phasing_10PNTidalCoeff(m1OverM) + lambda2*XLALSimInspiralTaylorF2Phasing_10PNTidalCoeff(m2OverM) ); case LAL_SIM_INSPIRAL_TIDAL_ORDER_0PN: break; default: XLAL_ERROR(XLAL_EINVAL, "Invalid tidal PN order %d", XLALSimInspiralWaveformParamsLookupPNTidalOrder(p) ); } /* The flux and energy coefficients below are used to compute SPA amplitude corrections */ /* flux coefficients */ const REAL8 FTaN = XLALSimInspiralPNFlux_0PNCoeff(eta); const REAL8 FTa2 = XLALSimInspiralPNFlux_2PNCoeff(eta); const REAL8 FTa3 = XLALSimInspiralPNFlux_3PNCoeff(eta); const REAL8 FTa4 = XLALSimInspiralPNFlux_4PNCoeff(eta); const REAL8 FTa5 = XLALSimInspiralPNFlux_5PNCoeff(eta); const REAL8 FTl6 = XLALSimInspiralPNFlux_6PNLogCoeff(eta); const REAL8 FTa6 = XLALSimInspiralPNFlux_6PNCoeff(eta); const REAL8 FTa7 = XLALSimInspiralPNFlux_7PNCoeff(eta); /* energy coefficients */ const REAL8 dETaN = 2. * XLALSimInspiralPNEnergy_0PNCoeff(eta); const REAL8 dETa1 = 2. * XLALSimInspiralPNEnergy_2PNCoeff(eta); const REAL8 dETa2 = 3. * XLALSimInspiralPNEnergy_4PNCoeff(eta); const REAL8 dETa3 = 4. * XLALSimInspiralPNEnergy_6PNCoeff(eta); /* Perform some initial checks */ if (m1_SI <= 0) XLAL_ERROR(XLAL_EDOM); if (m2_SI <= 0) XLAL_ERROR(XLAL_EDOM); if (f_ref < 0) XLAL_ERROR(XLAL_EDOM); if (r <= 0) XLAL_ERROR(XLAL_EDOM); /* extrinsic parameters */ amp0 = -4. * m1 * m2 / r * LAL_MRSUN_SI * LAL_MTSUN_SI * sqrt(LAL_PI/12.L); data = htilde->data->data; /* Compute the SPA phase at the reference point * N.B. f_ref == 0 means we define the reference time/phase at "coalescence" * when the frequency approaches infinity. In that case, * the integrals Eq. 3.15 of arXiv:0907.0700 vanish when evaluated at * f_ref == infinity. If f_ref is finite, we must compute the SPA phase * evaluated at f_ref, store it as ref_phasing and subtract it off. */ REAL8 ref_phasing = 0.; if( f_ref != 0. ) { const REAL8 vref = cbrt(piM*f_ref); const REAL8 logvref = log(vref); const REAL8 v2ref = vref * vref; const REAL8 v3ref = vref * v2ref; const REAL8 v4ref = vref * v3ref; const REAL8 v5ref = vref * v4ref; const REAL8 v6ref = vref * v5ref; const REAL8 v7ref = vref * v6ref; const REAL8 v8ref = vref * v7ref; const REAL8 v9ref = vref * v8ref; const REAL8 v10ref = vref * v9ref; const REAL8 v12ref = v2ref * v10ref; ref_phasing += pfa7 * v7ref; ref_phasing += (pfa6 + pfl6 * logvref) * v6ref; ref_phasing += (pfa5 + pfl5 * logvref) * v5ref; ref_phasing += pfa4 * v4ref; ref_phasing += pfa3 * v3ref; ref_phasing += pfa2 * v2ref; ref_phasing += pfa1 * vref; ref_phasing += pfaN; /* Tidal terms in reference phasing */ ref_phasing += pft12 * v12ref; ref_phasing += pft10 * v10ref; ref_phasing /= v5ref; } /* End of if(f_ref != 0) block */ #pragma omp parallel for for (i = 0; i < freqs->length; i++) { const REAL8 f = freqs->data[i]; const REAL8 v = cbrt(piM*f); const REAL8 logv = log(v); const REAL8 v2 = v * v; const REAL8 v3 = v * v2; const REAL8 v4 = v * v3; const REAL8 v5 = v * v4; const REAL8 v6 = v * v5; const REAL8 v7 = v * v6; const REAL8 v8 = v * v7; const REAL8 v9 = v * v8; const REAL8 v10 = v * v9; const REAL8 v12 = v2 * v10; REAL8 phasing = 0.; REAL8 dEnergy = 0.; REAL8 flux = 0.; REAL8 amp; phasing += pfa7 * v7; phasing += (pfa6 + pfl6 * logv) * v6; phasing += (pfa5 + pfl5 * logv) * v5; phasing += pfa4 * v4; phasing += pfa3 * v3; phasing += pfa2 * v2; phasing += pfa1 * v; phasing += pfaN; /* Tidal terms in phasing */ phasing += pft12 * v12; phasing += pft10 * v10; /* WARNING! Amplitude orders beyond 0 have NOT been reviewed! * Use at your own risk. The default is to turn them off. * These do not currently include spin corrections. * Note that these are not higher PN corrections to the amplitude. * They are the corrections to the leading-order amplitude arising * from the stationary phase approximation. See for instance * Eq 6.9 of arXiv:0810.5336 */ switch (amplitudeO) { case 7: flux += FTa7 * v7; case 6: flux += (FTa6 + FTl6*logv) * v6; dEnergy += dETa3 * v6; case 5: flux += FTa5 * v5; case 4: flux += FTa4 * v4; dEnergy += dETa2 * v4; case 3: flux += FTa3 * v3; case 2: flux += FTa2 * v2; dEnergy += dETa1 * v2; case -1: /* Default to no SPA amplitude corrections */ case 0: flux += 1.; dEnergy += 1.; } phasing /= v5; flux *= FTaN * v10; dEnergy *= dETaN * v; // Note the factor of 2 b/c phi_ref is orbital phase phasing += shft * f - 2.*phi_ref - ref_phasing; amp = amp0 * sqrt(-dEnergy/flux) * v; data[i+iStart] = amp * cos(phasing - LAL_PI_4) - amp * sin(phasing - LAL_PI_4) * 1.0j; } *htilde_out = htilde; return XLAL_SUCCESS; }