LALSimulation  5.4.0.1-fe68b98
LALSimIMRSEOBNRv1ROMDoubleSpin.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Puerrer, John Veitch
3  * Reduced Order Model for SEOBNR
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with with program; see the file COPYING. If not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301 USA
19  */
20 
21 
22 #ifdef __GNUC__
23 #define UNUSED __attribute__ ((unused))
24 #else
25 #define UNUSED
26 #endif
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <math.h>
31 #include <complex.h>
32 #include <time.h>
33 #include <stdbool.h>
34 #include <alloca.h>
35 #include <string.h>
36 #include <libgen.h>
37 
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>
48 #include <lal/Date.h>
49 #include <lal/StringInput.h>
50 #include <lal/Sequence.h>
51 #include <lal/LALStdio.h>
52 #include <lal/FileIO.h>
53 
54 #include <lal/LALSimInspiral.h>
55 #include <lal/LALSimIMR.h>
57 
58 #include <lal/LALConfig.h>
59 #ifdef LAL_PTHREAD_LOCK
60 #include <pthread.h>
61 #endif
62 
63 
64 /********* Input data for spline basis points **************/
65 #define nk_amp 95 // number of SVD-modes == number of basis functions for amplitude
66 #define nk_phi 123 // number of SVD-modes == number of basis functions for phase
67 
68 // Frequency points for amplitude and phase
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, \
86  0.15};
87 
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};
111 
112 #ifdef LAL_PTHREAD_LOCK
113 static pthread_once_t SEOBNRv1ROMDoubleSpin_is_initialized = PTHREAD_ONCE_INIT;
114 #endif
115 
116 /*************** type definitions ******************/
117 
118 typedef struct tagSEOBNRROMdataDS_coeff
119 {
120  gsl_vector* c_amp;
121  gsl_vector* c_phi;
123 
125 {
127  gsl_vector* cvec_amp;
128  gsl_vector* cvec_phi;
129  gsl_matrix *Bamp;
130  gsl_matrix *Bphi;
131  gsl_vector* cvec_amp_pre;
132 };
133 typedef struct tagSEOBNRROMdataDS SEOBNRROMdataDS;
134 
135 static SEOBNRROMdataDS __lalsim_SEOBNRv1ROMDS_data;
136 
137 typedef struct tagSplineData
138 {
139  gsl_bspline_workspace *bwx;
140  gsl_bspline_workspace *bwy;
141  gsl_bspline_workspace *bwz;
142  int ncx, ncy, ncz;
143 } SplineData;
144 
145 /**************** Internal functions **********************/
146 
147 static void SEOBNRv1ROMDoubleSpin_Init_LALDATA(void);
148 static int SEOBNRv1ROMDoubleSpin_Init(const char dir[]);
149 static bool SEOBNRv1ROMDoubleSpin_IsSetup(void);
150 
151 static int SEOBNRROMdataDS_Init(SEOBNRROMdataDS *romdata, const char dir[]);
152 static void SEOBNRROMdataDS_Cleanup(SEOBNRROMdataDS *romdata);
153 
154 static void SEOBNRROMdataDS_coeff_Init(SEOBNRROMdataDS_coeff **romdatacoeff);
155 static void SEOBNRROMdataDS_coeff_Cleanup(SEOBNRROMdataDS_coeff *romdatacoeff);
156 
157 static size_t NextPow2(const size_t n);
158 static void SplineData_Destroy(SplineData *splinedata);
159 static void SplineData_Init(SplineData **splinedata);
160 
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);
163 
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);
165 
166 static int TP_Spline_interpolation_3d(
167  REAL8 q, // Input: q-value for which projection coefficients should be evaluated
168  REAL8 chi1, // Input: chi1-value for which projection coefficients should be evaluated
169  REAL8 chi2, // Input: chi2-value for which projection coefficients should be evaluated
170  gsl_vector *cvec_amp, // Input: data for spline coefficients for amplitude
171  gsl_vector *cvec_phi, // Input: data for spline coefficients for phase
172  gsl_vector *cvec_amp_pre, // Input: data for spline coefficients for amplitude prefactor
173  gsl_vector *c_amp, // Output: interpolated projection coefficients for amplitude
174  gsl_vector *c_phi, // Output: interpolated projection coefficients for phase
175  REAL8 *amp_pre // Output: interpolated amplitude prefactor
176 );
177 
178 /*
179  * Core function for computing the ROM waveform.
180  * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi).
181  * Construct 1D splines for amplitude and phase.
182  * Compute strain waveform from amplitude and phase.
183 */
184 static int SEOBNRv1ROMDoubleSpinCore(
185  COMPLEX16FrequencySeries **hptilde,
186  COMPLEX16FrequencySeries **hctilde,
187  double phiRef,
188  double fRef,
189  double distance,
190  double inclination,
191  double Mtot_sec,
192  double q,
193  double chi1,
194  double chi2,
195  const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */
196  double deltaF
197  /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with
198  * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly.
199  * Then we will use deltaF = 0 to create the frequency series we return. */
200 );
201 
202 
203 /********************* Definitions begin here ********************/
204 
205 
206 /** Setup SEOBNRv1ROMDoubleSpin model using data files installed in dir
207  */
208 static int SEOBNRv1ROMDoubleSpin_Init(const char dir[]) {
209  if(__lalsim_SEOBNRv1ROMDS_data.setup) {
210  XLALPrintError("Error: SEOBNRROMdata was already set up!");
212  }
213 
215 
216  if(__lalsim_SEOBNRv1ROMDS_data.setup) {
217  return(XLAL_SUCCESS);
218  }
219  else {
220  return(XLAL_EFAILED);
221  }
222 }
223 
224 /** Helper function to check if the SEOBNRv1ROMDoubleSpin model has been initialised */
225 static bool SEOBNRv1ROMDoubleSpin_IsSetup(void) {
227  return true;
228  else
229  return false;
230 }
231 
232 // Read binary ROM data for basis functions and coefficients
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) {
234  // Load binary data for amplitude and phase spline coefficients as computed in Mathematica
235  int ret = XLAL_SUCCESS;
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);
241  return(ret);
242 }
243 
244 static void SplineData_Init( SplineData **splinedata )
245 {
246  if(!splinedata) exit(1);
247  if(*splinedata) SplineData_Destroy(*splinedata);
248 
249  (*splinedata)=XLALCalloc(1,sizeof(SplineData));
250 
251  int ncx = 41+2; // points in q
252  int ncy = 21+2; // points in chi1
253  int ncz = 21+2; // points in chi2
254  (*splinedata)->ncx = ncx;
255  (*splinedata)->ncy = ncy;
256  (*splinedata)->ncz = ncz;
257 
258  // Set up B-spline basis for desired knots
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};
267 
268  const size_t nbreak_x = ncx-2; // must have nbreak = n-2 for cubic splines
269  const size_t nbreak_y = ncy-2; // must have nbreak = n-2 for cubic splines
270  const size_t nbreak_z = ncz-2; // must have nbreak = n-2 for cubic splines
271 
272  // allocate a cubic bspline workspace (k = 4)
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);
276 
277  // set breakpoints (and thus knots by hand)
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);
281  for (UINT4 i=0; i<nbreak_x; i++)
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]);
287 
288  gsl_bspline_knots(breakpts_x, bwx);
289  gsl_bspline_knots(breakpts_y, bwy);
290  gsl_bspline_knots(breakpts_z, bwz);
291 
292  gsl_vector_free(breakpts_x);
293  gsl_vector_free(breakpts_y);
294  gsl_vector_free(breakpts_z);
295 
296  (*splinedata)->bwx=bwx;
297  (*splinedata)->bwy=bwy;
298  (*splinedata)->bwz=bwz;
299 }
300 
301 static void SplineData_Destroy(SplineData *splinedata)
302 {
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);
307  XLALFree(splinedata);
308 }
309 
310 // Interpolate projection coefficients for amplitude and phase over the parameter space (q, chi).
311 // The multi-dimensional interpolation is carried out via a tensor product decomposition.
313  REAL8 q, // Input: q-value for which projection coefficients should be evaluated
314  REAL8 chi1, // Input: chi1-value for which projection coefficients should be evaluated
315  REAL8 chi2, // Input: chi2-value for which projection coefficients should be evaluated
316  gsl_vector *cvec_amp, // Input: data for spline coefficients for amplitude
317  gsl_vector *cvec_phi, // Input: data for spline coefficients for phase
318  gsl_vector *cvec_amp_pre, // Input: data for spline coefficients for amplitude prefactor
319  gsl_vector *c_amp, // Output: interpolated projection coefficients for amplitude
320  gsl_vector *c_phi, // Output: interpolated projection coefficients for phase
321  REAL8 *amp_pre // Output: interpolated amplitude prefactor
322 ) {
323 
324  SplineData *splinedata=NULL;
325  SplineData_Init(&splinedata);
326  gsl_bspline_workspace *bwx=splinedata->bwx;
327  gsl_bspline_workspace *bwy=splinedata->bwy;
328  gsl_bspline_workspace *bwz=splinedata->bwz;
329 
330  int ncx = splinedata->ncx; // points in q
331  int ncy = splinedata->ncy; // points in chi1
332  int ncz = splinedata->ncz; // points in chi2
333  int N = ncx*ncy*ncz; // size of the data matrix for one SVD-mode
334 
335  // Evaluate the TP spline for all SVD modes - amplitude
336  for (int k=0; k<nk_amp; k++) { // For each SVD mode
337  gsl_vector v = gsl_vector_subvector(cvec_amp, k*N, N).vector; // Pick out the coefficient matrix corresponding to the k-th SVD mode.
338  REAL8 csum = Interpolate_Coefficent_Tensor(&v, q, chi1, chi2, ncy, ncz, bwx, bwy, bwz);
339  gsl_vector_set(c_amp, k, csum);
340  }
341 
342  // Evaluate the TP spline for all SVD modes - phase
343  for (int k=0; k<nk_phi; k++) { // For each SVD mode
344  gsl_vector v = gsl_vector_subvector(cvec_phi, k*N, N).vector; // Pick out the coefficient matrix corresponding to the k-th SVD mode.
345  REAL8 csum = Interpolate_Coefficent_Tensor(&v, q, chi1, chi2, ncy, ncz, bwx, bwy, bwz);
346  gsl_vector_set(c_phi, k, csum);
347  }
348 
349  // Evaluate the TP spline for the amplitude prefactor
350  *amp_pre = Interpolate_Coefficent_Tensor(cvec_amp_pre, q, chi1, chi2, ncy, ncz, bwx, bwy, bwz);
351 
352  SplineData_Destroy(splinedata);
353 
354  return(0);
355 }
356 
357 /* Set up a new ROM model, using data contained in dir */
358 static int SEOBNRROMdataDS_Init(SEOBNRROMdataDS *romdata, const char dir[]) {
359  // set up ROM
360  int ncx = 41+2; // points in q
361  int ncy = 21+2; // points in chi1
362  int ncz = 21+2; // points in chi2
363  int N = ncx*ncy*ncz; // size of the data matrix for one SVD-mode
364 
365  int ret = XLAL_FAILURE;
366 
367  /* Create storage for structures */
368  if(romdata->setup)
369  {
370  XLALPrintError("WARNING: You tried to setup the SEOBNRv1ROMDoubleSpin model that was already initialised. Ignoring\n");
371  return (XLAL_FAILURE);
372  }
373 
374  (romdata)->cvec_amp = gsl_vector_alloc(N*nk_amp);
375  (romdata)->cvec_phi = gsl_vector_alloc(N*nk_phi);
376  (romdata)->Bamp = gsl_matrix_alloc(nk_amp, nk_amp);
377  (romdata)->Bphi = gsl_matrix_alloc(nk_phi, 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);
380 
381  if(XLAL_SUCCESS==ret) romdata->setup=1;
382  else SEOBNRROMdataDS_Cleanup(romdata);
383 
384  return (ret);
385 }
386 
387 /* Deallocate contents of the given SSEOBNRROMdata structure */
388 static void SEOBNRROMdataDS_Cleanup(SEOBNRROMdataDS *romdata) {
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);
394  romdata->setup=0;
395 }
396 
397 /* Structure for internal use */
399 
400  if(!romdatacoeff) exit(1);
401  /* Create storage for structures */
402  if(!*romdatacoeff)
403  *romdatacoeff=XLALCalloc(1,sizeof(SEOBNRROMdataDS_coeff));
404  else
405  SEOBNRROMdataDS_coeff_Cleanup(*romdatacoeff);
406 
407  (*romdatacoeff)->c_amp = gsl_vector_alloc(nk_amp);
408  (*romdatacoeff)->c_phi = gsl_vector_alloc(nk_phi);
409 }
410 
411 /* Deallocate contents of the given SEOBNRROMdataDS_coeff structure */
413  if(romdatacoeff->c_amp) gsl_vector_free(romdatacoeff->c_amp);
414  if(romdatacoeff->c_phi) gsl_vector_free(romdatacoeff->c_phi);
415  XLALFree(romdatacoeff);
416 }
417 
418 /* Return the closest higher power of 2 */
419 static size_t NextPow2(const size_t n) {
420  return 1 << (size_t) ceil(log2(n));
421 }
422 
423 /*
424  * Core function for computing the ROM waveform.
425  * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi).
426  * Construct 1D splines for amplitude and phase.
427  * Compute strain waveform from amplitude and phase.
428 */
430  COMPLEX16FrequencySeries **hptilde,
431  COMPLEX16FrequencySeries **hctilde,
432  double phiRef,
433  double fRef,
434  double distance,
435  double inclination,
436  double Mtot_sec,
437  double q,
438  double chi1,
439  double chi2,
440  const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */
441  double deltaF
442  /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with
443  * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly.
444  * Then we will use deltaF = 0 to create the frequency series we return. */
445  )
446 {
447  /* Check output arrays */
448  if(!hptilde || !hctilde)
450  SEOBNRROMdataDS *romdata=&__lalsim_SEOBNRv1ROMDS_data;
451  if(*hptilde || *hctilde) {
452  XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde));
454  }
455  int retcode=0;
456 
457  // 'Nudge' parameter values to allowed boundary values if close by
458  if (q < 1.0) nudge(&q, 1.0, 1e-6);
459  if (q > 10.0) nudge(&q, 10.0, 1e-6);
460  if (chi1 < -1.0) nudge(&chi1, -1.0, 1e-6);
461  if (chi1 > 0.6) nudge(&chi1, 0.6, 1e-6);
462  if (chi2 < -1.0) nudge(&chi2, -1.0, 1e-6);
463  if (chi2 > 0.6) nudge(&chi2, 0.6, 1e-6);
464 
465  /* If either spin > 0.6, model not available, exit */
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__);
469  }
470 
471  if (q > 10) {
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);
474  }
475 
476  /* Find frequency bounds */
477  if (!freqs_in) XLAL_ERROR(XLAL_EFAULT);
478  double fLow = freqs_in->data[0];
479  double fHigh = freqs_in->data[freqs_in->length - 1];
480 
481  if(fRef==0.0)
482  fRef=fLow;
483 
484  /* Convert to geometric units for frequency */
485  double Mf_ROM_min = fmax(gA[0], gPhi[0]); // lowest allowed geometric frequency for ROM
486  double Mf_ROM_max = fmin(gA[nk_amp-1], gPhi[nk_phi-1]); // highest allowed geometric frequency for ROM
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;
491 
492  // Enforce allowed geometric frequency range
493  if (fLow_geom < Mf_ROM_min)
494  XLAL_ERROR(XLAL_EDOM, "Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g.\n", fLow_geom, Mf_ROM_min);
495  if (fHigh_geom == 0)
496  fHigh_geom = Mf_ROM_max;
497  else if (fHigh_geom > Mf_ROM_max) {
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);
499  fHigh_geom = Mf_ROM_max;
500  }
501  else if (fHigh_geom < Mf_ROM_min)
502  XLAL_ERROR(XLAL_EDOM, "End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom);
503  if (fRef_geom > Mf_ROM_max) {
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);
505  fRef_geom = Mf_ROM_max; // If fref > fhigh we reset fref to default value of cutoff frequency.
506  }
507  if (fRef_geom < Mf_ROM_min) {
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);
509  fRef_geom = Mf_ROM_min;
510  }
511 
512  /* Internal storage for w.f. coefficiencts */
513  SEOBNRROMdataDS_coeff *romdata_coeff=NULL;
514  SEOBNRROMdataDS_coeff_Init(&romdata_coeff);
515  REAL8 amp_pre;
516 
517  /* Interpolate projection coefficients and evaluate them at (q,chi1,chi2) */
519  q, // Input: q-value for which projection coefficients should be evaluated
520  chi1, // Input: chi1-value for which projection coefficients should be evaluated
521  chi2, // Input: chi2-value for which projection coefficients should be evaluated
522  romdata->cvec_amp, // Input: data for spline coefficients for amplitude
523  romdata->cvec_phi, // Input: data for spline coefficients for phase
524  romdata->cvec_amp_pre, // Input: data for spline coefficients for amplitude prefactor
525  romdata_coeff->c_amp, // Output: interpolated projection coefficients for amplitude
526  romdata_coeff->c_phi, // Output: interpolated projection coefficients for phase
527  &amp_pre // Output: interpolated amplitude prefactor
528  );
529 
530  if(retcode!=0) {
531  SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
532  XLAL_ERROR(retcode, "Parameter-space interpolation failed.");
533  }
534 
535  // Compute function values of amplitude an phase on sparse frequency points by evaluating matrix vector products
536  // amp_pts = B_A^T . c_A
537  // phi_pts = B_phi^T . c_phi
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);
542 
543  // Setup 1d splines in frequency
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);
547 
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);
551 
552 
553  size_t npts = 0;
554  LIGOTimeGPS tC = {0, 0};
555  UINT4 offset = 0; // Index shift between freqs and the frequency series
556  REAL8Sequence *freqs = NULL;
557  if (deltaF > 0) { // freqs contains uniform frequency grid with spacing deltaF; we start at frequency 0
558  /* Set up output array with size closest power of 2 */
559  npts = NextPow2(fHigh_geom / deltaF_geom) + 1;
560  if (fHigh_geom < fHigh * Mtot_sec) /* Resize waveform if user wants f_max larger than cutoff frequency */
561  npts = NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;
562 
563  XLALGPSAdd(&tC, -1. / deltaF); /* coalesce at t=0 */
564  *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);
565  *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts);
566 
567  // Recreate freqs using only the lower and upper bounds
568  // Use fLow, fHigh and deltaF rather than geometric frequencies for numerical accuracy
569  double fHigh_temp = fHigh_geom / Mtot_sec;
570  UINT4 iStart = (UINT4) ceil(fLow / deltaF);
571  UINT4 iStop = (UINT4) ceil(fHigh_temp / deltaF);
572  freqs = XLALCreateREAL8Sequence(iStop - iStart);
573  if (!freqs) {
574  XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
575  }
576  for (UINT4 i=iStart; i<iStop; i++)
577  freqs->data[i-iStart] = i*deltaF_geom;
578 
579  offset = iStart;
580  } else { // freqs contains frequencies with non-uniform spacing; we start at lowest given frequency
581  npts = freqs_in->length;
582  *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
583  *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts);
584  offset = 0;
585 
586  freqs = XLALCreateREAL8Sequence(freqs_in->length);
587  if (!freqs) {
588  XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed.");
589  }
590  for (UINT4 i=0; i<freqs_in->length; i++)
591  freqs->data[i] = freqs_in->data[i] * Mtot_sec;
592  }
593 
594 
595  if (!(*hptilde) || !(*hctilde))
596  {
598 
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);
605  SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
606  XLAL_ERROR(XLAL_EFUNC, "Waveform allocation failed.");
607  }
608  memset((*hptilde)->data->data, 0, npts * sizeof(COMPLEX16));
609  memset((*hctilde)->data->data, 0, npts * sizeof(COMPLEX16));
610 
611  XLALUnitMultiply(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit);
612  XLALUnitMultiply(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit);
613 
614  COMPLEX16 *pdata=(*hptilde)->data->data;
615  COMPLEX16 *cdata=(*hctilde)->data->data;
616 
617  REAL8 cosi = cos(inclination);
618  REAL8 pcoef = 0.5*(1.0 + cosi*cosi);
619  REAL8 ccoef = cosi;
620 
621  REAL8 s = 0.5; // Scale polarization amplitude so that strain agrees with FFT of SEOBNRv1
622  double Mtot = Mtot_sec / LAL_MTSUN_SI;
623  double amp0 = Mtot * amp_pre * Mtot_sec * LAL_MRSUN_SI / (distance); // Correct overall amplitude to undo mass-dependent scaling used in ROM
624 
625  // Evaluate reference phase for setting phiRef correctly
626  double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef;
627 
628  // Assemble waveform from aplitude and phase
629  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
630  double f = freqs->data[i];
631  if (f > Mf_ROM_max) continue; // We're beyond the highest allowed frequency; since freqs may not be ordered, we'll just skip the current frequency and leave zero in the buffer
632  int j = i + offset; // shift index for frequency series if needed
633  double A = gsl_spline_eval(spline_amp, f, acc_amp);
634  double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change;
635  COMPLEX16 htilde = s*amp0*A * cexp(I*phase);
636  pdata[j] = pcoef * htilde;
637  cdata[j] = -I * ccoef * htilde;
638  }
639 
640  /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */
641 
642  // Get SEOBNRv1 ringdown frequency for 22 mode
643  double Mf_final = SEOBNRROM_Ringdown_Mf_From_Mtot_q(Mtot_sec, q, chi1, chi2, SEOBNRv1);
644 
645  UINT4 L = freqs->length;
646  // prevent gsl interpolation errors
647  if (Mf_final > freqs->data[L-1])
648  Mf_final = freqs->data[L-1];
649  if (Mf_final < freqs->data[0])
650  {
652 
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);
659  SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
660  XLAL_ERROR(XLAL_EDOM, "f_ringdown < f_min");
661  }
662 
663  // Time correction is t(f_final) = 1/(2pi) dphi/df (f_final)
664  // We compute the dimensionless time correction t/M since we use geometric units.
665  REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*LAL_PI);
666 
667  // Now correct phase
668  for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence
669  double f = freqs->data[i] - fRef_geom;
670  int j = i + offset; // shift index for frequency series if needed
671  pdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
672  cdata[j] *= cexp(-2*LAL_PI * I * f * t_corr);
673  }
674 
676 
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);
683  SEOBNRROMdataDS_coeff_Cleanup(romdata_coeff);
684 
685  return(XLAL_SUCCESS);
686 }
687 
688 /**
689  * @addtogroup LALSimIMRSEOBNRROM_c
690  *
691  * @{
692  *
693  * @name SEOBNRv1 Reduced Order Model (Double Spin)
694  *
695  * @author Michael Puerrer, John Veitch
696  *
697  * @brief C code for SEOBNRv1 reduced order model (double spin version).
698  * See CQG 31 195010, 2014, arXiv:1402.4146 for details.
699  *
700  * This is a frequency domain model that approximates the time domain SEOBNRv1 model.
701  * Note that SEOBNRv2 supersedes SEOBNRv1.
702  *
703  * The binary data files are available at https://dcc.ligo.org/T1400701-v1.
704  * Put the untared data into a location in your LAL_DATA_PATH.
705  *
706  * @note Note that due to its construction the iFFT of the ROM has a small (~ 20 M) offset
707  * in the peak time that scales with total mass as compared to the time-domain SEOBNRv1 model.
708  *
709  * @note Parameter ranges:
710  * * q <= 10
711  * * -1 <= chi_i <= 0.6
712  * * Mtot >= 12Msun
713  *
714  * Aligned component spins chi1, chi2.
715  * Asymmetric mass-ratio q = max(m1/m2, m2/m1).
716  * Total mass Mtot.
717  *
718  * @{
719  */
720 
721 
722 /**
723  * Compute waveform in LAL format at specified frequencies for the SEOBNRv1_ROM_DoubleSpin model.
724  *
725  * XLALSimIMRSEOBNRv1ROMDoubleSpin() returns the plus and cross polarizations as a complex
726  * frequency series with equal spacing deltaF and contains zeros from zero frequency
727  * to the starting frequency and zeros beyond the cutoff frequency in the ringdown.
728  *
729  * In contrast, XLALSimIMRSEOBNRv1ROMDoubleSpinFrequencySequence() returns a
730  * complex frequency series with entries exactly at the frequencies specified in
731  * the sequence freqs (which can be unequally spaced). No zeros are added.
732  *
733  * If XLALSimIMRSEOBNRv1ROMDoubleSpinFrequencySequence() is called with frequencies that
734  * are beyond the maxium allowed geometric frequency for the ROM, zero strain is returned.
735  * It is not assumed that the frequency sequence is ordered.
736  *
737  * This function is designed as an entry point for reduced order quadratures.
738  */
740  struct tagCOMPLEX16FrequencySeries **hptilde, /**< Output: Frequency-domain waveform h+ */
741  struct tagCOMPLEX16FrequencySeries **hctilde, /**< Output: Frequency-domain waveform hx */
742  const REAL8Sequence *freqs, /**< Frequency points at which to evaluate the waveform (Hz), need to be strictly monotonically increasing */
743  REAL8 phiRef, /**< Orbital phase at reference time */
744  REAL8 fRef, /**< Reference frequency (Hz); 0 defaults to fLow */
745  REAL8 distance, /**< Distance of source (m) */
746  REAL8 inclination, /**< Inclination of source (rad) */
747  REAL8 m1SI, /**< Mass of companion 1 (kg) */
748  REAL8 m2SI, /**< Mass of companion 2 (kg) */
749  REAL8 chi1, /**< Dimensionless aligned component spin 1 */
750  REAL8 chi2) /**< Dimensionless aligned component spin 2 */
751 {
752  /* Internally we need m1 > m2, so change around if this is not the case */
753  if (m1SI < m2SI) {
754  /* Swap m1 and m2 */
755  double m1temp = m1SI;
756  double chi1temp = chi1;
757  m1SI = m2SI;
758  chi1 = chi2;
759  m2SI = m1temp;
760  chi2 = chi1temp;
761  }
762 
763  /* Get masses in terms of solar mass */
764  double mass1 = m1SI / LAL_MSUN_SI;
765  double mass2 = m2SI / LAL_MSUN_SI;
766  double Mtot = mass1+mass2;
767  double q = mass2 / mass1;
768  if(q<1.0) q=1./q;
769  /* Total mass in seconds */
770  double Mtot_sec = Mtot * LAL_MTSUN_SI;
771 
772  // Load ROM data if not loaded already
773 #ifdef LAL_PTHREAD_LOCK
774  (void) pthread_once(&SEOBNRv1ROMDoubleSpin_is_initialized, SEOBNRv1ROMDoubleSpin_Init_LALDATA);
775 #else
777 #endif
778 
779  if(!SEOBNRv1ROMDoubleSpin_IsSetup()) XLAL_ERROR(XLAL_EFAILED,"Error setting up SEOBNRv1ROMDoubleSpin - check your $LAL_DATA_PATH\n");
780 
781  // Call the internal core function with deltaF = 0 to indicate that freqs is non-uniformly
782  // spaced and we want the strain only at these frequencies
783  int retcode = SEOBNRv1ROMDoubleSpinCore(hptilde, hctilde,
784  phiRef, fRef, distance, inclination, Mtot_sec, q, chi1, chi2, freqs, 0);
785 
786  return(retcode);
787 }
788 
789 /**
790  * Compute waveform in LAL format for the SEOBNRv1_ROM_DoubleSpin model.
791  *
792  * Returns the plus and cross polarizations as a complex frequency series with
793  * equal spacing deltaF and contains zeros from zero frequency to the starting
794  * frequency fLow and zeros beyond the cutoff frequency fHigh to the next power of 2 in
795  * the size of the frequency series.
796  */
798  struct tagCOMPLEX16FrequencySeries **hptilde, /**< Output: Frequency-domain waveform h+ */
799  struct tagCOMPLEX16FrequencySeries **hctilde, /**< Output: Frequency-domain waveform hx */
800  REAL8 phiRef, /**< Orbital phase at reference frequency */
801  REAL8 deltaF, /**< Sampling frequency (Hz) */
802  REAL8 fLow, /**< Starting GW frequency (Hz) */
803  REAL8 fHigh, /**< End frequency; 0 defaults to Mf=0.14 */
804  REAL8 fRef, /**< Reference frequency (Hz); 0 defaults to fLow */
805  REAL8 distance, /**< Distance of source (m) */
806  REAL8 inclination, /**< Inclination of source (rad) */
807  REAL8 m1SI, /**< Mass of companion 1 (kg) */
808  REAL8 m2SI, /**< Mass of companion 2 (kg) */
809  REAL8 chi1, /**< Dimensionless aligned component spin 1 */
810  REAL8 chi2) /**< Dimensionless aligned component spin 2 */
811 {
812  /* Internally we need m1 > m2, so change around if this is not the case */
813  if (m1SI < m2SI)
814  {
815  /* Swap m1 and m2 */
816  double m1temp = m1SI;
817  double chi1temp = chi1;
818  m1SI = m2SI;
819  chi1 = chi2;
820  m2SI = m1temp;
821  chi2 = chi1temp;
822  }
823 
824  /* Get masses in terms of solar mass */
825  double mass1 = m1SI / LAL_MSUN_SI;
826  double mass2 = m2SI / LAL_MSUN_SI;
827  double Mtot = mass1+mass2;
828  double q = mass2 / mass1;
829  if(q<1.0) q=1./q;
830  /* Total mass in seconds */
831  double Mtot_sec = Mtot * LAL_MTSUN_SI;
832 
833  if(fRef==0.0)
834  fRef=fLow;
835 
836  // Load ROM data if not loaded already
837 #ifdef LAL_PTHREAD_LOCK
838  (void) pthread_once(&SEOBNRv1ROMDoubleSpin_is_initialized, SEOBNRv1ROMDoubleSpin_Init_LALDATA);
839 #else
841 #endif
842 
843  if(!SEOBNRv1ROMDoubleSpin_IsSetup()) XLAL_ERROR(XLAL_EFAILED,"Error setting up SEOBNRv1ROMDoubleSpin data - check your $LAL_DATA_PATH\n");
844  // Use fLow, fHigh, deltaF to compute freqs sequence
845  // Instead of building a full sequency we only transfer the boundaries and let
846  // the internal core function do the rest (and properly take care of corner cases).
848  freqs->data[0] = fLow;
849  freqs->data[1] = fHigh;
850 
851  int retcode = SEOBNRv1ROMDoubleSpinCore(hptilde, hctilde,
852  phiRef, fRef, distance, inclination, Mtot_sec, q, chi1, chi2, freqs, deltaF);
853 
855 
856  return(retcode);
857 }
858 
859 /** @} */
860 /** @} */
861 
862 /* Setup SEOBNRv1ROMDoubleSpin model using data files installed in $LAL_DATA_PATH
863  */
865 {
866  if (SEOBNRv1ROMDoubleSpin_IsSetup()) return;
867 
868  // If we find one ROM datafile in a directory listed in LAL_DATA_PATH,
869  // then we expect the remaining datafiles to also be there.
870  char datafile[] = "SEOBNRv1ROM_DS_Phase_ciall.dat";
871 
872  char *path = XLAL_FILE_RESOLVE_PATH(datafile);
873  if (path==NULL)
874  XLAL_ERROR_VOID(XLAL_EIO, "Unable to resolve data file %s in $LAL_DATA_PATH\n", datafile);
875  char *dir = dirname(path);
876  int ret = SEOBNRv1ROMDoubleSpin_Init(dir);
877  XLALFree(path);
878 
879  if(ret!=XLAL_SUCCESS)
880  XLAL_ERROR_VOID(XLAL_FAILURE, "Unable to find SEOBNRv1ROMDoubleSpin data files in $LAL_DATA_PATH\n");
881 }
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 const double gA[]
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)
int s
Definition: bh_qnmode.c:137
double i
Definition: bh_ringdown.c:118
double e
Definition: bh_ringdown.c:117
sigmaKerr data[0]
#define XLAL_FILE_RESOLVE_PATH(fname)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_MTSUN_SI
#define LAL_MRSUN_SI
double complex COMPLEX16
double REAL8
uint32_t UINT4
void * XLALCalloc(size_t m, size_t n)
void XLALFree(void *p)
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.
static const INT4 m
static const INT4 q
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(...)
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EDOM
XLAL_EIO
XLAL_EFAILED
XLAL_FAILURE
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
path
int N
int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
REAL8 * data
gsl_bspline_workspace * bwx
gsl_bspline_workspace * bwz
gsl_bspline_workspace * bwy