Пример #1
0
static void T4wdot_from_energy_flux(
    PNPhasingSeries *wdot,
    const REAL8 m1M,
    const REAL8 chi1,
    const REAL8 chi2,
    const REAL8 qm_def1,
    const REAL8 qm_def2
    )
{
    REAL8 m2M = 1.-m1M;
    REAL8 eta = m1M*m2M;
    /* Spins use the wacky lal convention */
    REAL8 S1L = m1M*m1M*chi1;
    REAL8 S2L = m2M*m2M*chi2;

    REAL8 energy[9];
    REAL8 flux[9];

    energy[1] = 0.;
    energy[2] = XLALSimInspiralPNEnergy_2PNCoeff(eta);
    energy[3] = 0.;
    energy[4] = XLALSimInspiralPNEnergy_4PNCoeff(eta);
    energy[5] = 0.;
    energy[6] = XLALSimInspiralPNEnergy_6PNCoeff(eta);
    energy[7] = 0.;
    //We do not add the non-spin part of the 4PN energy as the 4PN flux is unknown, apart from the SL terms
    energy[8] = 0.;

    flux[1] = 0.;
    flux[2] = XLALSimInspiralPNFlux_2PNCoeff(eta);
    flux[3] = XLALSimInspiralPNFlux_3PNCoeff(eta);
    flux[4] = XLALSimInspiralPNFlux_4PNCoeff(eta);
    flux[5] = XLALSimInspiralPNFlux_5PNCoeff(eta);
    flux[6] = XLALSimInspiralPNFlux_6PNCoeff(eta);
    flux[7] = XLALSimInspiralPNFlux_7PNCoeff(eta);
    flux[8] = 0.;

    /* Add the spin-orbit contributions */
    REAL8 energy_so3=XLALSimInspiralPNEnergy_3PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_3PNSOCoeff(m2M)*S2L;
    energy[3] += energy_so3;
    REAL8 energy_so5=XLALSimInspiralPNEnergy_5PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_5PNSOCoeff(m2M)*S2L;
    energy[5] += energy_so5;
    energy[7] +=XLALSimInspiralPNEnergy_7PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_7PNSOCoeff(m2M)*S2L;

    flux[3] += XLALSimInspiralPNFlux_3PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_3PNSOCoeff(m2M)*S2L;
    flux[5] += XLALSimInspiralPNFlux_5PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_5PNSOCoeff(m2M)*S2L;
    REAL8 flux_so6=XLALSimInspiralPNFlux_6PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_6PNSOCoeff(m2M)*S2L;
    flux[6] += flux_so6;
    flux[7] += XLALSimInspiralPNFlux_7PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_7PNSOCoeff(m2M)*S2L;
    flux[8] += XLALSimInspiralPNFlux_8PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_8PNSOCoeff(m2M)*S2L;

    memset(wdot, 0, sizeof(PNPhasingSeries));
    wdot->v[0] = -XLALSimInspiralPNFlux_0PNCoeff(eta)/(2./3.*XLALSimInspiralPNEnergy_0PNCoeff(eta));
    wdot->v[1] = 0.; /* there's no 0.5 PN term */
    for (int i = 2; i <8; i++)
    {
        wdot->v[i] = flux[i] - (1.+0.5*i)*energy[i] - sumE(energy, wdot->v, i);
    }
    wdot->vlogv[6]= XLALSimInspiralPNFlux_6PNLogCoeff(eta);

    // The 8PN SO term is check by hand
    wdot->v[8]=flux[8]-5.*energy[8] - flux_so6*2.*XLALSimInspiralPNEnergy_2PNCoeff(eta) - XLALSimInspiralPNFlux_5PNCoeff(eta)*5./2.*energy_so3 + XLALSimInspiralPNFlux_3PNCoeff(eta)*(-7./2.*energy_so5 + 10.*XLALSimInspiralPNEnergy_2PNCoeff(eta)*energy_so3);

    /* Calculate the leading-order spin-spin terms separately */
    REAL8 energy_ss4 = XLALSimInspiralPNEnergy_4PNS1S2OCoeff(eta)*S1L*S2L;
    energy_ss4 += XLALSimInspiralPNEnergy_4PNS1S2Coeff(eta)*S1L*S2L;
    energy_ss4 += qm_def1*XLALSimInspiralPNEnergy_4PNQM2SCoeff(m1M)*S1L*S1L;
    energy_ss4 += qm_def1*XLALSimInspiralPNEnergy_4PNQM2SOCoeff(m1M)*S1L*S1L;
    energy_ss4 += qm_def2*XLALSimInspiralPNEnergy_4PNQM2SCoeff(m2M)*S2L*S2L;
    energy_ss4 += qm_def2*XLALSimInspiralPNEnergy_4PNQM2SOCoeff(m2M)*S2L*S2L;

    REAL8 flux_ss4 = XLALSimInspiralPNFlux_4PNS1S2OCoeff(eta)*S1L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNS1S2Coeff(eta)*S1L*S2L;
    flux_ss4 += qm_def1*XLALSimInspiralPNFlux_4PNQM2SCoeff(m1M)*S1L*S1L;
    flux_ss4 += qm_def1*XLALSimInspiralPNFlux_4PNQM2SOCoeff(m1M)*S1L*S1L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SCoeff(m1M)*S1L*S1L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SOCoeff(m1M)*S1L*S1L;
    flux_ss4 += qm_def2*XLALSimInspiralPNFlux_4PNQM2SCoeff(m2M)*S2L*S2L;
    flux_ss4 += qm_def2*XLALSimInspiralPNFlux_4PNQM2SOCoeff(m2M)*S2L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SCoeff(m2M)*S2L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SOCoeff(m2M)*S2L*S2L;

    wdot->v[4] += flux_ss4 -3.*energy_ss4;

    REAL8 energy_ss6 = XLALSimInspiralPNEnergy_6PNS1S2OCoeff(eta)*S1L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNS1S2Coeff(eta)*S1L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SCoeff(m1M)*S1L*S1L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SOCoeff(m1M)*S1L*S1L;
    energy_ss6 += qm_def1*XLALSimInspiralPNEnergy_6PNQM2SCoeff(m1M)*S1L*S1L;
    energy_ss6 += qm_def1*XLALSimInspiralPNEnergy_6PNQM2SOCoeff(m1M)*S1L*S1L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SCoeff(m2M)*S2L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SOCoeff(m2M)*S2L*S2L;
    energy_ss6 += qm_def2*XLALSimInspiralPNEnergy_6PNQM2SCoeff(m2M)*S2L*S2L;
    energy_ss6 += qm_def2*XLALSimInspiralPNEnergy_6PNQM2SOCoeff(m2M)*S2L*S2L;

    REAL8 flux_ss6 = XLALSimInspiralPNFlux_6PNS1S2OCoeff(eta)*S1L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNS1S2Coeff(eta)*S1L*S2L;
    flux_ss6 += qm_def1*XLALSimInspiralPNFlux_6PNQM2SCoeff(m1M)*S1L*S1L;
    flux_ss6 += qm_def1*XLALSimInspiralPNFlux_6PNQM2SOCoeff(m1M)*S1L*S1L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SCoeff(m1M)*S1L*S1L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SOCoeff(m1M)*S1L*S1L;
    flux_ss6 += qm_def2*XLALSimInspiralPNFlux_6PNQM2SCoeff(m2M)*S2L*S2L;
    flux_ss6 += qm_def2*XLALSimInspiralPNFlux_6PNQM2SOCoeff(m2M)*S2L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SCoeff(m2M)*S2L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SOCoeff(m2M)*S2L*S2L;

    wdot->v[6] += flux_ss6 - 4.*energy_ss6 -3.*flux[2]*energy_ss4 - 2.*flux_ss4*energy[2] + 12.*energy[2]*energy_ss4;

    return;
}
Пример #2
0
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;
}
Пример #3
0
static void dtdv_from_energy_flux(
    PNPhasingSeries *dtdv,
    const REAL8 m1M,
    const REAL8 chi1,
    const REAL8 chi2,
    const REAL8 qm_def1,
    const REAL8 qm_def2
    )
{
    /* Check is performed for aligned spin only*/
    REAL8 m2M = 1.-m1M;
    REAL8 eta = m1M*m2M;
    /* Spins use the wacky lal convention */
    REAL8 S1L = m1M*m1M*chi1;
    REAL8 S2L = m2M*m2M*chi2;

    REAL8 energy[9];
    REAL8 flux[9];

    energy[1] = 0.;
    energy[2] = XLALSimInspiralPNEnergy_2PNCoeff(eta);
    energy[3] = XLALSimInspiralPNEnergy_3PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_3PNSOCoeff(m2M)*S2L;
    energy[4] = XLALSimInspiralPNEnergy_4PNCoeff(eta);
    energy[5] = XLALSimInspiralPNEnergy_5PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_5PNSOCoeff(m2M)*S2L;
    energy[6] = XLALSimInspiralPNEnergy_6PNCoeff(eta);
    energy[7] = XLALSimInspiralPNEnergy_7PNSOCoeff(m1M)*S1L + XLALSimInspiralPNEnergy_7PNSOCoeff(m2M)*S2L;

    flux[1] = 0.;
    flux[2] = XLALSimInspiralPNFlux_2PNCoeff(eta);
    flux[3] = XLALSimInspiralPNFlux_3PNCoeff(eta);
    flux[4] = XLALSimInspiralPNFlux_4PNCoeff(eta);
    flux[5] = XLALSimInspiralPNFlux_5PNCoeff(eta);
    flux[6] = XLALSimInspiralPNFlux_6PNCoeff(eta);
    flux[7] = XLALSimInspiralPNFlux_7PNCoeff(eta);
    /* Add the spin-orbit fluxes */
    flux[3] += XLALSimInspiralPNFlux_3PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_3PNSOCoeff(m2M)*S2L;
    flux[5] += XLALSimInspiralPNFlux_5PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_5PNSOCoeff(m2M)*S2L;
    flux[6] += XLALSimInspiralPNFlux_6PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_6PNSOCoeff(m2M)*S2L;
    flux[7] += XLALSimInspiralPNFlux_7PNSOCoeff(m1M)*S1L + XLALSimInspiralPNFlux_7PNSOCoeff(m2M)*S2L;

    REAL8 flux6l = XLALSimInspiralPNFlux_6PNLogCoeff(eta);

    memset(dtdv, 0, sizeof(PNPhasingSeries));
    dtdv->v[0] = -2.*XLALSimInspiralPNEnergy_0PNCoeff(eta) / XLALSimInspiralPNFlux_0PNCoeff(eta);
    dtdv->v[1] = 0.; /* there's no 0.5 PN term */
    for (int i = 2; i < 8; i++)
    {
      dtdv->v[i] = (1.+0.5*((double)i))*energy[i] - flux[i] - sum(flux, dtdv->v, i);
    }
    dtdv->vlogv[6] = -flux6l;

    /* Calculate the leading-order spin-spin terms separately
     * FIXME: For now, only do aligned spins
     */
    REAL8 energy_ss4 = XLALSimInspiralPNEnergy_4PNS1S2OCoeff(eta)*S1L*S2L;
    energy_ss4 += XLALSimInspiralPNEnergy_4PNS1S2Coeff(eta)*S1L*S2L;
    energy_ss4 += qm_def1*XLALSimInspiralPNEnergy_4PNQM2SCoeff(m1M)*S1L*S1L;
    energy_ss4 += qm_def1*XLALSimInspiralPNEnergy_4PNQM2SOCoeff(m1M)*S1L*S1L;
    energy_ss4 += qm_def2*XLALSimInspiralPNEnergy_4PNQM2SCoeff(m2M)*S2L*S2L;
    energy_ss4 += qm_def2*XLALSimInspiralPNEnergy_4PNQM2SOCoeff(m2M)*S2L*S2L;

    REAL8 flux_ss4 = XLALSimInspiralPNFlux_4PNS1S2OCoeff(eta)*S1L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNS1S2Coeff(eta)*S1L*S2L;

    flux_ss4 += qm_def1*XLALSimInspiralPNFlux_4PNQM2SCoeff(m1M)*S1L*S1L;
    flux_ss4 += qm_def1*XLALSimInspiralPNFlux_4PNQM2SOCoeff(m1M)*S1L*S1L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SCoeff(m1M)*S1L*S1L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SOCoeff(m1M)*S1L*S1L;

    flux_ss4 += qm_def2*XLALSimInspiralPNFlux_4PNQM2SCoeff(m2M)*S2L*S2L;
    flux_ss4 += qm_def2*XLALSimInspiralPNFlux_4PNQM2SOCoeff(m2M)*S2L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SCoeff(m2M)*S2L*S2L;
    flux_ss4 += XLALSimInspiralPNFlux_4PNSelf2SOCoeff(m2M)*S2L*S2L;

    dtdv->v[4] += 3.*energy_ss4 - flux_ss4;

    REAL8 energy_ss6 = XLALSimInspiralPNEnergy_6PNS1S2OCoeff(eta)*S1L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNS1S2Coeff(eta)*S1L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SCoeff(m1M)*S1L*S1L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SOCoeff(m1M)*S1L*S1L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SCoeff(m2M)*S2L*S2L;
    energy_ss6 += XLALSimInspiralPNEnergy_6PNSelf2SOCoeff(m2M)*S2L*S2L;
    energy_ss6 += qm_def1*XLALSimInspiralPNEnergy_6PNQM2SCoeff(m1M)*S1L*S1L;
    energy_ss6 += qm_def1*XLALSimInspiralPNEnergy_6PNQM2SOCoeff(m1M)*S1L*S1L;
    energy_ss6 += qm_def2*XLALSimInspiralPNEnergy_6PNQM2SCoeff(m2M)*S2L*S2L;
    energy_ss6 += qm_def2*XLALSimInspiralPNEnergy_6PNQM2SOCoeff(m2M)*S2L*S2L;

    REAL8 flux_ss6 = XLALSimInspiralPNFlux_6PNS1S2OCoeff(eta)*S1L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNS1S2Coeff(eta)*S1L*S2L;

    flux_ss6 += qm_def1*XLALSimInspiralPNFlux_6PNQM2SCoeff(m1M)*S1L*S1L;
    flux_ss6 += qm_def1*XLALSimInspiralPNFlux_6PNQM2SOCoeff(m1M)*S1L*S1L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SCoeff(m1M)*S1L*S1L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SOCoeff(m1M)*S1L*S1L;

    flux_ss6 += qm_def2*XLALSimInspiralPNFlux_6PNQM2SCoeff(m2M)*S2L*S2L;
    flux_ss6 += qm_def2*XLALSimInspiralPNFlux_6PNQM2SOCoeff(m2M)*S2L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SCoeff(m2M)*S2L*S2L;
    flux_ss6 += XLALSimInspiralPNFlux_6PNSelf2SOCoeff(m2M)*S2L*S2L;

    dtdv->v[6] += 4.*energy_ss6 - flux_ss6 -3.*flux[2]*energy_ss4 - 2.*flux_ss4*energy[2] + 2.*flux[2]*flux_ss4;

    return;
}