LALSimulation  5.4.0.1-fe68b98
LALSimInspiralSpinTaylor.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 E. Ochsner, 2014 A. Klein, 2015 R. Sturani
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with with program; see the file COPYING. If not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA 02110-1301 USA
18  */
19 
20 #include <math.h>
21 #include <lal/Units.h>
22 #include <lal/LALConstants.h>
23 #include <lal/LALSimInspiral.h>
24 #include <lal/LALAdaptiveRungeKuttaIntegrator.h>
25 #include <lal/TimeSeries.h>
26 #include <lal/FrequencySeries.h>
27 #include "check_series_macros.h"
29 #include <lal/XLALGSL.h>
30 
31 #define XLAL_BEGINGSL \
32  { \
33  gsl_error_handler_t *saveGSLErrorHandler_; \
34  saveGSLErrorHandler_ = gsl_set_error_handler_off();
35 
36 #define XLAL_ENDGSL \
37  gsl_set_error_handler( saveGSLErrorHandler_ ); \
38  }
39 
40 /* use error codes above 1024 to avoid conflicts with GSL */
41 #define LALSIMINSPIRAL_ST_TEST_ENERGY 1025
42 #define LALSIMINSPIRAL_ST_TEST_OMEGADOUBLEDOT 1026
43 #define LALSIMINSPIRAL_ST_TEST_COORDINATE 1027
44 #define LALSIMINSPIRAL_ST_TEST_OMEGANAN 1028
45 #define LALSIMINSPIRAL_ST_TEST_FREQBOUND 1029
46 #define LALSIMINSPIRAL_ST_DERIVATIVE_OMEGANONPOS 1030
47 #define LALSIMINSPIRAL_ST_TEST_LARGEV 1031
48 
49 /* (2x) Highest available PN order - UPDATE IF NEW ORDERS ADDED!!*/
50 #define LAL_MAX_PN_ORDER 8
51 /* Number of variables used for precessing waveforms */
52 #define LAL_NUM_ST4_VARIABLES 14
53 /* absolute and relative tolerance for adaptive Runge-Kutta ODE integrator */
54 /* 1.e-06 is too large for end of 1.4--1.4 M_sun BNS inspiral */
55 /* (phase difference at end will be ~10% of GW cycle). */
56 /* 1.e-12 is used so last data point isn't nan for 6PN tidal, */
57 /* since larger values probably cause larger step sizes. */
58 #define LAL_ST4_ABSOLUTE_TOLERANCE 1.e-12
59 #define LAL_ST4_RELATIVE_TOLERANCE 1.e-12
60 
61 /* Macro functions to rotate the components of a vector about an axis */
62 #define ROTATEZ(angle, vx, vy, vz)\
63  tmp1 = vx*cos(angle) - vy*sin(angle);\
64  tmp2 = vx*sin(angle) + vy*cos(angle);\
65  vx = tmp1;\
66  vy = tmp2
67 
68 #define ROTATEY(angle, vx, vy, vz)\
69  tmp1 = vx*cos(angle) + vz*sin(angle);\
70  tmp2 = - vx*sin(angle) + vz*cos(angle);\
71  vx = tmp1;\
72  vz = tmp2
73 
74 
75 static int XLALSimInspiralVectorCrossProduct(REAL8 **vout, REAL8 v1x, REAL8 v1y, REAL8 v1z, REAL8 v2x, REAL8 v2y, REAL8 v2z){
76  (*vout) = (double *) LALMalloc(sizeof(double) * 3);
77  (*vout)[0]=v1y*v2z-v1z*v2y;
78  (*vout)[1]=v1z*v2x-v1x*v2z;
79  (*vout)[2]=v1x*v2y-v1y*v2x;
80  return XLAL_SUCCESS;
81 }
82 
83 static REAL8 cdot(REAL8 v1x, REAL8 v1y, REAL8 v1z, REAL8 v2x, REAL8 v2y, REAL8 v2z){
84  return v1x*v2x+v1y*v2y+v1z*v2z;
85 }
86 
88  return vx*vx+vy*vy+vz*vz;
89 }
90 
91 
92 /* Declarations of static functions - defined below */
94  const double values[], double dvalues[], void *mparams);
96  const double values[], double dvalues[], void *mparams);
98  const double values[], double dvalues[], void *mparams);
100  REAL8Array **yout, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fEnd, REAL8 s1x,
101  REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx,
102  REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1,
103  REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2,
105  Approximant approx);
108  REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0,
109  REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x,
110  REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx,
111  REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1,
112  REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2,
113  LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, Approximant approx, INT4 phiRefAtEnd);
114 
115 
116 /* Appends the start and end time series together. Frees start and end before
117  * returning a pointer to the result. The last point of start can be the
118  * first point of end, and if so it removes the duplicate point.
119  */
121  REAL8Array *end, REAL8Array* combined) {
122  UINT4 len1 = start->dimLength->data[1];
123  UINT4 len2 = end->dimLength->data[1];
124  UINT4 lenTot;
125 
126  UINT4 nParams = start->dimLength->data[0];
127 
128  if(end->dimLength->data[0] != nParams)
129  {
130  XLALPrintError("XLAL Error - %s: cannot append series with different numbers of parameters %d and %d.\n", __func__, nParams, end->dimLength->data[0]);
132  }
133 
134  UINT4 i;
135  UINT4 doRemove;
136 
137  if(start->data[len1-1] != end->data[0])
138  {
139  doRemove = 0;
140  lenTot = len1 + len2;
141  }
142  else
143  {
144  doRemove = 1;
145  lenTot = len1 + len2 - 1;
146  }
147  combined = XLALCreateREAL8ArrayL(2, nParams, lenTot);
148 
149  for(i = 0; i < nParams; i++)
150  {
151  memcpy(&(combined->data[i*lenTot]), &(start->data[i*len1]), sizeof(REAL8)*len1);
152  if(doRemove)
153  {
154  memcpy(&(combined->data[i*lenTot + len1]), &(end->data[i*len2+1]), sizeof(REAL8)*(len2-1));
155  if(i && start->data[i*len1 + len1-1] != end->data[i*len2])
156  {
157  XLALPrintWarning("XLAL Warning - %s: time series inconsistent: parameter %d is %f or %f at the same time.\n", __func__, i, start->data[i*len1 + len1-1], end->data[i*len2]);
158  }
159  }
160  else
161  {
162  memcpy(&(combined->data[i*lenTot + len1]), &(end->data[i*len2]), sizeof(REAL8)*(len2));
163  }
164  }
165 
166  XLALDestroyREAL8Array(start);
168 
169  return combined;
170 }
171 
172 
173 /* Remove duplicates if the time is constant.
174  The time has to be the first parameter.
175  */
177  UINT4 lenTot = series->dimLength->data[1];
178  UINT4 newLen = lenTot;
179 
180  UINT4 nParams = series->dimLength->data[0];
181  UINT4 i, j, k;
182  UINT4 nDuplicates;
183 
184  if(nParams < 1)
185  {
186  XLALPrintError("XLAL Error - %s: bad time series, has %d parameters.\n", __func__, nParams);
188  }
189 
190  REAL8Array *temp;
191  temp = XLALCreateREAL8ArrayL(2, nParams, lenTot);
192 
193  REAL8Array *mean;
194  mean = XLALCreateREAL8ArrayL(1, nParams);
195 
196  for(i = 0, k = 0; i < lenTot; i++, k++)
197  {
198  nDuplicates = 0;
199  if(i < lenTot && series->data[i] == series->data[i+1])
200  {
201  for(j = 1; j < nParams; j++)
202  {
203  mean->data[j] = series->data[j*lenTot + i];
204  }
205  while(i < lenTot && series->data[i] == series->data[i+1])
206  {
207  nDuplicates++;
208  i++;
209  mean->data[0] = series->data[i];
210  for(j = 1; j < nParams; j++)
211  {
212  mean->data[j] += series->data[j*lenTot + i];
213  }
214  }
215  for(j = 1; j < nParams; j++)
216  {
217  mean->data[j] /= nDuplicates+1;
218  }
219  newLen -= nDuplicates;
220  for(j = 0; j < nParams; j++)
221  {
222  temp->data[j*lenTot + k] = mean->data[j];
223  }
224  }
225  else
226  {
227  for(j = 0; j < nParams; j++)
228  {
229  temp->data[j*lenTot + k] = series->data[j*lenTot + i];
230  }
231  }
232  }
233 
234  if(newLen != lenTot)
235  {
236  XLALDestroyREAL8Array(series);
237  series = XLALCreateREAL8ArrayL(2, nParams, newLen);
238  for(j = 0; j < nParams; j++)
239  {
240  memcpy(&series->data[j*newLen], &temp->data[j*lenTot], sizeof(REAL8)*newLen);
241  }
242  }
243 
244  XLALDestroyREAL8Array(temp);
245  XLALDestroyREAL8Array(mean);
246  return series;
247 }
248 
249 /* Setup coefficients of the energy function and
250  * of the spin derivative equations, which are common
251  * to all members of the SpinTaylor family.
252  */
254  XLALSimInspiralSpinTaylorTxCoeffs **params, /**< OUTPUT */
255  const REAL8 m1_SI, /**< mass of body 1 (kg) */
256  const REAL8 m2_SI, /**< mass of body 2 (kg) */
257  const REAL8 fStart, /**< Starting GW freq. (Hz) */
258  const REAL8 fEnd, /**< Ending GW freq. (Hz), 0 means integrate forwards as far as possible */
259  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
260  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
261  const INT4 phaseO, /**< twice PN order of spin effects */
262  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
263  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
264  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
265  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
266  const INT4 lscorr, /**< flag to include spin corrections to orbital angular momentum */
267  const INT4 phenomtp /**< flag for using spinO=7 and not spinO=6 terms with orbital-averaged quantities for phenomtphm approx */)
268 {
269 
270  REAL8 m1=m1_SI/LAL_MSUN_SI;
271  REAL8 m2=m2_SI/LAL_MSUN_SI;
272  REAL8 M=m1+m2;
273  REAL8 m1M=m1/M;
274  REAL8 m2M=m2/M;
275  REAL8 eta=m1M*m2M;
276  (*params)->wdotnewt = XLALSimInspiralTaylorT4wdot_0PNCoeff(eta);
277  (*params)->M = M;
278  (*params)->Mchirp = M*pow(eta,0.6);
279  (*params)->m1M = m1M;
280  (*params)->m2M = m2M;
281  (*params)->eta = eta;
282  (*params)->fStart = fStart;
283  (*params)->fEnd = fEnd;
284  (*params)->phaseO = phaseO;
285  (*params)->spinO = spinO;
286  (*params)->tideO = tideO;
287  (*params)->lscorr = lscorr;
288  (*params)->phenomtp = phenomtp;
289 
290  /* Set the non-dynamical coefficients of spin-independent
291  * Energy terms
292  */
293  switch( (*params)->phaseO ) {
294  case -1: /* highest available PN order */
295  case 8:
296  /* case LAL_PNORDER_THREE_POINT_FIVE: */
297  case 7:
298  (*params)->Ecoeff[7] = 0.;
299 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
300  __attribute__ ((fallthrough));
301 #endif
302  /* case LAL_PNORDER_THREE: */
303  case 6:
304  (*params)->Ecoeff[6] = XLALSimInspiralPNEnergy_6PNCoeff(eta);
305 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
306  __attribute__ ((fallthrough));
307 #endif
308  /* case LAL_PNORDER_TWO_POINT_FIVE: */
309  case 5:
310  (*params)->Ecoeff[5] = 0.;
311 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
312  __attribute__ ((fallthrough));
313 #endif
314  /* case LAL_PNORDER_TWO: */
315  case 4:
316  (*params)->Ecoeff[4] = XLALSimInspiralPNEnergy_4PNCoeff(eta);
317 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
318  __attribute__ ((fallthrough));
319 #endif
320  /*case LAL_PNORDER_ONE_POINT_FIVE:*/
321  case 3:
322  (*params)->Ecoeff[3] = 0.;
323 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
324  __attribute__ ((fallthrough));
325 #endif
326  /*case LAL_PNORDER_ONE:*/
327  case 2:
328  (*params)->Ecoeff[2] = XLALSimInspiralPNEnergy_2PNCoeff(eta);
329 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
330  __attribute__ ((fallthrough));
331 #endif
332  /*case LAL_PNORDER_HALF:*/
333  case 1:
334  (*params)->Ecoeff[1] = 0.;
335 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
336  __attribute__ ((fallthrough));
337 #endif
338  /*case LAL_PNORDER_NEWTONIAN:*/
339  case 0:
340  (*params)->Ecoeff[0] = 1.;
341  break;
342  default:
343  XLALPrintError("XLAL Error - %s: Invalid phase. PN order %d\n",
344  __func__, (*params)->phaseO );
346  break;
347  }
348 
349  /* Set the non-dynamical coefficients of spin-dependent
350  * Energy terms
351  */
352  switch( (*params)->spinO )
353  {
356  // 3.5PN spin-orbit
357  // For historical reasons phenomtp uses NNNNL spin-orbit terms but not NNNL spin^2 terms
358  if ( phenomtp ) {
359  // Energy coefficients
360  (*params)->E7S1O = XLALSimInspiralPNEnergy_7PNSOCoeff(m1M); // Coefficient of S1.LN
361  (*params)->E7S2O = XLALSimInspiralPNEnergy_7PNSOCoeff(m2M); // Coefficient of S2.LN
362  // Sdot coefficients
363  (*params)->S1dot7S2 = XLALSimInspiralSpinDot_7PNCoeff(m1M); // Coefficient of S2 x S1
364  (*params)->S2dot7S1 = XLALSimInspiralSpinDot_7PNCoeff(m2M); // Coefficient of S1 x S2
365  }
366 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
367  __attribute__ ((fallthrough));
368 #endif
370  // 3PN spin-spin
371  // For historical reasons phenomtp uses NNNNL spin-orbit terms but not NNNL spin^2 terms
372  if (!(phenomtp)) {
373  // Energy orbit-averaged coefficients
374  (*params)->E6S1S2Avg = XLALSimInspiralPNEnergy_6PNS1S2CoeffAvg(eta); // Coefficient of S1.S2
375  (*params)->E6S1OS2OAvg = XLALSimInspiralPNEnergy_6PNS1OS2OCoeffAvg(eta); // Coefficient of S1.LN S2.LN
376  (*params)->E6S1S1Avg = XLALSimInspiralPNEnergy_6PNS1S1CoeffAvg(m1M); // Coefficient of S1.S1
377  (*params)->E6S2S2Avg = XLALSimInspiralPNEnergy_6PNS1S1CoeffAvg(m2M); // Coefficient of S2.S2
378  (*params)->E6S1OS1OAvg = XLALSimInspiralPNEnergy_6PNS1OS1OCoeffAvg(m1M); // Coefficient of (S1.LN)^2
379  (*params)->E6S2OS2OAvg = XLALSimInspiralPNEnergy_6PNS1OS1OCoeffAvg(m2M); // Coefficient of (S2.LN)^2
380  (*params)->E6QMS1S1Avg = quadparam1 * XLALSimInspiralPNEnergy_6PNQMS1S1CoeffAvg(m1M); // Coefficient of quadrupole-monopole S1-squared
381  (*params)->E6QMS2S2Avg = quadparam2 * XLALSimInspiralPNEnergy_6PNQMS1S1CoeffAvg(m2M); // Coefficient of quadrupole-monopole S2-squared
382  (*params)->E6QMS1OS1OAvg = quadparam1 * XLALSimInspiralPNEnergy_6PNQMS1OS1OCoeffAvg(m1M); // Coefficient of quadrupole-monopole S1.L-squared
383  (*params)->E6QMS2OS2OAvg = quadparam2 * XLALSimInspiralPNEnergy_6PNQMS1OS1OCoeffAvg(m2M); // Coefficient of quadrupole-monopole S2.L-squared
384  // Sdot orbit-averaged coefficients
385  (*params)->S1dot6S2Avg = XLALSimInspiralSpinDot_6PNS2CoeffAvg(m1M); // Avg-Coefficient of S2xS1
386  (*params)->S2dot6S1Avg = XLALSimInspiralSpinDot_6PNS2CoeffAvg(m2M); // Avg-Coefficient of S1xS2
387  (*params)->S1dot6S2OAvg = XLALSimInspiralSpinDot_6PNS2OCoeffAvg(m1M); // Avg-Coefficient of L.S2 LxS1
388  (*params)->S1dot6S1OAvg = XLALSimInspiralSpinDot_6PNS1OCoeffAvg(m1M); // Avg-Coefficient of L.S1 LxS1
389  (*params)->S2dot6S1OAvg = XLALSimInspiralSpinDot_6PNS2OCoeffAvg(m2M); // Avg-Coefficient of L.S1 LxS2
390  (*params)->S2dot6S2OAvg = XLALSimInspiralSpinDot_6PNS1OCoeffAvg(m2M); // Avg-Coefficient of L.S2 LxS2
391  (*params)->S1dot6QMS1OAvg = quadparam1 * XLALSimInspiralSpinDot_6PNQMSOCoeffAvg(m1M); // Avg-Coefficient of QM L.S1 LxS1
392  (*params)->S2dot6QMS2OAvg = quadparam2 * XLALSimInspiralSpinDot_6PNQMSOCoeffAvg(m2M); // Avg-Coefficient of QM L.S2 LxS2
393  (*params)->omegashiftS1 = XLALSimInspiralLDot_3PNSOCoeff(m1M);
394  (*params)->omegashiftS2 = XLALSimInspiralLDot_3PNSOCoeff(m2M);
395  }
396 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
397  __attribute__ ((fallthrough));
398 #endif
400  // Energy coefficients
401  (*params)->E5S1O = XLALSimInspiralPNEnergy_5PNSOCoeff(m1M); // Coefficient of S1.LN
402  (*params)->E5S2O = XLALSimInspiralPNEnergy_5PNSOCoeff(m2M); // Coefficient of S2.LN
403  // Sdot coefficients
404  (*params)->S1dot5 = XLALSimInspiralSpinDot_5PNCoeff(m1M); // Coefficient of LNxS1
405  (*params)->S2dot5 = XLALSimInspiralSpinDot_5PNCoeff(m2M); // Coefficient of LNxS2
406 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
407  __attribute__ ((fallthrough));
408 #endif
410  /* One considers averaged spin^2 terms according to
411  * <n^i n^j> = 1/2(delta^{ij}-L^iL^j) +O(v^3), with n^i the unit
412  * vector pointing from BH 1 to BH 2.
413  * Such average introduce a v^3 error with respect to the leading order
414  * the spins enter at,
415  * see e.g. app. B of PRD80 (2009) 044010, arXiv:0812.4413.
416  */
417  // 2PN spin-spin averaged terms
418  (*params)->E4S1S2Avg = XLALSimInspiralPNEnergy_4PNS1S2CoeffAvg(eta); // Coefficient of S1.S2
419  (*params)->E4S1OS2OAvg = XLALSimInspiralPNEnergy_4PNS1OS2OCoeffAvg(eta); // Coefficient of S1.LN S2.LN
420  // 2PN quadrupole-monopole averaged self-spin terms
421  (*params)->E4QMS1S1Avg = quadparam1 * XLALSimInspiralPNEnergy_4PNQMS1S1CoeffAvg(m1M); // Coefficient of quad-monop term S1.S1
422  (*params)->E4QMS1OS1OAvg = quadparam1 * XLALSimInspiralPNEnergy_4PNQMS1OS1OCoeffAvg(m1M); // Coefficient of quad-monop term (S1.LN)^2
423  (*params)->E4QMS2S2Avg = quadparam2 * XLALSimInspiralPNEnergy_4PNQMS1S1CoeffAvg(m2M); // Coefficient of quad-monop term S2.S2
424  (*params)->E4QMS2OS2OAvg = quadparam2 * XLALSimInspiralPNEnergy_4PNQMS1OS1OCoeffAvg(m2M); // Coefficient of quad-monop term (S2.LN)^2
425  // Spin derivative
426  (*params)->S1dot4S2Avg = XLALSimInspiralSpinDot_4PNS2CoeffAvg; // Coefficient of S2xS1 in S1dot and S1xS2 in S2dot
427  (*params)->S1dot4S2OAvg = XLALSimInspiralSpinDot_4PNS2OCoeffAvg; // Coefficient of (LN.S1) S2xS1 in S1dot and (LN.S2) S1xS2 in S2dot
428  (*params)->S1dot4QMS1OAvg = quadparam1 * XLALSimInspiralSpinDot_4PNQMSOCoeffAvg(m1M); // Coefficient of quad-monop. term (S1.LN) LNxS1
429  (*params)->S2dot4QMS2OAvg = quadparam2 * XLALSimInspiralSpinDot_4PNQMSOCoeffAvg(m2M); // Coefficient of quad-monop. term (S2.LN) LNxS2
430 
431 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
432  __attribute__ ((fallthrough));
433 #endif
435  (*params)->E3S1O = XLALSimInspiralPNEnergy_3PNSOCoeff(m1M); // Coefficient of S1.LN
436  (*params)->E3S2O = XLALSimInspiralPNEnergy_3PNSOCoeff(m2M); // Coefficient of S2.LN
437  (*params)->S1dot3 = XLALSimInspiralSpinDot_3PNCoeff(m1M); // Coefficient of LNxS1
438  (*params)->S2dot3 = XLALSimInspiralSpinDot_3PNCoeff(m2M); // Coefficient of LNxS2
439 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
440  __attribute__ ((fallthrough));
441 #endif
445  break;
446  default:
447  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
448  __func__, (*params)->spinO );
450  break;
451  }
452 
453  switch( (*params)->tideO )
454  {
457  (*params)->Etidal12 = lambda1 * XLALSimInspiralPNEnergy_12PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralPNEnergy_12PNTidalCoeff(m2M);
458 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
459  __attribute__ ((fallthrough));
460 #endif
462  (*params)->Etidal10 = lambda1 * XLALSimInspiralPNEnergy_10PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralPNEnergy_10PNTidalCoeff(m2M);
463 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
464  __attribute__ ((fallthrough));
465 #endif
467  break;
468  default:
469  XLALPrintError("XLAL Error - %s: Invalid tidal PN order %d\n",
470  __func__, (*params)->tideO );
472  break;
473  }
474 
475  return XLAL_SUCCESS;
476 } // End of XLALSimSpinTaylorEnergySpinDerivativeSetup()
477 
478 /**
479  * Function computing spin precession equations, common to all member of the SpinTaylor family.
480  * Orbit averaged dynamics.
481  */
482 
484  REAL8 *dLNhy,
485  REAL8 *dLNhz,
486  REAL8 *dE1x,
487  REAL8 *dE1y,
488  REAL8 *dE1z,
489  REAL8 *dS1x,
490  REAL8 *dS1y,
491  REAL8 *dS1z,
492  REAL8 *dS2x,
493  REAL8 *dS2y,
494  REAL8 *dS2z,
495  const REAL8 v,
496  const REAL8 LNhx,
497  const REAL8 LNhy,
498  const REAL8 LNhz,
499  const REAL8 E1x,
500  const REAL8 E1y,
501  const REAL8 E1z,
502  const REAL8 S1x,
503  const REAL8 S1y,
504  const REAL8 S1z,
505  const REAL8 S2x,
506  const REAL8 S2y,
507  const REAL8 S2z,
508  const REAL8 LNhdotS1,
509  const REAL8 LNhdotS2,
511 {
512 
513  *dLNhx=0.;
514  *dLNhy=0.;
515  *dLNhz=0.;
516  *dE1x=0.;
517  *dE1y=0.;
518  *dE1z=0.;
519  *dS1x=0.;
520  *dS1y=0.;
521  *dS1z=0.;
522  *dS2x=0.;
523  *dS2y=0.;
524  *dS2z=0.;
525  INT4 lscorr=params->lscorr;
526 
527  REAL8 dLNhatx=0.; // Derivative of the Newtonian angular momentum unit vector
528  REAL8 dLNhaty=0.;
529  REAL8 dLNhatz=0.;
530 
531  const REAL8 eta=params->eta;
532  const REAL8 LN0mag=eta/v;
533  REAL8 LNmag=LN0mag;
534 
535  const REAL8 cS1 = XLALSimInspiralL_3PNSicoeffAvg(params->m1M);
536  const REAL8 cS1L = XLALSimInspiralL_3PNSiLcoeffAvg(params->m1M);
537  const REAL8 cS2 = XLALSimInspiralL_3PNSicoeffAvg(params->m2M);
538  const REAL8 cS2L = XLALSimInspiralL_3PNSiLcoeffAvg(params->m2M);
539 
540  /*
541  * dS1
542  * d S_1 / d \hat{t} = M * d S_1 / dt = \Omega_{S1,S2,LN,v} x S_1
543  * However, the papers referenced below uses spin variables which are M^2 times our spins
544  */
545 
546  if ( (params->spinO>=3) || (params->spinO<0) ) {
547  /* dS1,2 leading terms: eq. (8) of gr-qc/0405090.*/
548  const REAL8 v2=v*v;
549  const REAL8 omega=v2*v;
550  const REAL8 v5=omega*v2;
551 
552  REAL8 *LNhcS1=NULL;
553  XLALSimInspiralVectorCrossProduct(&LNhcS1,LNhx,LNhy,LNhz,S1x,S1y,S1z);
554  const REAL8 dS1xL = params->S1dot3 * v5 * LNhcS1[0];
555  const REAL8 dS1yL = params->S1dot3 * v5 * LNhcS1[1];
556  const REAL8 dS1zL = params->S1dot3 * v5 * LNhcS1[2];
557 
558  REAL8 *LNhcS2=NULL;
559  XLALSimInspiralVectorCrossProduct(&LNhcS2,LNhx,LNhy,LNhz,S2x,S2y,S2z);
560  const REAL8 dS2xL = params->S2dot3 * v5 * LNhcS2[0];
561  const REAL8 dS2yL = params->S2dot3 * v5 * LNhcS2[1];
562  const REAL8 dS2zL = params->S2dot3 * v5 * LNhcS2[2];
563 
564  *dS1x =dS1xL;
565  *dS1y =dS1yL;
566  *dS1z =dS1zL;
567 
568  *dS2x =dS2xL;
569  *dS2y =dS2yL;
570  *dS2z =dS2zL;
571 
572  const REAL8 dLxL=-(dS1xL+ dS2xL) ;
573  const REAL8 dLyL=-(dS1yL+ dS2yL);
574  const REAL8 dLzL=-(dS1zL+ dS2zL);
575 
576  /* dLNhat should be normalized by dividing by the modulus of LN.
577  * It will be done at the end of this fucntion. */
578  dLNhatx = dLxL;
579  dLNhaty = dLyL;
580  dLNhatz = dLzL;
581 
582  if ( (params->spinO>=4) || (params->spinO<0.) ) {
583  /* dS1,2 NLO term (v x leading), Spin^2 terms */
584  REAL8 omega2=omega*omega;
585  REAL8 *S1cS2= NULL;
586  XLALSimInspiralVectorCrossProduct(&S1cS2,S1x,S1y,S1z,S2x,S2y,S2z);
587  /* S1S2 contribution, see. eq. 4.17 of Phys.Rev. D52 (1995) 821-847, arxiv/gr-qc/9506022 */
588  REAL8 dS1xNL = omega2 * (-params->S1dot4S2Avg * S1cS2[0] + params->S1dot4S2OAvg * LNhdotS2 * LNhcS1[0]);
589  REAL8 dS1yNL = omega2 * (-params->S1dot4S2Avg * S1cS2[1] + params->S1dot4S2OAvg * LNhdotS2 * LNhcS1[1]);
590  REAL8 dS1zNL = omega2 * (-params->S1dot4S2Avg * S1cS2[2] + params->S1dot4S2OAvg * LNhdotS2 * LNhcS1[2]);
591  REAL8 dS2xNL = omega2 * ( params->S1dot4S2Avg * S1cS2[0] + params->S1dot4S2OAvg * LNhdotS1 * LNhcS2[0]);
592  REAL8 dS2yNL = omega2 * ( params->S1dot4S2Avg * S1cS2[1] + params->S1dot4S2OAvg * LNhdotS1 * LNhcS2[1]);
593  REAL8 dS2zNL = omega2 * ( params->S1dot4S2Avg * S1cS2[2] + params->S1dot4S2OAvg * LNhdotS1 * LNhcS2[2]);
594 
595  /* QM S1S1 contribution */
596  dS1xNL += omega2 * params->S1dot4QMS1OAvg * LNhdotS1 * LNhcS1[0]; // v6 terms
597  dS1yNL += omega2 * params->S1dot4QMS1OAvg * LNhdotS1 * LNhcS1[1];
598  dS1zNL += omega2 * params->S1dot4QMS1OAvg * LNhdotS1 * LNhcS1[2];
599 
600  /* QM S2S2 contribution */
601  dS2xNL += omega2 * params->S2dot4QMS2OAvg * LNhdotS2 * LNhcS2[0];
602  dS2yNL += omega2 * params->S2dot4QMS2OAvg * LNhdotS2 * LNhcS2[1];
603  dS2zNL += omega2 * params->S2dot4QMS2OAvg * LNhdotS2 * LNhcS2[2];
604 
605  *dS1x+= dS1xNL;
606  *dS1y+= dS1yNL;
607  *dS1z+= dS1zNL;
608 
609  *dS2x+= dS2xNL;
610  *dS2y+= dS2yNL;
611  *dS2z+= dS2zNL;
612 
613  const REAL8 dLxNL = -(dS1xNL+dS2xNL);
614  const REAL8 dLyNL = -(dS1yNL+dS2yNL);
615  const REAL8 dLzNL = -(dS1zNL+dS2zNL);
616 
617  /* dLNhat should be orthogonal to LNhat
618  * Here dL is not, dLNhat will be projected onto the space
619  * orthogonal to LNhat at the end of this function.
620  */
621  dLNhatx+=dLxNL;
622  dLNhaty+=dLyNL;
623  dLNhatz+=dLzNL;
624 
625  if ( (params->spinO>=5) || (params->spinO<0) ) {
626 
627  /* dLNhat is parallel to dL only until NLO (v x leading),
628  * since up to this order LNhat = Lhat.
629  * at this NNL order we have to include spin dependent terms in the orbital angular momentum.
630  */
631 
632  const REAL8 L1PN=XLALSimInspiralL_2PN(eta);
633  REAL8 v7=omega2*v;
634  LNmag+=LN0mag*v2*L1PN;
635 
636  /* dS1,2 NNLO, eq. 7.8 of Blanchet et al. gr-qc/0605140 */
637  const REAL8 dS1xNNL = params->S1dot5 * v7 * LNhcS1[0]; // v7 terms
638  const REAL8 dS1yNNL = params->S1dot5 * v7 * LNhcS1[1];
639  const REAL8 dS1zNNL = params->S1dot5 * v7 * LNhcS1[2];
640 
641  const REAL8 dS2xNNL = params->S2dot5 * v7 * LNhcS2[0];
642  const REAL8 dS2yNNL = params->S2dot5 * v7 * LNhcS2[1];
643  const REAL8 dS2zNNL = params->S2dot5 * v7 * LNhcS2[2];
644 
645  *dS1x+= dS1xNNL;
646  *dS1y+= dS1yNNL;
647  *dS1z+= dS1zNNL;
648 
649  *dS2x+= dS2xNNL;
650  *dS2y+= dS2yNNL;
651  *dS2z+= dS2zNNL;
652 
653  dLNhatx-= dS1xNNL + dS2xNNL;
654  dLNhaty-= dS1yNNL + dS2yNNL;
655  dLNhatz-= dS1zNNL + dS2zNNL;
656 
657  if (lscorr) {
658  /* At this order only the derivative of the spins are included into
659  * spin-dependent terms of orbital angular momentum.
660  * LO of spin derivative is v^5, derivative \hat L is v^6 at LO.
661  * Spin derivative at leading order are perpendicular to L.
662  */
663  dLNhatx -= eta*v2*( cS1*dS1xL + cS2*dS2xL);
664  dLNhaty -= eta*v2*( cS1*dS1yL + cS2*dS2yL);
665  dLNhatz -= eta*v2*( cS1*dS1zL + cS2*dS2zL);
666  }
667 
668  if ( (params->spinO>=6) || (params->spinO<0) ) {
669 
670  if (!(params->phenomtp)) {
671 
672  REAL8 v8=omega2*v2;
673 
674  REAL8 dS1xN3L=v8*(-params->S1dot6S2Avg*S1cS2[0] + (params->S1dot6S1OAvg*LNhdotS1 + params->S1dot6S2OAvg*LNhdotS2)*LNhcS1[0]);
675  REAL8 dS1yN3L=v8*(-params->S1dot6S2Avg*S1cS2[1] + (params->S1dot6S1OAvg*LNhdotS1 + params->S1dot6S2OAvg*LNhdotS2)*LNhcS1[1]);
676  REAL8 dS1zN3L=v8*(-params->S1dot6S2Avg*S1cS2[2] + (params->S1dot6S1OAvg*LNhdotS1 + params->S1dot6S2OAvg*LNhdotS2)*LNhcS1[2]);
677  REAL8 dS2xN3L=v8*( params->S2dot6S1Avg*S1cS2[0] + (params->S2dot6S1OAvg*LNhdotS1 + params->S2dot6S2OAvg*LNhdotS2)*LNhcS2[0]);
678  REAL8 dS2yN3L=v8*( params->S2dot6S1Avg*S1cS2[1] + (params->S2dot6S1OAvg*LNhdotS1 + params->S2dot6S2OAvg*LNhdotS2)*LNhcS2[1]);
679  REAL8 dS2zN3L=v8*( params->S2dot6S1Avg*S1cS2[2] + (params->S2dot6S1OAvg*LNhdotS1 + params->S2dot6S2OAvg*LNhdotS2)*LNhcS2[2]);
680 
681  // QM S1S1 terms
682  dS1xN3L += v8*(params->S1dot6QMS1OAvg * LNhdotS1 * LNhcS1[0] );
683  dS1yN3L += v8*(params->S1dot6QMS1OAvg * LNhdotS1 * LNhcS1[1] );
684  dS1zN3L += v8*(params->S1dot6QMS1OAvg * LNhdotS1 * LNhcS1[2] );
685 
686  // QM S2S2 terms
687  dS2xN3L += v8*(params->S2dot6QMS2OAvg * LNhdotS2 * LNhcS2[0] );
688  dS2yN3L += v8*(params->S2dot6QMS2OAvg * LNhdotS2 * LNhcS2[1] );
689  dS2zN3L += v8*(params->S2dot6QMS2OAvg * LNhdotS2 * LNhcS2[2] );
690 
691  *dS1x+= dS1xN3L;
692  *dS1y+= dS1yN3L;
693  *dS1z+= dS1zN3L;
694 
695  *dS2x+= dS2xN3L;
696  *dS2y+= dS2yN3L;
697  *dS2z+= dS2zN3L;
698 
699  dLNhatx -= dS1xN3L + dS2xN3L; // v8 terms
700  dLNhaty -= dS1yN3L + dS2yN3L;
701  dLNhatz -= dS1zN3L + dS2zN3L;
702 
703  if (lscorr) {
704  /* Contributions to dLNh coming from the S-dependent
705  * part of L, in particular: dS, dS_l at v6 order.
706  * We omit here terms parallel to LNhat
707  * as they will be projected out at the end.
708  */
709  dLNhatx-=eta*v2*( cS1*dS1xNL + cS2*dS2xNL + (cS1L*LNhdotS1+cS2L*LNhdotS2)*dLxL/LN0mag ); // v8 terms
710  dLNhaty-=eta*v2*( cS1*dS1yNL + cS2*dS2yNL + (cS1L*LNhdotS1+cS2L*LNhdotS2)*dLyL/LN0mag );
711  dLNhatz-=eta*v2*( cS1*dS1zNL + cS2*dS2zNL + (cS1L*LNhdotS1+cS2L*LNhdotS2)*dLzL/LN0mag );
712 
713  }
714 
715  }
716  /* spinO=7 in the orbit averaged case should not be used altogether, it is kept here
717  for use of phenompt approximat for backward compatibility */
718  else {
719  if ( (params->spinO>=7) || (params->spinO<0) ) {
720 
721  const REAL8 L2PN=XLALSimInspiralL_4PN(eta);
722  const REAL8 v4=v2*v2;
723  LNmag+=LN0mag*v4*L2PN;
724  const REAL8 omega3=omega2*omega;
725 
726  // dS1,2 at NNNNLO, eq. 3.4 of Class. Quantum Grav. 30 (2013) 075017, arXiv/1212.5520
727  const REAL8 dS1xN4L = params->S1dot7S2 * omega3 * LNhcS1[0]; //v9 terms
728  const REAL8 dS1yN4L = params->S1dot7S2 * omega3 * LNhcS1[1];
729  const REAL8 dS1zN4L = params->S1dot7S2 * omega3 * LNhcS1[2];
730 
731  const REAL8 dS2xN4L = params->S2dot7S1 * omega3 * LNhcS2[0];
732  const REAL8 dS2yN4L = params->S2dot7S1 * omega3 * LNhcS2[1];
733  const REAL8 dS2zN4L = params->S2dot7S1 * omega3 * LNhcS2[2];
734 
735  *dS1x+= dS1xN4L;
736  *dS1y+= dS1yN4L;
737  *dS1z+= dS1zN4L;
738 
739  *dS2x+= dS2xN4L;
740  *dS2y+= dS2yN4L;
741  *dS2z+= dS2zN4L;
742 
743  dLNhatx -= dS1xN4L + dS2xN4L;
744  dLNhaty -= dS1yN4L + dS2yN4L;
745  dLNhatz -= dS1zN4L + dS2zN4L;
746 
747  }
748  }
749  }
750  }
751  XLALFree(S1cS2);
752  }
753  if (LNhcS1)
754  XLALFree(LNhcS1);
755  if (LNhcS2)
756  XLALFree(LNhcS2);
757  }
758 
759  /* We have computed the derivative of the spin-independent part of the
760  * orbital angular momentum, which is parallel to the Newtonian angular momentum,
761  * we now have to find the precession vector Om.
762  */
763  // First we normalize dLNhat
764  dLNhatx/=LNmag;
765  dLNhaty/=LNmag;
766  dLNhatz/=LNmag;
767  /* Then we compute the precession vector Om=LNhat x dLNhat
768  * Note that component of dLNhat parallel to LNhat does not affect Om */
769  REAL8 *Om=NULL;
770  XLALSimInspiralVectorCrossProduct(&Om,LNhx,LNhy,LNhz,dLNhatx,dLNhaty,dLNhatz);
771  /* Take cross product of Om with LNhat */
772  *dLNhx = -Om[2]*LNhy + Om[1]*LNhz;
773  *dLNhy = -Om[0]*LNhz + Om[2]*LNhx;
774  *dLNhz = -Om[1]*LNhx + Om[0]*LNhy;
775 
776  /* Take cross product of Om with E_1 */
777  *dE1x = -Om[2]*E1y + Om[1]*E1z;
778  *dE1y = -Om[0]*E1z + Om[2]*E1x;
779  *dE1z = -Om[1]*E1x + Om[0]*E1y;
780 
781  XLALFree(Om);Om=NULL;
782 
783  return XLAL_SUCCESS;
784 
785 } /* End of XLALSimInspiralSpinDerivativesAvg() */
786 
787 /**
788  * See arXiv:0907.0700 for TaylorT4 definition.
789  */
791  XLALSimInspiralSpinTaylorTxCoeffs **params, /**< OUTPUT */
792  const REAL8 m1_SI, /**< mass of body 1 (kg) */
793  const REAL8 m2_SI, /**< mass of body 2 (kg) */
794  const REAL8 fStart, /**< Starting GW freq. (Hz) */
795  const REAL8 fEnd, /**< Ending GW freq. (Hz), 0 means integrate forwards as far as possible */
796  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
797  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
798  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
799  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
800  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
801  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
802  const INT4 phaseO, /**< twice post-Newtonian order */
803  const INT4 lscorr, /**< flag to include spin corrections to orbital angular momentum */
804  const INT4 phenomtp /**< flag for using spinO=7 and not spinO=6 terms with orbital-averaged quantities for phenomtphm approx */
805  )
806 {
808  memset(*params, 0, sizeof(XLALSimInspiralSpinTaylorTxCoeffs) );
809  int errCode=XLALSimSpinTaylorEnergySpinDerivativeSetup(params,m1_SI,m2_SI,fStart,fEnd,spinO,tideO,phaseO,lambda1,lambda2,quadparam1,quadparam2,lscorr,phenomtp);
810 
811  if ( (lscorr) && (phenomtp) ) {
812  XLALPrintError("XLAL Error - %s: Flag for spin corrections to orbital angular momentum is incompatible with IMRPhenomTP setup\n",__func__);
814  }
815 
816  REAL8 eta=(*params)->eta;
817  REAL8 m1M=(*params)->m1M;
818  REAL8 m2M=(*params)->m2M;
819 
820  /* Set omegadot coefficients up to PN order phaseO.
821  * wdotorb is the derivative of the orbital frequency \f$\dot{\omega}\f$.
822  * These are just the non-spinning contributions.
823  * Spin corrections must be recomputed at every step
824  * because the relative orientations of S, L can change
825  *
826  * The values can be found in Buonanno, Iyer, Ochsner, Pan and Sathyaprakash
827  * Phys. Rev. D 80, 084043 (2009) arXiv:0907.0700 (aka \"BIOPS\")
828  * Eq. 3.1 for the energy and Eq. 3.6 for \f$\dot{\omega}\f$
829  *
830  * Note that Eq. 3.6 actually gives dv/dt, but this relates to \f$\omega\f$
831  * by \f$d (M \omega)/dt = d (v^3)/dt = 3 v^2 dv/dt\f$
832  * so the PN corrections are the same
833  * but the leading order is 3 v^2 times Eq. 3.6
834  */
835  switch( phaseO )
836  {
837  case -1: /* highest available PN order */
838  case 8:
839  /* case LAL_PNORDER_THREE_POINT_FIVE: */
840  case 7:
841  (*params)->wdotcoeff[7] = XLALSimInspiralTaylorT4wdot_7PNCoeff(eta);
842 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
843  __attribute__ ((fallthrough));
844 #endif
845  /* case LAL_PNORDER_THREE: */
846  case 6:
847  (*params)->wdotcoeff[6] = XLALSimInspiralTaylorT4wdot_6PNCoeff(eta);
848  (*params)->wdotlogcoeff = XLALSimInspiralTaylorT4wdot_6PNLogCoeff(eta);
849 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
850  __attribute__ ((fallthrough));
851 #endif
852  /* case LAL_PNORDER_TWO_POINT_FIVE: */
853  case 5:
854  (*params)->wdotcoeff[5] = XLALSimInspiralTaylorT4wdot_5PNCoeff(eta);
855 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
856  __attribute__ ((fallthrough));
857 #endif
858  /* case LAL_PNORDER_TWO: */
859  case 4:
860  (*params)->wdotcoeff[4] = XLALSimInspiralTaylorT4wdot_4PNCoeff(eta);
861 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
862  __attribute__ ((fallthrough));
863 #endif
864  /*case LAL_PNORDER_ONE_POINT_FIVE:*/
865  case 3:
866  (*params)->wdotcoeff[3] = XLALSimInspiralTaylorT4wdot_3PNCoeff(eta);
867 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
868  __attribute__ ((fallthrough));
869 #endif
870  /*case LAL_PNORDER_ONE:*/
871  case 2:
872  (*params)->wdotcoeff[2] = XLALSimInspiralTaylorT4wdot_2PNCoeff(eta);
873 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
874  __attribute__ ((fallthrough));
875 #endif
876  /*case LAL_PNORDER_HALF:*/
877  case 1:
878  (*params)->wdotcoeff[1] = 0.;
879 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
880  __attribute__ ((fallthrough));
881 #endif
882  /*case LAL_PNORDER_NEWTONIAN:*/
883  case 0:
884  (*params)->wdotcoeff[0] = 1.;
885  break;
886  default:
887  XLALPrintError("XLAL Error - %s: Invalid phase. PN order %d\n",
888  __func__, phaseO );
890  break;
891  }
892 
893  /* Compute the non-dynamical coefficients of spin corrections
894  * to the evolution equations for omega, L, S1 and S2 and binary energy E.
895  */
896  switch( spinO )
897  {
900  if ( phenomtp ) {
901  (*params)->wdot7S1O = XLALSimInspiralTaylorT4wdot_7PNSOCoeff(m1M);
902  (*params)->wdot7S2O = XLALSimInspiralTaylorT4wdot_7PNSOCoeff(m2M);
903  }
904 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
905  __attribute__ ((fallthrough));
906 #endif
908  (*params)->wdot6S1O = XLALSimInspiralTaylorT4wdot_6PNSOCoeff(m1M);
909  (*params)->wdot6S2O = XLALSimInspiralTaylorT4wdot_6PNSOCoeff(m2M);
910  if (!(phenomtp)) {
911  (*params)->wdot6S1S2Avg = XLALSimInspiralTaylorT4wdot_6PNS1S2CoeffAvg(eta);
912  (*params)->wdot6S1OS2OAvg = XLALSimInspiralTaylorT4wdot_6PNS1OS2OCoeffAvg(eta);
913  (*params)->wdot6S1S1Avg = XLALSimInspiralTaylorT4wdot_6PNS1S1CoeffAvg(m1M);
914  (*params)->wdot6S1OS1OAvg = XLALSimInspiralTaylorT4wdot_6PNS1OS1OCoeffAvg(m1M);
915  (*params)->wdot6S2S2Avg = XLALSimInspiralTaylorT4wdot_6PNS1S1CoeffAvg(m2M);
916  (*params)->wdot6S2OS2OAvg = XLALSimInspiralTaylorT4wdot_6PNS1OS1OCoeffAvg(m2M);
917  (*params)->wdot6QMS1S1Avg = quadparam1 * XLALSimInspiralTaylorT4wdot_6PNQMS1S1CoeffAvg(m1M);
918  (*params)->wdot6QMS1OS1OAvg = quadparam1 * XLALSimInspiralTaylorT4wdot_6PNQMS1OS1OCoeffAvg(m1M);
919  (*params)->wdot6QMS2S2Avg = quadparam2 * XLALSimInspiralTaylorT4wdot_6PNQMS1S1CoeffAvg(m2M);
920  (*params)->wdot6QMS2OS2OAvg = quadparam2 * XLALSimInspiralTaylorT4wdot_6PNQMS1OS1OCoeffAvg(m2M);
921  }
922 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
923  __attribute__ ((fallthrough));
924 #endif
926  (*params)->wdot5S1O = XLALSimInspiralTaylorT4wdot_5PNSOCoeff(m1M);
927  (*params)->wdot5S2O = XLALSimInspiralTaylorT4wdot_5PNSOCoeff(m2M);
928 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
929  __attribute__ ((fallthrough));
930 #endif
932  /* Averaging terms bilinear in terms periodic in an orbit and
933  * confined to the orbital plane introduces v^3
934  * inaccuracies, see e.g. app. B of PRD80 (2009) 044010, arXiv:0812.4413.
935  * As a consequence orbital averaging 2PN spin^2 terms
936  * impact 3.5PN terms, hence the latter should only be used in the
937  * spin-aligned case only when orbit average is taken.
938  */
939  // Orbit-averaged terms
940  // 2PN spin-spin terms
941  (*params)->wdot4S1S2Avg = XLALSimInspiralTaylorT4wdot_4PNS1S2CoeffAvg(eta);
942  (*params)->wdot4S1OS2OAvg= XLALSimInspiralTaylorT4wdot_4PNS1OS2OCoeffAvg(eta);
943  // 2PN self-spin terms
944  (*params)->wdot4S1S1Avg = XLALSimInspiralTaylorT4wdot_4PNS1S1CoeffAvg(m1M);
945  (*params)->wdot4S1OS1OAvg= XLALSimInspiralTaylorT4wdot_4PNS1OS1OCoeffAvg(m1M);
946  (*params)->wdot4S2S2Avg = XLALSimInspiralTaylorT4wdot_4PNS1S1CoeffAvg(m2M);
947  (*params)->wdot4S2OS2OAvg= XLALSimInspiralTaylorT4wdot_4PNS1OS1OCoeffAvg(m2M);
948  // 2PN quadrupole-monopole terms
949  (*params)->wdot4QMS1S1Avg = quadparam1 * XLALSimInspiralTaylorT4wdot_4PNQMS1S1CoeffAvg(m1M);
950  (*params)->wdot4QMS1OS1OAvg= quadparam1 * XLALSimInspiralTaylorT4wdot_4PNQMS1OS1OCoeffAvg(m1M);
951  (*params)->wdot4QMS2S2Avg = quadparam2 * XLALSimInspiralTaylorT4wdot_4PNQMS1S1CoeffAvg(m2M);
952  (*params)->wdot4QMS2OS2OAvg= quadparam2 * XLALSimInspiralTaylorT4wdot_4PNQMS1OS1OCoeffAvg(m2M);
953 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
954  __attribute__ ((fallthrough));
955 #endif
957  (*params)->wdot3S1O = XLALSimInspiralTaylorT4wdot_3PNSOCoeff(m1M);
958  (*params)->wdot3S2O = XLALSimInspiralTaylorT4wdot_3PNSOCoeff(m2M);
959 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
960  __attribute__ ((fallthrough));
961 #endif
965  break;
966  default:
967  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
968  __func__, spinO );
970  break;
971  }
972 
973  /* Compute the coefficients of tidal corrections
974  * to the evolution equations for omega and binary energy E.
975  * Coefficients found from Eqs. 2.11 and 3.10 of
976  * Vines, Flanagan, Hinderer, PRD 83, 084051 (2011)
977  * and eq. 2 and 3 of PhysRevD.89.103012.
978  */
979  switch( tideO )
980  {
983  (*params)->wdottidal12 = lambda1 * XLALSimInspiralTaylorT4wdot_12PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralTaylorT4wdot_12PNTidalCoeff(m2M);
984 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
985  __attribute__ ((fallthrough));
986 #endif
988  (*params)->wdottidal10 = lambda1 * XLALSimInspiralTaylorT4wdot_10PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralTaylorT4wdot_10PNTidalCoeff(m2M);
989 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
990  __attribute__ ((fallthrough));
991 #endif
993  break;
994  default:
995  XLALPrintError("XLAL Error - %s: Invalid tidal PN order %d\n",
996  __func__, tideO );
998  break;
999  }
1000 
1001  return errCode;
1002 } // End of XLALSimInspiralSpinTaylorT4Setup()
1003 
1004 /**
1005  * See arXiv:0907.0700 for TaylorT1 definition.
1006  */
1008  XLALSimInspiralSpinTaylorTxCoeffs **params, /**< OUTPUT */
1009  const REAL8 m1_SI, /**< mass of body 1 (kg) */
1010  const REAL8 m2_SI, /**< mass of body 2 (kg) */
1011  const REAL8 fStart, /**< Starting GW freq. (Hz) */
1012  const REAL8 fEnd, /**< Ending GW freq. (Hz), 0 means integrate forwards as far as possible */
1013  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
1014  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
1015  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
1016  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
1017  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
1018  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
1019  const INT4 phaseO, /**< twice post-Newtonian order */
1020  const INT4 lscorr /**< flag to include spin corrections to orbital angular momentum */
1021  )
1022 {
1024  memset(*params, 0, sizeof(XLALSimInspiralSpinTaylorTxCoeffs) );
1025  int errCode=XLALSimSpinTaylorEnergySpinDerivativeSetup(params,m1_SI,m2_SI,fStart,fEnd,spinO,tideO,phaseO,lambda1,lambda2,quadparam1,quadparam2,lscorr,0);
1026 
1027  REAL8 eta=(*params)->eta;
1028  REAL8 m1M=(*params)->m1M;
1029  REAL8 m2M=(*params)->m2M;
1030  (*params)->Fnewt=XLALSimInspiralPNFlux_0PNCoeff(eta);
1031  (*params)->dEdvnewt=2.*XLALSimInspiralPNEnergy_0PNCoeff(eta);
1032 
1033  /* Set the flux coefficients up to PN order phaseO.
1034  * These are just the non-spinning contributions.
1035  * Spin corrections must be recomputed at every step
1036  * because the relative orientations of S, L can change
1037  *
1038  * The values can be found in Buonanno, Iyer, Ochsner, Pan and Sathyaprakash
1039  * Phys. Rev. D 80, 084043 (2009) arXiv:0907.0700 (aka \"BIOPS\")
1040  * Eq. 3.1 for the energy and Eq. 3.6 for \f$\dot{\omega}\f$
1041  *
1042  * Note that Eq. 3.6 actually gives dv/dt, but this relates to \f$\omega\f$
1043  * by \f$d (M \omega)/dt = d (v^3)/dt = 3 v^2 dv/dt\f$
1044  * so the PN corrections are the same
1045  * but the leading order is 3 v^2 times Eq. 3.6
1046  */
1047 
1048  switch( phaseO )
1049  {
1050  case -1: /* highest available PN order */
1051  case 8:
1052  /* case LAL_PNORDER_THREE_POINT_FIVE: */
1053  case 7:
1054  (*params)->Fcoeff[7] = XLALSimInspiralPNFlux_7PNCoeff(eta);
1055 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1056  __attribute__ ((fallthrough));
1057 #endif
1058  /* case LAL_PNORDER_THREE: */
1059  case 6:
1060  (*params)->Fcoeff[6] = XLALSimInspiralPNFlux_6PNCoeff(eta);
1061  (*params)->Flogcoeff = XLALSimInspiralPNFlux_6PNLogCoeff(eta);
1062 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1063  __attribute__ ((fallthrough));
1064 #endif
1065  /* case LAL_PNORDER_TWO_POINT_FIVE: */
1066  case 5:
1067  (*params)->Fcoeff[5] = XLALSimInspiralPNFlux_5PNCoeff(eta);
1068 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1069  __attribute__ ((fallthrough));
1070 #endif
1071  /* case LAL_PNORDER_TWO: */
1072  case 4:
1073  (*params)->Fcoeff[4] = XLALSimInspiralPNFlux_4PNCoeff(eta);
1074 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1075  __attribute__ ((fallthrough));
1076 #endif
1077  /*case LAL_PNORDER_ONE_POINT_FIVE:*/
1078  case 3:
1079  (*params)->Fcoeff[3] = XLALSimInspiralPNFlux_3PNCoeff(eta);
1080 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1081  __attribute__ ((fallthrough));
1082 #endif
1083  /*case LAL_PNORDER_ONE:*/
1084  case 2:
1085  (*params)->Fcoeff[2] = XLALSimInspiralPNFlux_2PNCoeff(eta);
1086 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1087  __attribute__ ((fallthrough));
1088 #endif
1089  /*case LAL_PNORDER_HALF:*/
1090  case 1:
1091  (*params)->Fcoeff[1] = 0.;
1092 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1093  __attribute__ ((fallthrough));
1094 #endif
1095  /*case LAL_PNORDER_NEWTONIAN:*/
1096  case 0:
1097  (*params)->Fcoeff[0] = 1.;
1098  break;
1099  default:
1100  XLALPrintError("XLAL Error - %s: Invalid phase. PN order %d\n",
1101  __func__, phaseO );
1103  break;
1104  }
1105 
1106  switch( spinO )
1107  {
1110  (*params)->F7S1O=XLALSimInspiralPNFlux_7PNSOCoeff(m1M);
1111  (*params)->F7S2O=XLALSimInspiralPNFlux_7PNSOCoeff(m2M);
1112 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1113  __attribute__ ((fallthrough));
1114 #endif
1116  (*params)->F6S1O = XLALSimInspiralPNFlux_6PNSOCoeff(m1M);
1117  (*params)->F6S2O = XLALSimInspiralPNFlux_6PNSOCoeff(m2M);
1118  (*params)->F6S1S2Avg = XLALSimInspiralPNFlux_6PNS1S2CoeffAvg(eta);
1119  (*params)->F6S1OS2OAvg = XLALSimInspiralPNFlux_6PNS1OS2OCoeffAvg(eta);
1120  (*params)->F6S1S1Avg = XLALSimInspiralPNFlux_6PNS1S1CoeffAvg(m1M);
1121  (*params)->F6S1OS1OAvg = XLALSimInspiralPNFlux_6PNS1OS1OCoeffAvg(m1M);
1122  (*params)->F6S2S2Avg = XLALSimInspiralPNFlux_6PNS1S1CoeffAvg(m2M);
1123  (*params)->F6S2OS2OAvg = XLALSimInspiralPNFlux_6PNS1OS1OCoeffAvg(m2M);
1124  (*params)->F6QMS1S1Avg = quadparam1*XLALSimInspiralPNFlux_6PNQMS1S1CoeffAvg(m1M);
1125  (*params)->F6QMS1OS1OAvg = quadparam1*XLALSimInspiralPNFlux_6PNQMS1OS1OCoeffAvg(m1M);
1126  (*params)->F6QMS2S2Avg = quadparam2*XLALSimInspiralPNFlux_6PNQMS1S1CoeffAvg(m2M);
1127  (*params)->F6QMS2OS2OAvg = quadparam2*XLALSimInspiralPNFlux_6PNQMS1OS1OCoeffAvg(m2M);
1128 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1129  __attribute__ ((fallthrough));
1130 #endif
1131  /* Averaging terms bilinear in terms periodic in an orbit and
1132  * confined to the orbital plane introduces v^3
1133  * inaccuracies, see e.g. app. B of PRD80 (2009) 044010, arXiv:0812.4413.
1134  * As a consequence orbital averaging 2PN spin^2 terms
1135  * impact 3.5PN terms, hence the latter should only be used in the
1136  * spin-aligned case only when orbit average is taken.
1137  */
1139  (*params)->F5S1O =XLALSimInspiralPNFlux_5PNSOCoeff(m1M);
1140  (*params)->F5S2O =XLALSimInspiralPNFlux_5PNSOCoeff(m2M);
1141 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1142  __attribute__ ((fallthrough));
1143 #endif
1145  /* Orbit Averaged */
1146  // 2PN spin-spin terms
1147  (*params)->F4S1S2Avg = XLALSimInspiralPNFlux_4PNS1S2CoeffAvg(eta);
1148  (*params)->F4S1OS2OAvg = XLALSimInspiralPNFlux_4PNS1OS2OCoeffAvg(eta);
1149  // 2PN self-spin terms
1150  (*params)->F4S1S1Avg = XLALSimInspiralPNFlux_4PNS1S1CoeffAvg(m1M);
1151  (*params)->F4S1OS1OAvg = XLALSimInspiralPNFlux_4PNS1OS1OCoeffAvg(m1M);
1152  (*params)->F4S2S2Avg = XLALSimInspiralPNFlux_4PNS1S1CoeffAvg(m2M);
1153  (*params)->F4S2OS2OAvg = XLALSimInspiralPNFlux_4PNS1OS1OCoeffAvg(m2M);
1154  // 2PN quadrupole-monopole terms
1155  (*params)->F4QMS1S1Avg = quadparam1*XLALSimInspiralPNFlux_4PNQMS1S1CoeffAvg(m1M);
1156  (*params)->F4QMS1OS1OAvg = quadparam1*XLALSimInspiralPNFlux_4PNQMS1OS1OCoeffAvg(m1M);
1157  (*params)->F4QMS2S2Avg = quadparam2*XLALSimInspiralPNFlux_4PNQMS1S1CoeffAvg(m2M);
1158  (*params)->F4QMS2OS2OAvg = quadparam2*XLALSimInspiralPNFlux_4PNQMS1OS1OCoeffAvg(m2M);
1159 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1160  __attribute__ ((fallthrough));
1161 #endif
1163  (*params)->F3S1O = XLALSimInspiralPNFlux_3PNSOCoeff(m1M);
1164  (*params)->F3S2O = XLALSimInspiralPNFlux_3PNSOCoeff(m2M);
1165 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1166  __attribute__ ((fallthrough));
1167 #endif
1171  break;
1172  default:
1173  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
1174  __func__, spinO );
1176  break;
1177  }
1178 
1179  /* Compute the coefficients of tidal corrections
1180  * to the evolution equations for omega and binary energy E.
1181  * Coefficients found from Eqs. 2.11 and 3.10 of
1182  * Vines, Flanagan, Hinderer, PRD 83, 084051 (2011).
1183  */
1184  switch( tideO )
1185  {
1188  (*params)->Ftidal12 = lambda1 * XLALSimInspiralPNFlux_12PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralPNFlux_12PNTidalCoeff(m2M);
1189 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1190  __attribute__ ((fallthrough));
1191 #endif
1193  (*params)->Ftidal10 = lambda1 * XLALSimInspiralPNFlux_10PNTidalCoeff(m1M) + lambda2 * XLALSimInspiralPNFlux_10PNTidalCoeff(m2M);
1194 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1195  __attribute__ ((fallthrough));
1196 #endif
1198  break;
1199  default:
1200  XLALPrintError("XLAL Error - %s: Invalid tidal PN order %d\n",
1201  __func__, tideO );
1203  break;
1204  }
1205 
1206  return errCode;
1207 } //End of XLALSimInspiralSpinTaylorT1Setup()
1208 
1209 /**
1210  * See arXiv:1107.1267 for TaylorT5 approximant definition. It is a variant
1211  * of TaylorT2 (see arXiv:0907.0700). SpinTaylorT5 as implemented in this
1212  * code was previously (earlier than June 2019) named SpinTaylorT2.
1213  */
1215  XLALSimInspiralSpinTaylorTxCoeffs **params, /**< OUTPUT */
1216  const REAL8 m1_SI, /**< mass of body 1 (kg) */
1217  const REAL8 m2_SI, /**< mass of body 2 (kg) */
1218  const REAL8 fStart, /**< Starting GW freq. (Hz) */
1219  const REAL8 fEnd, /**< Ending GW freq. (Hz), 0 means integrate forwards as far as possible */
1220  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
1221  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
1222  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
1223  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
1224  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
1225  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
1226  const INT4 phaseO, /**< twice post-Newtonian order */
1227  const INT4 lscorr /**< flag to include spin corrections to orbital angular momentum */
1228  )
1229 {
1231  memset(*params, 0, sizeof(XLALSimInspiralSpinTaylorTxCoeffs) );
1232  int errCode=XLALSimSpinTaylorEnergySpinDerivativeSetup(params,m1_SI,m2_SI,fStart,fEnd,spinO,tideO,phaseO,lambda1,lambda2,quadparam1,quadparam2,lscorr,0);
1233  REAL8 eta=(*params)->eta;
1234  REAL8 m1M=(*params)->m1M;
1235  REAL8 m2M=(*params)->m2M;
1236 
1237  /* Set wdot coefficients up to PN order phaseO.
1238  * wdot is the derivative of the orbital frequency \f$\dot{\omega}\f$.
1239  * These are just the non-spinning contributions.
1240  * Spin corrections must be recomputed at every step
1241  * because the relative orientations of S, L can change
1242  *
1243  * The values can be found in Buonanno, Iyer, Ochsner, Pan and Sathyaprakash
1244  * Phys. Rev. D 80, 084043 (2009) arXiv:0907.0700 (aka \"BIOPS\")
1245  * Eq. 3.1 for the energy and Eq. 3.6 for \f$\dot{\omega}\f$
1246  *
1247  * Note that Eq. 3.6 actually gives dv/dt, but this relates to \f$\omega\f$
1248  * by \f$d (M \omega)/dt = d (v^3)/dt = 3 v^2 dv/dt\f$
1249  * so the PN corrections are the same
1250  * but the leading order is 3 v^2 times Eq. 3.6
1251  */
1252  switch( phaseO )
1253  {
1254  case -1: /* highest available PN order */
1255  case 8:
1256  /* case LAL_PNORDER_THREE_POINT_FIVE: */
1257  case 7:
1258  (*params)->wdotcoeff[7] = XLALSimInspiralTaylorT2dtdv_7PNCoeff(eta);
1259 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1260  __attribute__ ((fallthrough));
1261 #endif
1262  /* case LAL_PNORDER_THREE: */
1263  case 6:
1264  (*params)->wdotcoeff[6] = XLALSimInspiralTaylorT2dtdv_6PNCoeff(eta);
1265  (*params)->wdotlogcoeff = XLALSimInspiralTaylorT2dtdv_6PNLogCoeff(eta);
1266 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1267  __attribute__ ((fallthrough));
1268 #endif
1269  /* case LAL_PNORDER_TWO_POINT_FIVE: */
1270  case 5:
1271  (*params)->wdotcoeff[5] = XLALSimInspiralTaylorT2dtdv_5PNCoeff(eta);
1272 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1273  __attribute__ ((fallthrough));
1274 #endif
1275  /* case LAL_PNORDER_TWO: */
1276  case 4:
1277  (*params)->wdotcoeff[4] = XLALSimInspiralTaylorT2dtdv_4PNCoeff(eta);
1278 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1279  __attribute__ ((fallthrough));
1280 #endif
1281  /*case LAL_PNORDER_ONE_POINT_FIVE:*/
1282  case 3:
1283  (*params)->wdotcoeff[3] = XLALSimInspiralTaylorT2dtdv_3PNCoeff(eta);
1284 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1285  __attribute__ ((fallthrough));
1286 #endif
1287  /*case LAL_PNORDER_ONE:*/
1288  case 2:
1289  (*params)->wdotcoeff[2] = XLALSimInspiralTaylorT2dtdv_2PNCoeff(eta);
1290 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1291  __attribute__ ((fallthrough));
1292 #endif
1293  /*case LAL_PNORDER_HALF:*/
1294  case 1:
1295  (*params)->wdotcoeff[1] = 0.;
1296 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1297  __attribute__ ((fallthrough));
1298 #endif
1299  /*case LAL_PNORDER_NEWTONIAN:*/
1300  case 0:
1301  (*params)->wdotcoeff[0] = 1.;
1302  break;
1303  default:
1304  XLALPrintError("XLAL Error - %s: Invalid phase. PN order %d\n",
1305  __func__, phaseO );
1307  break;
1308  }
1309 
1310  /* Compute the non-dynamical coefficients of spin corrections
1311  * to the evolution equations for omega, L, S1 and S2 and binary energy E.
1312  */
1313  switch( spinO )
1316  (*params)->wdot7S1O = XLALSimInspiralTaylorT2dtdv_7PNSOCoeff(m1M);
1317  (*params)->wdot7S2O = XLALSimInspiralTaylorT2dtdv_7PNSOCoeff(m2M);
1318 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1319  __attribute__ ((fallthrough));
1320 #endif
1322  /* Averaging terms bilinear in terms periodic in an orbit and
1323  * confined to the orbital plane introduces v^3
1324  * inaccuracies, see e.g. app. B of PRD80 (2009) 044010, arXiv:0812.4413.
1325  * As a consequence orbital averaging 2PN spin^2 terms
1326  * impact 3.5PN terms, hence the latter should only be used in the
1327  * spin-aligned case only when orbit average is taken.
1328  */
1329  (*params)->wdot6S1O = XLALSimInspiralTaylorT2dtdv_6PNSOCoeff(m1M);
1330  (*params)->wdot6S2O = XLALSimInspiralTaylorT2dtdv_6PNSOCoeff(m2M);
1331  (*params)->wdot6S1S2Avg = XLALSimInspiralTaylorT2dtdv_6PNS1S2CoeffAvg(eta);
1332  (*params)->wdot6S1OS2OAvg = XLALSimInspiralTaylorT2dtdv_6PNS1OS2OCoeffAvg(eta);
1333  (*params)->wdot6S1S1Avg = XLALSimInspiralTaylorT2dtdv_6PNS1S1CoeffAvg(m1M);
1334  (*params)->wdot6S1OS1OAvg = XLALSimInspiralTaylorT2dtdv_6PNS1OS1OCoeffAvg(m1M);
1335  (*params)->wdot6S2S2Avg = XLALSimInspiralTaylorT2dtdv_6PNS1S1CoeffAvg(m2M);
1336  (*params)->wdot6S2OS2OAvg = XLALSimInspiralTaylorT2dtdv_6PNS1OS1OCoeffAvg(m2M);
1337  (*params)->wdot6QMS1S1Avg = quadparam1*XLALSimInspiralTaylorT2dtdv_6PNQMS1S1CoeffAvg(m1M);
1338  (*params)->wdot6QMS2S2Avg = quadparam2*XLALSimInspiralTaylorT2dtdv_6PNQMS1S1CoeffAvg(m2M);
1339  (*params)->wdot6QMS1OS1OAvg = quadparam1*XLALSimInspiralTaylorT2dtdv_6PNQMS1OS1OCoeffAvg(m1M);
1340  (*params)->wdot6QMS2OS2OAvg = quadparam2*XLALSimInspiralTaylorT2dtdv_6PNQMS1OS1OCoeffAvg(m2M);
1341 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1342  __attribute__ ((fallthrough));
1343 #endif
1345  (*params)->wdot5S1O = XLALSimInspiralTaylorT2dtdv_5PNSOCoeff(m1M);
1346  (*params)->wdot5S2O = XLALSimInspiralTaylorT2dtdv_5PNSOCoeff(m2M);
1347 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1348  __attribute__ ((fallthrough));
1349 #endif
1351  // Orbit-averaged terms
1352  // 2PN spin1-spin2 terms
1353  (*params)->wdot4S1S2Avg = XLALSimInspiralTaylorT2dtdv_4PNS1S2CoeffAvg(eta);
1354  (*params)->wdot4S1OS2OAvg= XLALSimInspiralTaylorT2dtdv_4PNS1OS2OCoeffAvg(eta);
1355  // 2PN spin-self^2 terms
1356  (*params)->wdot4S1S1Avg = XLALSimInspiralTaylorT2dtdv_4PNS1S1CoeffAvg(m1M);
1357  (*params)->wdot4S1OS1OAvg= XLALSimInspiralTaylorT2dtdv_4PNS1OS1OCoeffAvg(m1M);
1358  (*params)->wdot4S2S2Avg = XLALSimInspiralTaylorT2dtdv_4PNS1S1CoeffAvg(m2M);
1359  (*params)->wdot4S2OS2OAvg= XLALSimInspiralTaylorT2dtdv_4PNS1OS1OCoeffAvg(m2M);
1360  // 2PN quadrupole-monopole self spin terms
1361  (*params)->wdot4QMS1S1Avg = quadparam1 * XLALSimInspiralTaylorT2dtdv_4PNQMS1S1CoeffAvg(m1M);
1362  (*params)->wdot4QMS1OS1OAvg= quadparam1 * XLALSimInspiralTaylorT2dtdv_4PNQMS1OS1OCoeffAvg(m1M);
1363  (*params)->wdot4QMS2S2Avg = quadparam2 * XLALSimInspiralTaylorT2dtdv_4PNQMS1S1CoeffAvg(m2M);
1364  (*params)->wdot4QMS2OS2OAvg= quadparam2 * XLALSimInspiralTaylorT2dtdv_4PNQMS1OS1OCoeffAvg(m2M);
1365 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1366  __attribute__ ((fallthrough));
1367 #endif
1369  // Note: LNHat do not have their signs reversed relative to T4
1370  // They are precession rather than orbital quantities
1371  (*params)->wdot3S1O = XLALSimInspiralTaylorT2dtdv_3PNSOCoeff(m1M);
1372  (*params)->wdot3S2O = XLALSimInspiralTaylorT2dtdv_3PNSOCoeff(m2M);
1373 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1374  __attribute__ ((fallthrough));
1375 #endif
1379  break;
1380  default:
1381  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
1382  __func__, spinO );
1384  break;
1385  }
1386 
1387  /*
1388  * Compute the coefficients of tidal corrections
1389  * to the evolution equations for omega and binary energy E.
1390  * Coefficients found from Eqs. 2.11 and 3.10 of
1391  * Vines, Flanagan, Hinderer, PRD 83, 084051 (2011).
1392  */
1393  switch( tideO )
1394  {
1397  (*params)->wdottidal12 = lambda1 * XLALSimInspiralTaylorT2dtdv_12PNTidalCoeff(m1M)
1399 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1400  __attribute__ ((fallthrough));
1401 #endif
1403  (*params)->wdottidal10 = lambda1 * XLALSimInspiralTaylorT2dtdv_10PNTidalCoeff(m1M)
1405 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
1406  __attribute__ ((fallthrough));
1407 #endif
1409  break;
1410  default:
1411  XLALPrintError("XLAL Error - %s: Invalid tidal PN order %d\n",
1412  __func__, tideO );
1414  break;
1415  }
1416 
1417  return errCode;
1418 } // End of XLALSimInspiralSpinTaylorT5Setup()
1419 
1420 /*
1421  * Internal driver function to generate any of SpinTaylorT1/T5/T4 in the Fourier domain.
1422  */
1424  COMPLEX16FrequencySeries **hplus, /**< +-polarization waveform */
1425  COMPLEX16FrequencySeries **hcross, /**< x-polarization waveform */
1426  REAL8 fMin, /**< minimum frequency of the returned series */
1427  REAL8 fMax, /**< maximum frequency of the returned series */
1428  REAL8 deltaF, /**< frequency interval of the returned series */
1429  INT4 kMax, /**< k_max as described in arXiv: 1408.5158 (min 0, max 10). */
1430  REAL8 phiRef, /**< orbital phase at reference pt. */
1431  REAL8 v0, /**< tail gauge term (default = 1) */
1432  REAL8 m1, /**< mass of companion 1 (kg) */
1433  REAL8 m2, /**< mass of companion 2 (kg) */
1434  REAL8 fStart, /**< start GW frequency (Hz) */
1435  REAL8 fRef, /**< reference GW frequency (Hz) */
1436  REAL8 r, /**< distance of source (m) */
1437  REAL8 s1x, /**< initial value of S1x */
1438  REAL8 s1y, /**< initial value of S1y */
1439  REAL8 s1z, /**< initial value of S1z */
1440  REAL8 s2x, /**< initial value of S2x */
1441  REAL8 s2y, /**< initial value of S2y */
1442  REAL8 s2z, /**< initial value of S2z */
1443  REAL8 lnhatx, /**< initial value of LNhatx */
1444  REAL8 lnhaty, /**< initial value of LNhaty */
1445  REAL8 lnhatz, /**< initial value of LNhatz */
1446  REAL8 e1x, /**< initial value of E1x */
1447  REAL8 e1y, /**< initial value of E1y */
1448  REAL8 e1z, /**< initial value of E1z */
1449  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
1450  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
1451  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
1452  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
1453  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
1454  INT4 phaseO, /**< twice PN phase order */
1455  INT4 amplitudeO, /**< twice PN amplitude order */
1456  Approximant approx, /**< PN approximant (SpinTaylorT1/T5/T4) */
1457  INT4 phiRefAtEnd /**< whether phiRef corresponds to the end of the inspiral */
1458  )
1459 {
1460  REAL8Array* y = 0;
1461  INT4 n;
1462  UINT4 i, j;
1463  UINT4 iRefPhi;
1464  REAL8 fS, fE, phiShift;
1465  /* The Schwarzschild ISCO frequency - for sanity checking fRef, and default maximum frequency */
1466  REAL8 fISCO = pow(LAL_C_SI,3) / (pow(6.,3./2.)*LAL_PI*(m1+m2)*LAL_G_SI);
1467 
1470 
1471  if(kMax < 0)
1472  {
1473  XLALPrintError("XLAL Error - %s: kMax = %d must be >= 0\n",
1474  __func__, kMax);
1476  }
1477 
1478  if(kMax > 10)
1479  {
1480  XLALPrintError("XLAL Error - %s: kMax = %d not implemented. Must be <= 10\n",
1481  __func__, kMax);
1483  }
1484 
1485 
1486 
1487  /* Sanity check fRef value */
1488  if( fRef < 0. )
1489  {
1490  XLALPrintError("XLAL Error - %s: fRef = %f must be >= 0\n",
1491  __func__, fRef);
1493  }
1494  if( fRef != 0. && fRef < fStart )
1495  {
1496  XLALPrintError("XLAL Error - %s: fRef = %f must be > fStart = %f\n",
1497  __func__, fRef, fStart);
1499  }
1500  if( fRef >= fISCO )
1501  {
1502  XLALPrintError("XLAL Error - %s: fRef = %f must be < Schwar. ISCO=%f\n",
1503  __func__, fRef, fISCO);
1505  }
1506 
1507 
1508  /* if fRef=0, just integrate from start to end. Let phiRef=phiC */
1509  if( fRef < LAL_REAL4_EPS)
1510  {
1511  fS = fStart;
1512  fE = 0.;
1513  /* Evolve the dynamical variables */
1515  m1, m2, fS, fE, s1x, s1y, s1z, s2x, s2y, s2z,
1516  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
1517  quadparam1, quadparam2, spinO, tideO, phaseO, approx);
1518  if( n < 0 )
1520 
1521  /* Apply phase shift so orbital phase ends with desired value */
1522  iRefPhi = ((y->dimLength->data[1])<<1)-1;
1523  phiShift = phiRef - y->data[iRefPhi];
1524  for( i = y->dimLength->data[1]; i <= iRefPhi; i++)
1525  {
1526  y->data[i] += phiShift;
1527  }
1528  }
1529  /* if fRef=fStart, just integrate from start to end. Let phiRef=phiStart */
1530  else if( fabs(fRef - fStart) < LAL_REAL4_EPS )
1531  {
1532  fS = fStart;
1533  fE = 0.;
1534  /* Evolve the dynamical variables */
1536  m1, m2, fS, fE, s1x, s1y, s1z, s2x, s2y, s2z,
1537  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
1538  quadparam1, quadparam2, spinO, tideO, phaseO, approx);
1539  if( n < 0 )
1541 
1542  /* Apply phase shift so orbital phase starts with desired value */
1543  iRefPhi = ((y->dimLength->data[1])<<1)-1;
1544  phiShift = phiRef - y->data[y->dimLength->data[1]];
1545  for( i = y->dimLength->data[1]; i <= iRefPhi; i++)
1546  {
1547  y->data[i] += phiShift;
1548  }
1549  }
1550  else /* Start in middle, integrate backward and forward, stitch together */
1551  {
1552  REAL8Array *yStart=NULL, *yEnd=NULL;
1553 
1554  /* Integrate backward to fStart */
1555  fS = fRef;
1556  fE = fStart;
1558  m1, m2, fS, fE, s1x, s1y, s1z, s2x, s2y,
1559  s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
1560  quadparam1, quadparam2, spinO, tideO, phaseO, approx);
1561 
1562  /* Apply phase shift so orbital phase has desired value at fRef */
1563  iRefPhi = ((yStart->dimLength->data[1])<<1)-1;
1564  phiShift = phiRef - yStart->data[iRefPhi];
1565  for( i = yStart->dimLength->data[1]; i <= iRefPhi; i++)
1566  {
1567  yStart->data[i] += phiShift;
1568  }
1569 
1570  /* Integrate forward to end of waveform */
1571  fS = fRef;
1572  fE = 0.;
1574  m1, m2, fS, fE, s1x, s1y, s1z, s2x, s2y,
1575  s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
1576  quadparam1, quadparam2, spinO, tideO, phaseO, approx);
1577 
1578  /* Apply phase shift so orbital phase has desired value at fRef */
1579  iRefPhi = ((yEnd->dimLength->data[1])<<1)-1;
1580  phiShift = phiRef - yEnd->data[yEnd->dimLength->data[1]];
1581  for( i = yEnd->dimLength->data[1]; i <= iRefPhi; i++)
1582  {
1583  yEnd->data[i] += phiShift;
1584  }
1585 
1586  /* Stitch 2nd set of vectors onto 1st set. Free 'em. */
1587  y = appendTAandFree(yStart, yEnd, y);
1588  }
1589 
1590  /* if phiRefAtEnd, let phiRef=phiC (to be compatible with TaylorT4 in ChooseFDWaveform). */
1591  if(phiRefAtEnd)
1592  {
1593  iRefPhi = ((y->dimLength->data[1])<<1)-1;
1594  phiShift = phiRef - y->data[iRefPhi];
1595  for( i = y->dimLength->data[1]; i <= iRefPhi; i++)
1596  {
1597  y->data[i] += phiShift;
1598  }
1599  }
1600 
1601  // We can now use the interpolation formulas to create the Fourier series
1602 
1603  REAL8 cSiDbl, Msec, M;
1604 
1605  cSiDbl = LAL_C_SI;
1606  M = m1 + m2;
1607  Msec = M*LAL_G_SI/(cSiDbl*cSiDbl*cSiDbl);
1608 
1609  UINT4 length = y->dimLength->data[1];
1610  UINT4 nParams = y->dimLength->data[0];
1611 
1612  /** minimum index for the a_k's adefined in Eq. (40) of arXiv: 1408.5158. */
1613  const INT4 iMinKMax[11] = {
1614  0,
1615  1,
1616  3,
1617  6,
1618  10,
1619  15,
1620  21,
1621  28,
1622  36,
1623  45,
1624  55
1625  };
1626 
1627  /** constants a_k defined in Eq. (40) of arXiv: 1408.5158. */
1628  const COMPLEX16 akCsts[66] = {
1629  1. + I*(0.), // 0
1630  1. + I*(1.), // 1
1631  0. + I*(- 1./2.),
1632  1./4. + I*(5./4.), // 2
1633  1./2. + I*(-2./3.),
1634  -1./8. + I*(1./24.),
1635  -1./6. + I*(17./18.), // 3
1636  13./16. + I*(-7./16.),
1637  -1./4. + I*(-1./20.),
1638  1./48. + I*(11./720.),
1639  -23./96. + I*(185./288.), // 4
1640  209./240. + I*(-47./240.),
1641  -67./240. + I*(-41./240.),
1642  7./240. + I*(251./5040.),
1643  -1./960. + I*(-29./6720.),
1644  -23./120. + I*(1669./3600.), // 5
1645  2393./2880. + I*(-3./64.),
1646  -323./1260. + I*(-43./168.),
1647  277./13440. + I*(659./8064.),
1648  13./15120. + I*(-23./2016.),
1649  -23./120960. + I*(143./201600.),
1650  -683./5400. + I*(16003./43200.), // 6
1651  26041./33600. + I*(19./576.),
1652  -31./140. + I*(-4933./16128.),
1653  1847./362880. + I*(7541./72576.),
1654  139./25200. + I*(-437./24192.),
1655  -209./201600. + I*(12769./6652800.),
1656  1./14175. + I*(-23./228096.),
1657  -2153./30240. + I*(341101./1058400.), // 7
1658  878963./1209600. + I*(36349./483840.),
1659  -343247./1814400. + I*(-121187./362880.),
1660  -40043./3628800. + I*(171209./1451520.),
1661  113557./9979200. + I*(-46247./1995840.),
1662  -19979./7983360. + I*(255173./79833600.),
1663  5909./19958400. + I*(-15427./51891840.),
1664  -643./39916800. + I*(20389./1452971520.),
1665  -1940303./67737600. + I*(6696113./22579200.), // 8
1666  13123063./19051200. + I*(426691./4354560.),
1667  -17712403./108864000. + I*(-1523929./4354560.),
1668  -2542391./99792000. + I*(20431./161280.),
1669  8333153./479001600. + I*(-2568281./95800320.),
1670  -3389161./778377600. + I*(13435997./3113510400.),
1671  5033293./7264857600. + I*(-4129./7687680.),
1672  -235007./3405402000. + I*(200537./4358914560.),
1673  2882417./871782912000. + I*(-181./90574848.),
1674  662159./182891520. + I*(387137501./1371686400.), // 9
1675  4022350847./6096384000. + I*(15021619./135475200.),
1676  -593412859./4191264000. + I*(-16734271./46569600.),
1677  -181044539./4790016000. + I*(379801511./2874009600.),
1678  359342129./15567552000. + I*(-461261./15724800.),
1679  -778483./121927680. + I*(50534819./9686476800.),
1680  6114053./4953312000. + I*(-12709559./16345929600.),
1681  -297352897./1743565824000. + I*(320849./3522355200.),
1682  511381./33530112000. + I*(-601231./82335052800.),
1683  -3471163./5230697472000. + I*(15721091./53353114214400.),
1684  1110580187./39191040000. + I*(1503012587./5486745600.), // 10
1685  76930217647./120708403200. + I*(529444847./4470681600.),
1686  -10037362331./80472268800. + I*(-543929527./1490227200.),
1687  -12597360953./261534873600. + I*(35472685841./261534873600.),
1688  7393112329./261534873600. + I*(-50167081./1614412800.),
1689  -55307796493./6538371840000. + I*(578597./97843200.),
1690  3938740549./2092278988800. + I*(-94645351./95103590400.),
1691  -820761239./2540624486400. + I*(93730183./658680422400.),
1692  2169874009./53353114214400. + I*(-15647627./988020633600.),
1693  -178160027./53353114214400. + I*(1209449069/1013709170073600.),
1694  356885411./2667655710720000. + I*(-1686571./37544784076800.)
1695  };
1696 
1697 
1698  INT4 status;
1699 
1700 
1701  REAL8 dm = (m1 - m2)/M;
1702  REAL8 eta = m1*m2/(M*M);
1703 
1704  // Construct cubic spline interpolation structures
1705  gsl_spline *interp[nParams-1];
1706  gsl_interp_accel *accel = NULL;
1707  gsl_interp_accel *accel_k = NULL;
1708  gsl_spline* interp_t_of_f;
1709 
1710 
1711  INT4 kMaxCur = kMax;
1712  INT4 k, iK;
1713 
1714  REAL8 tCur;
1715  REAL8 fCur;
1716  REAL8 omegaHatCur;
1717 
1718  REAL8 freqToOmegaHat = LAL_TWOPI*Msec;
1719 
1720  REAL8 dydt, T, phiOrb;
1721 
1722  REAL8 tK;
1723 
1724  REAL8 prefac = 2.*sqrt(LAL_TWOPI)*Msec*Msec*eta*cSiDbl/r;
1725 
1726  REAL8 vCur, lnhatxCur, lnhatyCur, lnhatzCur, s1xCur, s1yCur, s1zCur, s2xCur,
1727  s2yCur, s2zCur, E1xCur, E1yCur, E1zCur, TCur;
1728 
1729  INT4 nHarmonic, minHarmonic, maxHarmonic;
1730 
1731  COMPLEX16 htPlusHarmonic, htCrossHarmonic, htPlusTemp, htCrossTemp, cPhase;
1732 
1733  // compute ISCO orbital frequency
1734  REAL8 omegaHatISCO = 1./sqrt(216.);
1735  REAL8 tISCO;
1736 
1737  // Set the minimum and maximum harmonic needed for the amplitude PN order
1738  switch(amplitudeO)
1739  {
1740  case 0:
1741  minHarmonic = 2;
1742  maxHarmonic = 2;
1743  break;
1744  case 1:
1745  minHarmonic = 1;
1746  maxHarmonic = 3;
1747  break;
1748  case 2:
1749  minHarmonic = 1;
1750  maxHarmonic = 4;
1751  break;
1752  case -1: /* Use highest known PN order - move if new orders added */
1753  case 3:
1754  minHarmonic = 1;
1755  maxHarmonic = 5;
1756  break;
1757  default:
1758  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d\n",
1759  __func__, amplitudeO );
1761  break;
1762  }
1763 
1764 
1765  XLAL_BEGINGSL;
1766 
1767  // The TaylorT5 version sometimes returns duplicate time steps (i.e. two different steps happen at the same time, because df/dt is too large near the end)
1768  // So if this happens, we have to remove the duplicates and try again. If it fails then, there is another problem and the function exits with an error.
1769  UINT4 weHadAProblem = 0;
1770 
1771  accel = gsl_interp_accel_alloc();
1772  accel_k = gsl_interp_accel_alloc();
1773  interp_t_of_f = gsl_spline_alloc(gsl_interp_cspline,
1774  length);
1775  status = gsl_spline_init(interp_t_of_f, &y->data[length*2],
1776  y->data, length);
1777  if(status != GSL_SUCCESS)
1778  {
1779  weHadAProblem = 1;
1780  }
1781 
1782  // initiate interpolation objects
1783  for(i = 1; i < nParams; i++) {
1784  interp[i-1] = gsl_spline_alloc(gsl_interp_cspline,
1785  length);
1786  status = gsl_spline_init(interp[i-1], y->data,
1787  &y->data[length*i], length);
1788  if(status != GSL_SUCCESS)
1789  {
1790  weHadAProblem = 1;
1791  }
1792  }
1793 
1794  if(weHadAProblem)
1795  {
1796  y = removeDuplicates(y);
1797  length = y->dimLength->data[1];
1798 
1799  gsl_spline_free(interp_t_of_f);
1800 
1801  for(i = 0; i < nParams-1; i++) {
1802  gsl_spline_free(interp[i]);
1803  }
1804 
1805  interp_t_of_f = gsl_spline_alloc(gsl_interp_cspline,
1806  length);
1807  status = gsl_spline_init(interp_t_of_f, &y->data[length*2],
1808  y->data, length);
1809  if(status != GSL_SUCCESS)
1810  {
1811  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
1812  __func__, status );
1814  }
1815 
1816  // initiate interpolation objects
1817  for(i = 1; i < nParams; i++) {
1818  interp[i-1] = gsl_spline_alloc(gsl_interp_cspline,
1819  length);
1820  status = gsl_spline_init(interp[i-1], y->data,
1821  &y->data[length*i], length);
1822  if(status != GSL_SUCCESS)
1823  {
1824  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
1825  __func__, status );
1827  }
1828  }
1829  }
1830 
1831  // compute tISCO
1832  status = gsl_spline_eval_e(interp_t_of_f, omegaHatISCO,
1833  accel, &tISCO);
1834  if(status != GSL_SUCCESS)
1835  {
1836  // if ISCO not reached, set t=0 at the end of tthe simulation
1837  tISCO = y->data[length-1];
1838  }
1839 
1840  // set tStart so that tISCO corresponds to t=0.
1841  LIGOTimeGPS tStart = LIGOTIMEGPSZERO;
1842  REAL8 omegaHatMin = LAL_PI*Msec*fMin;
1843  REAL8 tMin;
1844  status = gsl_spline_eval_e(interp_t_of_f, omegaHatMin,
1845  accel, &tMin);
1846  tMin -= tISCO;
1847  tMin *= Msec;
1848  tStart.gpsSeconds += (INT4)floor(tMin);
1849  tStart.gpsNanoSeconds += (INT4)floor(1.e9*(tMin - tStart.gpsSeconds));
1850 
1851  // number of samples
1852  UINT4 nFreqSamples, iFirstSample;
1853  fMin = deltaF*floor(nextafter(fMin, INFINITY)/deltaF);
1854  if(fMax > fMin)
1855  {
1856  nFreqSamples = (UINT4)ceil((fMax - fMin)/deltaF);
1857  }
1858  else
1859  {
1860  nFreqSamples = (UINT4)ceil((fISCO - fMin)/deltaF);
1861  }
1862  iFirstSample = fMin/deltaF;
1863 
1864  *hplus = XLALCreateCOMPLEX16FrequencySeries("PLUS POLARIZATION", &tStart,
1865  0., deltaF, &lalSecondUnit, iFirstSample+nFreqSamples);
1866  *hcross = XLALCreateCOMPLEX16FrequencySeries("CROSS POLARIZATION", &tStart,
1867  0., deltaF, &lalSecondUnit, iFirstSample+nFreqSamples);
1868  XLALUnitMultiply(&(*hplus)->sampleUnits, &(*hplus)->sampleUnits, &lalStrainUnit);
1869  XLALUnitMultiply(&(*hcross)->sampleUnits, &(*hcross)->sampleUnits, &lalStrainUnit);
1870 
1871  COMPLEX16FrequencySeries* hplustilde = *hplus;
1872  COMPLEX16FrequencySeries* hcrosstilde = *hcross;
1873 
1874  memset(hplustilde->data->data, 0, sizeof(COMPLEX16)*(iFirstSample+nFreqSamples));
1875  memset(hcrosstilde->data->data, 0, sizeof(COMPLEX16)*(iFirstSample+nFreqSamples));
1876 
1877  // If nFreqSamples > length, better interpolate A(t), t(f), and Psi(f)
1878  // If nFreqSamples < length, better interpolate everything
1879  if(nFreqSamples < length)
1880  {
1881  // We interpolate every quantity at each frequency sample of the output
1882 
1883  for(i = 0, j = iFirstSample; i < nFreqSamples; i++, j++) // loop over frequency samples
1884  {
1885  fCur = j*deltaF;
1886 
1887  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++) // loop over relevant harmonics
1888  {
1889  htPlusHarmonic = 0.;
1890  htCrossHarmonic = 0.;
1891 
1892  omegaHatCur = freqToOmegaHat*fCur/nHarmonic;
1893 
1894  status = gsl_spline_eval_e(interp_t_of_f, omegaHatCur,
1895  accel, &tCur);
1896  // if return is non-zero, then the harmonic contributes nothing
1897  if(status == GSL_SUCCESS)
1898  {
1899  status = gsl_spline_eval_e(interp[14], tCur, accel,
1900  &dydt);
1901  status = gsl_spline_eval_e(interp[0], tCur, accel,
1902  &phiOrb);
1903 
1904  T = 1./sqrt(fabs(nHarmonic*dydt));
1905 
1906  // k = 0
1907  iK = iMinKMax[kMaxCur];
1908 
1909  status = gsl_spline_eval_e(interp[1], tCur, accel_k,
1910  &omegaHatCur);
1911  if(status != GSL_SUCCESS)
1912  {
1913  continue;
1914  }
1915  status = gsl_spline_eval_e(interp[2], tCur, accel_k,
1916  &lnhatxCur);
1917  status = gsl_spline_eval_e(interp[3], tCur, accel_k,
1918  &lnhatyCur);
1919  status = gsl_spline_eval_e(interp[4], tCur, accel_k,
1920  &lnhatzCur);
1921  // if the amplitude PN order is too low, no need to interpolate the spin orientation
1922  if(amplitudeO > 1 || amplitudeO == -1)
1923  {
1924  status = gsl_spline_eval_e(interp[5], tCur, accel_k,
1925  &s1xCur);
1926  status = gsl_spline_eval_e(interp[6], tCur, accel_k,
1927  &s1yCur);
1928  status = gsl_spline_eval_e(interp[7], tCur, accel_k,
1929  &s1zCur);
1930  status = gsl_spline_eval_e(interp[8], tCur, accel_k,
1931  &s2xCur);
1932  status = gsl_spline_eval_e(interp[9], tCur, accel_k,
1933  &s2yCur);
1934  status = gsl_spline_eval_e(interp[10], tCur,
1935  accel_k, &s2zCur);
1936  }
1937  status = gsl_spline_eval_e(interp[11], tCur, accel_k,
1938  &E1xCur);
1939  status = gsl_spline_eval_e(interp[12], tCur, accel_k,
1940  &E1yCur);
1941  status = gsl_spline_eval_e(interp[13], tCur, accel_k,
1942  &E1zCur);
1943 
1944  vCur = cbrt(omegaHatCur);
1945 
1947  &htCrossTemp, vCur, s1xCur, s1yCur, s1zCur, s2xCur, s2yCur, s2zCur,
1948  lnhatxCur, lnhatyCur, lnhatzCur, E1xCur, E1yCur, E1zCur, dm, eta,
1949  v0, nHarmonic, amplitudeO);
1950 
1951  htPlusHarmonic += akCsts[iK]*T*htPlusTemp;
1952  htCrossHarmonic += akCsts[iK]*T*htCrossTemp;
1953 
1954  for(k = 1, iK++; k <= kMaxCur; k++, iK++) // loop over k != 0
1955  {
1956  tK = tCur + k*T;
1957 
1958  status = gsl_spline_eval_e(interp[1], tK, accel_k,
1959  &omegaHatCur);
1960  // if return is non-zero, then the k value contributes nothing
1961  if(status == GSL_SUCCESS)
1962  {
1963  status = gsl_spline_eval_e(interp[2], tK, accel_k,
1964  &lnhatxCur);
1965  status = gsl_spline_eval_e(interp[3], tK, accel_k,
1966  &lnhatyCur);
1967  status = gsl_spline_eval_e(interp[4], tK, accel_k,
1968  &lnhatzCur);
1969  // if the amplitude PN order is too low, no need to interpolate the spin orientation
1970  if(amplitudeO > 1 || amplitudeO == -1)
1971  {
1972  status = gsl_spline_eval_e(interp[5], tK,
1973  accel_k, &s1xCur);
1974  status = gsl_spline_eval_e(interp[6], tK,
1975  accel_k, &s1yCur);
1976  status = gsl_spline_eval_e(interp[7], tK,
1977  accel_k, &s1zCur);
1978  status = gsl_spline_eval_e(interp[8], tK,
1979  accel_k, &s2xCur);
1980  status = gsl_spline_eval_e(interp[9], tK,
1981  accel_k, &s2yCur);
1982  status = gsl_spline_eval_e(interp[10], tK,
1983  accel_k, &s2zCur);
1984  }
1985  status = gsl_spline_eval_e(interp[11], tK,
1986  accel_k, &E1xCur);
1987  status = gsl_spline_eval_e(interp[12], tK,
1988  accel_k, &E1yCur);
1989  status = gsl_spline_eval_e(interp[13], tK,
1990  accel_k, &E1zCur);
1991  status = gsl_spline_eval_e(interp[14], tK,
1992  accel_k, &dydt);
1993 
1994  vCur = cbrt(omegaHatCur);
1995  TCur = 1./sqrt(fabs(nHarmonic*dydt));
1996 
1998  &htPlusTemp, &htCrossTemp, vCur, s1xCur, s1yCur, s1zCur,
1999  s2xCur, s2yCur, s2zCur, lnhatxCur, lnhatyCur, lnhatzCur, E1xCur,
2000  E1yCur, E1zCur, dm, eta, v0, nHarmonic, amplitudeO);
2001 
2002  htPlusHarmonic += akCsts[iK]*TCur*htPlusTemp;
2003  htCrossHarmonic += akCsts[iK]*TCur*htCrossTemp;
2004  }
2005 
2006  tK = tCur - k*T;
2007 
2008  status = gsl_spline_eval_e(interp[1], tK, accel_k,
2009  &omegaHatCur);
2010  // if return is non-zero, then the -k value contributes nothing
2011  if(status == GSL_SUCCESS)
2012  {
2013  status = gsl_spline_eval_e(interp[2], tK,
2014  accel_k, &lnhatxCur);
2015  status = gsl_spline_eval_e(interp[3], tK,
2016  accel_k, &lnhatyCur);
2017  status = gsl_spline_eval_e(interp[4], tK,
2018  accel_k, &lnhatzCur);
2019  // if the amplitude PN order is too low, no need to interpolate the spin orientation
2020  if(amplitudeO > 1 || amplitudeO == -1)
2021  {
2022  status = gsl_spline_eval_e(interp[5], tK,
2023  accel_k, &s1xCur);
2024  status = gsl_spline_eval_e(interp[6], tK,
2025  accel_k, &s1yCur);
2026  status = gsl_spline_eval_e(interp[7], tK,
2027  accel_k, &s1zCur);
2028  status = gsl_spline_eval_e(interp[8], tK,
2029  accel_k, &s2xCur);
2030  status = gsl_spline_eval_e(interp[9], tK,
2031  accel_k, &s2yCur);
2032  status = gsl_spline_eval_e(interp[10], tK,
2033  accel_k, &s2zCur);
2034  }
2035  status = gsl_spline_eval_e(interp[11], tK,
2036  accel_k, &E1xCur);
2037  status = gsl_spline_eval_e(interp[12], tK,
2038  accel_k, &E1yCur);
2039  status = gsl_spline_eval_e(interp[13], tK,
2040  accel_k, &E1zCur);
2041  status = gsl_spline_eval_e(interp[14], tK,
2042  accel_k, &dydt);
2043 
2044  vCur = cbrt(omegaHatCur);
2045  TCur = 1./sqrt(fabs(nHarmonic*dydt));
2046 
2048  &htPlusTemp, &htCrossTemp, vCur, s1xCur, s1yCur, s1zCur, s2xCur,
2049  s2yCur, s2zCur, lnhatxCur, lnhatyCur, lnhatzCur, E1xCur, E1yCur,
2050  E1zCur, dm, eta, v0, nHarmonic, amplitudeO);
2051 
2052  htPlusHarmonic += akCsts[iK]*TCur*htPlusTemp;
2053  htCrossHarmonic += akCsts[iK]*TCur*htCrossTemp;
2054  }
2055  }
2056 
2057  // apply phase factor for the particular harmonic
2058  cPhase = prefac*cexp(I*(freqToOmegaHat*fCur*(tCur - tISCO) - nHarmonic*phiOrb
2059  - LAL_PI_4));
2060  hplustilde->data->data[j] += conj(htPlusHarmonic*cPhase);
2061  hcrosstilde->data->data[j] += conj(htCrossHarmonic*cPhase);
2062  }
2063  }
2064  }
2065  }
2066  else
2067  {
2068  // if(nFreqSamples > length)
2069  // We compute the amplitude and phase of each harmonic for each sample of the Runge-Kutta, and then interpolate between them
2070 
2071  REAL8Array* freq = XLALCreateREAL8ArrayL(2, 5, length);
2072  REAL8Array* hPlusAmpRe = XLALCreateREAL8ArrayL(2, 5, length);
2073  REAL8Array* hPlusAmpIm = XLALCreateREAL8ArrayL(2, 5, length);
2074  REAL8Array* hCrossAmpRe = XLALCreateREAL8ArrayL(2, 5, length);
2075  REAL8Array* hCrossAmpIm = XLALCreateREAL8ArrayL(2, 5, length);
2076  REAL8Array* TArray = XLALCreateREAL8ArrayL(2, 5, length);
2077  REAL8Array* phase = XLALCreateREAL8ArrayL(2, 5, length);
2078 
2079  gsl_spline *interpHPlusRe[5];
2080  gsl_spline *interpHPlusIm[5];
2081  gsl_spline *interpHCrossRe[5];
2082  gsl_spline *interpHCrossIm[5];
2083  gsl_spline *interpPhase[5];
2084  gsl_spline *interpT[5];
2085 
2086  for(i = 0; i < length; i++) // loop over the samples output by the Runge-Kutta
2087  {
2088  tCur = y->data[i];
2089  omegaHatCur = y->data[2*length+i];
2090  vCur = cbrt(omegaHatCur);
2091  phiOrb = y->data[length+i];
2092  dydt = y->data[15*length+i];
2093 
2094  // create the series for the frequency, the phase, and the time derivative of the orbital frequency
2095  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++)
2096  {
2097  freq->data[length*(nHarmonic-1)+i] = nHarmonic*omegaHatCur/
2098  freqToOmegaHat;
2099  phase->data[length*(nHarmonic-1)+i] = nHarmonic*(omegaHatCur*(tCur - tISCO)
2100  - phiOrb) - LAL_PI_4;
2101  TArray->data[length*(nHarmonic-1)+i] = 1./sqrt(fabs(nHarmonic*dydt));
2102  }
2103 
2104  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++) // loop over the harmonic number
2105  {
2106  lnhatxCur = y->data[3*length+i];
2107  lnhatyCur = y->data[4*length+i];
2108  lnhatzCur = y->data[5*length+i];
2109  // if the amplitude PN order is too low, no need to take the spin orientation into account
2110  if(amplitudeO > 1 || amplitudeO == -1)
2111  {
2112  s1xCur = y->data[6*length+i];
2113  s1yCur = y->data[7*length+i];
2114  s1zCur = y->data[8*length+i];
2115  s2xCur = y->data[9*length+i];
2116  s2yCur = y->data[10*length+i];
2117  s2zCur = y->data[11*length+i];
2118  }
2119  E1xCur = y->data[12*length+i];
2120  E1yCur = y->data[13*length+i];
2121  E1zCur = y->data[14*length+i];
2122 
2124  &htCrossTemp, vCur, s1xCur, s1yCur, s1zCur, s2xCur, s2yCur, s2zCur,
2125  lnhatxCur, lnhatyCur, lnhatzCur, E1xCur, E1yCur, E1zCur, dm, eta, v0,
2126  nHarmonic, amplitudeO);
2127 
2128  htPlusHarmonic = (prefac*TArray->data[length*(nHarmonic-1)+i])*
2129  htPlusTemp;
2130  htCrossHarmonic = (prefac*TArray->data[length*(nHarmonic-1)+i])*
2131  htCrossTemp;
2132 
2133  // create the series for the amplitude
2134  hPlusAmpRe->data[length*(nHarmonic-1)+i] = creal(htPlusHarmonic);
2135  hPlusAmpIm->data[length*(nHarmonic-1)+i] = cimag(htPlusHarmonic);
2136  hCrossAmpRe->data[length*(nHarmonic-1)+i] = creal(htCrossHarmonic);
2137  hCrossAmpIm->data[length*(nHarmonic-1)+i] = cimag(htCrossHarmonic);
2138  }
2139  }
2140 
2141  //initiate the interpolation structures
2142  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++)
2143  {
2144  interpHPlusRe[nHarmonic-1] =
2145  gsl_spline_alloc(gsl_interp_cspline, length);
2146  status = gsl_spline_init(interpHPlusRe[nHarmonic-1],
2147  y->data, &hPlusAmpRe->data[length*(nHarmonic-1)], length);
2148  if(status != GSL_SUCCESS)
2149  {
2150  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2151  __func__, status );
2153  }
2154 
2155  interpHPlusIm[nHarmonic-1] =
2156  gsl_spline_alloc(gsl_interp_cspline, length);
2157  status = gsl_spline_init(interpHPlusIm[nHarmonic-1],
2158  y->data, &hPlusAmpIm->data[length*(nHarmonic-1)], length);
2159  if(status != GSL_SUCCESS)
2160  {
2161  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2162  __func__, status );
2164  }
2165 
2166  interpHCrossRe[nHarmonic-1] =
2167  gsl_spline_alloc(gsl_interp_cspline, length);
2168  status = gsl_spline_init(interpHCrossRe[nHarmonic-1],
2169  y->data, &hCrossAmpRe->data[length*(nHarmonic-1)], length);
2170  if(status != GSL_SUCCESS)
2171  {
2172  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2173  __func__, status );
2175  }
2176 
2177  interpHCrossIm[nHarmonic-1] =
2178  gsl_spline_alloc(gsl_interp_cspline, length);
2179  status = gsl_spline_init(interpHCrossIm[nHarmonic-1],
2180  y->data, &hCrossAmpIm->data[length*(nHarmonic-1)], length);
2181  if(status != GSL_SUCCESS)
2182  {
2183  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2184  __func__, status );
2186  }
2187 
2188  interpPhase[nHarmonic-1] =
2189  gsl_spline_alloc(gsl_interp_cspline, length);
2190  status = gsl_spline_init(interpPhase[nHarmonic-1],
2191  &freq->data[length*(nHarmonic-1)], &phase->data[length*(nHarmonic-1)],
2192  length);
2193  if(status != GSL_SUCCESS)
2194  {
2195  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2196  __func__, status );
2198  }
2199 
2200  interpT[nHarmonic-1] =
2201  gsl_spline_alloc(gsl_interp_cspline, length);
2202  status = gsl_spline_init(interpT[nHarmonic-1],
2203  &freq->data[length*(nHarmonic-1)], &TArray->data[length*(nHarmonic-1)],
2204  length);
2205  if(status != GSL_SUCCESS)
2206  {
2207  XLALPrintError("XLAL Error - %s: spline interpolation returned with error code %d\n",
2208  __func__, status );
2210  }
2211  }
2212 
2213  REAL8 Psi = 0.;
2214  REAL8 htPlusRe = 0.;
2215  REAL8 htPlusIm = 0.;
2216  REAL8 htCrossRe = 0.;
2217  REAL8 htCrossIm = 0.;
2218 
2219  for(i = 0, j = iFirstSample; i < nFreqSamples; i++, j++) // loop over the output frequencies
2220  {
2221  fCur = j*deltaF;
2222 
2223  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++) // loop over the harmonic number
2224  {
2225  omegaHatCur = freqToOmegaHat*fCur/nHarmonic;
2226 
2227  status = gsl_spline_eval_e(interp_t_of_f, omegaHatCur,
2228  accel, &tCur);
2229  // if return is non-zero, then the harmonic contributes nothing
2230  if(status == GSL_SUCCESS)
2231  {
2232  status = gsl_spline_eval_e(interpPhase[nHarmonic-1],
2233  fCur, accel, &Psi);
2234  status = gsl_spline_eval_e(interpT[nHarmonic-1],
2235  fCur, accel, &T);
2236 
2237  // k = 0
2238  iK = iMinKMax[kMaxCur];
2239 
2240  status = gsl_spline_eval_e(interpHPlusRe[nHarmonic-1], tCur,
2241  accel_k, &htPlusRe);
2242  status = gsl_spline_eval_e(interpHPlusIm[nHarmonic-1], tCur,
2243  accel_k, &htPlusIm);
2244  status = gsl_spline_eval_e(interpHCrossRe[nHarmonic-1], tCur,
2245  accel_k, &htCrossRe);
2246  status = gsl_spline_eval_e(interpHCrossIm[nHarmonic-1], tCur,
2247  accel_k, &htCrossIm);
2248 
2249  htPlusHarmonic = akCsts[iK]*(htPlusRe + I*htPlusIm);
2250  htCrossHarmonic = akCsts[iK]*(htCrossRe + I*htCrossIm);
2251 
2252  for(k = 1, iK++; k <= kMaxCur; k++, iK++) // loop over k
2253  {
2254  tK = tCur + k*T;
2255 
2256  status =
2257  gsl_spline_eval_e(interpHPlusRe[nHarmonic-1], tK,
2258  accel_k, &htPlusRe);
2259  // if return is non-zero, then the k value contributes nothing
2260  if(status == GSL_SUCCESS)
2261  {
2262  status =
2263  gsl_spline_eval_e(interpHPlusIm[nHarmonic-1], tK,
2264  accel_k, &htPlusIm);
2265  status =
2266  gsl_spline_eval_e(interpHCrossRe[nHarmonic-1], tK, accel_k,
2267  &htCrossRe);
2268  status =
2269  gsl_spline_eval_e(interpHCrossIm[nHarmonic-1], tK, accel_k,
2270  &htCrossIm);
2271 
2272  htPlusHarmonic += akCsts[iK]*(htPlusRe + I*htPlusIm);
2273  htCrossHarmonic += akCsts[iK]*(htCrossRe + I*htCrossIm);
2274  }
2275 
2276  tK = tCur - k*T;
2277 
2278  status = gsl_spline_eval_e(interpHPlusRe[nHarmonic-1], tK,
2279  accel_k, &htPlusRe);
2280  // if return is non-zero, then the -k value contributes nothing
2281  if(status == GSL_SUCCESS)
2282  {
2283  status = gsl_spline_eval_e(interpHPlusIm[nHarmonic-1], tK,
2284  accel_k, &htPlusIm);
2285  status = gsl_spline_eval_e(interpHCrossRe[nHarmonic-1], tK,
2286  accel_k, &htCrossRe);
2287  status = gsl_spline_eval_e(interpHCrossIm[nHarmonic-1], tK,
2288  accel_k, &htCrossIm);
2289 
2290  htPlusHarmonic += akCsts[iK]*(htPlusRe + I*htPlusIm);
2291  htCrossHarmonic += akCsts[iK]*(htCrossRe + I*htCrossIm);
2292  }
2293  }
2294 
2295  cPhase = cexp(I*Psi);
2296 
2297  hplustilde->data->data[j] += conj(htPlusHarmonic*cPhase);
2298  hcrosstilde->data->data[j] += conj(htCrossHarmonic*cPhase);
2299  }
2300  }
2301  }
2302 
2303  for(nHarmonic = minHarmonic; nHarmonic <= maxHarmonic; nHarmonic++) // free the interpolatin objects
2304  {
2305  gsl_spline_free(interpHPlusRe[nHarmonic-1]);
2306  gsl_spline_free(interpHPlusIm[nHarmonic-1]);
2307  gsl_spline_free(interpHCrossRe[nHarmonic-1]);
2308  gsl_spline_free(interpHCrossIm[nHarmonic-1]);
2309  gsl_spline_free(interpT[nHarmonic-1]);
2310  gsl_spline_free(interpPhase[nHarmonic-1]);
2311  }
2312 
2313  XLALDestroyREAL8Array(freq);
2314  XLALDestroyREAL8Array(hPlusAmpRe);
2315  XLALDestroyREAL8Array(hPlusAmpIm);
2316  XLALDestroyREAL8Array(hCrossAmpRe);
2317  XLALDestroyREAL8Array(hCrossAmpIm);
2318  XLALDestroyREAL8Array(TArray);
2319  XLALDestroyREAL8Array(phase);
2320  }
2321 
2322 
2323 
2324  gsl_interp_accel_free(accel);
2325  gsl_interp_accel_free(accel_k);
2326  gsl_spline_free(interp_t_of_f);
2327 
2328  for(i = 0; i < nParams-1; i++) {
2329  gsl_spline_free(interp[i]);
2330  }
2331 
2332  XLAL_ENDGSL;
2333 
2334 
2336 
2337  return XLAL_SUCCESS;
2338 }
2339 
2341  REAL8 *Espin4,
2342  REAL8 *Espin5,
2343  REAL8 *Espin6,
2344  REAL8 *Espin7,
2346  const REAL8 LNhdotS1,
2347  const REAL8 LNhdotS2,
2348  const REAL8 S1sq,
2349  const REAL8 S2sq,
2350  const REAL8 S1dotS2)
2351 {
2352  *Espin3=0.;
2353  *Espin4=0.;
2354  *Espin5=0.;
2355  *Espin6=0.;
2356  *Espin7=0.;
2357  switch( params->spinO ) {
2359  if (params->phenomtp)
2360  *Espin7 += params->E7S1O * LNhdotS1 + params->E7S2O * LNhdotS2;
2361 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2362  __attribute__ ((fallthrough));
2363 #endif
2365 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2366  __attribute__ ((fallthrough));
2367 #endif
2369  if (!(params->phenomtp))
2370  *Espin6 += params->E6S1S2Avg*S1dotS2 + params->E6S1OS2OAvg*LNhdotS1*LNhdotS2
2371  + (params->E6S1S1Avg + params->E6QMS1S1Avg)*S1sq
2372  + (params->E6S2S2Avg + params->E6QMS2S2Avg)*S2sq
2373  + (params->E6S1OS1OAvg + params->E6QMS1OS1OAvg)*LNhdotS1*LNhdotS1 +
2374  + (params->E6S2OS2OAvg + params->E6QMS2OS2OAvg)*LNhdotS2*LNhdotS2;
2375 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2376  __attribute__ ((fallthrough));
2377 #endif
2379  // Compute 2.5PN SO correction to energy
2380  // See Eq. 7.9 of gr-qc/0605140v4
2381  // Note that S_l/M^2 = (m1/M)^2 chi1 + (m2/M)^2 chi2
2382  // and Sigma_l/M^2 = (m2/M) chi2 - (m1/M) chi1
2383  *Espin5 += params->E5S1O * LNhdotS1 + params->E5S2O * LNhdotS2;
2384 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2385  __attribute__ ((fallthrough));
2386 #endif
2388  // Compute S1-S2 spin-spin term
2389  *Espin4 += params->E4S1S2Avg * S1dotS2 + params->E4S1OS2OAvg * LNhdotS1 * LNhdotS2;
2390  // Compute 2PN quadrupole-monopole correction to energy
2391  // See last line of Eq. 6 of astro-ph/0504538
2392  // or 2nd and 3rd lines of Eq. (C4) in arXiv:0810.5336v3
2393  *Espin4 += params->E4QMS1S1Avg * S1sq + params->E4QMS2S2Avg * S2sq
2394  + params->E4QMS1OS1OAvg * LNhdotS1 * LNhdotS1
2395  + params->E4QMS2OS2OAvg * LNhdotS2 * LNhdotS2;
2396 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2397  __attribute__ ((fallthrough));
2398 #endif
2400  // Compute 1.5PN SO correction to energy
2401  *Espin3 += params->E3S1O * LNhdotS1 + params->E3S2O * LNhdotS2;
2402 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2403  __attribute__ ((fallthrough));
2404 #endif
2408  break;
2409  default:
2410  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
2411  __func__, params->spinO );
2413  break;
2414  }
2415  return XLAL_SUCCESS;
2416 } //End of XLALSimInspiralSetEnergyPNTermsAvg()
2417 
2418 /*
2419  * Internal function called by the integration routine.
2420  * Stops the integration if
2421  * 1) The energy decreases with increasing orbital frequency
2422  * 2) The orbital frequency begins decreasing
2423  * 3) The orbital frequency becomes infinite
2424  * 4) The orbital frequency has gone outside the requested bounds
2425  * 5) The PN parameter v/c becomes >= 1
2426  * SpinTaylorT4 and SpinTaylorT5 both use this same stopping test
2427  */
2428 static int XLALSimInspiralSpinTaylorStoppingTest(double UNUSED t,
2429  const double values[],
2430  double dvalues[],
2431  void *mparams
2432  )
2433 {
2434  REAL8 omega, v, test, omegaStart, omegaEnd, ddomega;
2435  REAL8 LNhx, LNhy, LNhz, S1x, S1y, S1z, S2x, S2y, S2z;
2436  REAL8 LNhdotS1, LNhdotS2, S1dotS2, S1sq, S2sq;
2437  REAL8 Espin7=0.;
2438  REAL8 Espin6=0.;
2439  REAL8 Espin5=0.;
2440  REAL8 Espin4=0.;
2441  REAL8 Espin3=0.;
2443  = (XLALSimInspiralSpinTaylorTxCoeffs*) mparams;
2444  /* Spin-corrections to energy (including dynamical terms) */
2445 
2446  omega = values[1];
2447  v = cbrt(omega);
2448  LNhx = values[2]; LNhy = values[3]; LNhz = values[4] ;
2449  S1x = values[5]; S1y = values[6]; S1z = values[7] ;
2450  S2x = values[8]; S2y = values[9]; S2z = values[10];
2451  LNhdotS1 = cdot(LNhx,LNhy,LNhz,S1x,S1y,S1z);
2452  LNhdotS2 = cdot(LNhx,LNhy,LNhz,S2x,S2y,S2z);
2453  S1sq = normsq(S1x,S1y,S1z);
2454  S2sq = normsq(S2x,S2y,S2z);
2455  S1dotS2 = cdot(S1x,S1y,S1z,S2x,S2y,S2z);
2456 
2457  /* omega = PI G M f_GW / c^3
2458  * Note params->M is in solar mass units */
2459  omegaStart = LAL_PI * params->M*LAL_MTSUN_SI * params->fStart;
2460  omegaEnd = LAL_PI * params->M*LAL_MTSUN_SI * params->fEnd;
2461 
2462  XLALSimInspiralSetEnergyPNTermsAvg(&Espin3,&Espin4,&Espin5,&Espin6,&Espin7,params,LNhdotS1,LNhdotS2,S1sq,S2sq,S1dotS2);
2463 
2464  /* We are testing if the orbital energy increases with \f$\omega\f$.
2465  * We should be losing energy to GW flux, so if E increases
2466  * we stop integration because the dynamics are becoming unphysical.
2467  * 'test' is the PN expansion of \f$dE/d\omega\f$ without the prefactor,
2468  * i.e. \f$dE/d\omega = dE/dv * dv/d\omega = - (M^2*eta/6) * test\f$
2469  * Therefore, the energy is increasing with \f$\omega\f$ iff. test < 0.
2470  */
2471  test = 2. + v * v * ( 4. * params->Ecoeff[2]
2472  + v * ( 5. * (params->Ecoeff[3] + Espin3)
2473  + v * ( 6. * (params->Ecoeff[4] + Espin4)
2474  + v * ( 7. * (params->Ecoeff[5] + Espin5)
2475  + v * ( 8. * (params->Ecoeff[6] + Espin6)
2476  + v * ( 9. * (params->Ecoeff[7] + Espin7)
2477  + v * v * v * ( 12. * params->Etidal10
2478  + v * v * ( 14. * params->Etidal12 ) ) ) ) ) ) ) );
2479  // Check d^2omega/dt^2 > 0 (true iff current_domega - prev_domega > 0)
2480  ddomega = dvalues[1] - params->prev_domega;
2481  // ...but we can integrate forward or backward, so beware of the sign!
2482  if ( params->fEnd < params->fStart && params->fEnd != 0.
2483  && params->prev_domega != 0.)
2484  ddomega *= -1;
2485  // Copy current value of domega to prev. value of domega for next call
2486  params->prev_domega = dvalues[1];
2487 
2488  if( fabs(omegaEnd) > LAL_REAL4_EPS && omegaEnd > omegaStart
2489  && omega > omegaEnd) /* freq. above bound */
2491  else if( fabs(omegaEnd) > LAL_REAL4_EPS && omegaEnd < omegaStart
2492  && omega < omegaEnd) /* freq. below bound */
2494  else if (test < 0.0) /* energy test fails! */
2496  else if (isnan(omega)) /* omega is nan! */
2498  else if (v >= 1.) // v/c >= 1!
2500  else if (ddomega <= 0.) // d^2omega/dt^2 <= 0!
2502  else /* Step successful, continue integrating */
2503  return GSL_SUCCESS;
2504 } // End of XLALSimInspiralSpinTaylorStoppingTest()
2505 
2506 /*
2507  * Utility function to compute the 3PN contribution to \f$\omega\f$ of circular orbit
2508  * coming from precession.
2509  * There is due to the mismatch at 3PN between \f$\dot{\phi}\f$ and \f$\omega\f$,
2510  * as explained in arXiv:1507.00406, leading to
2511  * \f$\dot{\phi} = \omega-(\Omega\cdot\lambda)^2/(2\dot{\phi})\f$,
2512  * where \f$\Omega\f$ is the precession vector of \f$\hat{L_N}\f$:
2513  * \f$\Omega= \hat{L_N}\times \dot{\hat{L_N}}\f$, which after orbit average gives
2514  * \f$\dot{\phi}=\omega-\Omega^2/(4\dot{\phi})\simeq \omega-\Omega^2/(4\omega)\f$
2515  */
2516 static REAL8 omegashift(REAL8 S1sq, // Modulo square of S1
2517  REAL8 S2sq, // Modulo square of S2
2518  REAL8 S1S2, // Scalar product of S1 and S2
2519  REAL8 LNhS1, // Scalar product of LNh and S1
2520  REAL8 LNhS2, // Scalar product of LNh and S2
2521  REAL8 OmS1, // Coefficient of S1 in Omega
2522  REAL8 OmS2 // Coefficient of S2 in Omega
2523  )
2524 {
2525  return -0.25*(OmS1*OmS1*(S1sq-LNhS1*LNhS1)+OmS2*OmS2*(S2sq-LNhS2*LNhS2)+2.*OmS1*OmS2*(S1S2-LNhS1*LNhS2));
2526 }
2527 
2528 /*
2529  * Internal function called by the integration routine.
2530  * Given the values of all the dynamical variables 'values' at time 't',
2531  * This function computes their derivatives 'dvalues'
2532  * so the ODE integrator can take a step
2533  * All non-dynamical quantities (masses, etc.) are passed in \"mparams\"
2534  *
2535  * The derivatives for \f$\omega\f$ in the spin-less case, can be found
2536  * as Eqs. (1), (7) of gr-qc/0405090, see below for spin effects
2537  *
2538  */
2539 
2541  REAL8 UNUSED t,
2542  const REAL8 values[],
2543  REAL8 dvalues[],
2544  void *mparams
2545  )
2546 {
2547  /* coordinates and derivatives */
2548  REAL8 LNhx, LNhy, LNhz, E1x, E1y, E1z, S1x, S1y, S1z, S2x, S2y, S2z;
2549  REAL8 omega, domega, dLNhx, dLNhy, dLNhz, dE1x, dE1y, dE1z;
2550  REAL8 dS1x, dS1y, dS1z, dS2x, dS2y, dS2z;
2551  /* auxiliary variables */
2552  REAL8 v, v2, v11;
2553  REAL8 LNhdotS1, LNhdotS2, S1dotS2, S1sq, S2sq;
2554  REAL8 wspin3 = 0., wspin4Avg = 0., wspin5 = 0., wspin6Avg=0.;
2556  = (XLALSimInspiralSpinTaylorTxCoeffs*) mparams;
2557 
2558  /* copy variables */
2559  // UNUSED!!: s = values[0] ;
2560  omega = values[1] ;
2561  LNhx = values[2] ; LNhy = values[3] ; LNhz = values[4] ;
2562  S1x = values[5] ; S1y = values[6] ; S1z = values[7] ;
2563  S2x = values[8] ; S2y = values[9] ; S2z = values[10];
2564  E1x = values[11]; E1y = values[12] ; E1z = values[13];
2565 
2566  if (omega <= 0.0) /* orbital frequency must be positive! */
2567  {
2569  }
2570 
2571  v = cbrt(omega);
2572  v2 = v * v;
2573  v11= omega*omega*omega*v2;
2574 
2575  LNhdotS1 = cdot(LNhx,LNhy,LNhz,S1x,S1y,S1z);
2576  LNhdotS2 = cdot(LNhx,LNhy,LNhz,S2x,S2y,S2z);
2577  S1dotS2 = cdot(S1x,S1y,S1z,S2x,S2y,S2z);
2578  S1sq = cdot(S1x,S1y,S1z,S1x,S1y,S1z);
2579  S2sq = cdot(S2x,S2y,S2z,S2x,S2y,S2z);
2580 
2581  /*
2582  * domega
2583  *
2584  * Note we are actually computing \f$d \hat{\omega} / d \hat{t}\f$
2585  * where \f$\hat{\omega} = M \omega\f$ and \f$\hat{t} = t / M\f$
2586  * Therefore \f$domega = M^2 * d\omega / dt\f$
2587  *
2588  * See Eqs. (1)-(7) of gr-qc/0405090 But note that our spin variables
2589  * are scaled by component masses relative to that paper.
2590  * i.e. \f$S_i = (m_i/M)^2 * \hat{S_i}\f$
2591  *
2592  * non-spinning coefficients of \f$\dot{\omega}\f$ (params->wdotcoeff[i])
2593  * should have been set before this function was called
2594  */
2595 
2596  switch( params->spinO )
2599 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2600  __attribute__ ((fallthrough));
2601 #endif
2603  wspin6Avg = params->wdot6S1O * LNhdotS1 + params->wdot6S2O * LNhdotS2
2604  + params->wdot6S1OS2OAvg*LNhdotS1*LNhdotS2 + params->wdot6S1S2Avg*S1dotS2
2605  + (params->wdot6S1S1Avg+params->wdot6QMS1S1Avg)*S1sq + (params->wdot6S2S2Avg+params->wdot6QMS2S2Avg)*S2sq
2606  + (params->wdot6S1OS1OAvg + params->wdot6QMS1OS1OAvg)*LNhdotS1*LNhdotS1
2607  + (params->wdot6S2OS2OAvg + params->wdot6QMS2OS2OAvg)*LNhdotS2*LNhdotS2;
2608 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2609  __attribute__ ((fallthrough));
2610 #endif
2612  // Compute 2.5PN SO correction to domega/dt
2613  // See Eq. 8.3 of gr-qc/0605140v4
2614  // Note that S_l/M^2 = (m1/M)^2 chi1 + (m2/M)^2 chi2
2615  // and Sigma_l/M^2 = (m2/M) chi2 - (m1/M) chi1
2616  wspin5 = params->wdot5S1O*LNhdotS1 + params->wdot5S2O*LNhdotS2;
2617 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2618  __attribute__ ((fallthrough));
2619 #endif
2621  wspin4Avg = params->wdot4S1S2Avg * S1dotS2 + params->wdot4S1OS2OAvg * LNhdotS1 * LNhdotS2;
2622  // Compute 2PN QM and self-spin corrections to domega/dt
2623  // This is equivalent to Eqs. 9c + 9d of astro-ph/0504538
2624  wspin4Avg += (params->wdot4S1S1Avg + params->wdot4QMS1S1Avg) * S1sq
2625  + (params->wdot4S2S2Avg + params->wdot4QMS2S2Avg) * S2sq
2626  + (params->wdot4S1OS1OAvg + params->wdot4QMS1OS1OAvg) * LNhdotS1 * LNhdotS1
2627  + (params->wdot4S2OS2OAvg + params->wdot4QMS2OS2OAvg) * LNhdotS2 * LNhdotS2;
2628 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2629  __attribute__ ((fallthrough));
2630 #endif
2632  // Compute 1.5PN SO correction to domega/dt
2633  wspin3 = params->wdot3S1O*LNhdotS1 + params->wdot3S2O*LNhdotS2;
2634 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2635  __attribute__ ((fallthrough));
2636 #endif
2640  break;
2641  default:
2642  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
2643  __func__, params->spinO );
2645  break;
2646  }
2647 
2648  domega = params->wdotnewt * v11 * ( params->wdotcoeff[0]
2649  + v * ( params->wdotcoeff[1]
2650  + v * ( params->wdotcoeff[2]
2651  + v * ( params->wdotcoeff[3] + wspin3
2652  + v * ( params->wdotcoeff[4] + wspin4Avg
2653  + v * ( params->wdotcoeff[5] + wspin5
2654  + v * ( params->wdotcoeff[6] + wspin6Avg
2655  + params->wdotlogcoeff * log(v)
2656  + v * ( params->wdotcoeff[7]
2657  + omega * ( params->wdottidal10
2658  + v2 * ( params->wdottidal12 ) ) ) ) ) ) ) ) ) );
2659 
2660  XLALSimInspiralSpinDerivativesAvg(&dLNhx,&dLNhy,&dLNhz,&dE1x,&dE1y,&dE1z,&dS1x,&dS1y,&dS1z,&dS2x,&dS2y,&dS2z,v,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,LNhdotS1,LNhdotS2,params);
2661 
2662  /* dphi = d \phi / d \hat{t} = M d \phi /dt = M \omega = \hat{\omega} */
2663  dvalues[0] = omega*(1.+omega*omega*omegashift(S1sq,S2sq,S1dotS2,LNhdotS1,LNhdotS2,params->omegashiftS1,params->omegashiftS2));
2664  dvalues[1] = domega;
2665  dvalues[2] = dLNhx; dvalues[3] = dLNhy ; dvalues[4] = dLNhz;
2666  dvalues[5] = dS1x ; dvalues[6] = dS1y ; dvalues[7] = dS1z ;
2667  dvalues[8] = dS2x ; dvalues[9] = dS2y ; dvalues[10] = dS2z ;
2668  dvalues[11] = dE1x ; dvalues[12] = dE1y ; dvalues[13] = dE1z ;
2669 
2670  return GSL_SUCCESS;
2671 } //End of XLALSimInspiralSpinTaylorT4DerivativesAvg()
2672 
2673 /*
2674  * Internal function called by the integration routine.
2675  * Given the values of all the dynamical variables 'values' at time 't',
2676  * This function computes their derivatives 'dvalues'
2677  * so the ODE integrator can take a step
2678  * All non-dynamical quantities (masses, etc.) are passed in \"mparams\"
2679  *
2680  * The derivatives for \f$\omega\f$ in the spin-less case, can be found
2681  * as Eqs. (1), (7) of gr-qc/0405090, see below for spin effects
2682  *
2683  */
2684 
2686  double UNUSED t,
2687  const double values[],
2688  double dvalues[],
2689  void *mparams
2690  )
2691 {
2692  /* coordinates and derivatives */
2693  REAL8 LNhx, LNhy, LNhz, S1x, S1y, S1z, S2x, S2y, S2z,E1x,E1y,E1z;
2694  REAL8 omega, domega, dLNhx, dLNhy, dLNhz, dE1x, dE1y, dE1z;
2695  REAL8 dS1x, dS1y, dS1z, dS2x, dS2y, dS2z;
2696 
2697  /* auxiliary variables */
2698  REAL8 v, v2, v3, v4, v7, v11;
2699  REAL8 LNhdotS1, LNhdotS2, S1dotS2, S1sq, S2sq;
2700  REAL8 Fspin3 = 0., Fspin4Avg = 0., Fspin5 = 0., Fspin6Avg = 0.;
2701  REAL8 Espin3 = 0., Espin4Avg = 0., Espin5 = 0., Espin6Avg = 0., Espin7 = 0.;
2702 
2704  = (XLALSimInspiralSpinTaylorTxCoeffs*) mparams;
2705 
2706  /* copy variables */
2707  omega = values[1] ;
2708  LNhx = values[2] ; LNhy = values[3] ; LNhz = values[4] ;
2709  S1x = values[5] ; S1y = values[6] ; S1z = values[7] ;
2710  S2x = values[8] ; S2y = values[9] ; S2z = values[10];
2711  E1x = values[11]; E1y = values[12]; E1z = values[13];
2712 
2713  if (omega <= 0.0) /* orbital frequency must be positive! */
2714  {
2716  }
2717 
2718  v = cbrt(omega);
2719  v2 = v * v; v3 = v2 * v; v4 = v3 * v;
2720  v7 = v4 * v3; v11 = v7 * v4;
2721 
2722  LNhdotS1 = (LNhx*S1x + LNhy*S1y + LNhz*S1z);
2723  LNhdotS2 = (LNhx*S2x + LNhy*S2y + LNhz*S2z);
2724  S1dotS2 = (S1x*S2x + S1y*S2y + S1z*S2z );
2725  S1sq = (S1x*S1x + S1y*S1y + S1z*S1z);
2726  S2sq = (S2x*S2x + S2y*S2y + S2z*S2z);
2727  S1dotS2 = (S1x*S2x + S1y*S2y + S1z*S2z);
2728 
2729  /*
2730  * domega
2731  *
2732  * Note we are actually computing \f$d \hat{\omega} / d \hat{t}\f$
2733  * where \f$\hat{\omega} = M \omega\f$ and \f$\hat{t} = t / M\f$
2734  * Therefore \f$domega = M^2 * d\omega / dt\f$
2735  *
2736  * See Eqs. (1)-(7) of gr-qc/0405090 But note that our spin variables
2737  * are scaled by component masses relative to that paper.
2738  * i.e. \f$S_i = (m_i/M)^2 * \hat{S_i}\f$
2739  *
2740  * non-spinning coefficients of \f$\dot{\omega}\f$ (params->wdotcoeff[i])
2741  * should have been set before this function was called
2742  */
2743 
2744  switch( params->spinO )
2747 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2748  __attribute__ ((fallthrough));
2749 #endif
2751  Fspin6Avg = params->F6S1S2Avg*S1dotS2 + params->F6S1OS2OAvg * LNhdotS1*LNhdotS2;
2752  Fspin6Avg+= (params->F6S1S1Avg + params->F6QMS1S1Avg) * S1sq
2753  + (params->F6S2S2Avg + params->F6QMS2S2Avg) * S2sq
2754  + (params->F6S1OS1OAvg + params->F6QMS1OS1OAvg)* LNhdotS1 * LNhdotS1
2755  + (params->F6S2OS2OAvg + params->F6QMS2OS2OAvg)* LNhdotS2 * LNhdotS2;
2756 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2757  __attribute__ ((fallthrough));
2758 #endif
2760  // Compute 2.5PN SO correction to domega/dt
2761  // See Eq. 8.3 of gr-qc/0605140v4
2762  // Note that S_l/M^2 = (m1/M)^2 chi1 + (m2/M)^2 chi2
2763  // and Sigma_l/M^2 = (m2/M) chi2 - (m1/M) chi1
2764  Fspin5 += params->F5S1O*LNhdotS1 + params->F5S2O*LNhdotS2;
2765 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2766  __attribute__ ((fallthrough));
2767 #endif
2769  Fspin4Avg += params->F4S1S2Avg*S1dotS2 + params->F4S1OS2OAvg * LNhdotS1*LNhdotS2;
2770  // Compute 2PN QM and self-spin corrections to domega/dt
2771  Fspin4Avg += (params->F4S1S1Avg + params->F4QMS1S1Avg) * S1sq
2772  + (params->F4S2S2Avg + params->F4QMS2S2Avg) * S2sq
2773  + (params->F4S1OS1OAvg + params->F4QMS1OS1OAvg)* LNhdotS1 * LNhdotS1
2774  + (params->F4S2OS2OAvg + params->F4QMS2OS2OAvg)* LNhdotS2 * LNhdotS2;
2775 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2776  __attribute__ ((fallthrough));
2777 #endif
2779  // Compute 1.5PN SO correction to domega/dt
2780  Fspin3 = params->F3S1O*LNhdotS1 + params->F3S2O*LNhdotS2;
2781 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2782  __attribute__ ((fallthrough));
2783 #endif
2787  break;
2788  default:
2789  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
2790  __func__, params->spinO );
2792  break;
2793  }
2794  XLALSimInspiralSetEnergyPNTermsAvg(&Espin3,&Espin4Avg,&Espin5,&Espin6Avg,&Espin7,params,LNhdotS1,LNhdotS2,S1sq,S2sq,S1dotS2);
2795 
2796  XLALSimInspiralSpinDerivativesAvg(&dLNhx,&dLNhy,&dLNhz,&dE1x,&dE1y,&dE1z,&dS1x,&dS1y,&dS1z,&dS2x,&dS2y,&dS2z,v,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,LNhdotS1,LNhdotS2,params);
2797 
2798  domega =-6.0* (params->Fnewt/params->dEdvnewt) * v11 *
2799  (((( 1. + v * v * ( params->Fcoeff[2]
2800  + v * ( (params->Fcoeff[3] + Fspin3 )
2801  + v * ( (params->Fcoeff[4] + Fspin4Avg )
2802  + v * ( (params->Fcoeff[5] + Fspin5)
2803  + v * ( (params->Fcoeff[6] + Fspin6Avg+ params->Flogcoeff*log(v))
2804  + v * ( (params->Fcoeff[7])
2805  + v * v * v * ( params->Ftidal10
2806  + v * v * ( params->Ftidal12 ) ) )))))))))/
2807  ( 2. + v * v * ( 4. * params->Ecoeff[2]
2808  + v * (( 5. * (params->Ecoeff[3] + Espin3 ))
2809  + v * (( 6. * (params->Ecoeff[4] + Espin4Avg ))
2810  + v * (( 7. * (params->Ecoeff[5] + Espin5 ))
2811  + v * (( 8. * (params->Ecoeff[6] + Espin6Avg ))
2812  + v * ( (9. * (params->Ecoeff[7] ) )
2813  + v * v * v * (( 12. * params->Etidal10)
2814  + v * v * ( 14. * params->Etidal12 ) )
2815  ))))))) );
2816 
2817  /* dphi = d \phi / d \hat{t} = M d \phi /dt = M \omega = \hat{\omega} */
2818  dvalues[0] = omega*(1.+omega*omega*omegashift(S1sq,S2sq,S1dotS2,LNhdotS1,LNhdotS2,params->omegashiftS1,params->omegashiftS2));
2819  dvalues[1] = domega;
2820  dvalues[2] = dLNhx; dvalues[3] = dLNhy ; dvalues[4] = dLNhz;
2821  dvalues[5] = dS1x ; dvalues[6] = dS1y ; dvalues[7] = dS1z ;
2822  dvalues[8] = dS2x ; dvalues[9] = dS2y ; dvalues[10] = dS2z ;
2823  dvalues[11] = dE1x ; dvalues[12] = dE1y ; dvalues[13] = dE1z ;
2824 
2825  return GSL_SUCCESS;
2826 } // End of XLALSimInspiralSpinTaylorT1DerivativesAvg()
2827 
2828 /*
2829  * Internal function called by the integration routine.
2830  * Given the values of all the dynamical variables 'values' at time 't',
2831  * This function computes their derivatives 'dvalues'
2832  * so the ODE integrator can take a step
2833  * All non-dynamical quantities (masses, etc.) are passed in \"mparams\"
2834  *
2835  * The derivatives for \f$\omega\f$ in the spin-less case, can be found
2836  * as Eqs. (1), (7) of gr-qc/0405090, see below for spin effects
2837  *
2838  */
2839 
2841  double UNUSED t,
2842  const double values[],
2843  double dvalues[],
2844  void *mparams
2845  )
2846 {
2847  /* coordinates and derivatives */
2848  REAL8 LNhx, LNhy, LNhz, S1x, S1y, S1z, S2x, S2y, S2z, E1x, E1y, E1z;
2849  REAL8 omega, domega, dLNhx, dLNhy, dLNhz,dE1x,dE1y,dE1z;
2850  REAL8 dS1x, dS1y, dS1z, dS2x, dS2y, dS2z;
2851 
2852  /* auxiliary variables */
2853  REAL8 v,v11;
2854  REAL8 LNhdotS1, LNhdotS2, S1dotS2, S1sq, S2sq;
2855  REAL8 wspin3 = 0., wspin4Avg = 0., wspin5 = 0., wspin6Avg = 0.;
2856 
2858  = (XLALSimInspiralSpinTaylorTxCoeffs*) mparams;
2859 
2860  /* copy variables */
2861  omega = values[1] ;
2862  LNhx = values[2] ; LNhy = values[3] ; LNhz = values[4] ;
2863  S1x = values[5] ; S1y = values[6] ; S1z = values[7] ;
2864  S2x = values[8] ; S2y = values[9] ; S2z = values[10];
2865  E1x = values[11]; E1y = values[12]; E1z = values[13];
2866 
2867  if (omega <= 0.0) /* orbital frequency must be positive! */
2868  {
2870  }
2871 
2872  v = cbrt(omega);
2873  v11=omega*omega*omega*v*v;
2874 
2875  LNhdotS1 = (LNhx*S1x + LNhy*S1y + LNhz*S1z);
2876  LNhdotS2 = (LNhx*S2x + LNhy*S2y + LNhz*S2z);
2877  S1dotS2 = (S1x*S2x + S1y*S2y + S1z*S2z );
2878  S1sq = (S1x*S1x + S1y*S1y + S1z*S1z);
2879  S2sq = (S2x*S2x + S2y*S2y + S2z*S2z);
2880 
2881  /*
2882  * domega
2883  *
2884  * Note we are actually computing \f$d \hat{\omega} / d \hat{t}\f$
2885  * where \f$\hat{\omega} = M \omega\f$ and \f$\hat{t} = t / M\f$
2886  * Therefore \f$domega = M^2 * d\omega / dt\f$
2887  *
2888  * See Eqs. (1)-(7) of gr-qc/0405090 But note that our spin variables
2889  * are scaled by component masses relative to that paper.
2890  * i.e. \f$S_i = (m_i/M)^2 * \hat{S_i}\f$
2891  *
2892  * non-spinning coefficients of \f$\dot{\omega}\f$ (params->wdotcoeff[i])
2893  * should have been set before this function was called
2894  */
2895 
2896  switch( params->spinO )
2899 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2900  __attribute__ ((fallthrough));
2901 #endif
2903  wspin6Avg = params->wdot6S1O*LNhdotS1 + params->wdot6S2O*LNhdotS2
2904  + params->wdot6S1S2Avg*S1dotS2 + params->wdot6S1OS2OAvg*LNhdotS1*LNhdotS2
2905  + (params->wdot6S1S1Avg + params->wdot6QMS1S1Avg)*S1sq
2906  + (params->wdot6S2S2Avg + params->wdot6QMS2S2Avg)*S2sq
2907  + (params->wdot6S1OS1OAvg + params->wdot6QMS1OS1OAvg)*LNhdotS1*LNhdotS1 +
2908  + (params->wdot6S2OS2OAvg + params->wdot6QMS2OS2OAvg)*LNhdotS2*LNhdotS2;
2909 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2910  __attribute__ ((fallthrough));
2911 #endif
2913  // Compute 2.5PN SO correction to domega/dt
2914  // See Eq. 8.3 of gr-qc/0605140v4
2915  // Note that S_l/M^2 = (m1/M)^2 chi1 + (m2/M)^2 chi2
2916  // and Sigma_l/M^2 = (m2/M) chi2 - (m1/M) chi1
2917  wspin5 = params->wdot5S1O*LNhdotS1 + params->wdot5S2O*LNhdotS2;
2918 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2919  __attribute__ ((fallthrough));
2920 #endif
2922  wspin4Avg = params->wdot4S1S2Avg *S1dotS2 + params->wdot4S1OS2OAvg *LNhdotS1 * LNhdotS2;
2923  // Compute 2PN QM and self-spin corrections to domega/dt
2924  // See last line of Eq. 5.17 of arXiv:0812.4413
2925  // Also note this is equivalent to Eqs. 9c + 9d of astro-ph/0504538
2926  wspin4Avg += (params->wdot4S1S1Avg + params->wdot4QMS1S1Avg) * S1sq
2927  + (params->wdot4S2S2Avg + params->wdot4QMS2S2Avg) * S2sq
2928  + (params->wdot4S1OS1OAvg + params->wdot4QMS1OS1OAvg) * LNhdotS1 * LNhdotS1
2929  + (params->wdot4S2OS2OAvg + params->wdot4QMS2OS2OAvg) * LNhdotS2 * LNhdotS2;
2930 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2931  __attribute__ ((fallthrough));
2932 #endif
2934  // Compute 1.5PN SO correction to domega/dt
2935  wspin3 = params->wdot3S1O*LNhdotS1 + params->wdot3S2O*LNhdotS2;
2936 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2937  __attribute__ ((fallthrough));
2938 #endif
2942  break;
2943  default:
2944  XLALPrintError("XLAL Error - %s: Invalid spin PN order %d\n",
2945  __func__, params->spinO );
2947  break;
2948  }
2949 
2950  domega = params->wdotnewt * v11 / ( params->wdotcoeff[0]
2951  + v * ( params->wdotcoeff[1]
2952  + v * ( params->wdotcoeff[2]
2953  + v * ( params->wdotcoeff[3] + wspin3
2954  + v * ( params->wdotcoeff[4] + wspin4Avg
2955  + v * ( params->wdotcoeff[5] + wspin5
2956  + v * ( params->wdotcoeff[6] + wspin6Avg
2957  + params->wdotlogcoeff * log(v)
2958  + v * ( params->wdotcoeff[7]
2959  + omega * ( params->wdottidal10
2960  + v*v * ( params->wdottidal12 ) ) ) ) ) ) ) ) ) );
2961 
2962  XLALSimInspiralSpinDerivativesAvg(&dLNhx,&dLNhy,&dLNhz,&dE1x,&dE1y,&dE1z,&dS1x,&dS1y,&dS1z,&dS2x,&dS2y,&dS2z,v,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,LNhdotS1,LNhdotS2,params);
2963 
2964  /* dphi = d \phi / d \hat{t} = M d \phi /dt = M \omega = \hat{\omega} */
2965  dvalues[0] = omega*(1.+omega*omega*omegashift(S1sq,S2sq,S1dotS2,LNhdotS1,LNhdotS2,params->omegashiftS1,params->omegashiftS2));
2966  dvalues[1] = domega;
2967  dvalues[2] = dLNhx; dvalues[3] = dLNhy ; dvalues[4] = dLNhz;
2968  dvalues[5] = dS1x ; dvalues[6] = dS1y ; dvalues[7] = dS1z ;
2969  dvalues[8] = dS2x ; dvalues[9] = dS2y ; dvalues[10] = dS2z ;
2970  dvalues[11] = dE1x ; dvalues[12] = dE1y ; dvalues[13] = dE1z ;
2971 
2972  return GSL_SUCCESS;
2973 } /* End of XLALSimInspiralSpinTaylorT5DerivativesAvg() */
2974 
2975 /* Appends the start and end time series together, skipping the redundant first
2976  * sample of end. Frees end before returning a pointer to the result, which is
2977  * the resized start series. */
2979  REAL8TimeSeries *end) {
2980  unsigned int origlen = start->data->length;
2981  start = XLALResizeREAL8TimeSeries(start, 0,
2982  start->data->length + end->data->length - 1);
2983 
2984  memcpy(start->data->data + origlen, end->data->data+1,
2985  (end->data->length-1)*sizeof(REAL8));
2986 
2987  XLALGPSAdd(&(start->epoch), -end->deltaT*(end->data->length - 1));
2988 
2990 
2991  return start;
2992 }
2993 
2994 /**
2995  * Driver function to generate any of SpinTaylorT1/T5/T4
2996  * If the output entries are not null the relative variables are returned.
2997  * The dictionary LALparams is searched for
2998  * PNAmplitudeOrder, amplitude PN order, default -1, i.e. maximum order available
2999  * PNPhaseOrder, phasing PN order, default -1, i.e. maximum order available
3000  * PNSpinOrder, spin-dependent term maximum order in PN-phasing, default -1, they start at 1.5PN order
3001  * PNtidalOrder, tidal PN order, default -1, they start at 5PN order (spin-less case only)
3002  * Lscorr, flag to include spin correction to orbital angular momentum (1), default value 0, i.e. spin corrections not included
3003  * QuadMon1, value of quadrupole-monopole dimension-less coupling for component 1 diminished by 1, default 0 (BH case in GR)
3004  * QuadMon2, value of quadrupole-monopole dimension-less coupling for component 2 diminished by 1, default 0 (BH case in GR)
3005  * Lambda1, value of the dimension-less tidal parameter for component 1, default 0 (BH in GR)
3006  * Lambda2, value of the dimension-less tidal parameter for component 2, default 0 (BH in GR)
3007  * FinalFreq, value of the final frequency to integrate to, in Hz
3008  * OnlyFinal, flag to only output the final values and not output the waveform (1), default value 0, i.e., intermediate values and waveform output
3009  * To insert a value named "NAME" into the LALDict dictionary use the instruction
3010  * XLALSimInspiralWaveformParamsInsertNAME(LALparams, value)
3011  * to read a value named "NAME" from the LALDict dictionary use the instruction
3012  * XLALSimInspiralWaveformParamsLookupNAME(LALparams, value)
3013  * NAMEs checked over are
3014  * * PNAmplitudeOrder
3015  * * PNPhaseOrder
3016  * * PNSpinOrder
3017  * * PNTidalOrder
3018  * * Lscorr
3019  * * dQuadMon1
3020  * * dQuadMon2
3021  * * TidalLambda1
3022  * * TidalLambda2
3023  * * FinalFreq
3024  * * OnlyFinal
3025  * Next-to-last version REVIEWED completed on git hash 6640e79e60791d5230731acc63351676ce7ce413
3026  */
3028  REAL8TimeSeries **hplus, /**< +-polarization waveform */
3029  REAL8TimeSeries **hcross, /**< x-polarization waveform */
3030  REAL8TimeSeries **Vout, /**< PN parameter v */
3031  REAL8TimeSeries **Phiout, /**< main GW phase */
3032  REAL8TimeSeries **S1xout, /**< spin1 x-component*/
3033  REAL8TimeSeries **S1yout, /**< spin1 y-component*/
3034  REAL8TimeSeries **S1zout, /**< spin1 z-component*/
3035  REAL8TimeSeries **S2xout, /**< spin2 x-component*/
3036  REAL8TimeSeries **S2yout, /**< spin2 y-component*/
3037  REAL8TimeSeries **S2zout, /**< spin2 z-component*/
3038  REAL8TimeSeries **LNhxout, /**< Newtonian L unit vector x-component*/
3039  REAL8TimeSeries **LNhyout, /**< Newtonian L unit vector y-component*/
3040  REAL8TimeSeries **LNhzout, /**< Newtonian L unit vector <-component*/
3041  REAL8TimeSeries **E1xout, /**< x-axis triad unit vector x-component*/
3042  REAL8TimeSeries **E1yout, /**< x-axis triad unit vector y-component*/
3043  REAL8TimeSeries **E1zout, /**< x-axis triad unit vector z-component*/
3044  const REAL8 phiRef, /**< orbital phase at reference pt. */
3045  const REAL8 deltaT, /**< sampling interval (s) */
3046  const REAL8 m1_SI, /**< mass of companion 1 (kg) */
3047  const REAL8 m2_SI, /**< mass of companion 2 (kg) */
3048  const REAL8 fStart, /**< start GW frequency (Hz) */
3049  const REAL8 fRef, /**< reference GW frequency (Hz) */
3050  const REAL8 r, /**< distance of source (m) */
3051  const REAL8 s1x, /**< initial value of S1x */
3052  const REAL8 s1y, /**< initial value of S1y */
3053  const REAL8 s1z, /**< initial value of S1z */
3054  const REAL8 s2x, /**< initial value of S2x */
3055  const REAL8 s2y, /**< initial value of S2y */
3056  const REAL8 s2z, /**< initial value of S2z */
3057  const REAL8 lnhatx, /**< initial value of LNhatx */
3058  const REAL8 lnhaty, /**< initial value of LNhaty */
3059  const REAL8 lnhatz, /**< initial value of LNhatz */
3060  const REAL8 e1x, /**< initial value of E1x */
3061  const REAL8 e1y, /**< initial value of E1y */
3062  const REAL8 e1z, /**< initial value of E1z */
3063  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
3064  const Approximant approx /**< PN approximant (SpinTaylorT1/T5/T4) */
3065  )
3066 {
3067  if ( hplus )
3068  if ( *hplus ) {
3069  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*h+) is expected to be NULL; got %p\n",*hplus);
3071  }
3072  if ( hcross )
3073  if ( *hcross ) {
3074  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*hx) is expected to be NULL; got %p\n",*hcross);
3076  }
3077  if ( Phiout )
3078  if ( *Phiout ) {
3079  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*Phiout) is expected to be NULL; got %p\n",*Phiout);
3081  }
3082  if ( S1xout )
3083  if ( *S1xout ) {
3084  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S1xout) is expected to be NULL; got %p\n",*S1xout);
3086  }
3087  if ( S1yout )
3088  if ( *S1yout ) {
3089  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S1yout) is expected to be NULL; got %p\n",*S1yout);
3091  }
3092  if ( S1zout )
3093  if ( *S1zout ) {
3094  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S1zout) is expected to be NULL; got %p\n",*S1zout);
3096  }
3097  if ( S2xout )
3098  if ( *S2xout ) {
3099  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S2xout) is expected to be NULL; got %p\n",*S2xout);
3101  }
3102  if ( S2yout )
3103  if ( *S2yout ) {
3104  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S2yout) is expected to be NULL; got %p\n",*S2yout);
3106  }
3107  if ( S2zout )
3108  if ( *S2zout ) {
3109  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*S2zout) is expected to be NULL; got %p\n",*S2zout);
3111  }
3112  if ( LNhxout )
3113  if ( *LNhxout ) {
3114  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*LNhxout) is expected to be NULL; got %p\n",*LNhxout);
3116  }
3117  if ( LNhyout )
3118  if ( *LNhyout ) {
3119  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*LNhyout) is expected to be NULL; got %p\n",*LNhyout);
3121  }
3122  if ( LNhzout )
3123  if ( *LNhzout ) {
3124  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*LNhzout) is expected to be NULL; got %p\n",*LNhzout);
3126  }
3127  if ( E1xout )
3128  if ( *E1xout ) {
3129  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*E1xout) is expected to be NULL; got %p\n",*E1xout);
3131  }
3132  if ( E1yout )
3133  if ( *E1yout ) {
3134  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*E1yout) is expected to be NULL; got %p\n",*E1yout);
3136  }
3137  if ( E1zout )
3138  if ( *E1zout ) {
3139  XLALPrintError("** LALSimIMRPSpinInspiralRD ERROR **: (*E1zout) is expected to be NULL; got %p\n",*E1zout);
3141  }
3142 
3143  REAL8TimeSeries *V, *Phi, *S1x, *S1y, *S1z, *S2x, *S2y, *S2z;
3144  REAL8TimeSeries *LNhatx, *LNhaty, *LNhatz, *E1x, *E1y, *E1z;
3145  int status=0, n;
3146  unsigned int i;
3147  REAL8 fS, fE, phiShift;
3148  /* The Schwarzschild ISCO frequency - for sanity checking fRef */
3149  REAL8 fISCO = 1./(pow(6.,3./2.)*LAL_PI*(m1_SI+m2_SI)/LAL_MSUN_SI*LAL_MTSUN_SI);
3150 
3155  INT4 lscorr = XLALSimInspiralWaveformParamsLookupLscorr(LALparams);
3156  REAL8 quadparam1 = 1.+XLALSimInspiralWaveformParamsLookupdQuadMon1(LALparams);
3157  REAL8 quadparam2 = 1.+XLALSimInspiralWaveformParamsLookupdQuadMon2(LALparams);
3160 
3161  /* phiRef is used to rotate axis, not to shift phi*/
3162  REAL8 e1xtmp=e1x;
3163  REAL8 e1ytmp=e1y;
3164  REAL8 e1ztmp=e1z;
3165  REAL8 e1xp,e1yp,e1zp,e1xphi,e1yphi,e1zphi,lxy;
3166  REAL8 alpha=atan2(lnhaty,lnhatx);
3167  //Rotation in the x-y plane to bring L along x
3168  lxy=lnhatx*cos(alpha)+lnhaty*sin(alpha);
3169  e1xp=e1xtmp*cos(alpha)+e1ytmp*sin(alpha);
3170  e1yp=e1ytmp*cos(alpha)-e1xtmp*sin(alpha);
3171  e1xtmp=e1xp;
3172  e1ytmp=e1yp;
3173  REAL8 iota=atan2(lxy,lnhatz);
3174  //Rotation in the x-z plane to bring L along z
3175  e1xp=e1xtmp*cos(iota)-e1ztmp*sin(iota);
3176  e1zp=e1ztmp*cos(iota)+e1xtmp*sin(iota);
3177  e1xtmp=e1xp;
3178  e1ztmp=e1zp;
3179  /* Now L is along z, we can now rotate by phiRef in the x-y plane */
3180  e1xp=e1xtmp*cos(phiRef)-e1ytmp*sin(phiRef);
3181  e1yp=e1ytmp*cos(phiRef)+e1xtmp*sin(phiRef);
3182  e1xtmp=e1xp;
3183  e1ytmp=e1yp;
3184  /* Now we undo 2 rotations to go back to the initial frame */
3185  e1xp=e1xtmp*cos(iota)+e1ztmp*sin(iota);
3186  e1zp=e1ztmp*cos(iota)-e1xtmp*sin(iota);
3187  e1xphi=e1xp*cos(alpha)-e1yp*sin(alpha);
3188  e1yphi=e1yp*cos(alpha)+e1xp*sin(alpha);
3189  e1zphi=e1zp;
3190  /* Sanity check fRef value */
3191  if( fRef < 0. )
3192  {
3193  XLALPrintError("XLAL Error - %s: fRef = %f must be >= 0\n",
3194  __func__, fRef);
3196  }
3197  if( fRef != 0. && fRef < fStart )
3198  {
3199  XLALPrintError("XLAL Error - %s: fRef = %f must be > fStart = %f\n",
3200  __func__, fRef, fStart);
3202  }
3203  if( fRef >= fISCO )
3204  {
3205  XLALPrintError("XLAL Error - %s: fRef = %f must be < Schwar. ISCO=%f\n",
3206  __func__, fRef, fISCO);
3208  }
3209 
3211  {
3212  fS = fStart;
3214  /* Evolve the dynamical variables */
3216  &S1x, &S1y, &S1z, &S2x, &S2y, &S2z,
3217  &LNhatx, &LNhaty, &LNhatz, &E1x, &E1y, &E1z,
3218  deltaT, m1_SI, m2_SI, fS, fE, s1x, s1y, s1z, s2x, s2y, s2z,
3219  lnhatx, lnhaty, lnhatz, e1xphi, e1yphi, e1zphi, lambda1, lambda2,
3220  quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, approx);
3221  if( n < 0 )
3223 
3224  /* Set orbital phase to zero */
3225  Phi->data->data[0] = 0.;
3226  }
3227  else
3228  {
3229  /* if fRef=0, just integrate from start to end. Let phiRef=phiC */
3230  if( fRef < LAL_REAL4_EPS )
3231  {
3232  fS = fStart;
3234  /* Evolve the dynamical variables */
3236  &S1x, &S1y, &S1z, &S2x, &S2y, &S2z,
3237  &LNhatx, &LNhaty, &LNhatz, &E1x, &E1y, &E1z,
3238  deltaT, m1_SI, m2_SI, fS, fE, s1x, s1y, s1z, s2x, s2y, s2z,
3239  lnhatx, lnhaty, lnhatz, e1xphi, e1yphi, e1zphi, lambda1, lambda2,
3240  quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, approx);
3241  if( n < 0 )
3243 
3244  /* Apply phase shift so orbital phase ends with desired value */
3245  phiShift = /* phiRef*/- Phi->data->data[Phi->data->length-1];
3246  /* phiRef is used to rotate axis, not to shift phi*/
3247  for( i=0; i < Phi->data->length; i++)
3248  {
3249  Phi->data->data[i] += phiShift;
3250  }
3251  }
3252  /* if fRef=fStart, just integrate from start to end. Let phiRef=phiStart */
3253  else if( fabs(fRef - fStart) < LAL_REAL4_EPS )
3254  {
3255  fS = fStart;
3257  /* Evolve the dynamical variables */
3259  &S1x, &S1y, &S1z, &S2x, &S2y, &S2z,
3260  &LNhatx, &LNhaty, &LNhatz, &E1x, &E1y, &E1z,
3261  deltaT, m1_SI, m2_SI, fS, fE, s1x, s1y, s1z, s2x, s2y, s2z,
3262  lnhatx, lnhaty, lnhatz, e1xphi, e1yphi, e1zphi, lambda1, lambda2,
3263  quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, approx);
3264  if( n < 0 )
3266 
3267  /* Apply phase shift so orbital phase starts with desired value */
3268  phiShift = /*phiRef*/ - Phi->data->data[0];
3269  /* phiRef is used to rotate axis, not to shift phi*/
3270  for( i=0; i < Phi->data->length; i++)
3271  {
3272  Phi->data->data[i] += phiShift;
3273  }
3274  }
3275  else /* Start in middle, integrate backward and forward, stitch together */
3276  {
3277  REAL8TimeSeries *V1=NULL, *Phi1=NULL, *S1x1=NULL, *S1y1=NULL, *S1z1=NULL, *S2x1=NULL, *S2y1=NULL, *S2z1=NULL;
3278  REAL8TimeSeries *LNhatx1=NULL, *LNhaty1=NULL, *LNhatz1=NULL, *E1x1=NULL, *E1y1=NULL, *E1z1=NULL;
3279  REAL8TimeSeries *V2=NULL, *Phi2=NULL, *S1x2=NULL, *S1y2=NULL, *S1z2=NULL, *S2x2=NULL, *S2y2=NULL, *S2z2=NULL;
3280  REAL8TimeSeries *LNhatx2=NULL, *LNhaty2=NULL, *LNhatz2=NULL, *E1x2=NULL, *E1y2=NULL, *E1z2=NULL;
3281 
3282  /* Integrate backward to fStart */
3283  fS = fRef;
3284  fE = fStart;
3286  &S1x1, &S1y1, &S1z1, &S2x1, &S2y1, &S2z1,
3287  &LNhatx1, &LNhaty1, &LNhatz1, &E1x1, &E1y1, &E1z1,
3288  deltaT, m1_SI, m2_SI, fS, fE, s1x, s1y, s1z, s2x, s2y,
3289  s2z, lnhatx, lnhaty, lnhatz, e1xphi, e1yphi, e1zphi, lambda1, lambda2,
3290  quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, approx);
3291  if( n < 0 )
3292  {
3294  }
3295 
3296  /* Apply phase shift so orbital phase has desired value at fRef */
3297  phiShift = /*phiRef*/ - Phi1->data->data[Phi1->data->length-1];
3298  /* phiRef is used to rotate axis, not to shift phi*/
3299  for( i=0; i < Phi1->data->length; i++)
3300  {
3301  Phi1->data->data[i] += phiShift;
3302  }
3303 
3304  /* Integrate forward to end of waveform */
3305  fS = fRef;
3308  &S1x2, &S1y2, &S1z2, &S2x2, &S2y2, &S2z2,
3309  &LNhatx2, &LNhaty2, &LNhatz2, &E1x2, &E1y2, &E1z2,
3310  deltaT, m1_SI, m2_SI, fS, fE, s1x, s1y, s1z, s2x, s2y,
3311  s2z, lnhatx, lnhaty, lnhatz, e1xphi, e1yphi, e1zphi, lambda1, lambda2,
3312  quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, approx);
3313  if( n < 0 )
3314  {
3316  }
3317 
3318  /* Apply phase shift so orbital phase has desired value at fRef */
3319  phiShift = /*phiRef*/ - Phi2->data->data[0];
3320  /* phiRef is used to rotate axis, not to shift phi*/
3321  for( i=0; i < Phi2->data->length; i++)
3322  {
3323  Phi2->data->data[i] += phiShift;
3324  }
3325 
3326  /* Stitch 2nd set of vectors onto 1st set. Free 2nd set. */
3327  V = appendTSandFree(V1, V2);
3328  Phi = appendTSandFree(Phi1, Phi2);
3329  S1x = appendTSandFree(S1x1, S1x2);
3330  S1y = appendTSandFree(S1y1, S1y2);
3331  S1z = appendTSandFree(S1z1, S1z2);
3332  S2x = appendTSandFree(S2x1, S2x2);
3333  S2y = appendTSandFree(S2y1, S2y2);
3334  S2z = appendTSandFree(S2z1, S2z2);
3335  LNhatx = appendTSandFree(LNhatx1, LNhatx2);
3336  LNhaty = appendTSandFree(LNhaty1, LNhaty2);
3337  LNhatz = appendTSandFree(LNhatz1, LNhatz2);
3338  E1x = appendTSandFree(E1x1, E1x2);
3339  E1y = appendTSandFree(E1y1, E1y2);
3340  E1z = appendTSandFree(E1z1, E1z2);
3341  }
3342 
3343  /* Use the dynamical variables to build the polarizations */
3344  if (hplus && hcross) {
3346  V, Phi, S1x, S1y, S1z, S2x, S2y, S2z, LNhatx, LNhaty, LNhatz,
3347  E1x, E1y, E1z, m1_SI, m2_SI, r, ampO);
3348  }
3349  }
3350 
3351  /* Destroy vectors of dynamical variables, check for errors then exit */
3352  if (Vout)
3353  *Vout=V;
3354  else
3356  if (Phiout)
3357  *Phiout=Phi;
3358  else
3360  if (S1xout)
3361  *S1xout=S1x;
3362  else
3364  if (S1yout)
3365  *S1yout=S1y;
3366  else
3368  if (S1zout)
3369  *S1zout=S1z;
3370  else
3372  if (S2xout)
3373  *S2xout=S2x;
3374  else
3376  if (S2yout)
3377  *S2yout=S2y;
3378  else
3380  if (S2zout)
3381  *S2zout=S2z;
3382  else
3384  if (LNhxout)
3385  *LNhxout=LNhatx;
3386  else
3388  if (LNhyout)
3389  *LNhyout=LNhaty;
3390  else
3392  if (LNhzout)
3393  *LNhzout=LNhatz;
3394  else
3396  if (E1xout)
3397  *E1xout=E1x;
3398  else
3400  if (E1yout)
3401  *E1yout=E1y;
3402  else
3404  if (E1zout)
3405  *E1zout=E1z;
3406  else
3408 
3409  if( status < 0 )
3411 
3412  return n;
3413 } //End of XLALSimInspiralSpinTaylorDriver()
3414 
3415 /**
3416  * Driver function wrapper for XLALSimInspiralSpinTaylorDriver()
3417  * with the same output except for h+ and hx time series
3418  */
3420  REAL8TimeSeries **Vout, /**< PN parameter v */
3421  REAL8TimeSeries **Phiout, /**< main GW phase */
3422  REAL8TimeSeries **S1xout, /**< spin1 x-component*/
3423  REAL8TimeSeries **S1yout, /**< spin1 y-component*/
3424  REAL8TimeSeries **S1zout, /**< spin1 z-component*/
3425  REAL8TimeSeries **S2xout, /**< spin2 x-component*/
3426  REAL8TimeSeries **S2yout, /**< spin2 y-component*/
3427  REAL8TimeSeries **S2zout, /**< spin2 z-component*/
3428  REAL8TimeSeries **LNhxout, /**< Newtonian L unit vector x-component*/
3429  REAL8TimeSeries **LNhyout, /**< Newtonian L unit vector y-component*/
3430  REAL8TimeSeries **LNhzout, /**< Newtonian L unit vector <-component*/
3431  REAL8TimeSeries **E1xout, /**< x-axis triad unit vector x-component*/
3432  REAL8TimeSeries **E1yout, /**< x-axis triad unit vector y-component*/
3433  REAL8TimeSeries **E1zout, /**< x-axis triad unit vector z-component*/
3434  const REAL8 phiRef, /**< orbital phase at reference pt. */
3435  const REAL8 deltaT, /**< sampling interval (s) */
3436  const REAL8 m1_SI, /**< mass of companion 1 (kg) */
3437  const REAL8 m2_SI, /**< mass of companion 2 (kg) */
3438  const REAL8 fStart, /**< start GW frequency (Hz) */
3439  const REAL8 fRef, /**< reference GW frequency (Hz) */
3440  const REAL8 s1x, /**< initial value of S1x */
3441  const REAL8 s1y, /**< initial value of S1y */
3442  const REAL8 s1z, /**< initial value of S1z */
3443  const REAL8 s2x, /**< initial value of S2x */
3444  const REAL8 s2y, /**< initial value of S2y */
3445  const REAL8 s2z, /**< initial value of S2z */
3446  const REAL8 lnhatx, /**< initial value of LNhatx */
3447  const REAL8 lnhaty, /**< initial value of LNhaty */
3448  const REAL8 lnhatz, /**< initial value of LNhatz */
3449  const REAL8 e1x, /**< initial value of E1x */
3450  const REAL8 e1y, /**< initial value of E1y */
3451  const REAL8 e1z, /**< initial value of E1z */
3452  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
3453  const Approximant approx /**< PN approximant (SpinTaylorT1/T5/T4) */
3454  )
3455 {
3456  /* Since this function does not return polarizations,
3457  * the value of distance to pass to XLALSimInspiralSpinTaylorDriver()
3458  * is immaterial and set to 1 here.
3459  */
3460  return XLALSimInspiralSpinTaylorDriver(NULL,NULL,Vout,Phiout,S1xout,S1yout,S1zout,S2xout,S2yout,S2zout,LNhxout,LNhyout,LNhzout,E1xout,E1yout,E1zout,phiRef,deltaT,m1_SI,m2_SI,fStart,fRef,1.,s1x,s1y,s1z,s2x,s2y,s2z,lnhatx,lnhaty,lnhatz,e1x,e1y,e1z,LALparams,approx);
3461 }
3462 
3464  REAL8TimeSeries*V, /**< PN parameter v */
3465  REAL8TimeSeries *Phi, /**< orbital phase */
3466  REAL8TimeSeries *LNhx, /**< angular momentum unit vector x component */
3467  REAL8TimeSeries *LNhy, /**< angular momentum unit vector y component */
3468  REAL8TimeSeries *LNhz, /**< angular momentum unit vector z components */
3469  REAL8TimeSeries *E1x, /**< x-axis tetrad x component*/
3470  REAL8TimeSeries *E1y, /**< x-axis tetrad y component*/
3471  REAL8TimeSeries *E1z, /**< x-axis tetrad z component*/
3472  REAL8TimeSeries *S1x, /**< spin1-x component */
3473  REAL8TimeSeries *S1y, /**< spin1-y component */
3474  REAL8TimeSeries *S1z, /**< spin1-z component */
3475  REAL8TimeSeries *S2x, /**< spin2-x component */
3476  REAL8TimeSeries *S2y, /**< spin2-y component */
3477  REAL8TimeSeries *S2z, /**< spin2-z component */
3478  REAL8 m1_SI, /**< mass of companion 1 (kg) */
3479  REAL8 m2_SI, /**< mass of companion 2 (kg) */
3480  REAL8 dist_SI, /**< distance of source (m) */
3481  int ampO, /**< twice post-Newtonian amp-order */
3482  LALValue *modearray /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */)
3483 {
3484  const UINT4 lmax=4;
3485  UINT4 l;
3486  INT4 m;
3487  SphHarmTimeSeries *hlm_tmp=NULL;
3488  LALValue *modearray_int = XLALSimInspiralCreateModeArray();
3489  INT4 act, errCode=0;
3490  if ( modearray == NULL )
3491  for (l=2; l<=lmax; l++)
3493  else
3494  for (l=2; l <= lmax; l++) {
3495  m=-l-1;
3496  act=0;
3497  do {
3498  m++;
3499  act=XLALSimInspiralModeArrayIsModeActive(modearray, l, m);
3500  } while ( (m<(INT4)l) && (act==0) );
3501  if (act==1)
3503  }
3504  for (l=2; l<=lmax; l++) {
3505  m=l;
3506  if (XLALSimInspiralModeArrayIsModeActive(modearray_int, l, m) == 1 ) {
3507  if (l==2)
3508  errCode=XLALSimInspiralSpinPNMode2m(&hlm_tmp,V,Phi,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,m1_SI,m2_SI,dist_SI,ampO);
3509  else if (l==3)
3510  errCode=XLALSimInspiralSpinPNMode3m(&hlm_tmp,V,Phi,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,m1_SI,m2_SI,dist_SI,ampO);
3511  else if (l==4)
3512  errCode=XLALSimInspiralSpinPNMode4m(&hlm_tmp,V,Phi,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,m1_SI,m2_SI,dist_SI,ampO);
3513  for (m=-l; m<=(INT4)l; m++)
3515  }
3516  }
3517 
3518  return errCode;
3519 }
3520 
3522  REAL8 phiRef, /**< orbital phase at reference pt. */
3523  REAL8 dT, /**< sampling interval (s) */
3524  REAL8 m1_SI, /**< mass of companion 1 (kg) */
3525  REAL8 m2_SI, /**< mass of companion 2 (kg) */
3526  REAL8 fStart, /**< start GW frequency (Hz) */
3527  REAL8 fRef, /**< reference GW frequency (Hz) */
3528  REAL8 dist_SI, /**< distance of source (m) */
3529  REAL8 s1x, /**< ref value of S1x */
3530  REAL8 s1y, /**< ref value of S1y */
3531  REAL8 s1z, /**< ref value of S1z */
3532  REAL8 s2x, /**< ref value of S2x */
3533  REAL8 s2y, /**< ref value of S2y */
3534  REAL8 s2z, /**< ref value of S2z */
3535  REAL8 lnhatx, /**< ref value of LNhatx */
3536  REAL8 lnhaty, /**< ref value of LNhaty */
3537  REAL8 lnhatz, /**< ref value of LNhatz */
3538  REAL8 e1x, /**< ref value of E1x */
3539  REAL8 e1y, /**< ref value of E1y */
3540  REAL8 e1z, /**< ref value of E1z */
3541  int ampO, /**< twice post-Newtonian amp-order */
3542  LALValue *modearray, /**< Container for the ell and m modes to generate. To generate all available modes pass NULL */
3543  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
3544  Approximant approx /**< PN approximant (SpinTaylorT1/T2/T4) */
3545  )
3546 {
3547  REAL8TimeSeries *V=NULL;
3548  REAL8TimeSeries *Phi=NULL;
3549  REAL8TimeSeries *LNhx=NULL;
3550  REAL8TimeSeries *LNhy=NULL;
3551  REAL8TimeSeries *LNhz=NULL;
3552  REAL8TimeSeries *S1x=NULL;
3553  REAL8TimeSeries *S1y=NULL;
3554  REAL8TimeSeries *S1z=NULL;
3555  REAL8TimeSeries *S2x=NULL;
3556  REAL8TimeSeries *S2y=NULL;
3557  REAL8TimeSeries *S2z=NULL;
3558  REAL8TimeSeries *E1x=NULL;
3559  REAL8TimeSeries *E1y=NULL;
3560  REAL8TimeSeries *E1z=NULL;
3561 
3562  int err_code=XLALSimInspiralSpinTaylorDriver(NULL,NULL,&V,&Phi,&S1x,&S1y,&S1z,&S2x,&S2y,&S2z,&LNhx,&LNhy,&LNhz,&E1x,&E1y,&E1z,phiRef,dT,m1_SI,m2_SI,fStart,fRef,dist_SI,s1x,s1y,s1z,s2x,s2y,s2z,lnhatx,lnhaty,lnhatz,e1x,e1y,e1z,LALparams,approx);
3563  if (err_code!=XLAL_SUCCESS)
3565 
3566  return XLALSimInspiralSpinTaylorHlmModesFromOrbit(hlm,V,Phi,LNhx,LNhy,LNhz,E1x,E1y,E1z,S1x,S1y,S1z,S2x,S2y,S2z,m1_SI,m2_SI,dist_SI,ampO,modearray);
3567 
3568 }
3569 
3570 /**
3571  * This function evolves the orbital equations for a precessing binary using
3572  * the \"TaylorT5/T4\" approximant for solving the orbital dynamics
3573  * (see arXiv:0907.0700 for a review of the various PN approximants).
3574  *
3575  * It returns time series of the \"orbital velocity\", orbital phase,
3576  * and components for both individual spin vectors, the \"Newtonian\"
3577  * orbital angular momentum (which defines the instantaneous plane)
3578  * and "E1", a basis vector in the instantaneous orbital plane, as well as
3579  * the time derivative of the orbital frequency.
3580  * Note that LNhat and E1 completely specify the instantaneous orbital plane.
3581  *
3582  * For input, the function takes the two masses, the initial orbital phase,
3583  * Values of S1, S2, LNhat, E1 vectors at starting time,
3584  * the desired time step size, the starting GW frequency,
3585  * and PN order at which to evolve the phase,
3586  *
3587  * NOTE: All vectors are given in the so-called "radiation frame",
3588  * where the direction of propagation is the z-axis, the principal "+"
3589  * polarization axis is the x-axis, and the y-axis is given by the RH rule.
3590  * You must give the initial values in this frame, and the time series of the
3591  * vector components will also be returned in this frame
3592  *
3593  * !!!UNREVIEWED!!!
3594  *
3595  */
3597  REAL8Array **yout, /**< array holding the unevenly sampled output [returned] */
3598  REAL8 m1, /**< mass of companion 1 (kg) */
3599  REAL8 m2, /**< mass of companion 2 (kg) */
3600  REAL8 fStart, /**< starting GW frequency */
3601  REAL8 fEnd, /**< ending GW frequency, fEnd=0 means integrate as far forward as possible */
3602  REAL8 s1x, /**< initial value of S1x */
3603  REAL8 s1y, /**< initial value of S1y */
3604  REAL8 s1z, /**< initial value of S1z */
3605  REAL8 s2x, /**< initial value of S2x */
3606  REAL8 s2y, /**< initial value of S2y */
3607  REAL8 s2z, /**< initial value of S2z */
3608  REAL8 lnhatx, /**< initial value of LNhatx */
3609  REAL8 lnhaty, /**< initial value of LNhaty */
3610  REAL8 lnhatz, /**< initial value of LNhatz */
3611  REAL8 e1x, /**< initial value of E1x */
3612  REAL8 e1y, /**< initial value of E1y */
3613  REAL8 e1z, /**< initial value of E1z */
3614  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
3615  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
3616  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
3617  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
3618  LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
3619  LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
3620  INT4 phaseO, /**< twice post-Newtonian order */
3621  Approximant approx /**< PN approximant (SpinTaylorT1/T5/T4) */
3622  )
3623 {
3624  INT4 intreturn;
3625  void * params;
3626  LALAdaptiveRungeKuttaIntegrator *integrator = NULL; /* GSL integrator object */
3627  REAL8 yinit[LAL_NUM_ST4_VARIABLES]; /* initial values of parameters */
3628  REAL8Array *y; /* time series of variables returned from integrator */
3629  /* intermediate variables */
3630  UINT4 cutlen, len;
3631  REAL8 norm, dtStart, dtEnd, lengths, m1sec, m2sec, Msec, Mcsec, fTerm;
3632 
3633  /* Check start and end frequencies are positive */
3634  if( fStart <= 0. )
3635  {
3636  XLALPrintError("XLAL Error - %s: fStart = %f must be > 0.\n",
3637  __func__, fStart );
3639  }
3640  if( fEnd < 0. ) /* fEnd = 0 allowed as special case */
3641  {
3642  XLALPrintError("XLAL Error - %s: fEnd = %f must be >= 0.\n",
3643  __func__, fEnd );
3645  }
3646 
3647  // Fill params struct with values of constant coefficients of the model
3648  if( approx == SpinTaylorT4 )
3649  {
3651  XLALSimInspiralSpinTaylorT4Setup(&paramsT4, m1, m2, fStart, fEnd,
3652  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, 0, 0);
3653  params = (void *) &paramsT4;
3654  }
3655  else if( approx == SpinTaylorT5 )
3656  {
3658  XLALSimInspiralSpinTaylorT5Setup(&paramsT5, m1, m2, fStart, fEnd,
3659  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, 0);
3660  params = (void *) &paramsT5;
3661  }
3662  else if( approx == SpinTaylorT1 )
3663  {
3665  XLALSimInspiralSpinTaylorT1Setup(&paramsT1, m1, m2, fStart, fEnd,
3666  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, 0);
3667  params = (void *) &paramsT1;
3668  }
3669  else
3670  {
3671  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
3672  __func__, approx);
3674 
3675  }
3676  m1sec = m1 /LAL_MSUN_SI*LAL_MTSUN_SI;
3677  m2sec = m2 /LAL_MSUN_SI*LAL_MTSUN_SI;
3678  Msec = m1sec + m2sec;
3679  Mcsec = Msec * pow( m1sec*m2sec/Msec/Msec, 0.6);
3680 
3681  /* Estimate length of waveform using Newtonian t(f) formula */
3682  /* Time from freq. = fStart to infinity */
3683  dtStart = (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
3684  * pow(Mcsec * fStart,-5.0/3.0) / fStart;
3685  /* Time from freq. = fEnd to infinity. Set to zero if fEnd=0 */
3686  dtEnd = (fEnd == 0. ? 0. : (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
3687  * pow(Mcsec * fEnd,-5.0/3.0) / fEnd);
3688  /* Time in sec from fStart to fEnd. Note it can be positive or negative */
3689  lengths = dtStart - dtEnd;
3690 
3691  /* Put initial values into a single array for the integrator */
3692  yinit[0] = 0.; /* without loss of generality, set initial orbital phase=0 */
3693  yinit[1] = LAL_PI * Msec * fStart; /* \hat{omega} = (pi M f) */
3694  /* LNh(x,y,z) */
3695  yinit[2] = lnhatx;
3696  yinit[3] = lnhaty;
3697  yinit[4] = lnhatz;
3698  /* S1(x,y,z) */
3699  norm = m1sec * m1sec / Msec / Msec;
3700  yinit[5] = norm * s1x;
3701  yinit[6] = norm * s1y;
3702  yinit[7] = norm * s1z;
3703  /* S2(x,y,z) */
3704  norm = m2sec * m2sec / Msec / Msec;
3705  yinit[8] = norm * s2x;
3706  yinit[9] = norm * s2y;
3707  yinit[10]= norm * s2z;
3708  /* E1(x,y,z) */
3709  yinit[11] = e1x;
3710  yinit[12] = e1y;
3711  yinit[13] = e1z;
3712 
3713  /* initialize the integrator */
3714  if( approx == SpinTaylorT4 )
3719  else if( approx == SpinTaylorT5 )
3724  else if( approx == SpinTaylorT1 )
3729  else
3730  {
3731  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
3732  __func__, approx);
3734 
3735  }
3736  if( !integrator )
3737  {
3738  XLALPrintError("XLAL Error - %s: Cannot allocate integrator\n",
3739  __func__);
3741  }
3742 
3743  /* stop the integration only when the test is true */
3744  integrator->stopontestonly = 1;
3745 
3746  /* run the integration; note: time is measured in \hat{t} = t / M */
3747  len = XLALAdaptiveRungeKutta4IrregularIntervals(integrator, params, yinit,
3748  0.0, lengths/Msec, &y);
3749 
3750  intreturn = integrator->returncode;
3751  XLALAdaptiveRungeKuttaFree(integrator);
3752 
3753  if (!len)
3754  {
3755  XLALPrintError("XLAL Error - %s: integration failed with errorcode %d.\n", __func__, intreturn);
3757  }
3758 
3759  /* Print warning about abnormal termination */
3760  if (intreturn != 0 && intreturn != LALSIMINSPIRAL_ST_TEST_ENERGY
3761  && intreturn != LALSIMINSPIRAL_ST_TEST_FREQBOUND)
3762  {
3763  XLALPrintWarning("XLAL Warning - %s: integration terminated with code %d.\n Waveform parameters were m1 = %e, m2 = %e, s1 = (%e,%e,%e), s2 = (%e,%e,%e), inc = %e.\n",
3764  __func__, intreturn, m1 / LAL_MSUN_SI * LAL_MTSUN_SI,
3765  m2 / LAL_MSUN_SI * LAL_MTSUN_SI, s1x, s1y, s1z, s2x,
3766  s2y, s2z, acos(lnhatz));
3767  }
3768 
3769  cutlen = len;
3770 
3771  // Report termination condition and final frequency
3772  // Will only report this info if '4' bit of lalDebugLevel is 1
3773  fTerm = y->data[2*len+cutlen-1] / LAL_PI / Msec;
3774  XLALPrintInfo("XLAL Info - %s: integration terminated with code %d. The final GW frequency reached was %g\n", __func__, intreturn, fTerm);
3775 
3776  *yout = y;
3777 
3778  return XLAL_SUCCESS;
3779 }
3780 
3781 /**
3782  * @deprecated Use XLALSimInspiralChooseTDWaveform() instead
3783  * @addtogroup LALSimInspiralSpinTaylor_c
3784  * @brief Routines for generating spin precessing Taylor waveforms
3785  * @{
3786  */
3787 
3788 /**
3789  * Function to specify the desired orientation of a precessing binary in terms
3790  * of several angles and then compute the vector components in the so-called
3791  * \"radiation frame\" (with the z-axis along the direction of propagation) as
3792  * needed to specify binary configuration for ChooseTDWaveform.
3793  *
3794  * Input:
3795  * thetaJN is the inclination between total angular momentum (J) and the
3796  * direction of propagation (N)
3797  * theta1 and theta2 are the inclinations of S1 and S2
3798  * measured from the Newtonian orbital angular momentum (L_N)
3799  * phi12 is the difference in azimuthal angles of S1 and S2.
3800  * chi1, chi2 are the dimensionless spin magnitudes ( \f$0 \le chi1,2 \le 1\f$)
3801  * phiJL is the azimuthal angle of L_N on its cone about J.
3802  * m1, m2, f_ref are the component masses and reference GW frequency,
3803  * they are needed to compute the magnitude of L_N, and thus J.
3804  *
3805  * Output:
3806  * incl - inclination angle of L_N relative to N
3807  * x, y, z components S1 and S2 (unit spin vectors times their
3808  * dimensionless spin magnitudes - i.e. they have unit magnitude for
3809  * extremal BHs and smaller magnitude for slower spins).
3810  *
3811  * NOTE: Here the \"total\" angular momentum is computed as
3812  * J = L_N + S1 + S2
3813  * where L_N is the Newtonian orbital angular momentum. In fact, there are
3814  * PN corrections to L which contribute to J that are NOT ACCOUNTED FOR
3815  * in this function. This is done so the function does not need to know about
3816  * the PN order of the system and to avoid subtleties with spin-orbit
3817  * contributions to L. Also, it is believed that the difference in Jhat
3818  * with or without these PN corrections to L is quite small.
3819  *
3820  * NOTE: fRef = 0 is not a valid choice. If you will pass fRef=0 into
3821  * ChooseWaveform, then here pass in f_min, the starting GW frequency
3822  *
3823  * The various rotations in this transformation are described in more detail
3824  * in a Mathematica notebook available here:
3825  * https://www.lsc-group.phys.uwm.edu/ligovirgo/cbcnote/Waveforms/TransformPrecessingInitialConditions
3826  *
3827  * !!!UNREVIEWED!!!
3828  */
3830  REAL8 *incl, /**< Inclination angle of L_N (returned) */
3831  REAL8 *S1x, /**< S1 x component (returned) */
3832  REAL8 *S1y, /**< S1 y component (returned) */
3833  REAL8 *S1z, /**< S1 z component (returned) */
3834  REAL8 *S2x, /**< S2 x component (returned) */
3835  REAL8 *S2y, /**< S2 y component (returned) */
3836  REAL8 *S2z, /**< S2 z component (returned) */
3837  REAL8 thetaJN, /**< zenith angle between J and N (rad) */
3838  REAL8 phiJL, /**< azimuthal angle of L_N on its cone about J (rad) */
3839  REAL8 theta1, /**< zenith angle between S1 and LNhat (rad) */
3840  REAL8 theta2, /**< zenith angle between S2 and LNhat (rad) */
3841  REAL8 phi12, /**< difference in azimuthal angle btwn S1, S2 (rad) */
3842  REAL8 chi1, /**< dimensionless spin of body 1 */
3843  REAL8 chi2, /**< dimensionless spin of body 2 */
3844  REAL8 m1, /**< mass of body 1 (kg) */
3845  REAL8 m2, /**< mass of body 2 (kg) */
3846  REAL8 fRef /**< reference GW frequency (Hz) */
3847  )
3848 {
3849  /* Check that fRef is sane */
3850  if( fRef == 0. )
3851  {
3852  XLALPrintError("XLAL Error - %s: fRef=0 is invalid. Please pass in the starting GW frequency instead.\n", __func__);
3854  }
3855 
3856  REAL8 omega0, M, eta, theta0, phi0, Jnorm, tmp1, tmp2;
3857  REAL8 Jhatx, Jhaty, Jhatz, LNhx, LNhy, LNhz, Jx, Jy, Jz, LNmag;
3858  REAL8 s1hatx, s1haty, s1hatz, s2hatx, s2haty, s2hatz;
3859  REAL8 s1x, s1y, s1z, s2x, s2y, s2z;
3860 
3861  /* Starting frame: LNhat is along the z-axis and the unit
3862  * spin vectors are defined from the angles relative to LNhat.
3863  * Note that we put s1hat in the x-z plane, and phi12
3864  * sets the azimuthal angle of s2hat measured from the x-axis.
3865  */
3866  LNhx = 0.;
3867  LNhy = 0.;
3868  LNhz = 1.;
3869  s1hatx = sin(theta1);
3870  s1haty = 0.;
3871  s1hatz = cos(theta1);
3872  s2hatx = sin(theta2) * cos(phi12);
3873  s2haty = sin(theta2) * sin(phi12);
3874  s2hatz = cos(theta2);
3875 
3876  /* Define several internal variables needed for magnitudes */
3877  omega0 = LAL_PI * fRef; // orbital angular frequency at reference point
3878  m1 *= LAL_G_SI / LAL_C_SI / LAL_C_SI / LAL_C_SI;
3879  m2 *= LAL_G_SI / LAL_C_SI / LAL_C_SI / LAL_C_SI;
3880  M = m1 + m2;
3881  eta = m1 * m2 / M / M;
3882 
3883  /* Define S1, S2, J with proper magnitudes */
3884  LNmag = pow(M, 5./3.) * eta * pow(omega0, -1./3.);
3885  s1x = m1 * m1 * chi1 * s1hatx;
3886  s1y = m1 * m1 * chi1 * s1haty;
3887  s1z = m1 * m1 * chi1 * s1hatz;
3888  s2x = m2 * m2 * chi2 * s2hatx;
3889  s2y = m2 * m2 * chi2 * s2haty;
3890  s2z = m2 * m2 * chi2 * s2hatz;
3891  Jx = s1x + s2x;
3892  Jy = s1y + s2y;
3893  Jz = LNmag * LNhz + s1z + s2z;
3894 
3895  /* Normalize J to Jhat, find it's angles in starting frame */
3896  Jnorm = sqrt( Jx*Jx + Jy*Jy + Jz*Jz);
3897  Jhatx = Jx / Jnorm;
3898  Jhaty = Jy / Jnorm;
3899  Jhatz = Jz / Jnorm;
3900  theta0 = acos(Jhatz);
3901  phi0 = atan2(Jhaty, Jhatx);
3902 
3903  /* Rotation 1: Rotate about z-axis by -phi0 to put Jhat in x-z plane */
3904  ROTATEZ(-phi0, LNhx, LNhy, LNhz);
3905  ROTATEZ(-phi0, s1hatx, s1haty, s1hatz);
3906  ROTATEZ(-phi0, s2hatx, s2haty, s2hatz);
3907  ROTATEZ(-phi0, Jhatx, Jhaty, Jhatz);
3908 
3909  /* Rotation 2: Rotate about new y-axis by -theta0
3910  * to put Jhat along z-axis
3911  */
3912  ROTATEY(-theta0, LNhx, LNhy, LNhz);
3913  ROTATEY(-theta0, s1hatx, s1haty, s1hatz);
3914  ROTATEY(-theta0, s2hatx, s2haty, s2hatz);
3915  ROTATEY(-theta0, Jhatx, Jhaty, Jhatz);
3916 
3917  /* Rotation 3: Rotate about new z-axis by phiJL to put L at desired
3918  * azimuth about J. Note that is currently in x-z plane towards -x
3919  * (i.e. azimuth=pi). Hence we rotate about z by phiJL - LAL_PI
3920  */
3921  ROTATEZ(phiJL - LAL_PI, LNhx, LNhy, LNhz);
3922  ROTATEZ(phiJL - LAL_PI, s1hatx, s1haty, s1hatz);
3923  ROTATEZ(phiJL - LAL_PI, s2hatx, s2haty, s2hatz);
3924  ROTATEZ(phiJL - LAL_PI, Jhatx, Jhaty, Jhatz);
3925 
3926  /* Rotation 4: Let N be in x-z plane, inclined from J by thetaJN.
3927  * We don't need to explicitly construct it, but rotating the system
3928  * about the y-axis by - thetaJN will bring N onto the z-axis.
3929  */
3930  ROTATEY(-thetaJN, LNhx, LNhy, LNhz);
3931  ROTATEY(-thetaJN, s1hatx, s1haty, s1hatz);
3932  ROTATEY(-thetaJN, s2hatx, s2haty, s2hatz);
3933  ROTATEY(-thetaJN, Jhatx, Jhaty, Jhatz);
3934 
3935  /* Rotation 5: We already have N along z. To complete the
3936  * transformation into the radiation frame we rotate s.t.
3937  * LNhat is in the x-z plane. Thus, if LNhat has azimuth phi0,
3938  * we rotate about the z-axis by -phi0.
3939  */
3940  phi0 = atan2(LNhy, LNhx);
3941  ROTATEZ(-phi0, LNhx, LNhy, LNhz);
3942  ROTATEZ(-phi0, s1hatx, s1haty, s1hatz);
3943  ROTATEZ(-phi0, s2hatx, s2haty, s2hatz);
3944  ROTATEZ(-phi0, Jhatx, Jhaty, Jhatz);
3945 
3946  /* We have completed the transformation. Now find the inclination
3947  * of LN relative to N (the final z-axis). */
3948  *incl = acos(LNhz);
3949 
3950  /* Multiply spin unit vectors by chi magnitude (but NOT m_i^2) */
3951  s1hatx *= chi1;
3952  s1haty *= chi1;
3953  s1hatz *= chi1;
3954  s2hatx *= chi2;
3955  s2haty *= chi2;
3956  s2hatz *= chi2;
3957 
3958  /* Set pointers to rotated spin vectors */
3959  *S1x = s1hatx;
3960  *S1y = s1haty;
3961  *S1z = s1hatz;
3962  *S2x = s2hatx;
3963  *S2y = s2haty;
3964  *S2z = s2hatz;
3965 
3966  return XLAL_SUCCESS;
3967 }
3968 
3969 /**
3970  * Function to specify the desired orientation of the spin components of
3971  * a precessing binary.
3972  *
3973  * Input:
3974  * Depending on the values of the variable frameChoice
3975  * input parameters may represent different quantities.
3976  * incl is the angle between in the X-Y-Z frame specified by
3977  * * frameChoice = LAL_SIM_INSPIRAL_FRAME_AXIS_TOTAL_J
3978  * J // Z, N = (0, sin(inc), cos(inc))
3979  * * frameChoice = LAL_SIM_INSPIRAL_FRAME_AXIS_ORBITAL_L (default)
3980  * L // Z, N = (0, sin(inc), cos(inc))
3981  * * frameChoice = LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW
3982  * * N // Z, L = (sin(inc), 0, cos(inc))
3983  *
3984  * Cartesian components of S1 and S2 are given wrt axes x-y-Z (ORBITAL_L and VIEW cases),
3985  * being x the vector pointing from body 2 to body 1.
3986  * x-y axes are rotated wrt X-Y by phiRef counterclockwise, i.e. if
3987  * S1=(a,b,0) in fame x-y-Z, in frame X-Y-Z it will have components
3988  * S1'=(a cos(phiRef) - b sin(phiRef), a sin(phiRef) + b cos(phiRef), 0).
3989  * In the TOTAL_J case spin components are given wrt J, with the x-Z plane
3990  * spanned by the line connecting the two bodies and J.
3991  *
3992  * m1, m2, f_ref are the component masses and reference GW frequency,
3993  * they are needed to compute the magnitude of L_N and.
3994  * phi_ref is needed since the spin components in the plane of the orbit
3995  * are defined wrt assuming the x axis is parallel to the line joining the binary consistuents,
3996  * from body 2 to body 1.
3997  *
3998  * Output:
3999  * x, y, z components S1 and S2 wrt N
4000  * inc angle between L and N, i.e. N=(0,0,1), LN=(sin(inc),0,cos(inc))
4001  * as required by precessing waveforms routines in SpinTaylor and IRMPhenomP codes.
4002  *
4003  * NOTE: Here the \"total\" angular momentum is computed as
4004  * J = L_N(1+l_1PN) + S1 + S2
4005  * where L_N(1+l_1PN) is the 1PN-corrected orbital angular momentum,
4006  * which is parallel to Newtonian angular momentum.
4007  * PN corrections to L from 1.5PN order on (wrt to Newtonian value)
4008  * are NOT ACCOUNTED FOR in this function.
4009  */
4011  REAL8 *inc, /**< inclination angle (returned) */
4012  REAL8 *S1x, /**< S1x component (returned) */
4013  REAL8 *S1y, /**< S1y component (returned) */
4014  REAL8 *S1z, /**< S1z component (returned) */
4015  REAL8 *S2x, /**< S2x components (returned) */
4016  REAL8 *S2y, /**< S2y components (returned) */
4017  REAL8 *S2z, /**< S2z components (returned) */
4018  const REAL8 inclIn, /**< Inclination angle in input */
4019  const REAL8 S1xIn, /**< S1 x component */
4020  const REAL8 S1yIn, /**< S1 y component */
4021  const REAL8 S1zIn, /**< S1 z component */
4022  const REAL8 S2xIn, /**< S2 x component */
4023  const REAL8 S2yIn, /**< S2 y component */
4024  const REAL8 S2zIn, /**< S2 z component */
4025  const REAL8 m1, /**< mass of body 1 (kg) */
4026  const REAL8 m2, /**< mass of body 2 (kg) */
4027  const REAL8 fRef, /**< reference GW frequency (Hz) */
4028  const REAL8 phiRef, /**< reference GW phase */
4029  LALSimInspiralFrameAxis frameChoice /**< Flag to identify axis wrt which spin components are given. Pass in NULL (or None in python) for default (OrbitalL) */)
4030 {
4031  *S1x=S1xIn;
4032  *S1y=S1yIn;
4033  *S1z=S1zIn;
4034  *S2x=S2xIn;
4035  *S2y=S2yIn;
4036  *S2z=S2zIn;
4037 
4038  REAL8 Lmag=0.;
4039  REAL8 Lx,Ly,Lxy2,Lz;
4040  REAL8 LNhx,LNhy,LNhz;
4041  REAL8 v0,mass1,mass2,eta;
4042  REAL8 tmp1,tmp2;
4043  //Uncomment the following line to perform tests
4044  REAL8 Nhx,Nhy,Nhz;
4045  switch (frameChoice) {
4046  /* FRAME_AXIS_TOTAL_J
4047  * (spins wrt to J, inclIn is the angle between J and N: if
4048  * J=(0,0,1) N=(0,sin(inclIn),cos(inclIn)))
4049  */
4051  mass1=m1/LAL_MSUN_SI;
4052  mass2=m2/LAL_MSUN_SI;
4053  eta=mass1*mass2/(mass1+mass2)/(mass1+mass2);
4054  v0=cbrt(LAL_PI*fRef*(mass1+mass2)*LAL_MTSUN_SI);
4055  Lmag = XLALSimInspiralLN(mass1+mass2,eta,v0)*(1.+v0*v0*XLALSimInspiralL_2PN(eta));
4056  Lx = -(*S1x)*mass1*mass1-(*S2x)*mass2*mass2;
4057  Ly = -(*S1y)*mass1*mass1-(*S2y)*mass2*mass2;
4058  Lxy2= Lx*Lx+Ly*Ly;
4059  if (Lmag*Lmag>=Lxy2) {
4060  Lz=sqrt(Lmag*Lmag-Lxy2);
4061  if ( Lz<(S1zIn*mass1*mass1+S2zIn*mass2*mass2) ) {
4062  XLALPrintError("** XLALSimInspiralInitialConditionsPrecessingApproxs ERROR *** for s1 (%12.4e %12.4e %12.4e)\n",S1xIn,S1yIn,S1zIn);
4063  XLALPrintError(" s2 (%12.4e %12.4e %12.4e)\n",S2xIn,S2yIn,S2zIn);
4064  XLALPrintError(" wrt to J for m: (%12.4e %12.4e) and v= %12.4e\n",mass1,mass2,v0);
4065  XLALPrintError(" it is impossible to determine the sign of Lhz\n");
4067  }
4068  }
4069  else {
4070  XLALPrintError("** XLALSimInspiralInitialConditionsPrecessingApproxs ERROR *** unphysical values of s1 (%12.4e %12.4e %12.4e)\n",S1xIn,S1yIn,S1zIn);
4071  XLALPrintError(" s2 (%12.4e %12.4e %12.4e)\n",S2xIn,S2yIn,S2zIn);
4072  XLALPrintError(" wrt to J for m: (%12.4e %12.4e) and v= %12.4e\n",mass1,mass2,v0);
4074  }
4075  // 1PN corrections to L are collinear with LN
4076  // Rotation1: rotate N into z
4077  LNhx=Lx/Lmag;
4078  LNhy=Ly/Lmag;
4079  LNhz=Lz/Lmag;
4080  Nhx=0.;
4081  Nhy=sin(inclIn);
4082  Nhz=cos(inclIn);
4083  //Rotate to the orbital plane to rotate spin by phiRef there
4084  // R1:
4085  REAL8 phiLJ=atan2(LNhy,LNhx);
4086  ROTATEZ(-phiLJ,*S1x,*S1y,*S1z);
4087  ROTATEZ(-phiLJ,*S2x,*S2y,*S2z);
4088  ROTATEZ(-phiLJ,Nhx,Nhy,Nhz);
4089  ROTATEZ(-phiLJ,LNhx,LNhy,LNhz);
4090  // R2:
4091  REAL8 thetaLJ=acos(LNhz);
4092  ROTATEY(-thetaLJ,*S1x,*S1y,*S1z);
4093  ROTATEY(-thetaLJ,*S2x,*S2y,*S2z);
4094  ROTATEY(-thetaLJ,Nhx,Nhy,Nhz);
4095  ROTATEY(-thetaLJ,LNhx,LNhy,LNhz);
4096  // R3: (spins only)
4097  ROTATEZ(phiRef,*S1x,*S1y,*S1z);
4098  ROTATEZ(phiRef,*S2x,*S2y,*S2z);
4099  //Now let's go to the radiation frame
4100  // R4:
4101  REAL8 phiN=atan2(Nhy,Nhx);
4102  ROTATEZ(-phiN,*S1x,*S1y,*S1z);
4103  ROTATEZ(-phiN,*S2x,*S2y,*S2z);
4104  ROTATEZ(-phiN,LNhx,LNhy,LNhz);
4105  ROTATEZ(-phiN,Nhx,Nhy,Nhz);
4106  // R5:
4107  REAL8 thetaN=acos(Nhz);
4108  ROTATEY(-thetaN,*S1x,*S1y,*S1z);
4109  ROTATEY(-thetaN,*S2x,*S2y,*S2z);
4110  ROTATEY(-thetaN,LNhx,LNhy,LNhz);
4111  ROTATEY(-thetaN,Nhx,Nhy,Nhz);
4112  // Now rotating LNh into the x,z plane
4113  // R6:
4114  REAL8 phiL=atan2(LNhy,LNhx);
4115  ROTATEZ(-phiL,*S1x,*S1y,*S1z);
4116  ROTATEZ(-phiL,*S2x,*S2y,*S2z);
4117  ROTATEZ(-phiL,LNhx,LNhy,LNhz);
4118  ROTATEZ(-phiL,Nhx,Nhy,Nhz);
4119  *inc=acos(LNhz);
4120  //It follows that in the frame in which N=(0,0,1), LNhat=(sin(*inc),0,cos(*inc))
4121  //For a check uncomment the following lines
4122  //Anyway there is an automatic check at build in
4123  // lalsimulation/test/InitialSpinRotationTest
4124  /*printf("**************************************************\n");
4125  printf("** Check of LAL_SIM_INSPIRAL_FRAME_AXIS_TOTAL_J **\n");
4126  printf("**************************************************\n");
4127  printf("N: %12.4e %12.4e %12.4e norm: %12.4e\n",Nhx,Nhy,Nhz,sqrt(Nhx*Nhx+Nhy*Nhy+Nhz*Nhz));
4128  printf(" %12.4e %12.4e %12.4e\n",0.,0.,1.);
4129  printf("LNh: %12.4e %12.4e %12.4e norm: %12.4e\n",LNhx,LNhy,LNhz,sqrt(LNhx*LNhx+LNhy*LNhy+LNhz*LNhz));
4130  printf(" %12.4e %12.4e %12.4e\n",sin(*inc),0.,cos(*inc));
4131  printf("S1.L %12.4e %12.4e\n",(*S1x)*LNhx+(*S1y)*LNhy+(*S1z)*LNhz,(S1xIn*Lx+S1yIn*Ly+S1zIn*Lz)/Lmag);
4132  printf("S2.L %12.4e %12.4e\n",(*S2x)*LNhx+(*S2y)*LNhy+(*S2z)*LNhz,(S2xIn*Lx+S2yIn*Ly+S2zIn*Lz)/Lmag);
4133  printf("S1.S2 %12.4e %12.4e\n",(*S1x)*(*S2x)+(*S1y)*(*S2y)+(*S1z)*(*S2z),S1xIn*S2xIn+S1yIn*S2yIn+S1zIn*S2zIn);
4134  printf("**************************************************\n");*/
4135  break;
4136 
4138  /* FRAME_AXIS_VIEW
4139  * Spins at phiRef=0 are given wrt to view direction
4140  * inclIn is the angle between L and N: if
4141  * N=(0,0,1) LNhat=(sin(inclIn),0,cos(inclIn))
4142  * We need to perform the rotation by phiRef around LNhat on the spins only.
4143  */
4144  *inc=inclIn;
4145  ROTATEY(-inclIn,*S1x,*S1y,*S1z);
4146  ROTATEY(-inclIn,*S2x,*S2y,*S2z);
4147  ROTATEZ(phiRef,*S1x,*S1y,*S1z);
4148  ROTATEZ(phiRef,*S2x,*S2y,*S2z);
4149  ROTATEY(inclIn,*S1x,*S1y,*S1z);
4150  ROTATEY(inclIn,*S2x,*S2y,*S2z);
4151  //For a check uncomment the following lines
4152  //Anyway there is an automatic check at build in
4153  // lalsimulation/test/InitialSpinRotationTest
4154  /*printf("***********************************************\n");
4155  printf("** Check of LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW **\n");
4156  printf("***********************************************\n");
4157  LNhx=sin(inclIn);
4158  LNhy=0.;
4159  LNhz=cos(inclIn);
4160  ROTATEY(-inclIn, LNhx, LNhy, LNhz);
4161  ROTATEZ(phiRef, LNhx, LNhy, LNhz);
4162  ROTATEY(inclIn, LNhx, LNhy, LNhz);
4163  printf("LNh: %12.4e %12.4e %12.4e norm: %12.4e\n",LNhx,LNhy,LNhz,sqrt(LNhx*LNhx+LNhy*LNhy+LNhz*LNhz));
4164  printf(" %12.4e %12.4e %12.4e\n",sin(*inc),0.,cos(*inc));
4165  printf("S1.L %12.4e %12.4e\n",(*S1x)*LNhx+(*S1y)*LNhy+(*S1z)*LNhz,S1xIn*LNhx+S1yIn*LNhy+S1zIn*LNhz);
4166  printf("S2.L %12.4e %12.4e\n",(*S2x)*LNhx+(*S2y)*LNhy+(*S2z)*LNhz,S2xIn*LNhx+S2yIn*LNhy+S2zIn*LNhz);
4167  printf("S1.S2 %12.4e %12.4e\n",(*S1x)*(*S2x)+(*S1y)*(*S2y)+(*S1z)*(*S2z),S1xIn*S2xIn+S1yIn*S2yIn+S1zIn*S2zIn);
4168  printf("***********************************************\n");*/
4169  break;
4170 
4172  /* FRAME_AXIS_ORBITAL_L (default)
4173  * (spins wrt to L//z and x// body 2->1,
4174  * inclIn is the angle between L and N: if
4175  * LNhat=(0,0,1) N=(0,sin(inclIn),cos(inclIn)) in the Y-z plane,
4176  * where x is rotated by phiRef wrt X around z.
4177  */
4178  default:
4179  //We need to set N into the (0,0,1) axis and L into (sin(inc),0,cos(inc))
4180  //We can first rotate by phiRef-pi/2 around the angular momentum,
4181  //which brings the line of sight into the new xz plane and leaves the ang momentum as the z axis
4182  ROTATEZ(phiRef-LAL_PI/2.,*S1x,*S1y,*S1z);
4183  ROTATEZ(phiRef-LAL_PI/2.,*S2x,*S2y,*S2z);
4184  //We can then rotate by -inclIn around the y axis to bring the line of sight to the z axis.
4185  ROTATEY(-inclIn,*S1x,*S1y,*S1z);
4186  ROTATEY(-inclIn,*S2x,*S2y,*S2z);
4187  //The ang momentum is now in the xz plane but with negative projection on x
4188  //Now we rotate by Pi around z to bring L to the positive x half plane
4189  ROTATEZ(LAL_PI,*S1x,*S1y,*S1z);
4190  ROTATEZ(LAL_PI,*S2x,*S2y,*S2z);
4191  *inc=inclIn;
4192  //For a check uncomment the following lines
4193  //Anyway there is an automatic check at build in
4194  // lalsimulation/test/InitialSpinRotationTest
4195  /*printf("****************************************************\n");
4196  printf("** Check of LAL_SIM_INSPIRAL_FRAME_AXIS_ORBITAL_L **\n");
4197  printf("****************************************************\n");
4198  Nhx=0.;
4199  Nhy=sin(inclIn);
4200  Nhz=cos(inclIn);
4201  LNhx=0.;
4202  LNhy=0.;
4203  LNhz=1.;
4204  REAL8 nnx=1.;
4205  REAL8 nny=0.;
4206  REAL8 nnz=0.;
4207  REAL8 llx=0.;
4208  REAL8 lly=1.;
4209  REAL8 llz=0.;
4210  ROTATEZ(-LAL_PI/2.,Nhx,Nhy,Nhz);
4211  ROTATEZ(phiRef-LAL_PI/2.,nnx,nny,nnz);
4212  ROTATEZ(phiRef-LAL_PI/2.,llx,lly,llz);
4213  ROTATEY(-inclIn,Nhx,Nhy,Nhz);
4214  ROTATEY(-inclIn,LNhx,LNhy,LNhz);
4215  ROTATEY(-inclIn,nnx,nny,nnz);
4216  ROTATEY(-inclIn,llx,lly,llz);
4217  ROTATEZ(LAL_PI,Nhx,Nhy,Nhz);
4218  ROTATEZ(LAL_PI,LNhx,LNhy,LNhz);
4219  ROTATEZ(LAL_PI,nnx,nny,nnz);
4220  ROTATEZ(LAL_PI,llx,lly,llz);
4221  printf("N: %12.4e %12.4e %12.4e norm: %12.4e\n",Nhx,Nhy,Nhz,sqrt(Nhx*Nhx+Nhy*Nhy+Nhz*Nhz));
4222  printf(" 0. 0. 1.\n");
4223  printf("LNh: %12.4e %12.4e %12.4e norm: %12.4e\n",LNhx,LNhy,LNhz,sqrt(LNhx*LNhx+LNhy*LNhy+LNhz*LNhz));
4224  printf(" %12.4e %12.4e %12.4e\n",sin(*inc),0.,cos(*inc));
4225  printf("S1.L %12.4e %12.4e\n",(*S1x)*LNhx+(*S1y)*LNhy+(*S1z)*LNhz,S1zIn);
4226  printf("S2.L %12.4e %12.4e\n",(*S2x)*LNhx+(*S2y)*LNhy+(*S2z)*LNhz,S2zIn);
4227  printf("S1.S2 %12.4e %12.4e\n",(*S1x)*(*S2x)+(*S1y)*(*S2y)+(*S1z)*(*S2z),S1xIn*S2xIn+S1yIn*S2yIn+S1zIn*S2zIn);
4228  printf("S1.n %12.4e %12.4e\n",S1xIn,(*S1x)*nnx+(*S1y)*nny+(*S1z)*nnz);
4229  printf("S2.n %12.4e %12.4e\n",S2xIn,(*S2x)*nnx+(*S2y)*nny+(*S2z)*nnz);
4230  printf("S1.l %12.4e %12.4e\n",S1yIn,(*S1x)*llx+(*S1y)*lly+(*S1z)*llz);
4231  printf("S2.l %12.4e %12.4e\n",S2yIn,(*S2x)*llx+(*S2y)*lly+(*S2z)*llz);
4232  printf("L.n 0. %12.4e\n",nnx*sin(*inc)+nnz*cos(*inc));
4233  printf("L.l 0. %12.4e\n",llx*sin(*inc)+llz*cos(*inc));
4234  printf("N.n %12.4e %12.4e\n",sin(inclIn)*sin(phiRef),Nhx*nnx+Nhy*nny+Nhz*nnz);
4235  printf("N.l %12.4e %12.4e\n",sin(inclIn)*cos(phiRef),Nhx*llx+Nhy*lly+Nhz*llz);
4236  printf("n.l 0. %12.4e\n",nnx*llx+nny*lly+nnz*llz);
4237  printf("****************************************************\n");*/
4238  break;
4239  }
4240 
4241  return XLAL_SUCCESS;
4242 } // End of XLALSimInspiralInitialConditionsPrecessingApproxs()
4243 
4244 /**
4245  * This function evolves the orbital equations for a precessing binary using
4246  * the \"TaylorT1/T5/T4\" approximant for solving the orbital dynamics
4247  * (see arXiv:0907.0700 for a review of the various PN approximants).
4248  *
4249  * It returns time series of the \"orbital velocity\", orbital phase,
4250  * and components for both individual spin vectors, the \"Newtonian\"
4251  * orbital angular momentum (which defines the instantaneous plane)
4252  * and "E1", a basis vector in the instantaneous orbital plane.
4253  * Note that LNhat and E1 completely specify the instantaneous orbital plane.
4254  * It also returns the time and phase of the final time step
4255  *
4256  * For input, the function takes the two masses, the initial orbital phase,
4257  * Values of S1, S2, LNhat, E1 vectors at starting time,
4258  * the desired time step size, the starting GW frequency,
4259  * and PN order at which to evolve the phase,
4260  *
4261  * NOTE: All vectors are given in the frame
4262  * where the z-axis is set by the angular momentum at reference frequency,
4263  * the x-axis is chosen orthogonal to it, and the y-axis is given by the RH rule.
4264  * Initial values must be passed in this frame, and the time series of the
4265  * vector components will also be returned in this frame.
4266  *
4267  * Review completed on git hash ...
4268  *
4269  */
4271  REAL8TimeSeries **V, /**< post-Newtonian parameter [returned]*/
4272  REAL8TimeSeries **Phi, /**< orbital phase [returned]*/
4273  REAL8TimeSeries **S1x, /**< Spin1 vector x component [returned]*/
4274  REAL8TimeSeries **S1y, /**< " " " y component [returned]*/
4275  REAL8TimeSeries **S1z, /**< " " " z component [returned]*/
4276  REAL8TimeSeries **S2x, /**< Spin2 vector x component [returned]*/
4277  REAL8TimeSeries **S2y, /**< " " " y component [returned]*/
4278  REAL8TimeSeries **S2z, /**< " " " z component [returned]*/
4279  REAL8TimeSeries **LNhatx, /**< unit orbital ang. mom. x [returned]*/
4280  REAL8TimeSeries **LNhaty, /**< " " " y component [returned]*/
4281  REAL8TimeSeries **LNhatz, /**< " " " z component [returned]*/
4282  REAL8TimeSeries **E1x, /**< orb. plane basis vector x[returned]*/
4283  REAL8TimeSeries **E1y, /**< " " " y component [returned]*/
4284  REAL8TimeSeries **E1z, /**< " " " z component [returned]*/
4285  const REAL8 deltaT, /**< sampling interval (s) */
4286  const REAL8 m1_SI, /**< mass of companion 1 (kg) */
4287  const REAL8 m2_SI, /**< mass of companion 2 (kg) */
4288  const REAL8 fStart, /**< starting GW frequency */
4289  const REAL8 fEnd, /**< ending GW frequency, fEnd=0 means integrate as far forward as possible */
4290  const REAL8 s1x, /**< initial value of S1x */
4291  const REAL8 s1y, /**< initial value of S1y */
4292  const REAL8 s1z, /**< initial value of S1z */
4293  const REAL8 s2x, /**< initial value of S2x */
4294  const REAL8 s2y, /**< initial value of S2y */
4295  const REAL8 s2z, /**< initial value of S2z */
4296  const REAL8 lnhatx, /**< initial value of LNhatx */
4297  const REAL8 lnhaty, /**< initial value of LNhaty */
4298  const REAL8 lnhatz, /**< initial value of LNhatz */
4299  const REAL8 e1x, /**< initial value of E1x */
4300  const REAL8 e1y, /**< initial value of E1y */
4301  const REAL8 e1z, /**< initial value of E1z */
4302  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
4303  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
4304  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
4305  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
4306  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
4307  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
4308  const INT4 phaseO, /**< twice post-Newtonian order */
4309  const INT4 lscorr, /**< flag to control L_S terms */
4310  const Approximant approx /**< PN approximant (SpinTaylorT1/T5/T4) */
4311  )
4312 {
4313  INT4 intreturn;
4314  LALAdaptiveRungeKuttaIntegrator *integrator = NULL; /* GSL integrator object */
4315  REAL8 yinit[LAL_NUM_ST4_VARIABLES]; /* initial values of parameters */
4316  REAL8Array *yout; /* time series of variables returned from integrator */
4317  /* intermediate variables */
4318  UINT4 i, cutlen, len;
4319  int sgn, offset;
4320  REAL8 norm1, norm2, dtStart, dtEnd, lengths, wEnd, m1sec, m2sec, Msec, Mcsec, fTerm;
4321  LIGOTimeGPS tStart = LIGOTIMEGPSZERO;
4322 
4323  if ( !V || !Phi || !S1x || !S1y || !S1z || !S2x || !S2y || !S2z
4324  || !LNhatx || !LNhaty || !LNhatz || !E1x || !E1y || !E1z )
4325  {
4326  XLALPrintError("XLAL Error - %s: NULL(s) in output parameters\n",
4327  __func__);
4329  }
4330 
4331  if ( spinO>=7 ) {
4332  XLALPrintError("XLAL Error - %s: Averaged-orbit dynamics incompatible with spin order %d chosen.\n",__func__, spinO);
4334  }
4335 
4336  /* Check start and end frequencies are positive */
4337  if( fStart <= 0. )
4338  {
4339  XLALPrintError("XLAL Error - %s: fStart = %f must be > 0.\n",
4340  __func__, fStart );
4342  }
4343  if( fEnd < 0. ) /* fEnd = 0 allowed as special case */
4344  {
4345  XLALPrintError("XLAL Error - %s: fEnd = %f must be >= 0.\n",
4346  __func__, fEnd );
4348  }
4349 
4350  /* Set sign of time step according to direction of integration */
4351  if( fEnd < fStart && fEnd != 0. )
4352  sgn = -1;
4353  else
4354  sgn = 1;
4355 
4356  // Fill params struct with values of constant coefficients of the model
4358  if( approx == SpinTaylorT4 )
4359  {
4360  XLALSimInspiralSpinTaylorT4Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4361  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, 0);
4362 
4363  }
4364  else if( approx == SpinTaylorT5 )
4365  {
4366  XLALSimInspiralSpinTaylorT5Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4367  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr);
4368  }
4369  else if( approx == SpinTaylorT1 )
4370  {
4371  XLALSimInspiralSpinTaylorT1Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4372  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr);
4373  }
4374  else
4375  {
4376  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
4377  __func__, approx);
4379 
4380  }
4381  m1sec = m1_SI / LAL_MSUN_SI * LAL_MTSUN_SI;
4382  m2sec = m2_SI / LAL_MSUN_SI * LAL_MTSUN_SI;
4383  Msec = m1sec + m2sec;
4384  Mcsec = Msec * pow( m1sec*m2sec/Msec/Msec, 0.6);
4385 
4386  /* Estimate length of waveform using Newtonian t(f) formula */
4387  /* Time from freq. = fStart to infinity */
4388  dtStart = (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
4389  * pow(Mcsec * fStart,-5.0/3.0) / fStart;
4390  /* Time from freq. = fEnd to infinity. Set to zero if fEnd=0 */
4391  dtEnd = (fEnd == 0. ? 0. : (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
4392  * pow(Mcsec * fEnd,-5.0/3.0) / fEnd);
4393  /* Time in sec from fStart to fEnd. Note it can be positive or negative */
4394  lengths = dtStart - dtEnd;
4395 
4396  /* Put initial values into a single array for the integrator */
4397  yinit[0] = 0.; /* without loss of generality, set initial orbital phase=0 */
4398  yinit[1] = LAL_PI * Msec * fStart; /* \hat{omega} = (pi M f) */
4399  /* LNh(x,y,z) */
4400  yinit[2] = lnhatx;
4401  yinit[3] = lnhaty;
4402  yinit[4] = lnhatz;
4403  /* S1(x,y,z): LAL normalizes spins by total mass, not individual mass */
4404  norm1 = m1sec * m1sec / Msec / Msec;
4405  yinit[5] = norm1 * s1x;
4406  yinit[6] = norm1 * s1y;
4407  yinit[7] = norm1 * s1z;
4408  /* S2(x,y,z) */
4409  norm2 = m2sec * m2sec / Msec / Msec;
4410  yinit[8] = norm2 * s2x;
4411  yinit[9] = norm2 * s2y;
4412  yinit[10]= norm2 * s2z;
4413  /* E1(x,y,z) */
4414  yinit[11] = e1x;
4415  yinit[12] = e1y;
4416  yinit[13] = e1z;
4417 
4418  /* initialize the integrator */
4419  if( approx == SpinTaylorT4 )
4424  else if( approx == SpinTaylorT5 )
4429  else if( approx == SpinTaylorT1 )
4434  else
4435  {
4436  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
4437  __func__, approx);
4439 
4440  }
4441  if( !integrator )
4442  {
4443  XLALPrintError("XLAL Error - %s: Cannot allocate integrator\n",
4444  __func__);
4446  }
4447 
4448  /* stop the integration only when the test is true */
4449  integrator->stopontestonly = 1;
4450 
4451  /* run the integration; note: time is measured in \hat{t} = t / M */
4452  len = XLALAdaptiveRungeKutta4Hermite(integrator, params, yinit,
4453  0.0, lengths/Msec, sgn*deltaT/Msec, &yout);
4454 
4455  if (!yout)
4456  {
4457  XLALPrintError("XLAL Error - %s: integration failed (yout == NULL)\n",
4458  __func__);
4460  }
4461 
4462  intreturn = integrator->returncode;
4463  XLALAdaptiveRungeKuttaFree(integrator);
4464  LALFree(params);
4465 
4466  if (!len)
4467  {
4468  XLALPrintError("XLAL Error - %s: integration failed with errorcode %d.\n", __func__, intreturn);
4470  }
4471 
4472  /* Print warning about abnormal termination */
4473  if (intreturn != 0 && intreturn != LALSIMINSPIRAL_ST_TEST_ENERGY
4474  && intreturn != LALSIMINSPIRAL_ST_TEST_FREQBOUND)
4475  {
4476  XLALPrintWarning("XLAL Warning - %s: integration terminated with code %d.\n Waveform parameters were m1 = %e, m2 = %e, s1 = (%e,%e,%e), s2 = (%e,%e,%e), inc = %e.\n", __func__, intreturn, m1_SI / LAL_MSUN_SI, m2_SI / LAL_MSUN_SI, s1x, s1y, s1z, s2x, s2y, s2z, acos(lnhatz));
4477  }
4478 
4479  /*
4480  * If ending frequency was non-zero, we may have overshot somewhat.
4481  * The integrator takes one adaptive stride past fEnd,
4482  * but this may include several smaller interpolation steps.
4483  * Therefore, 'cutlen' will be the index of the first interpolated step
4484  * to cross fEnd and 'len' is the full length returned from the integrator.
4485  * If fEnd == 0, we integrated as far as possible and 'cutlen' = 'len'.
4486  */
4487  cutlen = len;
4488  if( fEnd != 0. && fEnd < fStart )
4489  {
4490  wEnd = LAL_PI * Msec * fEnd;/* Ending dimensionless freq. \hat{omega} */
4491  /* Integrator returns \hat{omega} in array 'yout'
4492  in range data[2*len] to data[2*len+(len-1)].
4493  Start at end and find where we cross wEnd */
4494  while( yout->data[2*len+cutlen-1] < wEnd )
4495  cutlen--;
4496  if( cutlen < len )
4497  cutlen++; /* while loop exits on wrong side of fEnd, so increment */
4498  }
4499  else if( fEnd > fStart )
4500  {
4501  wEnd = LAL_PI * Msec * fEnd;/* Ending dimensionless freq. \hat{omega} */
4502  /* Integrator returns \hat{omega} in array 'yout'
4503  in range data[2*len] to data[2*len+(len-1)].
4504  Start at end and find where we cross wEnd */
4505  while( yout->data[2*len+cutlen-1] > wEnd )
4506  cutlen--;
4507  if( cutlen < len )
4508  cutlen++; /* while loop exits on wrong side of fEnd, so increment */
4509  }
4510 
4511  /* Adjust tStart so last sample is at time=0 */
4512  XLALGPSAdd(&tStart, -1.0*(cutlen-1)*deltaT);
4513 
4514  // Report termination condition and final frequency
4515  // Will only report this info if '4' bit of lalDebugLevel is 1
4516  fTerm = yout->data[2*len+cutlen-1] / LAL_PI / Msec;
4517  XLALPrintInfo("XLAL Info - %s: integration terminated with code %d. The final GW frequency reached was %g\n", __func__, intreturn, fTerm);
4518 
4519  /* allocate memory for output vectors */
4520  *V = XLALCreateREAL8TimeSeries( "PN_EXPANSION_PARAMETER", &tStart, 0.,
4521  deltaT, &lalDimensionlessUnit, cutlen);
4522  *Phi = XLALCreateREAL8TimeSeries( "ORBITAL_PHASE", &tStart, 0.,
4523  deltaT, &lalDimensionlessUnit, cutlen);
4524  *S1x = XLALCreateREAL8TimeSeries( "SPIN1_X_COMPONENT", &tStart, 0.,
4525  deltaT, &lalDimensionlessUnit, cutlen);
4526  *S1y = XLALCreateREAL8TimeSeries( "SPIN1_Y_COMPONENT", &tStart, 0.,
4527  deltaT, &lalDimensionlessUnit, cutlen);
4528  *S1z = XLALCreateREAL8TimeSeries( "SPIN1_Z_COMPONENT", &tStart, 0.,
4529  deltaT, &lalDimensionlessUnit, cutlen);
4530  *S2x = XLALCreateREAL8TimeSeries( "SPIN2_X_COMPONENT", &tStart, 0.,
4531  deltaT, &lalDimensionlessUnit, cutlen);
4532  *S2y = XLALCreateREAL8TimeSeries( "SPIN2_Y_COMPONENT", &tStart, 0.,
4533  deltaT, &lalDimensionlessUnit, cutlen);
4534  *S2z = XLALCreateREAL8TimeSeries( "SPIN2_Z_COMPONENT", &tStart, 0.,
4535  deltaT, &lalDimensionlessUnit, cutlen);
4536  *LNhatx = XLALCreateREAL8TimeSeries( "LNHAT_X_COMPONENT", &tStart, 0.,
4537  deltaT, &lalDimensionlessUnit, cutlen);
4538  *LNhaty = XLALCreateREAL8TimeSeries( "LNHAT_Y_COMPONENT", &tStart, 0.,
4539  deltaT, &lalDimensionlessUnit, cutlen);
4540  *LNhatz = XLALCreateREAL8TimeSeries( "LNHAT_Z_COMPONENT", &tStart, 0.,
4541  deltaT, &lalDimensionlessUnit, cutlen);
4542  *E1x = XLALCreateREAL8TimeSeries( "E1_BASIS_X_COMPONENT", &tStart, 0.,
4543  deltaT, &lalDimensionlessUnit, cutlen);
4544  *E1y = XLALCreateREAL8TimeSeries( "E1_BASIS_Y_COMPONENT", &tStart, 0.,
4545  deltaT, &lalDimensionlessUnit, cutlen);
4546  *E1z = XLALCreateREAL8TimeSeries( "E1_BASIS_Z_COMPONENT", &tStart, 0.,
4547  deltaT, &lalDimensionlessUnit, cutlen);
4548  if ( !*V || !*Phi || !*S1x || !*S1y || !*S1z || !*S2x || !*S2y || !*S2z
4549  || !*LNhatx || !*LNhaty || !*LNhatz || !*E1x || !*E1y || !*E1z )
4550  {
4551  XLALDestroyREAL8Array(yout);
4553  }
4554 
4555  /* If we integrated backwards, offset & sgn will reverse order of samples */
4556  if( fEnd < fStart && fEnd != 0. )
4557  offset = cutlen-1;
4558  else
4559  offset = 0;
4560 
4561  /* Copy dynamical variables from yout array to output time series.
4562  * Note the first 'len' members of yout are the time steps.
4563  * Also, the for loop only goes to 'cutlen', in case we overshot fEnd.
4564  * If we integrated backwards, we copy backwards from 'cutlen'.
4565  */
4566  for( i = 0; i < cutlen; i++ )
4567  {
4568  int j = sgn*i+offset;
4569  (*Phi)->data->data[j] = yout->data[len+i];
4570  (*V)->data->data[j] = cbrt(yout->data[2*len+i]);
4571  (*LNhatx)->data->data[j] = yout->data[3*len+i];
4572  (*LNhaty)->data->data[j] = yout->data[4*len+i];
4573  (*LNhatz)->data->data[j] = yout->data[5*len+i];
4574  /* Spins are returned in the standard convention */
4575  (*S1x)->data->data[j] = yout->data[6*len+i]/norm1;
4576  (*S1y)->data->data[j] = yout->data[7*len+i]/norm1;
4577  (*S1z)->data->data[j] = yout->data[8*len+i]/norm1;
4578  (*S2x)->data->data[j] = yout->data[9*len+i]/norm2;
4579  (*S2y)->data->data[j] = yout->data[10*len+i]/norm2;
4580  (*S2z)->data->data[j] = yout->data[11*len+i]/norm2;
4581  (*E1x)->data->data[j] = yout->data[12*len+i];
4582  (*E1y)->data->data[j] = yout->data[13*len+i];
4583  (*E1z)->data->data[j] = yout->data[14*len+i];
4584  }
4585 
4586  XLALDestroyREAL8Array(yout);
4587 
4588  return XLAL_SUCCESS;
4589 }
4590 
4591 /**
4592  * This function evolves the orbital equations for a precessing binary using
4593  * the \"TaylorT1/T5/T4\" approximant for solving the orbital dynamics
4594  * (see arXiv:0907.0700 for a review of the various PN approximants).
4595  *
4596  * It returns the final values of the \"orbital velocity\", orbital phase,
4597  * and components for both individual spin vectors, the \"Newtonian\"
4598  * orbital angular momentum (which defines the instantaneous plane)
4599  * and "E1", a basis vector in the instantaneous orbital plane.
4600  * Note that LNhat and E1 completely specify the instantaneous orbital plane.
4601  * It also returns the time and phase of the final time step
4602  *
4603  * For input, the function takes the two masses, the initial orbital phase,
4604  * Values of S1, S2, LNhat, E1 vectors at starting time,
4605  * the desired time step size, the starting GW frequency,
4606  * and PN order at which to evolve the phase,
4607  *
4608  * NOTE: All vectors are given in the frame
4609  * where the z-axis is set by the angular momentum at reference frequency,
4610  * the x-axis is chosen orthogonal to it, and the y-axis is given by the RH rule.
4611  * Initial values must be passed in this frame, and the time series of the
4612  * vector components will also be returned in this frame.
4613  *
4614  * Review completed on git hash ...
4615  *
4616  */
4618  REAL8TimeSeries **V, /**< post-Newtonian parameter [returned]*/
4619  REAL8TimeSeries **Phi, /**< orbital phase [returned]*/
4620  REAL8TimeSeries **S1x, /**< Spin1 vector x component [returned]*/
4621  REAL8TimeSeries **S1y, /**< " " " y component [returned]*/
4622  REAL8TimeSeries **S1z, /**< " " " z component [returned]*/
4623  REAL8TimeSeries **S2x, /**< Spin2 vector x component [returned]*/
4624  REAL8TimeSeries **S2y, /**< " " " y component [returned]*/
4625  REAL8TimeSeries **S2z, /**< " " " z component [returned]*/
4626  REAL8TimeSeries **LNhatx, /**< unit orbital ang. mom. x [returned]*/
4627  REAL8TimeSeries **LNhaty, /**< " " " y component [returned]*/
4628  REAL8TimeSeries **LNhatz, /**< " " " z component [returned]*/
4629  REAL8TimeSeries **E1x, /**< orb. plane basis vector x[returned]*/
4630  REAL8TimeSeries **E1y, /**< " " " y component [returned]*/
4631  REAL8TimeSeries **E1z, /**< " " " z component [returned]*/
4632  const REAL8 deltaT, /**< sampling interval (s) */
4633  const REAL8 m1_SI, /**< mass of companion 1 (kg) */
4634  const REAL8 m2_SI, /**< mass of companion 2 (kg) */
4635  const REAL8 fStart, /**< starting GW frequency */
4636  const REAL8 fEnd, /**< ending GW frequency, fEnd=0 means integrate as far forward as possible */
4637  const REAL8 s1x, /**< initial value of S1x */
4638  const REAL8 s1y, /**< initial value of S1y */
4639  const REAL8 s1z, /**< initial value of S1z */
4640  const REAL8 s2x, /**< initial value of S2x */
4641  const REAL8 s2y, /**< initial value of S2y */
4642  const REAL8 s2z, /**< initial value of S2z */
4643  const REAL8 lnhatx, /**< initial value of LNhatx */
4644  const REAL8 lnhaty, /**< initial value of LNhaty */
4645  const REAL8 lnhatz, /**< initial value of LNhatz */
4646  const REAL8 e1x, /**< initial value of E1x */
4647  const REAL8 e1y, /**< initial value of E1y */
4648  const REAL8 e1z, /**< initial value of E1z */
4649  const REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
4650  const REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
4651  const REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
4652  const REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
4653  const LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
4654  const LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
4655  const INT4 phaseO, /**< twice post-Newtonian order */
4656  const INT4 lscorr, /**< flag to control L_S terms */
4657  const Approximant approx /**< PN approximant (SpinTaylorT1/T5/T4) */
4658  )
4659 {
4660  INT4 intreturn;
4661  LALAdaptiveRungeKuttaIntegrator *integrator = NULL; /* GSL integrator object */
4662  REAL8 yinit[LAL_NUM_ST4_VARIABLES]; /* initial values of parameters */
4663  /* intermediate variables */
4664  UINT4 out;
4665  int sgn;
4666  REAL8 norm1, norm2, dtStart, dtEnd, lengths, m1sec, m2sec, Msec, Mcsec;
4667  LIGOTimeGPS tStart = LIGOTIMEGPSZERO;
4668 
4669  if ( !V || !Phi || !S1x || !S1y || !S1z || !S2x || !S2y || !S2z
4670  || !LNhatx || !LNhaty || !LNhatz || !E1x || !E1y || !E1z )
4671  {
4672  XLALPrintError("XLAL Error - %s: NULL(s) in output parameters\n",
4673  __func__);
4675  }
4676 
4677  if ( spinO>=7 ) {
4678  XLALPrintError("XLAL Error - %s: Averaged-orbit dynamics incompatible with spin order %d chosen.\n",__func__, spinO);
4680  }
4681 
4682  /* Check start and end frequencies are positive */
4683  if( fStart <= 0. )
4684  {
4685  XLALPrintError("XLAL Error - %s: fStart = %f must be > 0.\n",
4686  __func__, fStart );
4688  }
4689  if( fEnd < 0. ) /* fEnd = 0 allowed as special case */
4690  {
4691  XLALPrintError("XLAL Error - %s: fEnd = %f must be >= 0.\n",
4692  __func__, fEnd );
4694  }
4695 
4696  /* Set sign of time step according to direction of integration */
4697  if( fEnd < fStart && fEnd != 0. )
4698  sgn = -1;
4699  else
4700  sgn = 1;
4701 
4702  // Fill params struct with values of constant coefficients of the model
4704  if( approx == SpinTaylorT4 )
4705  {
4706  XLALSimInspiralSpinTaylorT4Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4707  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr, 0);
4708 
4709  }
4710  else if( approx == SpinTaylorT5 )
4711  {
4712  XLALSimInspiralSpinTaylorT5Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4713  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr);
4714  }
4715  else if( approx == SpinTaylorT1 )
4716  {
4717  XLALSimInspiralSpinTaylorT1Setup(&params, m1_SI, m2_SI, fStart, fEnd,
4718  lambda1, lambda2, quadparam1, quadparam2, spinO, tideO, phaseO, lscorr);
4719  }
4720  else
4721  {
4722  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
4723  __func__, approx);
4725 
4726  }
4727  m1sec = m1_SI / LAL_MSUN_SI * LAL_MTSUN_SI;
4728  m2sec = m2_SI / LAL_MSUN_SI * LAL_MTSUN_SI;
4729  Msec = m1sec + m2sec;
4730  Mcsec = Msec * pow( m1sec*m2sec/Msec/Msec, 0.6);
4731 
4732  /* Estimate length of waveform using Newtonian t(f) formula */
4733  /* Time from freq. = fStart to infinity */
4734  dtStart = (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
4735  * pow(Mcsec * fStart,-5.0/3.0) / fStart;
4736  /* Time from freq. = fEnd to infinity. Set to zero if fEnd=0 */
4737  dtEnd = (fEnd == 0. ? 0. : (5.0/256.0) * pow(LAL_PI,-8.0/3.0)
4738  * pow(Mcsec * fEnd,-5.0/3.0) / fEnd);
4739  /* Time in sec from fStart to fEnd. Note it can be positive or negative */
4740  lengths = dtStart - dtEnd;
4741 
4742  /* Put initial values into a single array for the integrator */
4743  yinit[0] = 0.; /* without loss of generality, set initial orbital phase=0 */
4744  yinit[1] = LAL_PI * Msec * fStart; /* \hat{omega} = (pi M f) */
4745  /* LNh(x,y,z) */
4746  yinit[2] = lnhatx;
4747  yinit[3] = lnhaty;
4748  yinit[4] = lnhatz;
4749  /* S1(x,y,z): LAL normalizes spins by total mass, not individual mass */
4750  norm1 = m1sec * m1sec / Msec / Msec;
4751  yinit[5] = norm1 * s1x;
4752  yinit[6] = norm1 * s1y;
4753  yinit[7] = norm1 * s1z;
4754  /* S2(x,y,z) */
4755  norm2 = m2sec * m2sec / Msec / Msec;
4756  yinit[8] = norm2 * s2x;
4757  yinit[9] = norm2 * s2y;
4758  yinit[10]= norm2 * s2z;
4759  /* E1(x,y,z) */
4760  yinit[11] = e1x;
4761  yinit[12] = e1y;
4762  yinit[13] = e1z;
4763 
4764  /* initialize the integrator */
4765  if( approx == SpinTaylorT4 )
4770  else if( approx == SpinTaylorT5 )
4775  else if( approx == SpinTaylorT1 )
4780  else
4781  {
4782  XLALPrintError("XLAL Error - %s: Approximant must be one of SpinTaylorT1, SpinTaylorT5, SpinTaylorT4, but %i provided\n",
4783  __func__, approx);
4785 
4786  }
4787  if( !integrator )
4788  {
4789  XLALPrintError("XLAL Error - %s: Cannot allocate integrator\n",
4790  __func__);
4792  }
4793 
4794  /* stop the integration only when the test is true */
4795  integrator->stopontestonly = 1;
4796 
4797  /* run the integration; note: time is measured in \hat{t} = t / M */
4798  out = XLALAdaptiveRungeKutta4HermiteOnlyFinal(integrator, params, yinit,
4799  0.0, lengths/Msec, LAL_PI * Msec * fEnd, sgn*deltaT/Msec);
4800 
4801  intreturn = integrator->returncode;
4802  XLALAdaptiveRungeKuttaFree(integrator);
4803  LALFree(params);
4804 
4805  if (!out)
4806  {
4807  XLALPrintError("XLAL Error - %s: integration failed with errorcode %d.\n", __func__, intreturn);
4809  }
4810 
4811  /* Raise error about abnormal termination */
4812  if (intreturn != 0 && intreturn != LALSIMINSPIRAL_ST_TEST_ENERGY
4813  && intreturn != LALSIMINSPIRAL_ST_TEST_FREQBOUND)
4814  {
4815  XLALPrintError("XLAL Error - %s: integration terminated with code %d.\n Waveform parameters were m1 = %e, m2 = %e, s1 = (%e,%e,%e), s2 = (%e,%e,%e), inc = %e.\n", __func__, intreturn, m1_SI / LAL_MSUN_SI, m2_SI / LAL_MSUN_SI, s1x, s1y, s1z, s2x, s2y, s2z, acos(lnhatz));
4817  }
4818 
4819  /* allocate memory for output vectors */
4820  *V = XLALCreateREAL8TimeSeries( "PN_EXPANSION_PARAMETER", &tStart, 0.,
4822  *Phi = XLALCreateREAL8TimeSeries( "ORBITAL_PHASE", &tStart, 0.,
4824  *S1x = XLALCreateREAL8TimeSeries( "SPIN1_X_COMPONENT", &tStart, 0.,
4826  *S1y = XLALCreateREAL8TimeSeries( "SPIN1_Y_COMPONENT", &tStart, 0.,
4828  *S1z = XLALCreateREAL8TimeSeries( "SPIN1_Z_COMPONENT", &tStart, 0.,
4830  *S2x = XLALCreateREAL8TimeSeries( "SPIN2_X_COMPONENT", &tStart, 0.,
4832  *S2y = XLALCreateREAL8TimeSeries( "SPIN2_Y_COMPONENT", &tStart, 0.,
4834  *S2z = XLALCreateREAL8TimeSeries( "SPIN2_Z_COMPONENT", &tStart, 0.,
4836  *LNhatx = XLALCreateREAL8TimeSeries( "LNHAT_X_COMPONENT", &tStart, 0.,
4838  *LNhaty = XLALCreateREAL8TimeSeries( "LNHAT_Y_COMPONENT", &tStart, 0.,
4840  *LNhatz = XLALCreateREAL8TimeSeries( "LNHAT_Z_COMPONENT", &tStart, 0.,
4842  *E1x = XLALCreateREAL8TimeSeries( "E1_BASIS_X_COMPONENT", &tStart, 0.,
4844  *E1y = XLALCreateREAL8TimeSeries( "E1_BASIS_Y_COMPONENT", &tStart, 0.,
4846  *E1z = XLALCreateREAL8TimeSeries( "E1_BASIS_Z_COMPONENT", &tStart, 0.,
4848  if ( !*V || !*Phi || !*S1x || !*S1y || !*S1z || !*S2x || !*S2y || !*S2z
4849  || !*LNhatx || !*LNhaty || !*LNhatz || !*E1x || !*E1y || !*E1z )
4850  {
4852  }
4853 
4854  /* Copy dynamical variables from yinit array to output */
4855 
4856  (*Phi)->data->data[0] = yinit[0];
4857  (*V)->data->data[0] = cbrt(yinit[1]);
4858  (*LNhatx)->data->data[0] = yinit[2];
4859  (*LNhaty)->data->data[0] = yinit[3];
4860  (*LNhatz)->data->data[0] = yinit[4];
4861  (*S1x)->data->data[0] = yinit[5]/norm1;
4862  (*S1y)->data->data[0] = yinit[6]/norm1;
4863  (*S1z)->data->data[0] = yinit[7]/norm1;
4864  (*S2x)->data->data[0] = yinit[8]/norm2;
4865  (*S2y)->data->data[0] = yinit[9]/norm2;
4866  (*S2z)->data->data[0] = yinit[10]/norm2;
4867  (*E1x)->data->data[0] = yinit[11];
4868  (*E1y)->data->data[0] = yinit[12];
4869  (*E1z)->data->data[0] = yinit[13];
4870 
4871  return XLAL_SUCCESS;
4872 }
4873 
4874 
4875 /**
4876  * Driver routine to compute a precessing post-Newtonian inspiral waveform
4877  * with phasing computed from energy balance using the so-called \"T4\" method.
4878  *
4879  * This routine allows the user to specify different pN orders
4880  * for the phasing and amplitude of the waveform.
4881  *
4882  * The reference frequency fRef is used as follows:
4883  * 1) if fRef = 0: The initial values of s1, s2, lnhat and e1 will be the
4884  * values at frequency fStart. The orbital phase of the last sample is set
4885  * to phiRef (i.e. phiRef is the "coalescence phase", roughly speaking).
4886  * THIS IS THE DEFAULT BEHAVIOR CONSISTENT WITH OTHER APPROXIMANTS
4887  *
4888  * 2) If fRef = fStart: The initial values of s1, s2, lnhat and e1 will be the
4889  * values at frequency fStart. phiRef is used to set the orbital phase
4890  * of the first sample at fStart.
4891  *
4892  * 3) If fRef > fStart: The initial values of s1, s2, lnhat and e1 will be the
4893  * values at frequency fRef. phiRef is used to set the orbital phase at fRef.
4894  * The code will integrate forwards and backwards from fRef and stitch the
4895  * two together to create a complete waveform. This allows one to specify
4896  * the orientation of the binary in-band (or at any arbitrary point).
4897  * Otherwise, the user can only directly control the initial orientation.
4898  *
4899  * 4) fRef < 0 or fRef >= Schwarz. ISCO are forbidden and the code will abort.
4900  *
4901  * REVIEW completed on git hash 6640e79e60791d5230731acc63351676ce7ce413
4902  *
4903  */
4905  REAL8TimeSeries **hplus, /**< +-polarization waveform */
4906  REAL8TimeSeries **hcross, /**< x-polarization waveform */
4907  REAL8 phiRef, /**< orbital phase at reference pt. */
4908  REAL8 UNUSED v0, /**< tail gauge term (default = 1) */
4909  REAL8 deltaT, /**< sampling interval (s) */
4910  REAL8 m1, /**< mass of companion 1 (kg) */
4911  REAL8 m2, /**< mass of companion 2 (kg) */
4912  REAL8 fStart, /**< start GW frequency (Hz) */
4913  REAL8 fRef, /**< reference GW frequency (Hz) */
4914  REAL8 r, /**< distance of source (m) */
4915  REAL8 s1x, /**< initial value of S1x */
4916  REAL8 s1y, /**< initial value of S1y */
4917  REAL8 s1z, /**< initial value of S1z */
4918  REAL8 s2x, /**< initial value of S2x */
4919  REAL8 s2y, /**< initial value of S2y */
4920  REAL8 s2z, /**< initial value of S2z */
4921  REAL8 lnhatx, /**< initial value of LNhatx */
4922  REAL8 lnhaty, /**< initial value of LNhaty */
4923  REAL8 lnhatz, /**< initial value of LNhatz */
4924  REAL8 e1x, /**< initial value of E1x */
4925  REAL8 e1y, /**< initial value of E1y */
4926  REAL8 e1z, /**< initial value of E1z */
4927  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
4928  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
4929  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
4930  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
4931  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
4932  int phaseO, /**< twice PN phase order */
4933  int amplitudeO /**< twice PN amplitude order */
4934  )
4935 {
4936  Approximant approx = SpinTaylorT4;
4937  int n=XLALSimInspiralWaveformParamsInsertTidalLambda1(LALparams, lambda1);
4939  n=XLALSimInspiralWaveformParamsInsertdQuadMon1(LALparams, quadparam1);
4940  n=XLALSimInspiralWaveformParamsInsertdQuadMon2(LALparams, quadparam2);
4942  n=XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALparams, amplitudeO);
4943  n = XLALSimInspiralSpinTaylorDriver(hplus, hcross, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4944  phiRef, deltaT,
4945  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
4946  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, LALparams, approx);
4947 
4948  return n;
4949 }
4950 
4952  REAL8TimeSeries **hplus, /**< +-polarization waveform */
4953  REAL8TimeSeries **hcross, /**< x-polarization waveform */
4954  REAL8 phiRef, /**< orbital phase at reference pt. */
4955  REAL8 deltaT, /**< sampling interval (s) */
4956  REAL8 m1, /**< mass of companion 1 (kg) */
4957  REAL8 m2, /**< mass of companion 2 (kg) */
4958  REAL8 fStart, /**< start GW frequency (Hz) */
4959  REAL8 fRef, /**< reference GW frequency (Hz) */
4960  REAL8 r, /**< distance of source (m) */
4961  REAL8 s1x, /**< initial value of S1x */
4962  REAL8 s1y, /**< initial value of S1y */
4963  REAL8 s1z, /**< initial value of S1z */
4964  REAL8 s2x, /**< initial value of S2x */
4965  REAL8 s2y, /**< initial value of S2y */
4966  REAL8 s2z, /**< initial value of S2z */
4967  REAL8 lnhatx, /**< initial value of LNhatx */
4968  REAL8 lnhaty, /**< initial value of LNhaty */
4969  REAL8 lnhatz, /**< initial value of LNhatz */
4970  REAL8 e1x, /**< initial value of E1x */
4971  REAL8 e1y, /**< initial value of E1y */
4972  REAL8 e1z, /**< initial value of E1z */
4973  LALDict *LALparams /**< LAL dictionary containing accessory parameters */
4974  )
4975 {
4976  Approximant approx = SpinTaylorT4;
4977  int n = XLALSimInspiralSpinTaylorDriver(hplus, hcross, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
4978  phiRef, deltaT,
4979  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
4980  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, LALparams, approx);
4981 
4982  return n;
4983 }
4984 
4985 /**
4986  * Driver routine to compute a precessing post-Newtonian inspiral waveform
4987  * with phasing computed from energy balance using the so-called \"T1\" method.
4988  *
4989  * This routine allows the user to specify different pN orders
4990  * for the phasing and amplitude of the waveform.
4991  *
4992  * The reference frequency fRef is used as follows:
4993  * 1) if fRef = 0: The initial values of s1, s2, lnhat and e1 will be the
4994  * values at frequency fStart. The orbital phase of the last sample is set
4995  * to phiRef (i.e. phiRef is the "coalescence phase", roughly speaking).
4996  * THIS IS THE DEFAULT BEHAVIOR CONSISTENT WITH OTHER APPROXIMANTS
4997  *
4998  * 2) If fRef = fStart: The initial values of s1, s2, lnhat and e1 will be the
4999  * values at frequency fStart. phiRef is used to set the orbital phase
5000  * of the first sample at fStart.
5001  *
5002  * 3) If fRef > fStart: The initial values of s1, s2, lnhat and e1 will be the
5003  * values at frequency fRef. phiRef is used to set the orbital phase at fRef.
5004  * The code will integrate forwards and backwards from fRef and stitch the
5005  * two together to create a complete waveform. This allows one to specify
5006  * the orientation of the binary in-band (or at any arbitrary point).
5007  * Otherwise, the user can only directly control the initial orientation.
5008  *
5009  * 4) fRef < 0 or fRef >= Schwarz. ISCO are forbidden and the code will abort.
5010  *
5011  * REVIEW completed on git hash 6640e79e60791d5230731acc63351676ce7ce413
5012  *
5013  */
5015  REAL8TimeSeries **hplus, /**< +-polarization waveform */
5016  REAL8TimeSeries **hcross, /**< x-polarization waveform */
5017  REAL8 phiRef, /**< orbital phase at reference pt. */
5018  REAL8 UNUSED v0, /**< tail gauge term (default = 1) */
5019  REAL8 deltaT, /**< sampling interval (s) */
5020  REAL8 m1, /**< mass of companion 1 (kg) */
5021  REAL8 m2, /**< mass of companion 2 (kg) */
5022  REAL8 fStart, /**< start GW frequency (Hz) */
5023  REAL8 fRef, /**< reference GW frequency (Hz) */
5024  REAL8 r, /**< distance of source (m) */
5025  REAL8 s1x, /**< initial value of S1x */
5026  REAL8 s1y, /**< initial value of S1y */
5027  REAL8 s1z, /**< initial value of S1z */
5028  REAL8 s2x, /**< initial value of S2x */
5029  REAL8 s2y, /**< initial value of S2y */
5030  REAL8 s2z, /**< initial value of S2z */
5031  REAL8 lnhatx, /**< initial value of LNhatx */
5032  REAL8 lnhaty, /**< initial value of LNhaty */
5033  REAL8 lnhatz, /**< initial value of LNhatz */
5034  REAL8 e1x, /**< initial value of E1x */
5035  REAL8 e1y, /**< initial value of E1y */
5036  REAL8 e1z, /**< initial value of E1z */
5037  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
5038  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
5039  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
5040  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
5041  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
5042  int phaseO, /**< twice PN phase order */
5043  int amplitudeO /**< twice PN amplitude order */
5044  )
5045 {
5046  Approximant approx = SpinTaylorT1;
5047  int n=XLALSimInspiralWaveformParamsInsertTidalLambda1(LALparams, lambda1);
5049  n=XLALSimInspiralWaveformParamsInsertdQuadMon1(LALparams, quadparam1);
5050  n=XLALSimInspiralWaveformParamsInsertdQuadMon2(LALparams, quadparam2);
5052  n=XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALparams, amplitudeO);
5053  n = XLALSimInspiralSpinTaylorDriver(hplus, hcross, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
5054  phiRef, deltaT,
5055  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
5056  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, LALparams, approx);
5057 
5058  return n;
5059 }
5060 
5062  REAL8TimeSeries **hplus, /**< +-polarization waveform */
5063  REAL8TimeSeries **hcross, /**< x-polarization waveform */
5064  REAL8 phiRef, /**< orbital phase at reference pt. */
5065  REAL8 deltaT, /**< sampling interval (s) */
5066  REAL8 m1, /**< mass of companion 1 (kg) */
5067  REAL8 m2, /**< mass of companion 2 (kg) */
5068  REAL8 fStart, /**< start GW frequency (Hz) */
5069  REAL8 fRef, /**< reference GW frequency (Hz) */
5070  REAL8 r, /**< distance of source (m) */
5071  REAL8 s1x, /**< initial value of S1x */
5072  REAL8 s1y, /**< initial value of S1y */
5073  REAL8 s1z, /**< initial value of S1z */
5074  REAL8 s2x, /**< initial value of S2x */
5075  REAL8 s2y, /**< initial value of S2y */
5076  REAL8 s2z, /**< initial value of S2z */
5077  REAL8 lnhatx, /**< initial value of LNhatx */
5078  REAL8 lnhaty, /**< initial value of LNhaty */
5079  REAL8 lnhatz, /**< initial value of LNhatz */
5080  REAL8 e1x, /**< initial value of E1x */
5081  REAL8 e1y, /**< initial value of E1y */
5082  REAL8 e1z, /**< initial value of E1z */
5083  LALDict *LALparams /**< LAL dictionary containing accessory parameters */
5084  )
5085 {
5086  Approximant approx = SpinTaylorT1;
5087  int n = XLALSimInspiralSpinTaylorDriver(hplus, hcross, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
5088  phiRef, deltaT,
5089  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
5090  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, LALparams, approx);
5091 
5092  return n;
5093 }
5094 
5095 /**
5096  * Driver routine to compute a precessing post-Newtonian inspiral waveform
5097  * with phasing computed from energy balance using the so-called \"T5\" method.
5098  *
5099  * This routine allows the user to specify different pN orders
5100  * for the phasing, amplitude, spin and tidal effects of the waveform.
5101  *
5102  * The reference frequency fRef is used as follows:
5103  * 1) if fRef = 0: The initial values of s1, s2, lnhat and e1 will be the
5104  * values at frequency fStart. The orbital phase of the last sample is set
5105  * to phiRef (i.e. phiRef is the "coalescence phase", roughly speaking).
5106  * THIS IS THE DEFAULT BEHAVIOR CONSISTENT WITH OTHER APPROXIMANTS
5107  *
5108  * 2) If fRef = fStart: The initial values of s1, s2, lnhat and e1 will be the
5109  * values at frequency fStart. phiRef is used to set the orbital phase
5110  * of the first sample at fStart.
5111  *
5112  * 3) If fRef > fStart: The initial values of s1, s2, lnhat and e1 will be the
5113  * values at frequency fRef. phiRef is used to set the orbital phase at fRef.
5114  * The code will integrate forwards and backwards from fRef and stitch the
5115  * two together to create a complete waveform. This allows one to specify
5116  * the orientation of the binary in-band (or at any arbitrary point).
5117  * Otherwise, the user can only directly control the initial orientation.
5118  *
5119  * 4) fRef < 0 or fRef >= Schwarz. ISCO are forbidden and the code will abort.
5120  *
5121  * REVIEW completed on git hash ...
5122  *
5123  */
5125  REAL8TimeSeries **hplus, /**< +-polarization waveform */
5126  REAL8TimeSeries **hcross, /**< x-polarization waveform */
5127  REAL8 phiRef, /**< orbital phase at reference pt. */
5128  REAL8 deltaT, /**< sampling interval (s) */
5129  REAL8 m1, /**< mass of companion 1 (kg) */
5130  REAL8 m2, /**< mass of companion 2 (kg) */
5131  REAL8 fStart, /**< start GW frequency (Hz) */
5132  REAL8 fRef, /**< reference GW frequency (Hz) */
5133  REAL8 r, /**< distance of source (m) */
5134  REAL8 s1x, /**< initial value of S1x */
5135  REAL8 s1y, /**< initial value of S1y */
5136  REAL8 s1z, /**< initial value of S1z */
5137  REAL8 s2x, /**< initial value of S2x */
5138  REAL8 s2y, /**< initial value of S2y */
5139  REAL8 s2z, /**< initial value of S2z */
5140  REAL8 lnhatx, /**< initial value of LNhatx */
5141  REAL8 lnhaty, /**< initial value of LNhaty */
5142  REAL8 lnhatz, /**< initial value of LNhatz */
5143  REAL8 e1x, /**< initial value of E1x */
5144  REAL8 e1y, /**< initial value of E1y */
5145  REAL8 e1z, /**< initial value of E1z */
5146  LALDict *LALparams /**< LAL dictionary containing accessory parameters */
5147  )
5148 {
5149  Approximant approx = SpinTaylorT5;
5150  int n = XLALSimInspiralSpinTaylorDriver(hplus, hcross, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
5151  phiRef, deltaT,
5152  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
5153  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, LALparams, approx);
5154 
5155  return n;
5156 }
5157 
5158 /**
5159  * Compute the physical template family "Q" vectors for a spinning, precessing
5160  * binary when provided time series of all the dynamical quantities.
5161  * These vectors always supplied to dominant order.
5162  *
5163  * Based on Pan, Buonanno, Chan and Vallisneri PRD69 104017, (see also theses
5164  * of Diego Fazi and Ian Harry)
5165  *
5166  * NOTE: The vectors MUST be given in the so-called radiation frame where
5167  * Z is the direction of propagation, X is the principal '+' axis and Y = Z x X
5168  *
5169  * !!!UNREVIEWED!!!
5170  */
5172  REAL8TimeSeries **Q1, /**< PTF-Q1 waveform [returned] */
5173  REAL8TimeSeries **Q2, /**< PTF-Q2 waveform [returned] */
5174  REAL8TimeSeries **Q3, /**< PTF-Q2 waveform [returned] */
5175  REAL8TimeSeries **Q4, /**< PTF-Q2 waveform [returned] */
5176  REAL8TimeSeries **Q5, /**< PTF-Q2 waveform [returned] */
5177  REAL8TimeSeries *V, /**< post-Newtonian parameter */
5178  REAL8TimeSeries *Phi, /**< orbital phase */
5179  REAL8TimeSeries *S1x, /**< Spin1 vector x component */
5180  REAL8TimeSeries *S1y, /**< Spin1 vector y component */
5181  REAL8TimeSeries *S1z, /**< Spin1 vector z component */
5182  REAL8TimeSeries *S2x, /**< Spin2 vector x component */
5183  REAL8TimeSeries *S2y, /**< Spin2 vector y component */
5184  REAL8TimeSeries *S2z, /**< Spin2 vector z component */
5185  REAL8TimeSeries *LNhatx, /**< unit orbital ang. mom. x comp. */
5186  REAL8TimeSeries *LNhaty, /**< unit orbital ang. mom. y comp. */
5187  REAL8TimeSeries *LNhatz, /**< unit orbital ang. mom. z comp. */
5188  REAL8TimeSeries *E1x, /**< orbital plane basis vector x comp. */
5189  REAL8TimeSeries *E1y, /**< orbital plane basis vector y comp. */
5190  REAL8TimeSeries *E1z, /**< orbital plane basis vector z comp. */
5191  REAL8 m1, /**< mass of companion 1 (kg) */
5192  REAL8 m2, /**< mass of companion 2 (kg) */
5193  REAL8 r /**< distance of source (m) */
5194  )
5195 {
5196  REAL8 lnhx, lnhy, lnhz;
5197  REAL8 e1x, e1y, e1z, e2x, e2y, e2z, nx, ny, nz, lx, ly, lz;
5198  REAL8 nx2, ny2, nz2, lx2, ly2, lz2;
5199  REAL8 q1tmp, q2tmp, q3tmp, q4tmp, q5tmp;
5200  REAL8 M, eta, phi, v, v2, dist, ampfac;
5201  INT4 idx, len;
5202  REAL8 sqrt_three = pow(3,0.5);
5203 
5204  /* Macros to check time series vectors */
5232 
5233 
5234  /* Allocate polarization vectors and set to 0 */
5235  *Q1 = XLALCreateREAL8TimeSeries( "PTF_Q_1", &V->epoch,
5236  0.0, V->deltaT, &lalStrainUnit, V->data->length );
5237  *Q2 = XLALCreateREAL8TimeSeries( "PTF_Q_2", &V->epoch,
5238  0.0, V->deltaT, &lalStrainUnit, V->data->length );
5239  *Q3 = XLALCreateREAL8TimeSeries( "PTF_Q_3", &V->epoch,
5240  0.0, V->deltaT, &lalStrainUnit, V->data->length );
5241  *Q4 = XLALCreateREAL8TimeSeries( "PTF_Q_4", &V->epoch,
5242  0.0, V->deltaT, &lalStrainUnit, V->data->length );
5243  *Q5 = XLALCreateREAL8TimeSeries( "PTF_Q_5", &V->epoch,
5244  0.0, V->deltaT, &lalStrainUnit, V->data->length );
5245 
5246  if ( ! Q1 || ! Q2 || !Q3 || !Q4 || !Q5 )
5248  memset((*Q1)->data->data, 0,
5249  (*Q1)->data->length*sizeof(*(*Q1)->data->data));
5250  memset((*Q2)->data->data, 0,
5251  (*Q2)->data->length*sizeof(*(*Q2)->data->data));
5252  memset((*Q3)->data->data, 0,
5253  (*Q3)->data->length*sizeof(*(*Q3)->data->data));
5254  memset((*Q4)->data->data, 0,
5255  (*Q4)->data->length*sizeof(*(*Q4)->data->data));
5256  memset((*Q5)->data->data, 0,
5257  (*Q5)->data->length*sizeof(*(*Q5)->data->data));
5258 
5259  M = m1 + m2;
5260  eta = m1 * m2 / M / M; // symmetric mass ratio - '\nu' in the paper
5261  dist = r / LAL_C_SI; // r (m) / c (m/s) --> dist in units of seconds
5262  /* convert mass from kg to s, so ampfac ~ M/dist is dimensionless */
5263  ampfac = 2. * M * LAL_G_SI * pow(LAL_C_SI, -3) * eta / dist;
5264 
5265  /* loop over time steps and compute the Qi */
5266  len = V->data->length;
5267  for(idx = 0; idx < len; idx++)
5268  {
5269  /* Abbreviated names in lower case for time series at this sample */
5270  phi = Phi->data->data[idx]; v = V->data->data[idx]; v2 = v * v;
5271  lnhx = LNhatx->data->data[idx]; e1x = E1x->data->data[idx];
5272  lnhy = LNhaty->data->data[idx]; e1y = E1y->data->data[idx];
5273  lnhz = LNhatz->data->data[idx]; e1z = E1z->data->data[idx];
5274 
5275  /* E2 = LNhat x E1 */
5276  e2x = lnhy*e1z - lnhz*e1y;
5277  e2y = lnhz*e1x - lnhx*e1z;
5278  e2z = lnhx*e1y - lnhy*e1x;
5279 
5280  /* Unit orbital separation vector */
5281  nx = e1x*cos(phi) + e2x*sin(phi);
5282  ny = e1y*cos(phi) + e2y*sin(phi);
5283  nz = e1z*cos(phi) + e2z*sin(phi);
5284 
5285  /* Unit inst. orbital velocity vector */
5286  lx = e2x*cos(phi) - e1x*sin(phi);
5287  ly = e2y*cos(phi) - e1y*sin(phi);
5288  lz = e2z*cos(phi) - e1z*sin(phi);
5289 
5290  /* Powers of vector components */
5291  nx2 = nx*nx; ny2 = ny*ny; nz2 = nz*nz;
5292  lx2 = lx*lx; ly2 = ly*ly; lz2 = lz*lz;
5293 
5294  /*
5295  * NOTE: For PTF waveforms, we must use only the dominant amplitude
5296  * The Q values are computed from equations 13,14,17, 46 + 47 in PBCV or
5297  * more simply from equations (3.10) in Diego Fazi's thesis.
5298  * Note that Q5 is simplified from that shown in Fazi's thsis
5299  * by using traceless condition. As demonstrated in (6.29)
5300  * in Ian Harry's thesis.
5301  */
5302 
5303  q1tmp = lx2 - ly2 - nx2 + ny2;
5304  q2tmp = 2*lx*ly - 2*nx*ny;
5305  q3tmp = 2*lx*lz - 2*nx*nz;
5306  q4tmp = 2*ly*lz - 2*ny*nz;
5307  q5tmp = sqrt_three * (nz2 - lz2);
5308 
5309  /* Fill the output vectors */
5310  (*Q1)->data->data[idx] = ampfac * v2 * q1tmp;
5311  (*Q2)->data->data[idx] = ampfac * v2 * q2tmp;
5312  (*Q3)->data->data[idx] = ampfac * v2 * q3tmp;
5313  (*Q4)->data->data[idx] = ampfac * v2 * q4tmp;
5314  (*Q5)->data->data[idx] = ampfac * v2 * q5tmp;
5315  }
5316  return XLAL_SUCCESS;
5317 }
5318 
5319 /**
5320  * Driver routine to compute the physical template family "Q" vectors using
5321  * the \"T4\" method. Note that PTF describes single spin systems
5322  *
5323  * This routine requires leading-order amplitude dependence
5324  * but allows the user to specify the phase PN order
5325  *
5326  * !!!UNREVIEWED!!!
5327  */
5329  REAL8TimeSeries **Q1, /**< Q1 output vector */
5330  REAL8TimeSeries **Q2, /**< Q2 output vector */
5331  REAL8TimeSeries **Q3, /**< Q3 output vector */
5332  REAL8TimeSeries **Q4, /**< Q4 output vector */
5333  REAL8TimeSeries **Q5, /**< Q5 output vector */
5334  REAL8 deltaT, /**< sampling interval (s) */
5335  REAL8 m1, /**< mass of companion 1 (kg) */
5336  REAL8 m2, /**< mass of companion 2 (kg) */
5337  REAL8 chi1, /**< spin magnitude (|S1|) */
5338  REAL8 kappa1, /**< L . S1 (1 if they are aligned) */
5339  REAL8 fStart, /**< start GW frequency (Hz) */
5340  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of mody 1)^5 (dimensionless) */
5341  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
5342  LALSimInspiralSpinOrder spinO, /**< twice PN order of spin effects */
5343  LALSimInspiralTidalOrder tideO, /**< twice PN order of tidal effects */
5344  int phaseO /**< twice PN phase order */
5345  )
5346 {
5347  /* To generate the QVecs we need to choose a specific frame
5348  * This frame is set so that inclination, and most other extrinsic
5349  * angles are 0. This does not lead to loss in generality as PTF maximizes
5350  * over these angles. This follows the PBCV convention
5351  */
5352  Approximant approx = SpinTaylorT4;
5353  REAL8 fRef = 0., quadparam1 = 1., quadparam2 = 1.;
5354  REAL8 r = 10E6 * LAL_PC_SI; /* Setting an arbitrary distance of 10 MPc */
5355  REAL8 s1x = chi1 * pow((1 - kappa1*kappa1),0.5);
5356  REAL8 s1z = chi1 * kappa1;
5357  REAL8 s1y,s2x,s2y,s2z,lnhatx,lnhaty,lnhatz,e1x,e1y,e1z;
5358  s1y = s2x = s2y = s2z = lnhatx = lnhaty = e1y = e1z = 0;
5359  lnhatz = e1x = 1.;
5360 
5361  REAL8TimeSeries *V, *Phi, *S1x, *S1y, *S1z, *S2x, *S2y, *S2z;
5362  REAL8TimeSeries *LNhatx, *LNhaty, *LNhatz, *E1x, *E1y, *E1z;
5363  int status, n;
5364 
5365  /* Evolve the dynamical variables */
5366  n = XLALSimInspiralSpinTaylorPNEvolveOrbit(&V, &Phi, &S1x, &S1y, &S1z,
5367  &S2x, &S2y, &S2z, &LNhatx, &LNhaty, &LNhatz, &E1x, &E1y, &E1z,
5368  deltaT, m1, m2, fStart, fRef, s1x, s1y, s1z, s2x, s2y,
5369  s2z, lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
5370  quadparam1, quadparam2, spinO, tideO, phaseO, 0, approx);
5371  if( n < 0 )
5373 
5374  /* Use the dynamical variables to build the polarizations */
5375  status = XLALSimInspiralPrecessingPTFQWaveforms(Q1, Q2, Q3, Q4, Q5,
5376  V, Phi, S1x, S1y, S1z, S2x, S2y, S2z, LNhatx, LNhaty, LNhatz,
5377  E1x, E1y, E1z, m1, m2, r);
5378 
5379  /* Destroy vectors of dynamical variables, check for errors then exit */
5394  if( status < 0 )
5396 
5397  return n;
5398 }
5399 
5400 /**
5401  * Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain
5402  * with phasing computed from energy balance using the so-called \"T4\" method.
5403  *
5404  * This routine allows the user to specify different pN orders
5405  * for the phasing and amplitude of the waveform.
5406  *
5407  * The reference frequency fRef is used as follows:
5408  * 1) if fRef = 0: The initial values of s1, s2, lnhat and e1 will be the
5409  * values at frequency fStart. The orbital phase of the last sample is set
5410  * to phiRef (i.e. phiRef is the "coalescence phase", roughly speaking).
5411  * THIS IS THE DEFAULT BEHAVIOR CONSISTENT WITH OTHER APPROXIMANTS
5412  *
5413  * 2) If fRef = fStart: The initial values of s1, s2, lnhat and e1 will be the
5414  * values at frequency fStart. phiRef is used to set the orbital phase
5415  * of the first sample at fStart.
5416  *
5417  * 3) If fRef > fStart: The initial values of s1, s2, lnhat and e1 will be the
5418  * values at frequency fRef. phiRef is used to set the orbital phase at fRef.
5419  * The code will integrate forwards and backwards from fRef and stitch the
5420  * two together to create a complete waveform. This allows one to specify
5421  * the orientation of the binary in-band (or at any arbitrary point).
5422  * Otherwise, the user can only directly control the initial orientation.
5423  *
5424  * 4) fRef < 0 or fRef >= Schwarz. ISCO are forbidden and the code will abort.
5425  *
5426  * It is recommended, but not necessary to set fStart slightly smaller than fMin,
5427  * e.g. fStart = 9.5 for fMin = 10.
5428  *
5429  * The returned Fourier series are set so that the Schwarzschild ISCO frequency
5430  * corresponds to t = 0 as closely as possible.
5431  *
5432  * !!!UNREVIEWED!!!
5433  */
5435  COMPLEX16FrequencySeries **hplus, /**< +-polarization waveform */
5436  COMPLEX16FrequencySeries **hcross, /**< x-polarization waveform */
5437  REAL8 fMin, /**< minimum frequency of the returned series */
5438  REAL8 fMax, /**< maximum frequency of the returned series */
5439  REAL8 deltaF, /**< frequency interval of the returned series */
5440  INT4 kMax, /**< k_max as described in defined arXiv: 1408.5158 (min 0, max 10). */
5441  REAL8 phiRef, /**< orbital phase at reference pt. */
5442  REAL8 v0, /**< tail gauge term (default = 1) */
5443  REAL8 m1, /**< mass of companion 1 (kg) */
5444  REAL8 m2, /**< mass of companion 2 (kg) */
5445  REAL8 fStart, /**< start GW frequency (Hz) */
5446  REAL8 fRef, /**< reference GW frequency (Hz) */
5447  REAL8 r, /**< distance of source (m) */
5448  REAL8 s1x, /**< initial value of S1x */
5449  REAL8 s1y, /**< initial value of S1y */
5450  REAL8 s1z, /**< initial value of S1z */
5451  REAL8 s2x, /**< initial value of S2x */
5452  REAL8 s2y, /**< initial value of S2y */
5453  REAL8 s2z, /**< initial value of S2z */
5454  REAL8 lnhatx, /**< initial value of LNhatx */
5455  REAL8 lnhaty, /**< initial value of LNhaty */
5456  REAL8 lnhatz, /**< initial value of LNhatz */
5457  REAL8 e1x, /**< initial value of E1x */
5458  REAL8 e1y, /**< initial value of E1y */
5459  REAL8 e1z, /**< initial value of E1z */
5460  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
5461  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
5462  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
5463  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
5464  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
5465  INT4 phaseO, /**< twice PN phase order */
5466  INT4 amplitudeO, /**< twice PN amplitude order */
5467  INT4 phiRefAtEnd /**< whether phiRef corresponds to the end of the inspiral */
5468  )
5469 {
5470  Approximant approx = SpinTaylorT4;
5471  int n = XLALSimInspiralSpinTaylorDriverFourier(hplus, hcross, fMin, fMax,
5472  deltaF, kMax, phiRef, v0,
5473  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
5474  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
5475  quadparam1, quadparam2, LALparams, phaseO, amplitudeO, approx, phiRefAtEnd);
5476 
5477  return n;
5478 }
5479 
5480 /**
5481  * Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain
5482  * with phasing computed from energy balance using the so-called \"T2\" method
5483  * see arXiv: 0907.0700 for its definition,
5484  * but in its \"T5\" variant, see arXiv: 1107.1267.
5485  *
5486  * This routine allows the user to specify different pN orders
5487  * for the phasing and amplitude of the waveform.
5488  *
5489  * The reference frequency fRef is used as follows:
5490  * 1) if fRef = 0: The initial values of s1, s2, lnhat and e1 will be the
5491  * values at frequency fStart. The orbital phase of the last sample is set
5492  * to phiRef (i.e. phiRef is the "coalescence phase", roughly speaking).
5493  * THIS IS THE DEFAULT BEHAVIOR CONSISTENT WITH OTHER APPROXIMANTS
5494  *
5495  * 2) If fRef = fStart: The initial values of s1, s2, lnhat and e1 will be the
5496  * values at frequency fStart. phiRef is used to set the orbital phase
5497  * of the first sample at fStart.
5498  *
5499  * 3) If fRef > fStart: The initial values of s1, s2, lnhat and e1 will be the
5500  * values at frequency fRef. phiRef is used to set the orbital phase at fRef.
5501  * The code will integrate forwards and backwards from fRef and stitch the
5502  * two together to create a complete waveform. This allows one to specify
5503  * the orientation of the binary in-band (or at any arbitrary point).
5504  * Otherwise, the user can only directly control the initial orientation.
5505  *
5506  * 4) fRef < 0 or fRef >= Schwarz. ISCO are forbidden and the code will abort.
5507  *
5508  * It is recommended, but not necessary to set fStart slightly smaller than fMin,
5509  * e.g. fStart = 9.5 for fMin = 10.
5510  *
5511  * The returned Fourier series are set so that the Schwarzschild ISCO frequency
5512  * corresponds to t = 0 as closely as possible.
5513  *
5514  * !!!UNREVIEWED!!!
5515  */
5517  COMPLEX16FrequencySeries **hplus, /**< +-polarization waveform */
5518  COMPLEX16FrequencySeries **hcross, /**< x-polarization waveform */
5519  REAL8 fMin, /**< minimum frequency of the returned series */
5520  REAL8 fMax, /**< maximum frequency of the returned series */
5521  REAL8 deltaF, /**< frequency interval of the returned series */
5522  INT4 kMax, /**< k_max as described in arXiv: 1408.5158 (min 0, max 10). */
5523  REAL8 phiRef, /**< orbital phase at reference pt. */
5524  REAL8 v0, /**< tail gauge term (default = 1) */
5525  REAL8 m1, /**< mass of companion 1 (kg) */
5526  REAL8 m2, /**< mass of companion 2 (kg) */
5527  REAL8 fStart, /**< start GW frequency (Hz) */
5528  REAL8 fRef, /**< reference GW frequency (Hz) */
5529  REAL8 r, /**< distance of source (m) */
5530  REAL8 s1x, /**< initial value of S1x */
5531  REAL8 s1y, /**< initial value of S1y */
5532  REAL8 s1z, /**< initial value of S1z */
5533  REAL8 s2x, /**< initial value of S2x */
5534  REAL8 s2y, /**< initial value of S2y */
5535  REAL8 s2z, /**< initial value of S2z */
5536  REAL8 lnhatx, /**< initial value of LNhatx */
5537  REAL8 lnhaty, /**< initial value of LNhaty */
5538  REAL8 lnhatz, /**< initial value of LNhatz */
5539  REAL8 e1x, /**< initial value of E1x */
5540  REAL8 e1y, /**< initial value of E1y */
5541  REAL8 e1z, /**< initial value of E1z */
5542  REAL8 lambda1, /**< (tidal deformability of mass 1) / (mass of body 1)^5 (dimensionless) */
5543  REAL8 lambda2, /**< (tidal deformability of mass 2) / (mass of body 2)^5 (dimensionless) */
5544  REAL8 quadparam1, /**< phenom. parameter describing induced quad. moment of body 1 (=1 for BHs, ~2-12 for NSs) */
5545  REAL8 quadparam2, /**< phenom. parameter describing induced quad. moment of body 2 (=1 for BHs, ~2-12 for NSs) */
5546  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
5547  INT4 phaseO, /**< twice PN phase order */
5548  INT4 amplitudeO, /**< twice PN amplitude order */
5549  INT4 phiRefAtEnd /**< whether phiRef corresponds to the end of the inspiral */
5550  )
5551 {
5552  Approximant approx = SpinTaylorT5;
5553  int n = XLALSimInspiralSpinTaylorDriverFourier(hplus, hcross, fMin,
5554  fMax, deltaF, kMax, phiRef, v0,
5555  m1, m2, fStart, fRef, r, s1x, s1y, s1z, s2x, s2y, s2z,
5556  lnhatx, lnhaty, lnhatz, e1x, e1y, e1z, lambda1, lambda2,
5557  quadparam1, quadparam2, LALparams, phaseO, amplitudeO, approx, phiRefAtEnd);
5558 
5559  return n;
5560 }
5561 
5562 /** @} */
#define LALMalloc(n)
#define LALFree(p)
INT4 XLALSimInspiralSpinPNMode4m(SphHarmTimeSeries **hlm, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *LNhx, REAL8TimeSeries *LNhy, REAL8TimeSeries *LNhz, REAL8TimeSeries *e1x, REAL8TimeSeries *e1y, REAL8TimeSeries *e1z, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8 m1, REAL8 m2, REAL8 distance, int ampO)
static const REAL8 UNUSED XLALSimInspiralSpinDot_4PNS2OCoeffAvg
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_5PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_12PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_3PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_5PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_4PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_7PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_0PNCoeff(REAL8 eta)
Computes the flux PN Coefficients.
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_7PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_10PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_12PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_3PNCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_5PNCoeff(REAL8 eta)
static const REAL8 UNUSED XLALSimInspiralSpinDot_4PNS2CoeffAvg
static REAL8 UNUSED XLALSimInspiralPNEnergy_2PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_3PNCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_0PNCoeff(REAL8 eta)
Computes the PN Coefficients for using in the TaylorT4 frequency equation.
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_2PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_7PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralSpinDot_6PNS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralSpinDot_4PNQMSOCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_4PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_12PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralL_4PN(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralSpinDot_6PNS2OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_7PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_0PNCoeff(REAL8 eta)
Computes the PN Coefficients for using in the PN energy equation.
static REAL8 UNUSED XLALSimInspiralPNFlux_10PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralSpinDot_6PNQMSOCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralLN(REAL8 M, REAL8 eta, REAL8 v)
static REAL8 UNUSED XLALSimInspiralPNFlux_2PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNLogCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_7PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_3PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_5PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_3PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_10PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNLogCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNEnergy_4PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNEnergy_12PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralL_3PNSiLcoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_7PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralL_3PNSicoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralSpinDot_3PNCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_7PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_4PNS1OS2OCoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralSpinDot_7PNCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNEnergy_4PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_6PNLogCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNQMS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_5PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralSpinDot_5PNCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_5PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_2PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNFlux_3PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_10PNTidalCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralL_2PN(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_3PNCoeff(REAL8 UNUSED eta)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNFlux_4PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNQMS1OS1OCoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_5PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_6PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralPNEnergy_6PNS1S2CoeffAvg(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralLDot_3PNSOCoeff(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT2dtdv_4PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralSpinDot_6PNS2CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_4PNS1S1CoeffAvg(REAL8 mByM)
static REAL8 UNUSED XLALSimInspiralTaylorT4wdot_6PNS1OS2OCoeffAvg(REAL8 eta)
static int XLALSimInspiralVectorCrossProduct(REAL8 **vout, REAL8 v1x, REAL8 v1y, REAL8 v1z, REAL8 v2x, REAL8 v2y, REAL8 v2z)
static REAL8 omegashift(REAL8 S1sq, REAL8 S2sq, REAL8 S1S2, REAL8 LNhS1, REAL8 LNhS2, REAL8 OmS1, REAL8 OmS2)
INT4 XLALSimInspiralSpinTaylorT4DerivativesAvg(REAL8 UNUSED t, const REAL8 values[], REAL8 dvalues[], void *mparams)
#define LAL_ST4_RELATIVE_TOLERANCE
static int XLALSimInspiralSpinTaylorStoppingTest(double t, const double values[], double dvalues[], void *mparams)
int XLALSimInspiralSpinTaylorT5Setup(XLALSimInspiralSpinTaylorTxCoeffs **params, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const INT4 lscorr)
See arXiv:1107.1267 for TaylorT5 approximant definition.
INT4 XLALSimInspiralSpinTaylorHlmModesFromOrbit(SphHarmTimeSeries **hlm, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *LNhx, REAL8TimeSeries *LNhy, REAL8TimeSeries *LNhz, REAL8TimeSeries *E1x, REAL8TimeSeries *E1y, REAL8TimeSeries *E1z, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8 m1_SI, REAL8 m2_SI, REAL8 dist_SI, int ampO, LALValue *modearray)
#define ROTATEZ(angle, vx, vy, vz)
static REAL8Array * removeDuplicates(REAL8Array *series)
#define XLAL_ENDGSL
INT4 XLALSimInspiralSpinDerivativesAvg(REAL8 *dLNhx, REAL8 *dLNhy, REAL8 *dLNhz, REAL8 *dE1x, REAL8 *dE1y, REAL8 *dE1z, REAL8 *dS1x, REAL8 *dS1y, REAL8 *dS1z, REAL8 *dS2x, REAL8 *dS2y, REAL8 *dS2z, const REAL8 v, const REAL8 LNhx, const REAL8 LNhy, const REAL8 LNhz, const REAL8 E1x, const REAL8 E1y, const REAL8 E1z, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, const REAL8 LNhdotS1, const REAL8 LNhdotS2, XLALSimInspiralSpinTaylorTxCoeffs *params)
Function computing spin precession equations, common to all member of the SpinTaylor family.
#define LALSIMINSPIRAL_ST_TEST_ENERGY
static REAL8TimeSeries * appendTSandFree(REAL8TimeSeries *start, REAL8TimeSeries *end)
int XLALSimInspiralSpinTaylorDriver(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries **Vout, REAL8TimeSeries **Phiout, REAL8TimeSeries **S1xout, REAL8TimeSeries **S1yout, REAL8TimeSeries **S1zout, REAL8TimeSeries **S2xout, REAL8TimeSeries **S2yout, REAL8TimeSeries **S2zout, REAL8TimeSeries **LNhxout, REAL8TimeSeries **LNhyout, REAL8TimeSeries **LNhzout, REAL8TimeSeries **E1xout, REAL8TimeSeries **E1yout, REAL8TimeSeries **E1zout, const REAL8 phiRef, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fRef, const REAL8 r, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, const REAL8 lnhatx, const REAL8 lnhaty, const REAL8 lnhatz, const REAL8 e1x, const REAL8 e1y, const REAL8 e1z, LALDict *LALparams, const Approximant approx)
Driver function to generate any of SpinTaylorT1/T5/T4 If the output entries are not null the relative...
static REAL8Array * appendTAandFree(REAL8Array *start, REAL8Array *end, REAL8Array *combined)
INT4 XLALSimInspiralSpinTaylorT4Setup(XLALSimInspiralSpinTaylorTxCoeffs **params, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const INT4 lscorr, const INT4 phenomtp)
See arXiv:0907.0700 for TaylorT4 definition.
#define LALSIMINSPIRAL_ST_DERIVATIVE_OMEGANONPOS
static int XLALSimInspiralSpinTaylorDriverFourier(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, Approximant approx, INT4 phiRefAtEnd)
#define LAL_ST4_ABSOLUTE_TOLERANCE
#define LALSIMINSPIRAL_ST_TEST_LARGEV
INT4 XLALSimSpinTaylorEnergySpinDerivativeSetup(XLALSimInspiralSpinTaylorTxCoeffs **params, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const INT4 lscorr, const INT4 phenomtp)
#define LALSIMINSPIRAL_ST_TEST_OMEGANAN
INT4 XLALSimInspiralSetEnergyPNTermsAvg(REAL8 *Espin3, REAL8 *Espin4, REAL8 *Espin5, REAL8 *Espin6, REAL8 *Espin7, XLALSimInspiralSpinTaylorTxCoeffs *params, const REAL8 LNhdotS1, const REAL8 LNhdotS2, const REAL8 S1sq, const REAL8 S2sq, const REAL8 S1dotS2)
#define XLAL_BEGINGSL
#define ROTATEY(angle, vx, vy, vz)
static REAL8 normsq(REAL8 vx, REAL8 vy, REAL8 vz)
static int XLALSimInspiralSpinTaylorT1DerivativesAvg(double t, const double values[], double dvalues[], void *mparams)
#define LAL_NUM_ST4_VARIABLES
int XLALSimInspiralSpinTaylorOrbitalDriver(REAL8TimeSeries **Vout, REAL8TimeSeries **Phiout, REAL8TimeSeries **S1xout, REAL8TimeSeries **S1yout, REAL8TimeSeries **S1zout, REAL8TimeSeries **S2xout, REAL8TimeSeries **S2yout, REAL8TimeSeries **S2zout, REAL8TimeSeries **LNhxout, REAL8TimeSeries **LNhyout, REAL8TimeSeries **LNhzout, REAL8TimeSeries **E1xout, REAL8TimeSeries **E1yout, REAL8TimeSeries **E1zout, const REAL8 phiRef, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fRef, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, const REAL8 lnhatx, const REAL8 lnhaty, const REAL8 lnhatz, const REAL8 e1x, const REAL8 e1y, const REAL8 e1z, LALDict *LALparams, const Approximant approx)
Driver function wrapper for XLALSimInspiralSpinTaylorDriver() with the same output except for h+ and ...
#define LALSIMINSPIRAL_ST_TEST_FREQBOUND
static int XLALSimInspiralSpinTaylorT5DerivativesAvg(double t, const double values[], double dvalues[], void *mparams)
int XLALSimInspiralSpinTaylorT1Setup(XLALSimInspiralSpinTaylorTxCoeffs **params, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const INT4 lscorr)
See arXiv:0907.0700 for TaylorT1 definition.
static int XLALSimInspiralSpinTaylorPNEvolveOrbitIrregularIntervals(REAL8Array **yout, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fEnd, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALSimInspiralSpinOrder spinO, LALSimInspiralTidalOrder tideO, INT4 phaseO, Approximant approx)
This function evolves the orbital equations for a precessing binary using the "TaylorT5/T4" approxima...
static REAL8 cdot(REAL8 v1x, REAL8 v1y, REAL8 v1z, REAL8 v2x, REAL8 v2y, REAL8 v2z)
#define LALSIMINSPIRAL_ST_TEST_OMEGADOUBLEDOT
INT4 XLALSimInspiralSpinTaylorHlmModes(SphHarmTimeSeries **hlm, REAL8 phiRef, REAL8 dT, REAL8 m1_SI, REAL8 m2_SI, REAL8 fStart, REAL8 fRef, REAL8 dist_SI, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, int ampO, LALValue *modearray, LALDict *LALparams, Approximant approx)
int XLALSimInspiralWaveformParamsInsertPNPhaseOrder(LALDict *params, INT4 value)
REAL8 XLALSimInspiralWaveformParamsLookupdQuadMon1(LALDict *params)
int XLALSimInspiralWaveformParamsInsertTidalLambda1(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupTidalLambda2(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupOnlyFinal(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupTidalLambda1(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupPNPhaseOrder(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(LALDict *params)
int XLALSimInspiralWaveformParamsInsertTidalLambda2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALDict *params, INT4 value)
REAL8 XLALSimInspiralWaveformParamsLookupdQuadMon2(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupPNTidalOrder(LALDict *params)
int XLALSimInspiralWaveformParamsInsertdQuadMon2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon1(LALDict *params, REAL8 value)
INT4 XLALSimInspiralWaveformParamsLookupPNSpinOrder(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupFinalFreq(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupLscorr(LALDict *params)
REAL8 tmp1
int l
Definition: bh_qnmode.c:135
REAL8 M
Definition: bh_qnmode.c:133
double i
Definition: bh_ringdown.c:118
#define LAL_CHECK_VALID_SERIES(s, val)
#define LAL_CHECK_CONSISTENT_TIME_SERIES(s1, s2, val)
const double ny
const double vy
sigmaKerr data[0]
const double vz
const double nz
const double vx
const double nx
#define __attribute__(x)
REAL8Array * XLALCreateREAL8ArrayL(UINT4,...)
void XLALDestroyREAL8Array(REAL8Array *)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALAdaptiveRungeKuttaFree(LALAdaptiveRungeKuttaIntegrator *integrator)
int XLALAdaptiveRungeKutta4IrregularIntervals(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend_in, REAL8Array **yout)
int XLALAdaptiveRungeKutta4HermiteOnlyFinal(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend_in, REAL8 y1_final, REAL8 deltat)
int XLALAdaptiveRungeKutta4Hermite(LALAdaptiveRungeKuttaIntegrator *integrator, void *params, REAL8 *yinit, REAL8 tinit, REAL8 tend_in, REAL8 deltat, REAL8Array **yout)
LALAdaptiveRungeKuttaIntegrator * XLALAdaptiveRungeKutta4Init(int dim, int(*dydt)(double t, const double y[], double dydt[], void *params), int(*stop)(double t, const double y[], double dydt[], void *params), double eps_abs, double eps_rel)
#define LAL_C_SI
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_TWOPI
#define LAL_MTSUN_SI
#define LAL_PC_SI
#define LAL_PI_4
#define LAL_G_SI
#define LAL_REAL4_EPS
#define LIGOTIMEGPSZERO
double complex COMPLEX16
double REAL8
uint32_t UINT4
int32_t INT4
void XLALFree(void *p)
int XLALSimInspiralPrecessingPolarizationWaveformHarmonic(COMPLEX16 *hplus, COMPLEX16 *hcross, REAL8 v, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhx, REAL8 lnhy, REAL8 lnhz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 dm, REAL8 eta, REAL8 v0, INT4 n, INT4 ampO)
Computes polarizations h+ and hx for a spinning, precessing binary when provided a single value of al...
int XLALSimInspiralPrecessingPolarizationWaveforms(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8TimeSeries *LNhatx, REAL8TimeSeries *LNhaty, REAL8TimeSeries *LNhatz, REAL8TimeSeries *E1x, REAL8TimeSeries *E1y, REAL8TimeSeries *E1z, REAL8 m1, REAL8 m2, REAL8 r, INT4 ampO)
Computes polarizations h+ and hx for a spinning, precessing binary when provided time series of all t...
LALSimInspiralSpinOrder
Enumeration of allowed PN orders of spin effects.
LALSimInspiralFrameAxis
Enumerator for choosing the reference frame associated with PSpinInspiralRD waveforms.
LALSimInspiralTidalOrder
Enumeration of allowed PN orders of tidal effects.
Approximant
Enum that specifies the PN approximant to be used in computing the waveform.
@ LAL_SIM_INSPIRAL_SPIN_ORDER_0PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_25PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_35PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_ALL
@ LAL_SIM_INSPIRAL_SPIN_ORDER_2PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_15PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_1PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_05PN
@ LAL_SIM_INSPIRAL_SPIN_ORDER_3PN
@ LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW
Set z-axis along direction of GW propagation (line of sight)
@ LAL_SIM_INSPIRAL_FRAME_AXIS_TOTAL_J
Set z-axis along the initial total angular momentum.
@ LAL_SIM_INSPIRAL_FRAME_AXIS_ORBITAL_L
Set z-axis along the initial orbital angular momentum.
@ LAL_SIM_INSPIRAL_TIDAL_ORDER_5PN
@ LAL_SIM_INSPIRAL_TIDAL_ORDER_6PN
@ LAL_SIM_INSPIRAL_TIDAL_ORDER_ALL
@ LAL_SIM_INSPIRAL_TIDAL_ORDER_0PN
@ SpinTaylorT4
Spinning case T4 models (lalsimulation's equivalent of SpinTaylorFrameless).
@ SpinTaylorT5
Spinning case T5 models, which is a variant of the spinning version of the original TaylorT2 (see ) d...
@ SpinTaylorT1
Spinning case T1 models.
INT4 XLALSimInspiralSpinPNMode2m(SphHarmTimeSeries **hlm, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *LNhx, REAL8TimeSeries *LNhy, REAL8TimeSeries *LNhz, REAL8TimeSeries *e1x, REAL8TimeSeries *e1y, REAL8TimeSeries *e1z, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8 m1, REAL8 m2, REAL8 distance, int ampO)
Computes the 5 l=2 modes of spherical harmonic decomposition of the post-Newtonian inspiral waveform ...
INT4 XLALSimInspiralSpinPNMode3m(SphHarmTimeSeries **hlm, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *LNhx, REAL8TimeSeries *LNhy, REAL8TimeSeries *LNhz, REAL8TimeSeries *e1x, REAL8TimeSeries *e1y, REAL8TimeSeries *e1z, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8 m1, REAL8 m2, REAL8 distance, int ampO)
Computes all l=3 modes of spherical harmonic decomposition of the post-Newtonian inspiral waveform fo...
int XLALSimInspiralSpinTaylorT1OLD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 UNUSED v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, int phaseO, int amplitudeO)
Driver routine to compute a precessing post-Newtonian inspiral waveform with phasing computed from en...
int XLALSimInspiralSpinTaylorT5Fourier(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, INT4 phiRefAtEnd)
Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain with ph...
int XLALSimInspiralSpinTaylorPNEvolveOrbit(REAL8TimeSeries **V, REAL8TimeSeries **Phi, REAL8TimeSeries **S1x, REAL8TimeSeries **S1y, REAL8TimeSeries **S1z, REAL8TimeSeries **S2x, REAL8TimeSeries **S2y, REAL8TimeSeries **S2z, REAL8TimeSeries **LNhatx, REAL8TimeSeries **LNhaty, REAL8TimeSeries **LNhatz, REAL8TimeSeries **E1x, REAL8TimeSeries **E1y, REAL8TimeSeries **E1z, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, const REAL8 lnhatx, const REAL8 lnhaty, const REAL8 lnhatz, const REAL8 e1x, const REAL8 e1y, const REAL8 e1z, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const INT4 lscorr, const Approximant approx)
This function evolves the orbital equations for a precessing binary using the "TaylorT1/T5/T4" approx...
int XLALSimInspiralPrecessingPTFQWaveforms(REAL8TimeSeries **Q1, REAL8TimeSeries **Q2, REAL8TimeSeries **Q3, REAL8TimeSeries **Q4, REAL8TimeSeries **Q5, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8TimeSeries *LNhatx, REAL8TimeSeries *LNhaty, REAL8TimeSeries *LNhatz, REAL8TimeSeries *E1x, REAL8TimeSeries *E1y, REAL8TimeSeries *E1z, REAL8 m1, REAL8 m2, REAL8 r)
Compute the physical template family "Q" vectors for a spinning, precessing binary when provided time...
int XLALSimInspiralSpinTaylorT4OLD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 UNUSED v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, int phaseO, int amplitudeO)
Driver routine to compute a precessing post-Newtonian inspiral waveform with phasing computed from en...
int XLALSimInspiralTransformPrecessingObsoleteInitialConditions(REAL8 *incl, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, REAL8 thetaJN, REAL8 phiJL, REAL8 theta1, REAL8 theta2, REAL8 phi12, REAL8 chi1, REAL8 chi2, REAL8 m1, REAL8 m2, REAL8 fRef)
Function to specify the desired orientation of a precessing binary in terms of several angles and the...
int XLALSimInspiralSpinTaylorPNEvolveOrbitOnlyFinal(REAL8TimeSeries **V, REAL8TimeSeries **Phi, REAL8TimeSeries **S1x, REAL8TimeSeries **S1y, REAL8TimeSeries **S1z, REAL8TimeSeries **S2x, REAL8TimeSeries **S2y, REAL8TimeSeries **S2z, REAL8TimeSeries **LNhatx, REAL8TimeSeries **LNhaty, REAL8TimeSeries **LNhatz, REAL8TimeSeries **E1x, REAL8TimeSeries **E1y, REAL8TimeSeries **E1z, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, const REAL8 lnhatx, const REAL8 lnhaty, const REAL8 lnhatz, const REAL8 e1x, const REAL8 e1y, const REAL8 e1z, const REAL8 lambda1, const REAL8 lambda2, const REAL8 quadparam1, const REAL8 quadparam2, const LALSimInspiralSpinOrder spinO, const LALSimInspiralTidalOrder tideO, const INT4 phaseO, const INT4 lscorr, const Approximant approx)
This function evolves the orbital equations for a precessing binary using the "TaylorT1/T5/T4" approx...
int XLALSimInspiralSpinTaylorT5(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, LALDict *LALparams)
Driver routine to compute a precessing post-Newtonian inspiral waveform with phasing computed from en...
int XLALSimInspiralInitialConditionsPrecessingApproxs(REAL8 *inc, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, const REAL8 inclIn, const REAL8 S1xIn, const REAL8 S1yIn, const REAL8 S1zIn, const REAL8 S2xIn, const REAL8 S2yIn, const REAL8 S2zIn, const REAL8 m1, const REAL8 m2, const REAL8 fRef, const REAL8 phiRef, LALSimInspiralFrameAxis frameChoice)
Function to specify the desired orientation of the spin components of a precessing binary.
int XLALSimInspiralSpinTaylorT4(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, LALDict *LALparams)
int XLALSimInspiralSpinTaylorT1(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, LALDict *LALparams)
int XLALSimInspiralSpinTaylorT4PTFQVecs(REAL8TimeSeries **Q1, REAL8TimeSeries **Q2, REAL8TimeSeries **Q3, REAL8TimeSeries **Q4, REAL8TimeSeries **Q5, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 chi1, REAL8 kappa1, REAL8 fStart, REAL8 lambda1, REAL8 lambda2, LALSimInspiralSpinOrder spinO, LALSimInspiralTidalOrder tideO, int phaseO)
Driver routine to compute the physical template family "Q" vectors using the "T4" method.
int XLALSimInspiralSpinTaylorT4Fourier(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, INT4 phiRefAtEnd)
Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain with ph...
LALValue * XLALSimInspiralCreateModeArray(void)
Create a LALValue pointer to store the mode array.
int XLALSimInspiralModeArrayIsModeActive(LALValue *modes, unsigned l, int m)
LALValue * XLALSimInspiralModeArrayActivateAllModesAtL(LALValue *modes, unsigned l)
SphHarmTimeSeries * XLALSphHarmTimeSeriesAddMode(SphHarmTimeSeries *appended, const COMPLEX16TimeSeries *inmode, UINT4 l, INT4 m)
Prepend a node to a linked list of SphHarmTimeSeries, or create a new head.
COMPLEX16TimeSeries * XLALSphHarmTimeSeriesGetMode(SphHarmTimeSeries *ts, UINT4 l, INT4 m)
Get the time series of a waveform's (l,m) spherical harmonic mode from a SphHarmTimeSeries linked lis...
static const INT4 r
static const INT4 m
REAL8TimeSeries * XLALResizeREAL8TimeSeries(REAL8TimeSeries *series, int first, size_t length)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
const LALUnit lalDimensionlessUnit
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
#define XLAL_ERROR_NULL(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#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_EINVAL
XLAL_FAILURE
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
list y
string status
end
double alpha
Definition: sgwb.c:106
COMPLEX16Sequence * data
COMPLEX16 * data
INT4 gpsNanoSeconds
UINT4Vector * dimLength
REAL8 * data
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
Structure to carry a collection of spherical harmonic modes in COMPLEX16 time series.
UINT4 * data
Definition: burst.c:245
double V
Definition: unicorn.c:25
double deltaT
Definition: unicorn.c:24