23 #define UNUSED __attribute__ ((unused))
38 #include <gsl/gsl_errno.h>
39 #include <gsl/gsl_bspline.h>
40 #include <gsl/gsl_blas.h>
41 #include <gsl/gsl_min.h>
42 #include <gsl/gsl_spline.h>
43 #include <lal/Units.h>
44 #include <lal/SeqFactories.h>
45 #include <lal/LALConstants.h>
46 #include <lal/XLALError.h>
47 #include <lal/FrequencySeries.h>
49 #include <lal/StringInput.h>
50 #include <lal/Sequence.h>
51 #include <lal/LALStdio.h>
52 #include <lal/FileIO.h>
54 #include <lal/LALSimInspiral.h>
55 #include <lal/LALSimIMR.h>
58 #include <lal/LALConfig.h>
59 #ifdef LAL_PTHREAD_LOCK
69 static const double gA[] = {0.000631238, 0.000669113, 0.00070926, 0.000751815, 0.000796924, \
70 0.000844739, 0.000895424, 0.000949149, 0.0010061, 0.00106646, \
71 0.00113045, 0.00119828, 0.00127018, 0.00134639, 0.00142717, \
72 0.0015128, 0.00160357, 0.00169978, 0.00180177, 0.00190987, \
73 0.00202447, 0.00214594, 0.00227469, 0.00241117, 0.00255584, \
74 0.00270919, 0.00287175, 0.00304405, 0.00322669, 0.00342029, \
75 0.00362551, 0.00384304, 0.00407363, 0.00431804, 0.00457713, \
76 0.00485175, 0.00514286, 0.00545143, 0.00577852, 0.00612523, \
77 0.00649274, 0.00688231, 0.00729524, 0.00773296, 0.00819694, \
78 0.00868875, 0.00921008, 0.00976268, 0.0103484, 0.0109693, 0.0116275, \
79 0.0123252, 0.0130647, 0.0138486, 0.0146795, 0.0155602, 0.0164938, \
80 0.0174835, 0.0185325, 0.0196444, 0.0208231, 0.0220725, 0.0233968, \
81 0.0248006, 0.0262887, 0.027866, 0.029538, 0.0313102, 0.0331889, \
82 0.0351802, 0.037291, 0.0395285, 0.0419002, 0.0444142, 0.047079, \
83 0.0499038, 0.052898, 0.0560719, 0.0594362, 0.0630024, 0.0667825, \
84 0.0707895, 0.0750368, 0.079539, 0.0843114, 0.0893701, 0.0947323, \
85 0.100416, 0.106441, 0.112828, 0.119597, 0.126773, 0.13438, 0.142442, \
88 static const double gPhi[] = {0.00062519, 0.000638554, 0.000652301, 0.000666444, 0.000680997, \
89 0.000695976, 0.000711395, 0.000727272, 0.000743622, 0.000760465, \
90 0.000777818, 0.000795701, 0.000814135, 0.00083314, 0.000852738, \
91 0.000872954, 0.000893812, 0.000915337, 0.000937555, 0.000960495, \
92 0.000984187, 0.00100866, 0.00103395, 0.00106009, 0.00108711, \
93 0.00111506, 0.00114396, 0.00117387, 0.00120483, 0.00123688, \
94 0.00127008, 0.00130446, 0.00134009, 0.00137703, 0.00141533, \
95 0.00145506, 0.00149628, 0.00153906, 0.00158349, 0.00162963, \
96 0.00167757, 0.0017274, 0.00177922, 0.00183312, 0.00188921, \
97 0.00194759, 0.0020084, 0.00207175, 0.00213777, 0.00220662, \
98 0.00227844, 0.00235339, 0.00243165, 0.0025134, 0.00259883, \
99 0.00268816, 0.0027816, 0.0028794, 0.00298181, 0.0030891, 0.00320158, \
100 0.00331954, 0.00344334, 0.00357333, 0.00370991, 0.00385349, \
101 0.00400452, 0.0041635, 0.00433095, 0.00450744, 0.00469358, \
102 0.00489005, 0.00509755, 0.00531687, 0.00554887, 0.00579446, \
103 0.00605465, 0.00633054, 0.00662331, 0.00693427, 0.00726485, \
104 0.0076166, 0.00799125, 0.00839066, 0.00881692, 0.00927229, \
105 0.00975928, 0.0102807, 0.0108395, 0.0114393, 0.0120836, 0.0127768, \
106 0.0135236, 0.0143291, 0.0151992, 0.0161404, 0.0171602, 0.0182667, \
107 0.0194694, 0.0207788, 0.0222069, 0.0237674, 0.0254758, 0.0273498, \
108 0.0294099, 0.0316794, 0.0341854, 0.0369591, 0.0400368, 0.043461, \
109 0.0472811, 0.0515553, 0.0563523, 0.0617535, 0.0678557, 0.0747749, \
110 0.0826504, 0.0916509, 0.101981, 0.113893, 0.127695, 0.143771, 0.15};
112 #ifdef LAL_PTHREAD_LOCK
113 static pthread_once_t SEOBNRv1ROMDoubleSpin_is_initialized = PTHREAD_ONCE_INIT;
118 typedef struct tagSEOBNRROMdataDS_coeff
137 typedef struct tagSplineData
139 gsl_bspline_workspace *
bwx;
140 gsl_bspline_workspace *
bwy;
141 gsl_bspline_workspace *
bwz;
157 static size_t NextPow2(
const size_t n);
161 static int read_vector(
const char dir[],
const char fname[], gsl_vector *v);
162 static int read_matrix(
const char dir[],
const char fname[], gsl_matrix *
m);
164 static int load_data(
const char dir[], gsl_vector *cvec_amp, gsl_vector *cvec_phi, gsl_matrix *Bamp, gsl_matrix *Bphi, gsl_vector *cvec_amp_pre);
170 gsl_vector *cvec_amp,
171 gsl_vector *cvec_phi,
172 gsl_vector *cvec_amp_pre,
233 static int load_data(
const char dir[], gsl_vector *cvec_amp, gsl_vector *cvec_phi, gsl_matrix *Bamp, gsl_matrix *Bphi, gsl_vector *cvec_amp_pre) {
236 ret |=
read_vector(dir,
"SEOBNRv1ROM_DS_Amp_ciall.dat", cvec_amp);
237 ret |=
read_vector(dir,
"SEOBNRv1ROM_DS_Phase_ciall.dat", cvec_phi);
238 ret |=
read_matrix(dir,
"SEOBNRv1ROM_DS_Bamp_bin.dat", Bamp);
239 ret |=
read_matrix(dir,
"SEOBNRv1ROM_DS_Bphase_bin.dat", Bphi);
240 ret |=
read_vector(dir,
"SEOBNRv1ROM_DS_AmpPrefac_ci.dat", cvec_amp_pre);
246 if(!splinedata) exit(1);
254 (*splinedata)->ncx = ncx;
255 (*splinedata)->ncy = ncy;
256 (*splinedata)->ncz = ncz;
259 double qvec[] = {1., 1.125, 1.25, 1.375, 1.5, 1.625, 1.75, 1.875, 2., 2.25, 2.5, \
260 2.75, 3., 3.25, 3.5, 3.75, 4., 4.25, 4.5, 4.75, 5., 5.25, 5.5, 5.75, \
261 6., 6.25, 6.5, 6.75, 7., 7.25, 7.5, 7.75, 8., 8.25, 8.5, 8.75, 9., \
262 9.25, 9.5, 9.75, 10.};
263 double chi1vec[] = {-1., -0.95, -0.9, -0.85, -0.8, -0.75, -0.7, -0.6, -0.5, -0.4, -0.3, \
264 -0.2, -0.1, 0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.55, 0.6};
265 double chi2vec[] = {-1., -0.95, -0.9, -0.85, -0.8, -0.75, -0.7, -0.6, -0.5, -0.4, -0.3, \
266 -0.2, -0.1, 0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.55, 0.6};
268 const size_t nbreak_x = ncx-2;
269 const size_t nbreak_y = ncy-2;
270 const size_t nbreak_z = ncz-2;
273 gsl_bspline_workspace *bwx = gsl_bspline_alloc(4, nbreak_x);
274 gsl_bspline_workspace *bwy = gsl_bspline_alloc(4, nbreak_y);
275 gsl_bspline_workspace *bwz = gsl_bspline_alloc(4, nbreak_z);
278 gsl_vector *breakpts_x = gsl_vector_alloc(nbreak_x);
279 gsl_vector *breakpts_y = gsl_vector_alloc(nbreak_y);
280 gsl_vector *breakpts_z = gsl_vector_alloc(nbreak_z);
282 gsl_vector_set(breakpts_x,
i, qvec[
i]);
283 for (
UINT4 j=0; j<nbreak_y; j++)
284 gsl_vector_set(breakpts_y, j, chi1vec[j]);
285 for (
UINT4 k=0; k<nbreak_z; k++)
286 gsl_vector_set(breakpts_z, k, chi2vec[k]);
288 gsl_bspline_knots(breakpts_x, bwx);
289 gsl_bspline_knots(breakpts_y, bwy);
290 gsl_bspline_knots(breakpts_z, bwz);
292 gsl_vector_free(breakpts_x);
293 gsl_vector_free(breakpts_y);
294 gsl_vector_free(breakpts_z);
296 (*splinedata)->bwx=bwx;
297 (*splinedata)->bwy=bwy;
298 (*splinedata)->bwz=bwz;
303 if(!splinedata)
return;
304 if(splinedata->
bwx) gsl_bspline_free(splinedata->
bwx);
305 if(splinedata->
bwy) gsl_bspline_free(splinedata->
bwy);
306 if(splinedata->
bwz) gsl_bspline_free(splinedata->
bwz);
316 gsl_vector *cvec_amp,
317 gsl_vector *cvec_phi,
318 gsl_vector *cvec_amp_pre,
326 gsl_bspline_workspace *bwx=splinedata->
bwx;
327 gsl_bspline_workspace *bwy=splinedata->
bwy;
328 gsl_bspline_workspace *bwz=splinedata->
bwz;
330 int ncx = splinedata->
ncx;
331 int ncy = splinedata->
ncy;
332 int ncz = splinedata->
ncz;
336 for (
int k=0; k<
nk_amp; k++) {
337 gsl_vector v = gsl_vector_subvector(cvec_amp, k*
N,
N).vector;
339 gsl_vector_set(c_amp, k, csum);
343 for (
int k=0; k<
nk_phi; k++) {
344 gsl_vector v = gsl_vector_subvector(cvec_phi, k*
N,
N).vector;
346 gsl_vector_set(c_phi, k, csum);
370 XLALPrintError(
"WARNING: You tried to setup the SEOBNRv1ROMDoubleSpin model that was already initialised. Ignoring\n");
374 (romdata)->cvec_amp = gsl_vector_alloc(
N*
nk_amp);
375 (romdata)->cvec_phi = gsl_vector_alloc(
N*
nk_phi);
378 (romdata)->cvec_amp_pre = gsl_vector_alloc(
N);
379 ret=
load_data(dir, (romdata)->cvec_amp, (romdata)->cvec_phi, (romdata)->Bamp, (romdata)->Bphi, (romdata)->cvec_amp_pre);
389 if(romdata->cvec_amp) gsl_vector_free(romdata->cvec_amp);
390 if(romdata->cvec_phi) gsl_vector_free(romdata->cvec_phi);
391 if(romdata->Bamp) gsl_matrix_free(romdata->Bamp);
392 if(romdata->Bphi) gsl_matrix_free(romdata->Bphi);
393 if(romdata->cvec_amp_pre) gsl_vector_free(romdata->cvec_amp_pre);
400 if(!romdatacoeff) exit(1);
407 (*romdatacoeff)->c_amp = gsl_vector_alloc(
nk_amp);
408 (*romdatacoeff)->c_phi = gsl_vector_alloc(
nk_phi);
413 if(romdatacoeff->
c_amp) gsl_vector_free(romdatacoeff->
c_amp);
414 if(romdatacoeff->
c_phi) gsl_vector_free(romdatacoeff->
c_phi);
420 return 1 << (size_t) ceil(log2(n));
448 if(!hptilde || !hctilde)
451 if(*hptilde || *hctilde) {
452 XLALPrintError(
"(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde));
459 if (
q > 10.0)
nudge(&
q, 10.0, 1
e-6);
460 if (chi1 < -1.0)
nudge(&chi1, -1.0, 1
e-6);
461 if (chi1 > 0.6)
nudge(&chi1, 0.6, 1
e-6);
462 if (chi2 < -1.0)
nudge(&chi2, -1.0, 1
e-6);
463 if (chi2 > 0.6)
nudge(&chi2, 0.6, 1
e-6);
466 if ( chi1 < -1.0 || chi2 < -1.0 || chi1 > 0.6 || chi2 > 0.6 ) {
467 XLALPrintError(
"XLAL Error - %s: chi1 or chi2 smaller than -1 or larger than 0.6!\nSEOBNRv1ROMDoubleSpin is only available for spins in the range -1 <= a/M <= 0.6.\n", __func__);
472 XLALPrintError(
"XLAL Error - %s: q=%lf larger than 10!\nSEOBNRv1ROMDoubleSpin is only available for q in the range 1 <= q <= 10.\n", __func__,
q);
478 double fLow = freqs_in->
data[0];
479 double fHigh = freqs_in->
data[freqs_in->
length - 1];
487 double fLow_geom = fLow * Mtot_sec;
488 double fHigh_geom = fHigh * Mtot_sec;
489 double fRef_geom = fRef * Mtot_sec;
490 double deltaF_geom = deltaF * Mtot_sec;
498 XLALPrintWarning(
"Maximal frequency Mf_high=%g is greater than highest ROM frequency Mf_ROM_Max=%g. Using Mf_high=Mf_ROM_Max.", fHigh_geom,
Mf_ROM_max);
502 XLAL_ERROR(
XLAL_EDOM,
"End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom);
504 XLALPrintWarning(
"Reference frequency Mf_ref=%g is greater than maximal frequency in ROM Mf=%g. Starting at maximal frequency in ROM.\n", fRef_geom,
Mf_ROM_max);
508 XLALPrintWarning(
"Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fRef_geom,
Mf_ROM_min);
524 romdata->cvec_amp_pre,
525 romdata_coeff->
c_amp,
526 romdata_coeff->
c_phi,
532 XLAL_ERROR(retcode,
"Parameter-space interpolation failed.");
538 gsl_vector* amp_f = gsl_vector_alloc(
nk_amp);
539 gsl_vector* phi_f = gsl_vector_alloc(
nk_phi);
540 gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bamp, romdata_coeff->
c_amp, 0.0, amp_f);
541 gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bphi, romdata_coeff->
c_phi, 0.0, phi_f);
544 gsl_interp_accel *acc_amp = gsl_interp_accel_alloc();
545 gsl_spline *spline_amp = gsl_spline_alloc(gsl_interp_cspline,
nk_amp);
546 gsl_spline_init(spline_amp,
gA, gsl_vector_const_ptr(amp_f,0),
nk_amp);
548 gsl_interp_accel *acc_phi = gsl_interp_accel_alloc();
549 gsl_spline *spline_phi = gsl_spline_alloc(gsl_interp_cspline,
nk_phi);
550 gsl_spline_init(spline_phi,
gPhi, gsl_vector_const_ptr(phi_f,0),
nk_phi);
559 npts =
NextPow2(fHigh_geom / deltaF_geom) + 1;
560 if (fHigh_geom < fHigh * Mtot_sec)
561 npts =
NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;
569 double fHigh_temp = fHigh_geom / Mtot_sec;
571 UINT4 iStop = (
UINT4) ceil(fHigh_temp / deltaF);
577 freqs->
data[
i-iStart] =
i*deltaF_geom;
591 freqs->
data[
i] = freqs_in->
data[
i] * Mtot_sec;
595 if (!(*hptilde) || !(*hctilde))
599 gsl_spline_free(spline_amp);
600 gsl_spline_free(spline_phi);
601 gsl_interp_accel_free(acc_amp);
602 gsl_interp_accel_free(acc_phi);
603 gsl_vector_free(amp_f);
604 gsl_vector_free(phi_f);
608 memset((*hptilde)->data->data, 0, npts *
sizeof(
COMPLEX16));
609 memset((*hctilde)->data->data, 0, npts *
sizeof(
COMPLEX16));
617 REAL8 cosi = cos(inclination);
618 REAL8 pcoef = 0.5*(1.0 + cosi*cosi);
623 double amp0 = Mtot * amp_pre * Mtot_sec *
LAL_MRSUN_SI / (distance);
626 double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef;
630 double f = freqs->
data[
i];
633 double A = gsl_spline_eval(spline_amp, f, acc_amp);
634 double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change;
636 pdata[j] = pcoef * htilde;
637 cdata[j] = -I * ccoef * htilde;
647 if (Mf_final > freqs->
data[L-1])
648 Mf_final = freqs->
data[L-1];
649 if (Mf_final < freqs->
data[0])
653 gsl_spline_free(spline_amp);
654 gsl_spline_free(spline_phi);
655 gsl_interp_accel_free(acc_amp);
656 gsl_interp_accel_free(acc_phi);
657 gsl_vector_free(amp_f);
658 gsl_vector_free(phi_f);
665 REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*
LAL_PI);
669 double f = freqs->
data[
i] - fRef_geom;
671 pdata[j] *= cexp(-2*
LAL_PI * I * f * t_corr);
672 cdata[j] *= cexp(-2*
LAL_PI * I * f * t_corr);
677 gsl_spline_free(spline_amp);
678 gsl_spline_free(spline_phi);
679 gsl_interp_accel_free(acc_amp);
680 gsl_interp_accel_free(acc_phi);
681 gsl_vector_free(amp_f);
682 gsl_vector_free(phi_f);
740 struct tagCOMPLEX16FrequencySeries **hptilde,
741 struct tagCOMPLEX16FrequencySeries **hctilde,
755 double m1temp = m1SI;
756 double chi1temp = chi1;
766 double Mtot = mass1+mass2;
767 double q = mass2 / mass1;
773 #ifdef LAL_PTHREAD_LOCK
784 phiRef, fRef, distance, inclination, Mtot_sec,
q, chi1, chi2, freqs, 0);
798 struct tagCOMPLEX16FrequencySeries **hptilde,
799 struct tagCOMPLEX16FrequencySeries **hctilde,
816 double m1temp = m1SI;
817 double chi1temp = chi1;
827 double Mtot = mass1+mass2;
828 double q = mass2 / mass1;
837 #ifdef LAL_PTHREAD_LOCK
848 freqs->
data[0] = fLow;
849 freqs->
data[1] = fHigh;
852 phiRef, fRef, distance, inclination, Mtot_sec,
q, chi1, chi2, freqs, deltaF);
870 char datafile[] =
"SEOBNRv1ROM_DS_Phase_ciall.dat";
875 char *dir = dirname(
path);
static const REAL8 Mf_ROM_max
static const REAL8 Mf_ROM_min
static void nudge(REAL8 *x, REAL8 X, REAL8 epsilon)
Auxiliary functions for SEOBNRv1/v2 reduced order modeling codes in LALSimIMRSEOBNRv2ROMDoubleSpin....
static UNUSED double SEOBNRROM_Ringdown_Mf_From_Mtot_q(const double Mtot_sec, const double q, const double chi1, const double chi2, Approximant apx)
static UNUSED REAL8 Interpolate_Coefficent_Tensor(gsl_vector *v, REAL8 eta, REAL8 chi1, REAL8 chi2, int ncy, int ncz, gsl_bspline_workspace *bwx, gsl_bspline_workspace *bwy, gsl_bspline_workspace *bwz)
static void SEOBNRv1ROMDoubleSpin_Init_LALDATA(void)
static bool SEOBNRv1ROMDoubleSpin_IsSetup(void)
Helper function to check if the SEOBNRv1ROMDoubleSpin model has been initialised.
static int SEOBNRROMdataDS_Init(SEOBNRROMdataDS *romdata, const char dir[])
static void SplineData_Destroy(SplineData *splinedata)
static const double gPhi[]
static int read_vector(const char dir[], const char fname[], gsl_vector *v)
static int SEOBNRv1ROMDoubleSpinCore(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, double phiRef, double fRef, double distance, double inclination, double Mtot_sec, double q, double chi1, double chi2, const REAL8Sequence *freqs_in, double deltaF)
static void SplineData_Init(SplineData **splinedata)
static void SEOBNRROMdataDS_coeff_Cleanup(SEOBNRROMdataDS_coeff *romdatacoeff)
static int SEOBNRv1ROMDoubleSpin_Init(const char dir[])
Setup SEOBNRv1ROMDoubleSpin model using data files installed in dir.
static SEOBNRROMdataDS __lalsim_SEOBNRv1ROMDS_data
static void SEOBNRROMdataDS_Cleanup(SEOBNRROMdataDS *romdata)
static size_t NextPow2(const size_t n)
static int load_data(const char dir[], gsl_vector *cvec_amp, gsl_vector *cvec_phi, gsl_matrix *Bamp, gsl_matrix *Bphi, gsl_vector *cvec_amp_pre)
static int TP_Spline_interpolation_3d(REAL8 q, REAL8 chi1, REAL8 chi2, gsl_vector *cvec_amp, gsl_vector *cvec_phi, gsl_vector *cvec_amp_pre, gsl_vector *c_amp, gsl_vector *c_phi, REAL8 *amp_pre)
static void SEOBNRROMdataDS_coeff_Init(SEOBNRROMdataDS_coeff **romdatacoeff)
static int read_matrix(const char dir[], const char fname[], gsl_matrix *m)
#define XLAL_FILE_RESOLVE_PATH(fname)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void * XLALCalloc(size_t m, size_t n)
int XLALSimIMRSEOBNRv1ROMDoubleSpinFrequencySequence(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs, REAL8 phiRef, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2)
Compute waveform in LAL format at specified frequencies for the SEOBNRv1_ROM_DoubleSpin model.
int XLALSimIMRSEOBNRv1ROMDoubleSpin(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2)
Compute waveform in LAL format for the SEOBNRv1_ROM_DoubleSpin model.
@ SEOBNRv1
Spin-aligned EOBNR model.
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
#define XLAL_ERROR_VOID(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
gsl_bspline_workspace * bwx
gsl_bspline_workspace * bwz
gsl_bspline_workspace * bwy
gsl_vector * cvec_amp_pre