/* * Routine that returns selected frame library: * if LAL_FRAME_LIBRARY is set, use the value from that environment; * otherwise use the default value. * Note: this is NOT threadsafe, but I doubt the frame libraries are * threadsafe in any case.... */ static int XLALFrameLibrary(void) { static int lalFrameLibrary = -1; if (lalFrameLibrary < 0) { const char *env = getenv("LAL_FRAME_LIBRARY"); if (env) { if (strcmp(env, "FrameL") == 0) { #if defined HAVE_FRAMEL_H && defined HAVE_LIBFRAME lalFrameLibrary = LAL_FRAMEU_FRAME_LIBRARY_FRAMEL; #else XLAL_ERROR_VAL(LAL_FRAMEU_FRAME_LIBRARY_UNAVAILABLE, XLAL_ESYS, "LAL_FRAME_LIBRARY=%s: FrameL frame library not available", env); #endif } else if (strcmp(env, "FrameC") == 0) { #if defined HAVE_FRAMECPPC_FRAMEC_H && defined HAVE_LIBFRAMECPPC lalFrameLibrary = LAL_FRAMEU_FRAME_LIBRARY_FRAMEC; #else XLAL_ERROR_VAL(LAL_FRAMEU_FRAME_LIBRARY_UNAVAILABLE, XLAL_ESYS, "LAL_FRAME_LIBRARY=%s: FrameC frame library not available", env); #endif } else { XLAL_PRINT_WARNING("LAL_FRAME_LIBRARY=%s: No valid frame library specified [expect: \"FrameL\" or \"FrameC\"]", env); lalFrameLibrary = LAL_FRAMEU_FRAME_LIBRARY_DEFAULT; } } else { lalFrameLibrary = LAL_FRAMEU_FRAME_LIBRARY_DEFAULT; } switch (lalFrameLibrary) { case LAL_FRAMEU_FRAME_LIBRARY_FRAMEL: XLAL_PRINT_INFO("Using the FrameL frame library"); break; case LAL_FRAMEU_FRAME_LIBRARY_FRAMEC: XLAL_PRINT_INFO("Using the FrameC frame library"); break; default: XLAL_ERROR_VAL(LAL_FRAMEU_FRAME_LIBRARY_UNAVAILABLE, XLAL_EERR, "No frame library available"); } } return lalFrameLibrary; }
static int read_matrix(const char dir[], const char fname[], gsl_matrix *m) { size_t size = strlen(dir) + strlen(fname) + 2; char *path = XLALMalloc(size); snprintf(path, size, "%s/%s", dir, fname); FILE *f = fopen(path, "rb"); if (!f) XLAL_ERROR(XLAL_EIO, "Could not find ROM data file at path `%s'", path); int ret = gsl_matrix_fread(f, m); if (ret != 0) XLAL_ERROR(XLAL_EIO, "Error reading data from `%s'", path); fclose(f); XLAL_PRINT_INFO("Sucessfully read data file `%s'", path); XLALFree(path); return(XLAL_SUCCESS); }
static int IMRPhenomCGenerateFD( COMPLEX16FrequencySeries **htilde, /**< FD waveform */ const REAL8 phi0, /**< phase at peak */ const REAL8 deltaF, /**< frequency resolution */ const REAL8 m1, /**< mass of companion 1 [solar masses] */ const REAL8 m2, /**< mass of companion 2 [solar masses] */ //const REAL8 chi, /**< mass-weighted aligned-spin parameter */ const REAL8 f_min, /**< start frequency */ const REAL8 f_max, /**< end frequency */ const REAL8 distance, /**< distance to source (m) */ const BBHPhenomCParams *params /**< from ComputeIMRPhenomCParams */ ) { LIGOTimeGPS ligotimegps_zero = LIGOTIMEGPSZERO; // = {0, 0} int errcode = XLAL_SUCCESS; /* We can't call XLAL_ERROR() directly with OpenMP on. Keep track of return codes for each thread and in addition use flush to get out of the parallel for loop as soon as possible if something went wrong in any thread. */ const REAL8 M = m1 + m2; const REAL8 eta = m1 * m2 / (M * M); /* Memory to temporarily store components of amplitude and phase */ /* REAL8 phSPA, phPM, phRD, aPM, aRD; REAL8 wPlusf1, wPlusf2, wMinusf1, wMinusf2, wPlusf0, wMinusf0; */ /* compute the amplitude pre-factor */ REAL8 amp0 = 2. * sqrt(5. / (64.*LAL_PI)) * M * LAL_MRSUN_SI * M * LAL_MTSUN_SI / distance; /* allocate htilde */ size_t n = NextPow2(f_max / deltaF) + 1; /* coalesce at t=0 */ XLALGPSAdd(&ligotimegps_zero, -1. / deltaF); // shift by overall length in time *htilde = XLALCreateCOMPLEX16FrequencySeries("htilde: FD waveform", &ligotimegps_zero, 0.0, deltaF, &lalStrainUnit, n); memset((*htilde)->data->data, 0, n * sizeof(COMPLEX16)); XLALUnitMultiply(&((*htilde)->sampleUnits), &((*htilde)->sampleUnits), &lalSecondUnit); if (!(*htilde)) XLAL_ERROR(XLAL_EFUNC); size_t ind_min = (size_t) (f_min / deltaF); size_t ind_max = (size_t) (f_max / deltaF); /* Set up spline for phase */ gsl_interp_accel *acc = gsl_interp_accel_alloc(); size_t L = ind_max - ind_min; gsl_spline *phiI = gsl_spline_alloc(gsl_interp_cspline, L); REAL8 *freqs = XLALMalloc(L*sizeof(REAL8)); REAL8 *phis = XLALMalloc(L*sizeof(REAL8)); /* now generate the waveform */ #pragma omp parallel for for (size_t i = ind_min; i < ind_max; i++) { REAL8 phPhenomC = 0.0; REAL8 aPhenomC = 0.0; REAL8 f = i * deltaF; int per_thread_errcode; #pragma omp flush(errcode) if (errcode != XLAL_SUCCESS) goto skip; per_thread_errcode = IMRPhenomCGenerateAmpPhase( &aPhenomC, &phPhenomC, f, eta, params ); if (per_thread_errcode != XLAL_SUCCESS) { errcode = per_thread_errcode; #pragma omp flush(errcode) } phPhenomC -= 2.*phi0; // factor of 2 b/c phi0 is orbital phase freqs[i-ind_min] = f; phis[i-ind_min] = -phPhenomC; // PhenomP uses cexp(-I*phPhenomC); want to use same phase adjustment code, so we will flip the sign of the phase /* generate the waveform */ ((*htilde)->data->data)[i] = amp0 * aPhenomC * cos(phPhenomC); ((*htilde)->data->data)[i] += -I * amp0 * aPhenomC * sin(phPhenomC); skip: /* this statement intentionally left blank */; } if( errcode != XLAL_SUCCESS ) XLAL_ERROR(errcode); /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */ gsl_spline_init(phiI, freqs, phis, L); REAL8 f_final = params->fRingDown; XLAL_PRINT_INFO("f_ringdown = %g\n", f_final); // Prevent gsl interpolation errors if (f_final > freqs[L-1]) f_final = freqs[L-1]; if (f_final < freqs[0]) XLAL_ERROR(XLAL_EDOM, "f_ringdown <= f_min\n"); /* Time correction is t(f_final) = 1/(2pi) dphi/df (f_final) */ REAL8 t_corr = gsl_spline_eval_deriv(phiI, f_final, acc) / (2*LAL_PI); XLAL_PRINT_INFO("t_corr = %g\n", t_corr); /* Now correct phase */ for (size_t i = ind_min; i < ind_max; i++) { REAL8 f = i * deltaF; ((*htilde)->data->data)[i] *= cexp(-2*LAL_PI * I * f * t_corr); } gsl_spline_free(phiI); gsl_interp_accel_free(acc); XLALFree(freqs); XLALFree(phis); return XLAL_SUCCESS; }
/* Everything needs to be declared as unused in case HDF is not enabled. */ int XLALSimInspiralNRWaveformGetHplusHcross( UNUSED REAL8TimeSeries **hplus, /**< Output h_+ vector */ UNUSED REAL8TimeSeries **hcross, /**< Output h_x vector */ UNUSED REAL8 phiRef, /**< orbital phase at reference pt. */ UNUSED REAL8 inclination, /**< inclination angle */ UNUSED REAL8 deltaT, /**< sampling interval (s) */ UNUSED REAL8 m1, /**< mass of companion 1 (kg) */ UNUSED REAL8 m2, /**< mass of companion 2 (kg) */ UNUSED REAL8 r, /**< distance of source (m) */ UNUSED REAL8 fStart, /**< start GW frequency (Hz) */ UNUSED REAL8 fRef, /**< reference GW frequency (Hz) */ UNUSED REAL8 s1x, /**< initial value of S1x */ UNUSED REAL8 s1y, /**< initial value of S1y */ UNUSED REAL8 s1z, /**< initial value of S1z */ UNUSED REAL8 s2x, /**< initial value of S2x */ UNUSED REAL8 s2y, /**< initial value of S2y */ UNUSED REAL8 s2z, /**< initial value of S2z */ UNUSED const char *NRDataFile, /**< Location of NR HDF file */ UNUSED LALValue* ModeArray /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */ ) { #ifndef LAL_HDF5_ENABLED XLAL_ERROR(XLAL_EFAILED, "HDF5 support not enabled"); #else /* Declarations */ UINT4 curr_idx, nr_file_format; INT4 model, modem; size_t array_length; REAL8 nrEta; REAL8 S1x, S1y, S1z, S2x, S2y, S2z; REAL8 Mflower, time_start_M, time_start_s, time_end_M, time_end_s; REAL8 est_start_time, curr_h_real, curr_h_imag; REAL8 theta, psi, calpha, salpha; REAL8 distance_scale_fac; COMPLEX16 curr_ylm; REAL8TimeSeries *hplus_corr; REAL8TimeSeries *hcross_corr; /* These keys follow a strict formulation and cannot be longer than 11 * characters */ char amp_key[20]; char phase_key[20]; gsl_vector *tmpVector=NULL; LALH5File *file, *group; LIGOTimeGPS tmpEpoch = LIGOTIMEGPSZERO; REAL8Vector *curr_amp, *curr_phase; /* Use solar masses for units. NR files will use * solar masses as well, so easier for that conversion */ m1 = m1 / LAL_MSUN_SI; m2 = m2 / LAL_MSUN_SI; file = XLALH5FileOpen(NRDataFile, "r"); if (file == NULL) { XLAL_ERROR(XLAL_EIO, "NR SIMULATION DATA FILE %s NOT FOUND.\n", NRDataFile); } /* Sanity checks on physical parameters passed to waveform * generator to guarantee consistency with NR data file. */ XLALH5FileQueryScalarAttributeValue(&nrEta, file, "eta"); if (fabs((m1 * m2) / pow((m1 + m2),2.0) - nrEta) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "MASSES (%e and %e) ARE INCONSISTENT WITH THE MASS RATIO OF THE NR SIMULATION (eta=%e).\n", m1, m2, nrEta); } /* Read spin metadata, L_hat, n_hat from HDF5 metadata and make sure * the ChooseTDWaveform() input values are consistent with the data * recorded in the metadata of the HDF5 file. * PS: This assumes that the input spins are in the LAL frame! */ XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format < 2) { XLALPrintInfo("This NR file is format %d. Only formats 2 and above support the use of reference frequency. For formats < 2 the reference frequency always corresponds to the start of the waveform.", nr_file_format); fRef = -1; } XLALSimInspiralNRWaveformGetSpinsFromHDF5FilePointer(&S1x, &S1y, &S1z, &S2x, &S2y, &S2z, fRef, m1+m2, file); if (fabs(S1x - s1x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1y - s1y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S1z - s1z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN1Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2x - s2x) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2X IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2y - s2y) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Y IS INCONSISTENT WITH THE NR SIMULATION.\n"); } if (fabs(S2z - s2z) > 1E-3) { XLAL_ERROR(XLAL_EDOM, "SPIN2Z IS INCONSISTENT WITH THE NR SIMULATION.\n"); } /* First estimate the length of time series that is needed. * Demand that 22 mode that is present and use that to figure this out */ XLALH5FileQueryScalarAttributeValue(&Mflower, file, "f_lower_at_1MSUN"); /* Figure out start time of data */ group = XLALH5GroupOpen(file, "amp_l2_m2"); ReadHDF5RealVectorDataset(group, "X", &tmpVector); time_start_M = (REAL8)(gsl_vector_get(tmpVector, 0)); time_end_M = (REAL8)(gsl_vector_get(tmpVector, tmpVector->size - 1)); gsl_vector_free(tmpVector); time_start_s = time_start_M * (m1 + m2) * LAL_MTSUN_SI; time_end_s = time_end_M * (m1 + m2) * LAL_MTSUN_SI; /* We don't want to return the *entire* waveform if it will be much longer * than the specified f_lower. Therefore guess waveform length using * the SEOBNR_ROM function and add 10% for safety. * FIXME: Is this correct for precessing waveforms? */ if (fStart < Mflower / (m1 + m2) ) { XLAL_ERROR(XLAL_EDOM, "WAVEFORM IS NOT LONG ENOUGH TO REACH f_low. %e %e %e", fStart, Mflower, Mflower / (m1 + m2)); } XLALH5FileQueryScalarAttributeValue(&nr_file_format, file, "Format"); if (nr_file_format > 1) { if (XLALSimInspiralNRWaveformCheckFRef(file, fStart * (m1+m2)) > 0) { /* Can use Omega array to get start time */ est_start_time = XLALSimInspiralNRWaveformGetRefTimeFromRefFreq(file, fStart * (m1+m2)) * (m1 + m2) * LAL_MTSUN_SI; } else { /* This is the potential weird case where Omega-vs-time does not start * at precisely the same time as flower_at_1MSUN. This gap should be * small, so just use the full waveform here. */ est_start_time = time_start_s; } } else { /* Fall back on SEOBNR chirp time estimate */ XLALSimIMRSEOBNRv4ROMTimeOfFrequency(&est_start_time, fStart, m1 * LAL_MSUN_SI, m2 * LAL_MSUN_SI, s1z, s2z); est_start_time = (-est_start_time) * 1.1; } if (est_start_time > time_start_s) { /* Restrict start time of waveform */ time_start_s = est_start_time; time_start_M = time_start_s / ((m1 + m2) * LAL_MTSUN_SI); } array_length = (UINT4)(ceil( (time_end_s - time_start_s) / deltaT)); /* Compute correct angles for hplus and hcross following LAL convention. */ theta = psi = calpha = salpha = 0.; XLALSimInspiralNRWaveformGetRotationAnglesFromH5File(&theta, &psi, &calpha, &salpha, file, inclination, phiRef, fRef*(m1+m2)); /* Create the return time series, use arbitrary epoch here. We set this * properly later. */ XLALGPSAdd(&tmpEpoch, time_start_s); *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hplus_corr = XLALCreateREAL8TimeSeries("H_PLUS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); hcross_corr = XLALCreateREAL8TimeSeries("H_CROSS", &tmpEpoch, 0.0, deltaT, &lalStrainUnit, array_length ); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { hplus_corr->data->data[curr_idx] = 0.0; hcross_corr->data->data[curr_idx] = 0.0; } /* Create the distance scale factor */ distance_scale_fac = (m1 + m2) * LAL_MRSUN_SI / r; /* Generate the waveform */ /* NOTE: We assume that for a given ell mode, all m modes are present */ INT4 NRLmax; XLALH5FileQueryScalarAttributeValue(&NRLmax, file, "Lmax"); if ( ModeArray == NULL ) {/* Default behaviour: Generate all modes upto NRLmax */ ModeArray = XLALSimInspiralCreateModeArray(); for (int ell=2; ell<=NRLmax; ell++) { XLALSimInspiralModeArrayActivateAllModesAtL(ModeArray, ell); } } /* else Use the ModeArray given */ for (model=2; model < (NRLmax + 1) ; model++) { for (modem=-model; modem < (model+1); modem++) { /* first check if (l,m) mode is 'activated' in the ModeArray */ /* if activated then generate the mode, else skip this mode. */ if (XLALSimInspiralModeArrayIsModeActive(ModeArray, model, modem) != 1) { XLAL_PRINT_INFO("SKIPPING model = %i modem = %i\n", model, modem); continue; } XLAL_PRINT_INFO("generateing model = %i modem = %i\n", model, modem); snprintf(amp_key, sizeof(amp_key), "amp_l%d_m%d", model, modem); snprintf(phase_key, sizeof(phase_key), "phase_l%d_m%d", model, modem); /* Check that both groups exist */ if (XLALH5FileCheckGroupExists(file, amp_key) == 0) { continue; } if (XLALH5FileCheckGroupExists(file, phase_key) == 0) { continue; } /* Get amplitude and phase from file */ XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_amp, file, (m1 + m2), time_start_s, array_length, deltaT, amp_key); XLALSimInspiralNRWaveformGetDataFromHDF5File(&curr_phase, file, (m1 + m2), time_start_s, array_length, deltaT, phase_key); curr_ylm = XLALSpinWeightedSphericalHarmonic(theta, psi, -2, model, modem); for (curr_idx = 0; curr_idx < array_length; curr_idx++) { curr_h_real = curr_amp->data[curr_idx] * cos(curr_phase->data[curr_idx]) * distance_scale_fac; curr_h_imag = curr_amp->data[curr_idx] * sin(curr_phase->data[curr_idx]) * distance_scale_fac; hplus_corr->data->data[curr_idx] = hplus_corr->data->data[curr_idx] + curr_h_real * creal(curr_ylm) - curr_h_imag * cimag(curr_ylm); hcross_corr->data->data[curr_idx] = hcross_corr->data->data[curr_idx] - curr_h_real * cimag(curr_ylm) - curr_h_imag * creal(curr_ylm); } XLALDestroyREAL8Vector(curr_amp); XLALDestroyREAL8Vector(curr_phase); } } /* Correct for the "alpha" angle as given in T1600045 to translate * from the NR wave frame to LAL wave-frame * Helper time series needed. */ for (curr_idx = 0; curr_idx < array_length; curr_idx++) { (*hplus)->data->data[curr_idx] = (calpha*calpha - salpha*salpha) * hplus_corr->data->data[curr_idx] - 2.0*calpha*salpha * hcross_corr->data->data[curr_idx]; (*hcross)->data->data[curr_idx] = + 2.0*calpha*salpha * hplus_corr->data->data[curr_idx] + (calpha*calpha - salpha*salpha) * hcross_corr->data->data[curr_idx]; } XLALDestroyREAL8TimeSeries(hplus_corr); XLALDestroyREAL8TimeSeries(hcross_corr); XLALH5FileClose(file); XLALDestroyValue(ModeArray); return XLAL_SUCCESS; #endif }
/** * @brief Creates a 4-parameter piecewise-polytrope Equation of State. * @details A 4-piece piecewise polytrope as described in * Physical Review D 79, 124032 (2009) in which the low-density part is * fit to the SLY4 EOS. The remaining pieces are described by adiabatic * indices gamma1, gamma2, and gamma3, where gamma1 is the adiabatic index * for densities < 10^17.7 kg/m^3, gamma2 is the adiabatic index for densities * in the range 10^17.7 kg/m^3 to 10^18 kg/m^3, and gamma3 is the adiabatic * index for densities > 10^18 kg/m^3. The base-10 logarithm of the pressure in * Pa at a density of 10^17.7 kg/m^3 is specified by logp1_si. * @param logp1_si Base 10 logarithm of the pressure in Pa at the reference * density of 10^17.7 kg/m^3. * @param gamma1 Adiabatic index for densities below 10^17.7 kg/m^3. * @param gamma2 Adiabatic index for densities from 10^17.7 kg/m^3 * to 10^18 kg/m^3. * @param gamma3 Adiabatic index for densities above 10^18 kg/m^3. * @return A pointer to a newly created EOS structure. */ LALSimNeutronStarEOS *XLALSimNeutronStarEOS4ParameterPiecewisePolytrope(double logp1_si, double gamma1, double gamma2, double gamma3) { LALSimNeutronStarEOS *eos; LALSimNeutronStarEOSDataPiecewisePolytrope *data; /* Data for the 4-piece piecewise polytrope fit to the low-density part of * the SLY4 EOS. Pressure is defined in Pa (N/m^2), and rest-mass density * is in kg/m^3. In the paper PRD 79, 124032 (2009) which used cgs, the * k_i values in Table II should be multiplied by c^2. */ double rhoLow[] = { 0, 2.44033979e10, 3.78358138e14, 2.62780487e15 }; double kLow[] = { 1.0801158752700761e7, 1.311359898998385e10, 6.507604807550857e19, 3.053461077133694e8 }; double gammaLow[] = { 1.58424999, 1.28732904, 0.62223344, 1.35692395 }; /* * These are the cgs values: * double rhoLow[] = {0, 2.44033979e7, 3.78358138e11, 2.62780487e12}; * double kLow[] = {6.11252036792443e12, 9.54352947022931e14, 4.787640050002652e22, 3.593885515256112e13}; * double gammaLow[] = {1.58424999, 1.28732904, 0.62223344, 1.35692395}; */ double rho0, rho1, rho2; double p1; /* pressure at 10^17.7 kg/m^3 */ double p1min; /* Minimum allowed value of p1 s.t. high density EOS has larger pressure than low density EOS */ double k1, k2, k3; double rhoJoin1, rhoJoin2, pJoin1, pJoin2, gammaJoin, kJoin; /* constants for extra polytrope if it's needed */ int i; double k_i, rho_i, gamma_i, p_i, n_i, a_i, a_im1, n_im1, epsilon_i, enthalpy_i, h_i; if (gamma1 <= 1.0 || gamma2 <= 1.0 || gamma3 <= 1.0) XLAL_ERROR_NULL(XLAL_EINVAL, "Adiabitic indices gamma1=%g, gamma2=%g, and gamma3=%g " "must all be greater than 1", gamma1, gamma2, gamma3); /* Transition densities between the 3 high-density polytropes */ rho1 = pow(10, 17.7); rho2 = pow(10, 18.0); /* pressure at rho1 */ p1 = pow(10, logp1_si); /* pressure constants */ k1 = p1 / pow(rho1, gamma1); k2 = p1 / pow(rho1, gamma2); k3 = k2 * pow(rho2, gamma2 - gamma3); /* Calculate the variable joining density rho0 between the high and low * density EOS */ rho0 = pow(kLow[3] / k1, 1.0 / (gamma1 - gammaLow[3])); p1min = kLow[3] * pow(rho1, gammaLow[3]); if (logp1_si < log10(p1min) || logp1_si > 34.5) XLAL_ERROR_NULL(XLAL_EINVAL, "logp1_si=%g should be between %g and 34.5", logp1_si, log10(p1min)); /* allocate memory */ eos = LALCalloc(1, sizeof(*eos)); data = LALCalloc(1, sizeof(*data)); eos->datatype = LALSIM_NEUTRON_STAR_EOS_DATA_TYPE_PIECEWISE_POLYTROPE; eos->data.piecewisePolytrope = data; if(snprintf(eos->name, sizeof(eos->name), "4-Piece Polytrope (p1=10^%g Pa," "Gamma1=%g,Gamma2=%g,Gamma3=%g)", logp1_si, gamma1, gamma2, gamma3) >= (int) sizeof(eos->name)) XLAL_ERROR_NULL(XLAL_EINVAL, "eos name overflow"); /* setup function pointers */ eos->free = eos_free_piecewise_polytrope; eos->e_of_p = eos_e_of_p_piecewise_polytrope; eos->h_of_p = eos_h_of_p_piecewise_polytrope; eos->e_of_h = eos_e_of_h_piecewise_polytrope; eos->rho_of_h = eos_rho_of_h_piecewise_polytrope; eos->p_of_h = eos_p_of_h_piecewise_polytrope; eos->dedp_of_p = eos_dedp_of_p_piecewise_polytrope; eos->v_of_h = eos_v_of_h_piecewise_polytrope; /* Add another polytrope if the joining density is below the start of the * last low density polytrope or above the end of the first high density * polytrope. */ if ((rho0 > rhoLow[3]) && (rho0 < rho1)) { /* No issue. There will be a total of 7 polytropes. */ eos->data.piecewisePolytrope->kTab[0] = kLow[0]; eos->data.piecewisePolytrope->kTab[1] = kLow[1]; eos->data.piecewisePolytrope->kTab[2] = kLow[2]; eos->data.piecewisePolytrope->kTab[3] = kLow[3]; eos->data.piecewisePolytrope->kTab[4] = k1; eos->data.piecewisePolytrope->kTab[5] = k2; eos->data.piecewisePolytrope->kTab[6] = k3; eos->data.piecewisePolytrope->gammaTab[0] = gammaLow[0]; eos->data.piecewisePolytrope->gammaTab[1] = gammaLow[1]; eos->data.piecewisePolytrope->gammaTab[2] = gammaLow[2]; eos->data.piecewisePolytrope->gammaTab[3] = gammaLow[3]; eos->data.piecewisePolytrope->gammaTab[4] = gamma1; eos->data.piecewisePolytrope->gammaTab[5] = gamma2; eos->data.piecewisePolytrope->gammaTab[6] = gamma3; eos->data.piecewisePolytrope->rhoTab[0] = rhoLow[0]; eos->data.piecewisePolytrope->rhoTab[1] = rhoLow[1]; eos->data.piecewisePolytrope->rhoTab[2] = rhoLow[2]; eos->data.piecewisePolytrope->rhoTab[3] = rhoLow[3]; eos->data.piecewisePolytrope->rhoTab[4] = rho0; eos->data.piecewisePolytrope->rhoTab[5] = rho1; eos->data.piecewisePolytrope->rhoTab[6] = rho2; eos->data.piecewisePolytrope->nPoly = 7; } else { /* You have to add an 8th polytrope between gammaLow[3] and gamma1. */ /* It will be between the densities rhoJoin1 and rhoJoin2. */ rhoJoin1 = 5.0e15; rhoJoin2 = 1.0e16; /* Calculate the pressure at the start and end densities. */ pJoin1 = kLow[3] * pow(rhoJoin1, gammaLow[3]); pJoin2 = k1 * pow(rhoJoin2, gamma1); /* Calculate K and Gamma for the joining polytrope */ gammaJoin = log(pJoin2 / pJoin1) / log(rhoJoin2 / rhoJoin1); kJoin = pJoin1 / pow(rhoJoin1, gammaJoin); /* Now join all 8 polytropes. */ eos->data.piecewisePolytrope->kTab[0] = kLow[0]; eos->data.piecewisePolytrope->kTab[1] = kLow[1]; eos->data.piecewisePolytrope->kTab[2] = kLow[2]; eos->data.piecewisePolytrope->kTab[3] = kLow[3]; eos->data.piecewisePolytrope->kTab[4] = kJoin; eos->data.piecewisePolytrope->kTab[5] = k1; eos->data.piecewisePolytrope->kTab[6] = k2; eos->data.piecewisePolytrope->kTab[7] = k3; eos->data.piecewisePolytrope->gammaTab[0] = gammaLow[0]; eos->data.piecewisePolytrope->gammaTab[1] = gammaLow[1]; eos->data.piecewisePolytrope->gammaTab[2] = gammaLow[2]; eos->data.piecewisePolytrope->gammaTab[3] = gammaLow[3]; eos->data.piecewisePolytrope->gammaTab[4] = gammaJoin; eos->data.piecewisePolytrope->gammaTab[5] = gamma1; eos->data.piecewisePolytrope->gammaTab[6] = gamma2; eos->data.piecewisePolytrope->gammaTab[7] = gamma3; eos->data.piecewisePolytrope->rhoTab[0] = rhoLow[0]; eos->data.piecewisePolytrope->rhoTab[1] = rhoLow[1]; eos->data.piecewisePolytrope->rhoTab[2] = rhoLow[2]; eos->data.piecewisePolytrope->rhoTab[3] = rhoLow[3]; eos->data.piecewisePolytrope->rhoTab[4] = rhoJoin1; eos->data.piecewisePolytrope->rhoTab[5] = rhoJoin2; eos->data.piecewisePolytrope->rhoTab[6] = rho1; eos->data.piecewisePolytrope->rhoTab[7] = rho2; eos->data.piecewisePolytrope->nPoly = 8; XLAL_PRINT_INFO("An extra polytrope was used to join the low and high density regions."); } /* convert to geometric units and place in piecwisePolytrope structure */ for (i = 0; i < eos->data.piecewisePolytrope->nPoly; i++) { eos->data.piecewisePolytrope->rhoTab[i] *= LAL_G_C2_SI; gamma_i = eos->data.piecewisePolytrope->gammaTab[i]; eos->data.piecewisePolytrope->kTab[i] *= pow(LAL_G_SI, 1.0 - gamma_i) * pow((double)LAL_C_SI, 2.0 * gamma_i - 4.0); } /* calculate remaining quantities (p, n, a, epsilon, h) in data structure */ for (i = 0; i < eos->data.piecewisePolytrope->nPoly; i++) { k_i = eos->data.piecewisePolytrope->kTab[i]; rho_i = eos->data.piecewisePolytrope->rhoTab[i]; gamma_i = eos->data.piecewisePolytrope->gammaTab[i]; p_i = k_i * pow(rho_i, gamma_i); n_i = 1.0 / (gamma_i - 1.0); if (i == 0) { a_i = 0.0; } else { a_im1 = eos->data.piecewisePolytrope->aTab[i - 1]; n_im1 = eos->data.piecewisePolytrope->nTab[i - 1]; a_i = a_im1 + (n_im1 - n_i) * p_i / rho_i; } epsilon_i = (1.0 + a_i) * rho_i + n_i * p_i; if (i == 0) { enthalpy_i = 1.0; /* p/rho -> 0 as rho -> 0, and a_0 = 0 */ } else { enthalpy_i = 1.0 + a_i + (n_i + 1) * p_i / rho_i; } h_i = log(enthalpy_i); eos->data.piecewisePolytrope->pTab[i] = p_i; eos->data.piecewisePolytrope->nTab[i] = n_i; eos->data.piecewisePolytrope->aTab[i] = a_i; eos->data.piecewisePolytrope->epsilonTab[i] = epsilon_i; eos->data.piecewisePolytrope->hTab[i] = h_i; } eos->pmax = 10.0 * LAL_NUCLEAR_DENSITY_GEOM_SI; eos->hmax = eos_h_of_p_piecewise_polytrope(eos->pmax, eos); eos->hMinAcausal = eos_min_acausal_pseudo_enthalpy_piecewise_polytrope(eos->hmax, eos); #if 0 print_piecewise_polytrope_data(eos->data.piecewisePolytrope); printf("datatype = %d\n", eos->datatype); printf("pmax = %e\n", eos->pmax); printf("hmax = %e\n", eos->hmax); printf("hMinAcausal = %e\n", eos->hMinAcausal); #endif return eos; }
static int XLALSimIMRSpinEOBInitialConditionsPrec( REAL8Vector * initConds, /**<< OUTPUT, Initial dynamical variables */ const REAL8 mass1, /**<< mass 1 */ const REAL8 mass2, /**<< mass 2 */ const REAL8 fMin, /**<< Initial frequency (given) */ const REAL8 inc, /**<< Inclination */ const REAL8 spin1[], /**<< Initial spin vector 1 */ const REAL8 spin2[], /**<< Initial spin vector 2 */ SpinEOBParams * params /**<< Spin EOB parameters */ ) { #ifndef LAL_NDEBUG if (!initConds) { XLAL_ERROR(XLAL_EINVAL); } #endif int debugPK = 0; int printPK = 0; FILE* UNUSED out = NULL; if (printPK) { XLAL_PRINT_INFO("Inside the XLALSimIMRSpinEOBInitialConditionsPrec function!\n"); XLAL_PRINT_INFO( "Inputs: m1 = %.16e, m2 = %.16e, fMin = %.16e, inclination = %.16e\n", mass1, mass2, (double)fMin, (double)inc); XLAL_PRINT_INFO("Inputs: mSpin1 = {%.16e, %.16e, %.16e}\n", spin1[0], spin1[1], spin1[2]); XLAL_PRINT_INFO("Inputs: mSpin2 = {%.16e, %.16e, %.16e}\n", spin2[0], spin2[1], spin2[2]); fflush(NULL); } static const int UNUSED lMax = 8; int i; /* Variable to keep track of whether the user requested the tortoise */ int tmpTortoise; UINT4 SpinAlignedEOBversion; REAL8 mTotal; REAL8 eta; REAL8 omega , v0; /* Initial velocity and angular * frequency */ REAL8 ham; /* Hamiltonian */ REAL8 LnHat [3]; /* Initial orientation of angular * momentum */ REAL8 rHat [3]; /* Initial orientation of radial * vector */ REAL8 vHat [3]; /* Initial orientation of velocity * vector */ REAL8 Lhat [3]; /* Direction of relativistic ang mom */ REAL8 qHat [3]; REAL8 pHat [3]; /* q and p vectors in Cartesian and spherical coords */ REAL8 qCart [3], pCart[3]; REAL8 qSph [3], pSph[3]; /* We will need to manipulate the spin vectors */ /* We will use temporary vectors to do this */ REAL8 tmpS1 [3]; REAL8 tmpS2 [3]; REAL8 tmpS1Norm[3]; REAL8 tmpS2Norm[3]; REAL8Vector qCartVec, pCartVec; REAL8Vector s1Vec, s2Vec, s1VecNorm, s2VecNorm; REAL8Vector sKerr, sStar; REAL8 sKerrData[3], sStarData[3]; REAL8 a = 0.; //, chiS, chiA; //REAL8 chi1, chi2; /* * We will need a full values vector for calculating derivs of * Hamiltonian */ REAL8 sphValues[12]; REAL8 cartValues[12]; /* Matrices for rotating to the new basis set. */ /* It is more convenient to calculate the ICs in a simpler basis */ gsl_matrix *rotMatrix = NULL; gsl_matrix *invMatrix = NULL; gsl_matrix *rotMatrix2 = NULL; gsl_matrix *invMatrix2 = NULL; /* Root finding stuff for finding the spherical orbit */ SEOBRootParams rootParams; const gsl_multiroot_fsolver_type *T = gsl_multiroot_fsolver_hybrid; gsl_multiroot_fsolver *rootSolver = NULL; gsl_multiroot_function rootFunction; gsl_vector *initValues = NULL; gsl_vector *finalValues = NULL; INT4 gslStatus; INT4 cntGslNoProgress = 0, MAXcntGslNoProgress = 5; //INT4 cntGslNoProgress = 0, MAXcntGslNoProgress = 50; REAL8 multFacGslNoProgress = 3./5.; //const int maxIter = 2000; const int maxIter = 10000; memset(&rootParams, 0, sizeof(rootParams)); mTotal = mass1 + mass2; eta = mass1 * mass2 / (mTotal * mTotal); memcpy(tmpS1, spin1, sizeof(tmpS1)); memcpy(tmpS2, spin2, sizeof(tmpS2)); memcpy(tmpS1Norm, spin1, sizeof(tmpS1Norm)); memcpy(tmpS2Norm, spin2, sizeof(tmpS2Norm)); for (i = 0; i < 3; i++) { tmpS1Norm[i] /= mTotal * mTotal; tmpS2Norm[i] /= mTotal * mTotal; } SpinAlignedEOBversion = params->seobCoeffs->SpinAlignedEOBversion; /* We compute the ICs for the non-tortoise p, and convert at the end */ tmpTortoise = params->tortoise; params->tortoise = 0; EOBNonQCCoeffs *nqcCoeffs = NULL; nqcCoeffs = params->nqcCoeffs; /* * STEP 1) Rotate to LNhat0 along z-axis and N0 along x-axis frame, * where LNhat0 and N0 are initial normal to orbital plane and * initial orbital separation; */ /* Set the initial orbital ang mom direction. Taken from STPN code */ LnHat[0] = sin(inc); LnHat[1] = 0.; LnHat[2] = cos(inc); /* * Set the radial direction - need to take care to avoid singularity * if L is along z axis */ if (LnHat[2] > 0.9999) { rHat[0] = 1.; rHat[1] = rHat[2] = 0.; } else { REAL8 theta0 = atan(-LnHat[2] / LnHat[0]); /* theta0 is between 0 * and Pi */ rHat[0] = sin(theta0); rHat[1] = 0; rHat[2] = cos(theta0); } /* Now we can complete the triad */ vHat[0] = CalculateCrossProductPrec(0, LnHat, rHat); vHat[1] = CalculateCrossProductPrec(1, LnHat, rHat); vHat[2] = CalculateCrossProductPrec(2, LnHat, rHat); NormalizeVectorPrec(vHat); /* Vectors BEFORE rotation */ if (printPK) { for (i = 0; i < 3; i++) XLAL_PRINT_INFO(" LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n", i, LnHat[i], i, rHat[i], i, vHat[i]); XLAL_PRINT_INFO("\n\n"); for (i = 0; i < 3; i++) XLAL_PRINT_INFO(" s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i]); fflush(NULL); } /* Allocate and compute the rotation matrices */ XLAL_CALLGSL(rotMatrix = gsl_matrix_alloc(3, 3)); XLAL_CALLGSL(invMatrix = gsl_matrix_alloc(3, 3)); if (!rotMatrix || !invMatrix) { if (rotMatrix) gsl_matrix_free(rotMatrix); if (invMatrix) gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_ENOMEM); } if (CalculateRotationMatrixPrec(rotMatrix, invMatrix, rHat, vHat, LnHat) == XLAL_FAILURE) { gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_ENOMEM); } /* Rotate the orbital vectors and spins */ ApplyRotationMatrixPrec(rotMatrix, rHat); ApplyRotationMatrixPrec(rotMatrix, vHat); ApplyRotationMatrixPrec(rotMatrix, LnHat); ApplyRotationMatrixPrec(rotMatrix, tmpS1); ApplyRotationMatrixPrec(rotMatrix, tmpS2); ApplyRotationMatrixPrec(rotMatrix, tmpS1Norm); ApplyRotationMatrixPrec(rotMatrix, tmpS2Norm); /* See if Vectors have been rotated fine */ if (printPK) { XLAL_PRINT_INFO("\nAfter applying rotation matrix:\n\n"); for (i = 0; i < 3; i++) XLAL_PRINT_INFO(" LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n", i, LnHat[i], i, rHat[i], i, vHat[i]); XLAL_PRINT_INFO("\n"); for (i = 0; i < 3; i++) XLAL_PRINT_INFO(" s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i]); fflush(NULL); } /* * STEP 2) After rotation in STEP 1, in spherical coordinates, phi0 * and theta0 are given directly in Eq. (4.7), r0, pr0, ptheta0 and * pphi0 are obtained by solving Eqs. (4.8) and (4.9) (using * gsl_multiroot_fsolver). At this step, we find initial conditions * for a spherical orbit without radiation reaction. */ /* Initialise the gsl stuff */ XLAL_CALLGSL(rootSolver = gsl_multiroot_fsolver_alloc(T, 3)); if (!rootSolver) { gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_ENOMEM); } XLAL_CALLGSL(initValues = gsl_vector_calloc(3)); if (!initValues) { gsl_multiroot_fsolver_free(rootSolver); gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_ENOMEM); } rootFunction.f = XLALFindSphericalOrbitPrec; rootFunction.n = 3; rootFunction.params = &rootParams; /* Calculate the initial velocity from the given initial frequency */ omega = LAL_PI * mTotal * LAL_MTSUN_SI * fMin; v0 = cbrt(omega); /* Given this, we can start to calculate the initial conditions */ /* for spherical coords in the new basis */ rootParams.omega = omega; rootParams.params = params; /* To start with, we will just assign Newtonian-ish ICs to the system */ rootParams.values[0] = scale1 * 1. / (v0 * v0); /* Initial r */ rootParams.values[4] = scale2 * v0; /* Initial p */ rootParams.values[5] = scale3 * 1e-3; //PK memcpy(rootParams.values + 6, tmpS1, sizeof(tmpS1)); memcpy(rootParams.values + 9, tmpS2, sizeof(tmpS2)); if (printPK) { XLAL_PRINT_INFO("ICs guess: x = %.16e, py = %.16e, pz = %.16e\n", rootParams.values[0]/scale1, rootParams.values[4]/scale2, rootParams.values[5]/scale3); fflush(NULL); } gsl_vector_set(initValues, 0, rootParams.values[0]); gsl_vector_set(initValues, 1, rootParams.values[4]); gsl_vector_set(initValues, 2, rootParams.values[5]); gsl_multiroot_fsolver_set(rootSolver, &rootFunction, initValues); /* We are now ready to iterate to find the solution */ i = 0; if(debugPK){ out = fopen("ICIterations.dat", "w"); } do { XLAL_CALLGSL(gslStatus = gsl_multiroot_fsolver_iterate(rootSolver)); if (debugPK) { fprintf( out, "%d\t", i ); /* Write to file */ fprintf( out, "%.16e\t%.16e\t%.16e\t", rootParams.values[0]/scale1, rootParams.values[4]/scale2, rootParams.values[5]/scale3 ); /* Residual Function values whose roots we are trying to find */ finalValues = gsl_multiroot_fsolver_f(rootSolver); /* Write to file */ fprintf( out, "%.16e\t%.16e\t%.16e\t", gsl_vector_get(finalValues, 0), gsl_vector_get(finalValues, 1), gsl_vector_get(finalValues, 2) ); /* Step sizes in each of function variables */ finalValues = gsl_multiroot_fsolver_dx(rootSolver); /* Write to file */ fprintf( out, "%.16e\t%.16e\t%.16e\t%d\n", gsl_vector_get(finalValues, 0)/scale1, gsl_vector_get(finalValues, 1)/scale2, gsl_vector_get(finalValues, 2)/scale3, gslStatus ); } if (gslStatus == GSL_ENOPROG || gslStatus == GSL_ENOPROGJ) { XLAL_PRINT_INFO( "\n NO PROGRESS being made by Spherical orbit root solver\n"); /* Print Residual Function values whose roots we are trying to find */ finalValues = gsl_multiroot_fsolver_f(rootSolver); XLAL_PRINT_INFO("Function value here given by the following:\n"); XLAL_PRINT_INFO(" F1 = %.16e, F2 = %.16e, F3 = %.16e\n", gsl_vector_get(finalValues, 0), gsl_vector_get(finalValues, 1), gsl_vector_get(finalValues, 2)); /* Print Step sizes in each of function variables */ finalValues = gsl_multiroot_fsolver_dx(rootSolver); // XLAL_PRINT_INFO("Stepsizes in each dimension:\n"); // XLAL_PRINT_INFO(" x = %.16e, py = %.16e, pz = %.16e\n", // gsl_vector_get(finalValues, 0)/scale1, // gsl_vector_get(finalValues, 1)/scale2, // gsl_vector_get(finalValues, 2)/scale3); /* Only allow this flag to be caught MAXcntGslNoProgress no. of times */ cntGslNoProgress += 1; if (cntGslNoProgress >= MAXcntGslNoProgress) { cntGslNoProgress = 0; if(multFacGslNoProgress < 1.){ multFacGslNoProgress *= 1.02; } else{ multFacGslNoProgress /= 1.01; } } /* Now that no progress is being made, we need to reset the initial guess * for the (r,pPhi, pTheta) and reset the integrator */ rootParams.values[0] = scale1 * 1. / (v0 * v0); /* Initial r */ rootParams.values[4] = scale2 * v0; /* Initial p */ if( cntGslNoProgress % 2 ) rootParams.values[5] = scale3 * 1e-3 / multFacGslNoProgress; else rootParams.values[5] = scale3 * 1e-3 * multFacGslNoProgress; //PK memcpy(rootParams.values + 6, tmpS1, sizeof(tmpS1)); memcpy(rootParams.values + 9, tmpS2, sizeof(tmpS2)); if (printPK) { XLAL_PRINT_INFO("New ICs guess: x = %.16e, py = %.16e, pz = %.16e\n", rootParams.values[0]/scale1, rootParams.values[4]/scale2, rootParams.values[5]/scale3); fflush(NULL); } gsl_vector_set(initValues, 0, rootParams.values[0]); gsl_vector_set(initValues, 1, rootParams.values[4]); gsl_vector_set(initValues, 2, rootParams.values[5]); gsl_multiroot_fsolver_set(rootSolver, &rootFunction, initValues); } else if (gslStatus == GSL_EBADFUNC) { XLALPrintError( "Inf or Nan encountered in evaluluation of spherical orbit Eqn\n"); gsl_multiroot_fsolver_free(rootSolver); gsl_vector_free(initValues); gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_EDOM); } else if (gslStatus != GSL_SUCCESS) { XLALPrintError("Error in GSL iteration function!\n"); gsl_multiroot_fsolver_free(rootSolver); gsl_vector_free(initValues); gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_EDOM); } /* different ways to test convergence of the method */ XLAL_CALLGSL(gslStatus = gsl_multiroot_test_residual(rootSolver->f, 1.0e-8)); /*XLAL_CALLGSL(gslStatus= gsl_multiroot_test_delta( gsl_multiroot_fsolver_dx(rootSolver), gsl_multiroot_fsolver_root(rootSolver), 1.e-8, 1.e-5));*/ i++; } while (gslStatus == GSL_CONTINUE && i <= maxIter); if(debugPK) { fflush(NULL); fclose(out); } if (i > maxIter && gslStatus != GSL_SUCCESS) { gsl_multiroot_fsolver_free(rootSolver); gsl_vector_free(initValues); gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); //XLAL_ERROR(XLAL_EMAXITER); XLAL_ERROR(XLAL_EDOM); } finalValues = gsl_multiroot_fsolver_root(rootSolver); if (printPK) { XLAL_PRINT_INFO("Spherical orbit conditions here given by the following:\n"); XLAL_PRINT_INFO(" x = %.16e, py = %.16e, pz = %.16e\n", gsl_vector_get(finalValues, 0)/scale1, gsl_vector_get(finalValues, 1)/scale2, gsl_vector_get(finalValues, 2)/scale3); } memset(qCart, 0, sizeof(qCart)); memset(pCart, 0, sizeof(pCart)); qCart[0] = gsl_vector_get(finalValues, 0)/scale1; pCart[1] = gsl_vector_get(finalValues, 1)/scale2; pCart[2] = gsl_vector_get(finalValues, 2)/scale3; /* Free the GSL root finder, since we're done with it */ gsl_multiroot_fsolver_free(rootSolver); gsl_vector_free(initValues); /* * STEP 3) Rotate to L0 along z-axis and N0 along x-axis frame, where * L0 is the initial orbital angular momentum and L0 is calculated * using initial position and linear momentum obtained in STEP 2. */ /* Now we can calculate the relativistic L and rotate to a new basis */ memcpy(qHat, qCart, sizeof(qCart)); memcpy(pHat, pCart, sizeof(pCart)); NormalizeVectorPrec(qHat); NormalizeVectorPrec(pHat); Lhat[0] = CalculateCrossProductPrec(0, qHat, pHat); Lhat[1] = CalculateCrossProductPrec(1, qHat, pHat); Lhat[2] = CalculateCrossProductPrec(2, qHat, pHat); NormalizeVectorPrec(Lhat); XLAL_CALLGSL(rotMatrix2 = gsl_matrix_alloc(3, 3)); XLAL_CALLGSL(invMatrix2 = gsl_matrix_alloc(3, 3)); if (CalculateRotationMatrixPrec(rotMatrix2, invMatrix2, qHat, pHat, Lhat) == XLAL_FAILURE) { gsl_matrix_free(rotMatrix); gsl_matrix_free(invMatrix); XLAL_ERROR(XLAL_ENOMEM); } ApplyRotationMatrixPrec(rotMatrix2, rHat); ApplyRotationMatrixPrec(rotMatrix2, vHat); ApplyRotationMatrixPrec(rotMatrix2, LnHat); ApplyRotationMatrixPrec(rotMatrix2, tmpS1); ApplyRotationMatrixPrec(rotMatrix2, tmpS2); ApplyRotationMatrixPrec(rotMatrix2, tmpS1Norm); ApplyRotationMatrixPrec(rotMatrix2, tmpS2Norm); ApplyRotationMatrixPrec(rotMatrix2, qCart); ApplyRotationMatrixPrec(rotMatrix2, pCart); gsl_matrix_free(rotMatrix); gsl_matrix_free(rotMatrix2); if (printPK) { XLAL_PRINT_INFO("qCart after rotation2 %3.10f %3.10f %3.10f\n", qCart[0], qCart[1], qCart[2]); XLAL_PRINT_INFO("pCart after rotation2 %3.10f %3.10f %3.10f\n", pCart[0], pCart[1], pCart[2]); XLAL_PRINT_INFO("S1 after rotation2 %3.10f %3.10f %3.10f\n", tmpS1Norm[0], tmpS1Norm[1], tmpS1Norm[2]); XLAL_PRINT_INFO("S2 after rotation2 %3.10f %3.10f %3.10f\n", tmpS2Norm[0], tmpS2Norm[1], tmpS2Norm[2]); } /* * STEP 4) In the L0-N0 frame, we calculate (dE/dr)|sph using Eq. * (4.14), then initial dr/dt using Eq. (4.10), and finally pr0 using * Eq. (4.15). */ /* Now we can calculate the flux. Change to spherical co-ords */ CartesianToSphericalPrec(qSph, pSph, qCart, pCart); memcpy(sphValues, qSph, sizeof(qSph)); memcpy(sphValues + 3, pSph, sizeof(pSph)); memcpy(sphValues + 6, tmpS1, sizeof(tmpS1)); memcpy(sphValues + 9, tmpS2, sizeof(tmpS2)); memcpy(cartValues, qCart, sizeof(qCart)); memcpy(cartValues + 3, pCart, sizeof(pCart)); memcpy(cartValues + 6, tmpS1, sizeof(tmpS1)); memcpy(cartValues + 9, tmpS2, sizeof(tmpS2)); REAL8 dHdpphi , d2Hdr2, d2Hdrdpphi; REAL8 rDot , dHdpr, flux, dEdr; d2Hdr2 = XLALCalculateSphHamiltonianDeriv2Prec(0, 0, sphValues, params); d2Hdrdpphi = XLALCalculateSphHamiltonianDeriv2Prec(0, 5, sphValues, params); if (printPK) XLAL_PRINT_INFO("d2Hdr2 = %.16e, d2Hdrdpphi = %.16e\n", d2Hdr2, d2Hdrdpphi); /* New code to compute derivatives w.r.t. cartesian variables */ REAL8 tmpDValues[14]; int UNUSED status; for (i = 0; i < 3; i++) { cartValues[i + 6] /= mTotal * mTotal; cartValues[i + 9] /= mTotal * mTotal; } UINT4 oldignoreflux = params->ignoreflux; params->ignoreflux = 1; status = XLALSpinPrecHcapNumericalDerivative(0, cartValues, tmpDValues, params); params->ignoreflux = oldignoreflux; for (i = 0; i < 3; i++) { cartValues[i + 6] *= mTotal * mTotal; cartValues[i + 9] *= mTotal * mTotal; } dHdpphi = tmpDValues[1] / sqrt(cartValues[0] * cartValues[0] + cartValues[1] * cartValues[1] + cartValues[2] * cartValues[2]); //XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, params) / sphValues[0]; dEdr = -dHdpphi * d2Hdr2 / d2Hdrdpphi; if (printPK) XLAL_PRINT_INFO("d2Hdr2 = %.16e d2Hdrdpphi = %.16e dHdpphi = %.16e\n", d2Hdr2, d2Hdrdpphi, dHdpphi); if (d2Hdr2 != 0.0) { /* We will need to calculate the Hamiltonian to get the flux */ s1Vec.length = s2Vec.length = s1VecNorm.length = s2VecNorm.length = sKerr.length = sStar.length = 3; s1Vec.data = tmpS1; s2Vec.data = tmpS2; s1VecNorm.data = tmpS1Norm; s2VecNorm.data = tmpS2Norm; sKerr.data = sKerrData; sStar.data = sStarData; qCartVec.length = pCartVec.length = 3; qCartVec.data = qCart; pCartVec.data = pCart; //chi1 = tmpS1[0] * LnHat[0] + tmpS1[1] * LnHat[1] + tmpS1[2] * LnHat[2]; //chi2 = tmpS2[0] * LnHat[0] + tmpS2[1] * LnHat[1] + tmpS2[2] * LnHat[2]; //if (debugPK) //XLAL_PRINT_INFO("magS1 = %.16e, magS2 = %.16e\n", chi1, chi2); //chiS = 0.5 * (chi1 / (mass1 * mass1) + chi2 / (mass2 * mass2)); //chiA = 0.5 * (chi1 / (mass1 * mass1) - chi2 / (mass2 * mass2)); XLALSimIMRSpinEOBCalculateSigmaKerr(&sKerr, mass1, mass2, &s1Vec, &s2Vec); XLALSimIMRSpinEOBCalculateSigmaStar(&sStar, mass1, mass2, &s1Vec, &s2Vec); /* * The a in the flux has been set to zero, but not in the * Hamiltonian */ a = sqrt(sKerr.data[0] * sKerr.data[0] + sKerr.data[1] * sKerr.data[1] + sKerr.data[2] * sKerr.data[2]); //XLALSimIMREOBCalcSpinPrecFacWaveformCoefficients(params->eobParams->hCoeffs, mass1, mass2, eta, /* a */ 0.0, chiS, chiA); //XLALSimIMRCalculateSpinPrecEOBHCoeffs(params->seobCoeffs, eta, a); ham = XLALSimIMRSpinPrecEOBHamiltonian(eta, &qCartVec, &pCartVec, &s1VecNorm, &s2VecNorm, &sKerr, &sStar, params->tortoise, params->seobCoeffs); if (printPK) XLAL_PRINT_INFO("Stas: hamiltonian in ICs at this point is %.16e\n", ham); /* And now, finally, the flux */ REAL8Vector polarDynamics, cartDynamics; REAL8 polarData[4], cartData[12]; polarDynamics.length = 4; polarDynamics.data = polarData; polarData[0] = qSph[0]; polarData[1] = 0.; polarData[2] = pSph[0]; polarData[3] = pSph[2]; cartDynamics.length = 12; cartDynamics.data = cartData; memcpy(cartData, qCart, 3 * sizeof(REAL8)); memcpy(cartData + 3, pCart, 3 * sizeof(REAL8)); memcpy(cartData + 6, tmpS1Norm, 3 * sizeof(REAL8)); memcpy(cartData + 9, tmpS2Norm, 3 * sizeof(REAL8)); //XLAL_PRINT_INFO("Stas: starting FLux calculations\n"); flux = XLALInspiralPrecSpinFactorizedFlux(&polarDynamics, &cartDynamics, nqcCoeffs, omega, params, ham, lMax, SpinAlignedEOBversion); /* * flux = XLALInspiralSpinFactorizedFlux( &polarDynamics, * nqcCoeffs, omega, params, ham, lMax, SpinAlignedEOBversion * ); */ //XLAL_PRINT_INFO("Stas flux = %.16e \n", flux); //exit(0); flux = flux / eta; rDot = -flux / dEdr; if (debugPK) { XLAL_PRINT_INFO("Stas here I am 2 \n"); } /* * We now need dHdpr - we take it that it is safely linear up * to a pr of 1.0e-3 PK: Ideally, the pr should be of the * order of other momenta, in order for its contribution to * the Hamiltonian to not get buried in the numerical noise * in the numerically larger momenta components */ cartValues[3] = 1.0e-3; for (i = 0; i < 3; i++) { cartValues[i + 6] /= mTotal * mTotal; cartValues[i + 9] /= mTotal * mTotal; } oldignoreflux = params->ignoreflux; params->ignoreflux = 1; params->seobCoeffs->updateHCoeffs = 1; status = XLALSpinPrecHcapNumericalDerivative(0, cartValues, tmpDValues, params); params->ignoreflux = oldignoreflux; for (i = 0; i < 3; i++) { cartValues[i + 6] *= mTotal * mTotal; cartValues[i + 9] *= mTotal * mTotal; } REAL8 csi = sqrt(XLALSimIMRSpinPrecEOBHamiltonianDeltaT(params->seobCoeffs, qSph[0], eta, a)*XLALSimIMRSpinPrecEOBHamiltonianDeltaR(params->seobCoeffs, qSph[0], eta, a)) / (qSph[0] * qSph[0] + a * a); dHdpr = csi*tmpDValues[0]; //XLALSpinPrecHcapNumDerivWRTParam(3, cartValues, params); if (debugPK) { XLAL_PRINT_INFO("Ingredients going into prDot:\n"); XLAL_PRINT_INFO("flux = %.16e, dEdr = %.16e, dHdpr = %.16e, dHdpr/pr = %.16e\n", flux, dEdr, dHdpr, dHdpr / cartValues[3]); } /* * We can now calculate what pr should be taking into account * the flux */ pSph[0] = rDot / (dHdpr / cartValues[3]); } else { /* * Since d2Hdr2 has evaluated to zero, we cannot do the * above. Just set pr to zero */ //XLAL_PRINT_INFO("d2Hdr2 is zero!\n"); pSph[0] = 0; } /* Now we are done - convert back to cartesian coordinates ) */ SphericalToCartesianPrec(qCart, pCart, qSph, pSph); /* * STEP 5) Rotate back to the original inertial frame by inverting * the rotation of STEP 3 and then inverting the rotation of STEP 1. */ /* Undo rotations to get back to the original basis */ /* Second rotation */ ApplyRotationMatrixPrec(invMatrix2, rHat); ApplyRotationMatrixPrec(invMatrix2, vHat); ApplyRotationMatrixPrec(invMatrix2, LnHat); ApplyRotationMatrixPrec(invMatrix2, tmpS1); ApplyRotationMatrixPrec(invMatrix2, tmpS2); ApplyRotationMatrixPrec(invMatrix2, tmpS1Norm); ApplyRotationMatrixPrec(invMatrix2, tmpS2Norm); ApplyRotationMatrixPrec(invMatrix2, qCart); ApplyRotationMatrixPrec(invMatrix2, pCart); /* First rotation */ ApplyRotationMatrixPrec(invMatrix, rHat); ApplyRotationMatrixPrec(invMatrix, vHat); ApplyRotationMatrixPrec(invMatrix, LnHat); ApplyRotationMatrixPrec(invMatrix, tmpS1); ApplyRotationMatrixPrec(invMatrix, tmpS2); ApplyRotationMatrixPrec(invMatrix, tmpS1Norm); ApplyRotationMatrixPrec(invMatrix, tmpS2Norm); ApplyRotationMatrixPrec(invMatrix, qCart); ApplyRotationMatrixPrec(invMatrix, pCart); gsl_matrix_free(invMatrix); gsl_matrix_free(invMatrix2); /* If required, apply the tortoise transform */ if (tmpTortoise) { REAL8 r = sqrt(qCart[0] * qCart[0] + qCart[1] * qCart[1] + qCart[2] * qCart[2]); REAL8 deltaR = XLALSimIMRSpinPrecEOBHamiltonianDeltaR(params->seobCoeffs, r, eta, a); REAL8 deltaT = XLALSimIMRSpinPrecEOBHamiltonianDeltaT(params->seobCoeffs, r, eta, a); REAL8 csi = sqrt(deltaT * deltaR) / (r * r + a * a); REAL8 pr = (qCart[0] * pCart[0] + qCart[1] * pCart[1] + qCart[2] * pCart[2]) / r; params->tortoise = tmpTortoise; if (debugPK) { XLAL_PRINT_INFO("Applying the tortoise to p (csi = %.26e)\n", csi); XLAL_PRINT_INFO("pCart = %3.10f %3.10f %3.10f\n", pCart[0], pCart[1], pCart[2]); } for (i = 0; i < 3; i++) { pCart[i] = pCart[i] + qCart[i] * pr * (csi - 1.) / r; } } /* Now copy the initial conditions back to the return vector */ memcpy(initConds->data, qCart, sizeof(qCart)); memcpy(initConds->data + 3, pCart, sizeof(pCart)); memcpy(initConds->data + 6, tmpS1Norm, sizeof(tmpS1Norm)); memcpy(initConds->data + 9, tmpS2Norm, sizeof(tmpS2Norm)); for (i=0; i<12; i++) { if (fabs(initConds->data[i]) <=1.0e-15) { initConds->data[i] = 0.; } } if (debugPK) { XLAL_PRINT_INFO("THE FINAL INITIAL CONDITIONS:\n"); XLAL_PRINT_INFO(" %.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n", initConds->data[0], initConds->data[1], initConds->data[2], initConds->data[3], initConds->data[4], initConds->data[5], initConds->data[6], initConds->data[7], initConds->data[8], initConds->data[9], initConds->data[10], initConds->data[11]); } return XLAL_SUCCESS; }
/** * Wrapper for calculating specific derivative of the Hamiltonian in spherical co-ordinates, * dH/dr, dH/dptheta and dH/dpphi. * It only works for the specific co-ord system we use here */ static double GSLSpinHamiltonianDerivWrapperPrec(double x, /**<< Derivative at x */ void *params /**<< Function parameters */ ) { int debugPK = 0; HcapSphDeriv2Params *dParams = (HcapSphDeriv2Params *) params; REAL8 mTotal = dParams->params->eobParams->m1 + dParams->params->eobParams->m2; REAL8 sphValues[12]; REAL8 cartValues[12]; REAL8 dHdr , dHdx, dHdpy, dHdpz; REAL8 r , ptheta, pphi; memcpy(sphValues, dParams->sphValues, sizeof(sphValues)); sphValues[dParams->varyParam1] = x; SphericalToCartesianPrec(cartValues, cartValues + 3, sphValues, sphValues + 3); memcpy(cartValues + 6, sphValues + 6, 6 * sizeof(REAL8)); r = sphValues[0]; ptheta = sphValues[4]; pphi = sphValues[5]; /* New code to compute derivatives w.r.t. cartesian variables */ REAL8 tmpDValues[14]; int UNUSED status; for (int i = 0; i < 3; i++) { cartValues[i + 6] /= mTotal * mTotal; cartValues[i + 9] /= mTotal * mTotal; } UINT4 oldignoreflux = dParams->params->ignoreflux; dParams->params->ignoreflux = 1; status = XLALSpinPrecHcapNumericalDerivative(0, cartValues, tmpDValues, dParams->params); dParams->params->ignoreflux = oldignoreflux; for (int i = 0; i < 3; i++) { cartValues[i + 6] *= mTotal * mTotal; cartValues[i + 9] *= mTotal * mTotal; } double rvec [3] = {cartValues[0], cartValues[1], cartValues[2]}; double pvec [3] = {cartValues[3], cartValues[4], cartValues[5]}; double chi1vec [3] = {cartValues[6], cartValues[7], cartValues[8]}; double chi2vec [3] = {cartValues[9], cartValues[10], cartValues[11]}; double Lvec [3] = {CalculateCrossProductPrec(0, rvec, pvec), CalculateCrossProductPrec(1, rvec, pvec), CalculateCrossProductPrec(2, rvec, pvec)}; double theta1 = acos(CalculateDotProductPrec(chi1vec, Lvec) / sqrt(CalculateDotProductPrec(chi1vec, chi1vec)) / sqrt(CalculateDotProductPrec(Lvec, Lvec))); double theta2 = acos(CalculateDotProductPrec(chi2vec, Lvec) / sqrt(CalculateDotProductPrec(chi2vec, chi2vec)) / sqrt(CalculateDotProductPrec(Lvec, Lvec))); if (debugPK) { XLAL_PRINT_INFO("In GSLSpinHamiltonianDerivWrapperPrec"); XLAL_PRINT_INFO("rvec = %.16e %.16e %.16e\n", rvec[0], rvec[1], rvec[2]); XLAL_PRINT_INFO("pvec = %.16e %.16e %.16e\n", pvec[0], pvec[1], pvec[2]); XLAL_PRINT_INFO("theta1 = %.16e\n", theta1); XLAL_PRINT_INFO("theta2 = %.16e\n", theta2); } if (theta1 > 1.0e-6 && theta2 >= 1.0e-6) { switch (dParams->varyParam2) { case 0: /* dHdr */ dHdx = -tmpDValues[3]; //XLALSpinPrecHcapNumDerivWRTParam(0, cartValues, dParams->params); dHdpy = tmpDValues[1]; //XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, dParams->params); dHdpz = tmpDValues[2]; //XLALSpinPrecHcapNumDerivWRTParam(5, cartValues, dParams->params); dHdr = dHdx - dHdpy * pphi / (r * r) + dHdpz * ptheta / (r * r); //XLAL_PRINT_INFO("dHdr = %.16e\n", dHdr); return dHdr; break; case 4: /* dHdptheta */ dHdpz = tmpDValues[2]; //XLALSpinPrecHcapNumDerivWRTParam(5, cartValues, dParams->params); return -dHdpz / r; break; case 5: /* dHdpphi */ dHdpy = tmpDValues[1]; //XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, dParams->params); return dHdpy / r; break; default: XLALPrintError("This option is not supported in the second derivative function!\n"); XLAL_ERROR_REAL8(XLAL_EINVAL); break; } } else { switch (dParams->varyParam2) { case 0: /* dHdr */ dHdx = XLALSpinPrecHcapNumDerivWRTParam(0, cartValues, dParams->params); dHdpy = XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, dParams->params); dHdpz = XLALSpinPrecHcapNumDerivWRTParam(5, cartValues, dParams->params); dHdr = dHdx - dHdpy * pphi / (r * r) + dHdpz * ptheta / (r * r); //XLAL_PRINT_INFO("dHdr = %.16e\n", dHdr); return dHdr; break; case 4: /* dHdptheta */ dHdpz = XLALSpinPrecHcapNumDerivWRTParam(5, cartValues, dParams->params); return -dHdpz / r; break; case 5: /* dHdpphi */ dHdpy = XLALSpinPrecHcapNumDerivWRTParam(4, cartValues, dParams->params); return dHdpy / r; break; default: XLALPrintError("This option is not supported in the second derivative function!\n"); XLAL_ERROR_REAL8(XLAL_EINVAL); break; } } }
/** * Root function for gsl root finders. * The gsl root finder will look for gsl_vector *x position in parameter space * where the returned values in gsl_vector *f are zero. * The functions on which we search for roots are: * dH/dr, dH/dptheta and dH/dpphi-omega, * namely, Eqs. 4.8 and 4.9 of Buonanno et al. PRD 74, 104005 (2006). */ static int XLALFindSphericalOrbitPrec( const gsl_vector * x, /**<< Parameters requested by gsl root finder */ void *params, /**<< Spin EOB parameters */ gsl_vector * f /**<< Function values for the given parameters*/ ) { int debugPK = 0; SEOBRootParams *rootParams = (SEOBRootParams *) params; REAL8 mTotal = rootParams->params->eobParams->m1 + rootParams->params->eobParams->m2; if (debugPK) XLAL_PRINT_INFO("\n\nmtotal in XLALFindSphericalOrbitPrec = %f\n", (float)mTotal); REAL8 py , pz, r, ptheta, pphi; /* Numerical derivative of Hamiltonian wrt given value */ REAL8 dHdx , dHdpy, dHdpz; REAL8 dHdr , dHdptheta, dHdpphi; /* Populate the appropriate values */ /* In the special theta=pi/2 phi=0 case, r is x */ rootParams->values[0] = r = gsl_vector_get(x, 0)/scale1; rootParams->values[4] = py = gsl_vector_get(x, 1)/scale2; rootParams->values[5] = pz = gsl_vector_get(x, 2)/scale3; if(isnan(rootParams->values[0])) { rootParams->values[0] = 100.; } if(isnan(rootParams->values[4])) { rootParams->values[4] = 0.1; } if(isnan(rootParams->values[5])) { rootParams->values[5] = 0.01; } if (debugPK) { XLAL_PRINT_INFO("%3.10f %3.10f %3.10f %3.10f %3.10f %3.10f\n", rootParams->values[0], rootParams->values[1], rootParams->values[2], rootParams->values[3], rootParams->values[4], rootParams->values[5]); XLAL_PRINT_INFO("Values r = %.16e, py = %.16e, pz = %.16e\n", r, py, pz); fflush(NULL); } ptheta = -r * pz; pphi = r * py; if (debugPK) XLAL_PRINT_INFO("Input Values r = %.16e, py = %.16e, pz = %.16e\n pthetha = %.16e pphi = %.16e\n", r, py, pz, ptheta, pphi); /* dH by dR and dP */ REAL8 tmpDValues[14]; int UNUSED status; for (int i = 0; i < 3; i++) { rootParams->values[i + 6] /= mTotal * mTotal; rootParams->values[i + 9] /= mTotal * mTotal; } UINT4 oldignoreflux = rootParams->params->ignoreflux; rootParams->params->ignoreflux = 1; status = XLALSpinPrecHcapNumericalDerivative(0, rootParams->values, tmpDValues, rootParams->params); rootParams->params->ignoreflux = oldignoreflux; for (int i = 0; i < 3; i++) { rootParams->values[i + 6] *= mTotal * mTotal; rootParams->values[i + 9] *= mTotal * mTotal; } REAL8 rvec[3] = {rootParams->values[0], rootParams->values[1], rootParams->values[2]}; REAL8 pvec[3] = {rootParams->values[3], rootParams->values[4], rootParams->values[5]}; REAL8 chi1vec[3] = {rootParams->values[6], rootParams->values[7], rootParams->values[8]}; REAL8 chi2vec[3] = {rootParams->values[9], rootParams->values[10], rootParams->values[11]}; REAL8 Lvec[3] = {CalculateCrossProductPrec(0, rvec, pvec), CalculateCrossProductPrec(1, rvec, pvec), CalculateCrossProductPrec(2, rvec, pvec)}; REAL8 theta1 = acos(CalculateDotProductPrec(chi1vec, Lvec) / sqrt(CalculateDotProductPrec(chi1vec, chi1vec)) / sqrt(CalculateDotProductPrec(Lvec, Lvec))); REAL8 theta2 = acos(CalculateDotProductPrec(chi2vec, Lvec) / sqrt(CalculateDotProductPrec(chi2vec, chi2vec)) / sqrt(CalculateDotProductPrec(Lvec, Lvec))); if (debugPK) { XLAL_PRINT_INFO("rvec = %.16e %.16e %.16e\n", rvec[0], rvec[1], rvec[2]); XLAL_PRINT_INFO("pvec = %.16e %.16e %.16e\n", pvec[0], pvec[1], pvec[2]); XLAL_PRINT_INFO("theta1 = %.16e\n", theta1); XLAL_PRINT_INFO("theta2 = %.16e\n", theta2); } if (theta1 > 1.0e-6 && theta2 >= 1.0e-6) { dHdx = -tmpDValues[3]; dHdpy = tmpDValues[1]; dHdpz = tmpDValues[2]; } else { //rootParams->values[5] = 0.; //rootParams->values[6] = 0.; //rootParams->values[7] = 0.; //rootParams->values[8] = sqrt(CalculateDotProductPrec(chi1vec, chi1vec)); //rootParams->values[9] = 0.; //rootParams->values[10]= 0.; //rootParams->values[11]= sqrt(CalculateDotProductPrec(chi2vec, chi2vec)); dHdx = XLALSpinPrecHcapNumDerivWRTParam(0, rootParams->values, rootParams->params); dHdpy = XLALSpinPrecHcapNumDerivWRTParam(4, rootParams->values, rootParams->params); dHdpz = XLALSpinPrecHcapNumDerivWRTParam(5, rootParams->values, rootParams->params); } if (XLAL_IS_REAL8_FAIL_NAN(dHdx)) { XLAL_ERROR(XLAL_EDOM); } if (XLAL_IS_REAL8_FAIL_NAN(dHdpy)) { XLAL_ERROR(XLAL_EDOM); } if (XLAL_IS_REAL8_FAIL_NAN(dHdpz)) { XLAL_ERROR(XLAL_EDOM); } if (debugPK) XLAL_PRINT_INFO("dHdx = %.16e, dHdpy = %.16e, dHdpz = %.16e\n", dHdx, dHdpy, dHdpz); /* Now convert to spherical polars */ dHdr = dHdx - dHdpy * pphi / (r * r) + dHdpz * ptheta / (r * r); dHdptheta = -dHdpz / r; dHdpphi = dHdpy / r; if (debugPK) XLAL_PRINT_INFO("dHdr = %.16e dHdptheta = %.16e dHdpphi = %.16e\n", dHdr, dHdptheta, dHdpphi); /* populate the function vector */ gsl_vector_set(f, 0, dHdr); gsl_vector_set(f, 1, dHdptheta); gsl_vector_set(f, 2, dHdpphi - rootParams->omega); if (debugPK) XLAL_PRINT_INFO("Current funcvals = %.16e %.16e %.16e\n", gsl_vector_get(f, 0), gsl_vector_get(f, 1), gsl_vector_get(f, 2) ); /* Rescale back */ rootParams->values[0] *= scale1; rootParams->values[4] *= scale2; rootParams->values[5] *= scale3; return XLAL_SUCCESS; }
/** * @brief Advance a LALFrStream stream to the beginning of the next frame * @details * The position of a LALFrStream is advanced so that the next read will * be at the next frame. If the stream is at the end, the #LAL_FR_STREAM_END * bit of the LALFrStreamState state is set, and the routine returns the * return code 1. If there is a gap in the data before the next frame, * the #LAL_FR_STREAM_GAP bit of the LALFrStreamState state is set, and the * routine returns the return code 2. If, however, the * #LAL_FR_STREAM_IGNOREGAP_MODE bit is not set in the LALFrStreamMode mode * then the routine produces an error if a gap is encountered. * @param stream Pointer to a #LALFrStream structure. * @retval 2 Gap in the data is encountered. * @retval 1 End of stream encountered. * @retval 0 Normal success. * @retval <0 Failure. */ int XLALFrStreamNext(LALFrStream * stream) { /* timing accuracy: tenth of a sample interval for a 16kHz fast channel */ const INT8 tacc = (INT8) floor(0.1 * 1e9 / 16384.0); const char *url1; const char *url2; int pos1; int pos2; INT8 texp = 0; INT8 tact; if (stream->state & LAL_FR_STREAM_END) return 1; /* end code */ /* turn off gap bit */ stream->state &= ~LAL_FR_STREAM_GAP; url2 = url1 = stream->cache->list[stream->fnum].url; pos2 = pos1 = stream->pos; /* open a new file if necessary */ if (!stream->file) { if (stream->fnum >= stream->cache->length) { stream->state |= LAL_FR_STREAM_END; return 1; } if (XLALFrStreamFileOpen(stream, stream->fnum) < 0) XLAL_ERROR(XLAL_EFUNC); } if (stream->file) { INT4 nFrame = XLALFrFileQueryNFrame(stream->file); if (stream->pos < nFrame) { LIGOTimeGPS gpstime; XLALGPSToINT8NS(XLALFrFileQueryGTime(&gpstime, stream->file, stream->pos)); texp = XLALGPSToINT8NS(XLALGPSAdd(&gpstime, XLALFrFileQueryDt(stream->file, stream->pos))); ++stream->pos; } if (stream->pos >= nFrame) { XLALFrStreamFileClose(stream); ++stream->fnum; } pos2 = stream->pos; } /* open a new file if necessary */ if (!stream->file) { if (stream->fnum >= stream->cache->length) { stream->state |= LAL_FR_STREAM_END; return 1; } if (XLALFrStreamFileOpen(stream, stream->fnum) < 0) XLAL_ERROR(XLAL_EFUNC); url2 = stream->cache->list[stream->fnum].url; pos2 = stream->pos; } /* compute actual start time of this new frame */ tact = XLALGPSToINT8NS(XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos)); /* INT8 is platform dependent, cast to long long for llabs() call */ if (llabs((long long)(texp - tact)) > tacc) { /* there is a gap */ stream->state |= LAL_FR_STREAM_GAP; if (stream->mode & LAL_FR_STREAM_GAPINFO_MODE) { XLAL_PRINT_INFO("Gap in frame data between times %.6f and %.6f", 1e-9 * texp, 1e-9 * tact); } if (!(stream->mode & LAL_FR_STREAM_IGNOREGAP_MODE)) { XLAL_PRINT_ERROR("Gap in frame data"); XLAL_PRINT_ERROR("Time %.6f is end of frame %d of file %s", 1e-9 * texp, pos1, url1); XLAL_PRINT_ERROR("Time %.6f is start of frame %d of file %s", 1e-9 * tact, pos2, url2); XLAL_ERROR(XLAL_ETIME); } return 2; /* gap code */ } return 0; }
double XLALSimLocateOmegaTime( REAL8Array *dynamicsHi, unsigned int numdynvars, unsigned int retLenHi, SpinEOBParams seobParams, SpinEOBHCoeffs seobCoeffs, REAL8 m1, REAL8 m2, REAL8Vector *radiusVec, int *found, REAL8* tMaxOmega, INT4 use_optimized ) { *tMaxOmega = 0; //Zach E: Fixes Heisenbug with ICC 16 and 17 compilers (5181); removing this line will result in segfaults with both compilers. /* * Locate merger point (max omega), * WaveStep 1.1: locate merger point */ int debugPK = 0; int debugRD = 0; FILE *out = NULL; gsl_spline *spline = NULL; gsl_interp_accel *acc = NULL; if (debugPK) {debugRD = 0;} unsigned int peakIdx, i, j; REAL8Vector *values = NULL; REAL8Vector *dvalues = NULL; REAL8Vector *omegaHi = NULL; if ( !(values = XLALCreateREAL8Vector( numdynvars )) ) { XLAL_ERROR( XLAL_ENOMEM ); } if ( !(dvalues = XLALCreateREAL8Vector( numdynvars )) ) { XLAL_ERROR( XLAL_ENOMEM ); } if ( !(omegaHi = XLALCreateREAL8Vector( retLenHi )) ) { XLAL_ERROR( XLAL_ENOMEM ); } REAL8 rdotvec[3] = {0,0,0}; REAL8 rvec[3] = {0,0,0}; REAL8 rcrossrdot[3] = {0,0,0}; REAL8Vector timeHi; timeHi.length = retLenHi; timeHi.data = dynamicsHi->data; double dt = timeHi.data[1] - timeHi.data[0]; double ddradiusVec[timeHi.length - 2]; unsigned int k; for (k = 1; k < timeHi.length-1; k++) { ddradiusVec[k] = (radiusVec->data[k+1] - 2.*radiusVec->data[k] + radiusVec->data[k-1])/dt/dt; // XLAL_PRINT_INFO("%3.10f %3.10f\n", timeHi->data[k], ddradiusVec[k]); } // for (k = timeHi->length-3; k>=1; k--) { // XLAL_PRINT_INFO("%3.10f %3.10f\n", timeHi->data[k], ddradiusVec[k]); // if (ddradiusVec[k] < 0) { // break; // } // } for (k = 0; k < timeHi.length-2; k++) { // XLAL_PRINT_INFO("%3.10f %3.10f\n", timeHi->data[k], ddradiusVec[k]); if (dt*k > dt*( timeHi.length-2)-20 && ddradiusVec[k] > 0) { break; } } double minoff = dt*( timeHi.length-2 - k) > 0.2 ? dt*( timeHi.length-2 - k) : 0.2; if (debugPK) { XLAL_PRINT_INFO("Change of sign in ddr %3.10f M before the end\n", minoff ); } // First we search for the maximum (extremum) of amplitude double maxoff = 20.0; unsigned int Nps = timeHi.length; // this definesthe search interval for maximum (we might use min0ff= 0.051 instead) double tMin = timeHi.data[Nps-1] - maxoff; // FIXME // minoff = 0.0; double tMax = timeHi.data[Nps-1] - minoff; *tMaxOmega = tMax; tMin = tMax - 20.; if ( debugPK ) { XLAL_PRINT_INFO("tMin, tMax = %3.10f %3.10f\n", tMin, tMax); } double omega = 0.0; double magR; double time1, time2, omegaDeriv, omegaDerivMid, tPeakOmega; if(debugPK) { out = fopen( "omegaHi.dat", "w" ); XLAL_PRINT_INFO("length of values = %d, retLenHi = %d\n", values->length, retLenHi); fflush(NULL); } if(debugRD) { out = fopen( "omegaHi.dat", "w" ); } for ( i = 0; i < retLenHi; i++ ) { for ( j = 0; j < values->length; j++ ) { values->data[j] = *(dynamicsHi->data+(j+1)*retLenHi+i); } /* Calculate dr/dt */ memset( dvalues->data, 0, numdynvars*sizeof(dvalues->data[0])); if(use_optimized){ if( XLALSpinPrecHcapRvecDerivative_exact( 0, values->data, dvalues->data, &seobParams) != XLAL_SUCCESS ) { XLAL_PRINT_INFO( " Calculation of dr/dt failed while computing omegaHi time series\n"); XLAL_ERROR( XLAL_EFUNC ); } } else { if( XLALSpinPrecHcapRvecDerivative( 0, values->data, dvalues->data, &seobParams) != XLAL_SUCCESS ) { XLAL_PRINT_INFO( " Calculation of dr/dt failed while computing omegaHi time series\n"); XLAL_ERROR( XLAL_EFUNC ); } } /* Calculare r x dr/dt */ for (j=0; j<3; j++){ rvec[j] = values->data[j]; rdotvec[j] = dvalues->data[j]; } //memcpy(rdotvec, dvalues->data, 3*sizeof(REAL8)); //rvec[0] = posVecxHi.data[i]; rvec[1] = posVecyHi.data[i]; //rvec[2] = posVeczHi.data[i]; cross_product( rvec, rdotvec, rcrossrdot ); /* Calculate omega = |r x dr/dt| / r*r */ magR = sqrt(inner_product(rvec, rvec)); omegaHi->data[i] = sqrt(inner_product(rcrossrdot, rcrossrdot)) / (magR*magR); if(debugPK || debugRD){ fprintf( out, "%.16e\t%.16e\n", timeHi.data[i], omegaHi->data[i]); } } // Searching for crude omega_max (extremum) peakIdx = 0; *found = 0; for ( i = 1, peakIdx = 0; i < retLenHi-1; i++ ){ omega = omegaHi->data[i]; if (omega >= omegaHi->data[i-1] && omega > omegaHi->data[i+1] && tMax>=timeHi.data[i] && timeHi.data[i]>=tMin){ peakIdx = i; *found = 1; if (debugPK){ XLAL_PRINT_INFO("PK: Crude peak of Omega is at idx = %d. t = %f, OmegaPeak = %.16e\n", peakIdx, timeHi.data[peakIdx], omega); fflush(NULL); } } } if(debugPK) { fclose(out); if (peakIdx ==0){ XLAL_PRINT_INFO("Stas: peak of orbital frequency was not found. peakIdx = %d, retLenHi = %d, i at exit = %d\n", peakIdx, retLenHi, i); fflush(NULL); } } if(debugRD) { fclose(out); } // refining the omega_max search (if it is found) tPeakOmega = 0.0; if(peakIdx != 0){ spline = gsl_spline_alloc( gsl_interp_cspline, retLenHi ); acc = gsl_interp_accel_alloc(); time1 = timeHi.data[peakIdx-2]; gsl_spline_init( spline, timeHi.data, omegaHi->data, retLenHi ); omegaDeriv = gsl_spline_eval_deriv( spline, time1, acc ); if ( omegaDeriv > 0. ) { time2 = timeHi.data[peakIdx+2]; } else{ time2 = time1; peakIdx = peakIdx-2; time1 = timeHi.data[peakIdx-2]; omegaDeriv = gsl_spline_eval_deriv( spline, time1, acc ); } do { tPeakOmega = ( time1 + time2 ) / 2.; omegaDerivMid = gsl_spline_eval_deriv( spline, tPeakOmega, acc ); if ( omegaDerivMid * omegaDeriv < 0.0 ) { time2 = tPeakOmega; } else { omegaDeriv = omegaDerivMid; time1 = tPeakOmega; } if (debugPK){ XLAL_PRINT_INFO("Stas: searching for orbital max: %f, %f, %f, %f \n", time1, time2, omegaDeriv, omegaDerivMid); } } while ( time2 - time1 > 1.0e-5 ); if(debugPK) { XLAL_PRINT_INFO( "Estimation of the orbital peak is now at time %.16e \n", tPeakOmega); fflush(NULL); } } if(*found == 0 || debugRD || debugPK){ if(debugPK){ XLAL_PRINT_INFO("Stas: We couldn't find the maximum of orbital frequency, search for maximum of A(r)/r^2 \n"); } REAL8 rad, rad2, m1PlusetaKK, bulk, logTerms, deltaU, u, u2, u3, u4, u5; REAL8 listAOverr2[retLenHi]; REAL8 Aoverr2; REAL8Vector *sigmaStar = NULL; REAL8Vector *sigmaKerr = NULL; if ( !(sigmaStar = XLALCreateREAL8Vector( 3 )) ) { XLALDestroyREAL8Vector( sigmaStar ); XLAL_ERROR( XLAL_ENOMEM ); } if ( !(sigmaKerr = XLALCreateREAL8Vector( 3 )) ) { XLALDestroyREAL8Vector( sigmaStar ); XLAL_ERROR( XLAL_ENOMEM ); } REAL8Vector s1Vec, s2Vec; s1Vec.length = s2Vec.length = 3; REAL8 s1Data[3], s2Data[3]; REAL8 mTotal = m1 + m2; REAL8 a; REAL8 eta = m1*m2/(mTotal*mTotal); if(debugPK || debugRD){ out = fopen( "OutAofR.dat", "w" ); } for ( i = 0; i < retLenHi; i++ ) { for ( j = 0; j < values->length; j++ ) { values->data[j] = *(dynamicsHi->data+(j+1)*retLenHi+i); } for( j = 0; j < 3; j++ ) { //s1DataNorm[k] = values->data[k+6]; //s2DataNorm[k] = values->data[k+9]; s1Data[j] = values->data[j+6] * mTotal * mTotal; s2Data[j] = values->data[j+9] * mTotal * mTotal; } s1Vec.data = s1Data; s2Vec.data = s2Data; XLALSimIMRSpinEOBCalculateSigmaStar( sigmaStar, m1, m2, &s1Vec, &s2Vec ); XLALSimIMRSpinEOBCalculateSigmaKerr( sigmaKerr, m1, m2, &s1Vec, &s2Vec ); seobParams.a = a = sqrt(inner_product(sigmaKerr->data, sigmaKerr->data)); m1PlusetaKK = -1. + eta * seobCoeffs.KK; rad2 = values->data[0]*values->data[0] + values->data[1]*values->data[1] + values->data[2]*values->data[2]; rad = sqrt(rad2); u = 1./rad; u2 = u*u; u3 = u2*u; u4 = u2*u2; u5 = u4*u; bulk = 1./(m1PlusetaKK*m1PlusetaKK) + (2.*u)/m1PlusetaKK + a*a*u2; logTerms = 1. + eta*seobCoeffs.k0 + eta*log(1. + seobCoeffs.k1*u + seobCoeffs.k2*u2 + seobCoeffs.k3*u3 + seobCoeffs.k4*u4 + seobCoeffs.k5*u5 + seobCoeffs.k5l*u5*log(u)); deltaU = bulk*logTerms; listAOverr2[i] = deltaU / rad2; if(debugPK || debugRD){ fprintf(out, "%3.10f %3.10f\n", timeHi.data[i], listAOverr2[i]); } } if(debugPK || debugRD ) fclose(out); if (*found == 0){ // searching formaximum of A(r)/r^2 peakIdx = 0; //*found = 0; for ( i = 1, peakIdx = 0; i < retLenHi-1; i++ ){ Aoverr2 = listAOverr2[i]; if (Aoverr2 >= listAOverr2[i-1] && Aoverr2 > listAOverr2[i+1]){ if (timeHi.data[i] > tMin){ peakIdx = i; tPeakOmega = timeHi.data[i]; *found = 1; if (debugPK){ XLAL_PRINT_INFO("PK: Peak of A(r)/r^2 is at idx = %d. t = %f, Peak ampl. = %.16e\n", peakIdx, timeHi.data[peakIdx], Aoverr2); fflush(NULL); } break; } } } } if(debugPK) { if (peakIdx ==0){ XLAL_PRINT_INFO("Stas: peak of A(r)/r^2 was not found. \ peakIdx = %d, retLenHi = %d, i at exit = %d\n", peakIdx, retLenHi, i); fflush(NULL); } } XLALDestroyREAL8Vector(sigmaStar); XLALDestroyREAL8Vector(sigmaKerr); }
static REAL8 XLALInspiralPrecSpinFactorizedFlux( REAL8Vector * polvalues, /**< \f$(r,\phi,p_r,p_\phi)\f$ */ REAL8Vector * values, /**< dynamical variables */ EOBNonQCCoeffs * nqcCoeffs, /**< pre-computed NQC coefficients */ const REAL8 omega, /**< orbital frequency */ SpinEOBParams * ak, /**< physical parameters */ const REAL8 H, /**< real Hamiltonian */ const INT4 lMax, /**< upper limit of the summation over l */ const UINT4 SpinAlignedEOBversion /**< 1 for SEOBNRv1, 2 for SEOBNRv2 */ ) { int debugPK = 0; int i = 0; double radius = sqrt(values->data[0]*values->data[0] + values->data[1] *values->data[1] + values->data[2] *values->data[2] ); if (radius < 1.) { return 0.; } if (1){ for( i =0; i < 4; i++) if( isnan(polvalues->data[i]) ) { XLAL_PRINT_INFO("XLALInspiralPrecSpinFactorizedFlux (from input)::polvalues %3.10f %3.10f %3.10f %3.10f\n", polvalues->data[0], polvalues->data[1], polvalues->data[2], polvalues->data[3]); XLALPrintError( "XLAL Error - %s: nan polvalues: %3.10f %3.10f %3.10f %3.10f \n", __func__, polvalues->data[0], polvalues->data[1], polvalues->data[2], polvalues->data[3] ); XLAL_ERROR( XLAL_EINVAL ); } for( i =0; i < 12; i++) if( isnan(values->data[i]) ) { XLAL_PRINT_INFO("XLALInspiralPrecSpinFactorizedFlux (from input)::values %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f\n", values->data[0], values->data[1], values->data[2], values->data[3], values->data[4], values->data[5], values->data[6], values->data[7], values->data[8], values->data[9], values->data[10], values->data[11]); XLALPrintError( "XLAL Error - %s: nan in input values: %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f \n", __func__, values->data[0], values->data[1], values->data[2], values->data[3], values->data[4], values->data[5], values->data[6], values->data[7], values->data[8], values->data[9], values->data[10], values->data[11] ); XLAL_ERROR( XLAL_EINVAL ); } } REAL8 flux = 0.0; REAL8 v; REAL8 omegaSq; COMPLEX16 hLM; INT4 l , m; //EOBNonQCCoeffs nqcCoeffs; #ifndef LAL_NDEBUG if (!values || !ak) { XLAL_ERROR_REAL8(XLAL_EFAULT); } #endif if (lMax < 2) { XLAL_ERROR_REAL8(XLAL_EINVAL); } /* Omega is the derivative of phi */ omegaSq = omega * omega; v = cbrt(omega); /* Update the factorized multipole coefficients, w.r.t. new spins */ if (0) { /* {{{ */ XLAL_PRINT_INFO("\nValues inside Flux:\n"); for (i = 0; i < 11; i++) XLAL_PRINT_INFO("values[%d] = %.12e\n", i, values->data[i]); /* * Assume that initial conditions are available at this * point, to compute the chiS and chiA parameters. Calculate * the values of chiS and chiA, as given in Eq.16 of * Precessing EOB paper Pan et.al. arXiv:1307.6232 (or PRD 89, 084006 (2014)). Assuming \vec{L} to be pointing in * the direction of \vec{r}\times\vec{p} */ REAL8 rcrossp [3], rcrosspMag, s1dotL, s2dotL; REAL8 chiS , chiA, tplspin; rcrossp[0] = values->data[1] * values->data[5] - values->data[2] * values->data[4]; rcrossp[1] = values->data[2] * values->data[3] - values->data[0] * values->data[5]; rcrossp[2] = values->data[0] * values->data[4] - values->data[1] * values->data[3]; rcrosspMag = sqrt(rcrossp[0] * rcrossp[0] + rcrossp[1] * rcrossp[1] + rcrossp[2] * rcrossp[2]); rcrossp[0] /= rcrosspMag; rcrossp[1] /= rcrosspMag; rcrossp[2] /= rcrosspMag; s1dotL = values->data[6] * rcrossp[0] + values->data[7] * rcrossp[1] + values->data[8] * rcrossp[2]; s2dotL = values->data[9] * rcrossp[0] + values->data[10] * rcrossp[1] + values->data[11] * rcrossp[2]; chiS = 0.5 * (s1dotL + s2dotL); chiA = 0.5 * (s1dotL - s2dotL); /* * Compute the test-particle limit spin of the deformed-Kerr * background */ switch (SpinAlignedEOBversion) { case 1: tplspin = 0.0; break; case 2: tplspin = (1. - 2. * ak->eobParams->eta) * chiS + (ak->eobParams->m1 - ak->eobParams->m2) / (ak->eobParams->m1 + ak->eobParams->m2) * chiA; break; default: XLALPrintError("XLAL Error - %s: Unknown SEOBNR version!\nAt present only v1 and v2 are available.\n", __func__); XLAL_ERROR(XLAL_EINVAL); break; } /* ************************************************* */ /* Re-Populate the Waveform structures */ /* ************************************************* */ /* Re-compute the spinning coefficients for hLM */ //debugPK XLAL_PRINT_INFO("Re-calculating waveform coefficients in the Flux function with chiS, chiA = %e, %e!\n", chiS, chiA); chiS = 0.3039435650957116; chiA = -0.2959424290852973; XLAL_PRINT_INFO("Changed them to the correct values = %e, %e!\n", chiS, chiA); if (ak->alignedSpins==1) { if (XLALSimIMREOBCalcSpinPrecFacWaveformCoefficients(ak->eobParams->hCoeffs, ak->eobParams->m1, ak->eobParams->m2, ak->eobParams->eta, tplspin, chiS, chiA, SpinAlignedEOBversion) == XLAL_FAILURE) { XLALDestroyREAL8Vector(values); XLAL_ERROR(XLAL_EFUNC); } } else { if (XLALSimIMREOBCalcSpinPrecFacWaveformCoefficients(ak->eobParams->hCoeffs, ak->eobParams->m1, ak->eobParams->m2, ak->eobParams->eta, tplspin, chiS, chiA, 3) == XLAL_FAILURE) { XLALDestroyREAL8Vector(values); XLAL_ERROR(XLAL_EFUNC); } } } /* }}} */ //XLAL_PRINT_INFO("v = %.16e\n", v); COMPLEX16 hLMTab[lMax+1][lMax+1]; if (XLALSimIMRSpinEOBFluxGetPrecSpinFactorizedWaveform(&hLMTab[0][0], polvalues, values, v, H, lMax, ak) == XLAL_FAILURE) { XLAL_ERROR_REAL8(XLAL_EFUNC); } for (l = 2; l <= lMax; l++) { for (m = 1; m <= l; m++) { if (debugPK) XLAL_PRINT_INFO("\nGetting (%d, %d) mode for flux!\n", l, m); //XLAL_PRINT_INFO("Stas, computing the waveform l = %d, m =%d\n", l, m); hLM = hLMTab[l][m]; //XLAL_PRINT_INFO("Stas: done\n"); /* * For the 2,2 mode, we apply NQC correction to the * flux */ if (l == 2 && m == 2) { COMPLEX16 hNQC; /* * switch ( SpinAlignedEOBversion ) { case 1: * XLALSimIMRGetEOBCalibratedSpinNQC( * &nqcCoeffs, l, m, ak->eobParams->eta, * ak->a ); break; case 2: // * XLALSimIMRGetEOBCalibratedSpinNQCv2( * &nqcCoeffs, l, m, ak->eobParams->eta, * ak->a ); * XLALSimIMRGetEOBCalibratedSpinNQC3D( * &nqcCoeffs, l, m, ak->eobParams->eta, * ak->a, (ak->chi1 - ak->chi2)/2. ); break; * default: XLALPrintError( "XLAL Error - %s: * Unknown SEOBNR version!\nAt present only * v1 and v2 are available.\n", __func__); * XLAL_ERROR( XLAL_EINVAL ); break; } */ if (debugPK) XLAL_PRINT_INFO("\tl = %d, m = %d, NQC: a1 = %.16e, a2 = %.16e, a3 = %.16e, a3S = %.16e, a4 = %.16e, a5 = %.16e\n\tb1 = %.16e, b2 = %.16e, b3 = %.16e, b4 = %.16e\n", 2, 2, nqcCoeffs->a1, nqcCoeffs->a2, nqcCoeffs->a3, nqcCoeffs->a3S, nqcCoeffs->a4, nqcCoeffs->a5, nqcCoeffs->b1, nqcCoeffs->b2, nqcCoeffs->b3, nqcCoeffs->b4); XLALSimIMREOBNonQCCorrection(&hNQC, polvalues, omega, nqcCoeffs); if (debugPK) XLAL_PRINT_INFO("\tl = %d, m = %d, hNQC = %.16e + i%.16e, |hNQC| = %.16e\n", l, m, creal(hNQC), cimag(hNQC), sqrt(creal(hNQC) * creal(hNQC) + cimag(hLM) * cimag(hLM))); if((m * m) * omegaSq * (creal(hLM) * creal(hLM) + cimag(hLM) * cimag(hLM)) > 5.) { XLAL_PRINT_INFO("\tl = %d, m = %d, mag(hLM) = %.17e, mag(hNQC) = %.17e, omega = %.16e\n", l, m, sqrt(creal(hLM) * creal(hLM) + cimag(hLM) * cimag(hLM)), sqrt(creal(hNQC) * creal(hNQC) + cimag(hNQC) * cimag(hNQC)), omega); XLAL_PRINT_INFO("XLALInspiralPrecSpinFactorizedFlux (from input)::values %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f %3.10f\n", values->data[0], values->data[1], values->data[2], values->data[3], values->data[4], values->data[5], values->data[6], values->data[7], values->data[8], values->data[9], values->data[10], values->data[11]); } /* Eq. 16 */ //FIXME hLM *= hNQC; } if (debugPK) XLAL_PRINT_INFO("\tl = %d, m = %d, mag(hLM) = %.17e, omega = %.16e\n", l, m, sqrt(creal(hLM) * creal(hLM) + cimag(hLM) * cimag(hLM)), omega); /* Eq. 13 */ flux += (REAL8) (m * m) * omegaSq * (creal(hLM) * creal(hLM) + cimag(hLM) * cimag(hLM)); } } if( (omegaSq > 1 || flux > 5) ) { if(debugPK) { XLAL_PRINT_INFO("In XLALInspiralPrecSpinFactorizedFlux: omegaSq = %3.12f, FLUX = %3.12f, r = %3.12f\n", omegaSq, flux,radius); } flux = 0.; } if (debugPK) XLAL_PRINT_INFO("\tStas, FLUX = %.16e\n", flux * LAL_1_PI / 8.0); return flux * LAL_1_PI / 8.0; }