Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-8a6b96f
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
69static 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
88static 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
113static pthread_once_t SEOBNRv1ROMDoubleSpin_is_initialized = PTHREAD_ONCE_INIT;
114#endif
115
116/*************** type definitions ******************/
117
118typedef 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};
133typedef struct tagSEOBNRROMdataDS SEOBNRROMdataDS;
134
135static SEOBNRROMdataDS __lalsim_SEOBNRv1ROMDS_data;
136
137typedef 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
147static void SEOBNRv1ROMDoubleSpin_Init_LALDATA(void);
148static int SEOBNRv1ROMDoubleSpin_Init(const char dir[]);
149static bool SEOBNRv1ROMDoubleSpin_IsSetup(void);
150
151static int SEOBNRROMdataDS_Init(SEOBNRROMdataDS *romdata, const char dir[]);
152static void SEOBNRROMdataDS_Cleanup(SEOBNRROMdataDS *romdata);
153
154static void SEOBNRROMdataDS_coeff_Init(SEOBNRROMdataDS_coeff **romdatacoeff);
156
157static size_t NextPow2(const size_t n);
158static void SplineData_Destroy(SplineData *splinedata);
159static void SplineData_Init(SplineData **splinedata);
160
161static int read_vector(const char dir[], const char fname[], gsl_vector *v);
162static int read_matrix(const char dir[], const char fname[], gsl_matrix *m);
163
164static 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
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*/
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 */
208static int SEOBNRv1ROMDoubleSpin_Init(const char dir[]) {
210 XLALPrintError("Error: SEOBNRROMdata was already set up!");
212 }
213
215
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 */
227 return true;
228 else
229 return false;
230}
231
232// Read binary ROM data for basis functions and coefficients
233static 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
244static 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
301static 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 */
358static 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 */
388static 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 */
419static 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
REAL8 * data
gsl_bspline_workspace * bwx
gsl_bspline_workspace * bwz
gsl_bspline_workspace * bwy