Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
FindChirpPTFWaveform.c
Go to the documentation of this file.
1/*-----------------------------------------------------------------------
2 *
3 * File Name: FindChirpPTFWaveform.c
4 *
5 * Author: Brown, D. A., and Fazi, D.
6 *
7 *-----------------------------------------------------------------------
8 */
9
10/**
11 * \author Brown, D. A., and Fazi, D.
12 * \file
13 * \ingroup FindChirpPTF_h
14 *
15 * \brief Provides functions to create physical template family templates in a
16 * form that can be used by the <tt>FindChirpPTFFilter()</tt> function.
17 *
18 * ### Prototypes ###
19 *
20 * The function <tt>LALFindChirpPTFWaveform()</tt> creates vectors containing the
21 * evolution of the dynamical variables needed by the physical template family
22 * template as described by the algorithm below.
23 *
24 * ### Algorithm ###
25 *
26 * Blah.
27 *
28 */
29
30#include <math.h>
31#include <gsl/gsl_errno.h>
32#include <gsl/gsl_math.h>
33#include <gsl/gsl_odeiv.h>
34#include <lal/LALStdlib.h>
35#include <lal/LALConstants.h>
36#include <lal/AVFactories.h>
37#include <lal/LALInspiral.h>
38#include <lal/FindChirp.h>
39#include <lal/FindChirpPTF.h>
40
41#ifdef __GNUC__
42#define UNUSED __attribute__ ((unused))
43#else
44#define UNUSED
45#endif
46
47/* define a structure so that the ptf waveform parameters */
48/* can be used by the GSL ODE integrator */
49typedef struct
50{
51 /* input parameters which control evolution */
52 REAL4Vector* orbital; /* pn param of orbital evolution */
53 REAL4Vector* spin; /* pn params of spin compt of orbital evolution */
54 REAL4 S1_spin_orbit; /* coeff of S-O term in first spin evolution */
55 REAL4 LNhat; /* coeff which multiples dS_dt to get dLNhat_dt */
56 REAL4 mag_S1; /* magnitude of the spin = chi1 * m1 *m1 */
57 /* output parameters used to monitor evolution */
58 REAL8 LNhat_dot_S1; /* dot product of LNhat and S1 */
59}
61
62
63/* function that computes the derivatives of the dynamical */
64/* variables for the GSL ODE integrator */
66 REAL8 UNUSED t, const REAL8 y[11], REAL8 dydt[11], void* params )
67{
68 /* equation numbers in description of variables and algorithms refer to
69 * Pan, Buonanno, Chan and Vallisneri, Phys. Rev. D 69, 104017 (2004)
70 */
71
72 /* In this code the first body is the larger, spinning body with spin
73 * magnitude given by |S1| = chi1 * m1^2 with 0 \le chi1 \le 1
74 */
75
76 /* post newtonian coeffients which are independent of time */
78
79 /* evolution variables */
80 /* y[0] stores Phi, the gravitational wave phase as in Eq. (15), but it */
81 /* not needed in the evolution equations for the precession convention */
82 const REAL8 omega = y[1]; /* omega as in Eq. (5) */
83 const REAL8 S1x = y[2]; /* x-cmpt of first bodies spin in Eq. (6) */
84 const REAL8 S1y = y[3]; /* y-cmpt of first bodies spin in Eq. (6) */
85 const REAL8 S1z = y[4]; /* z-cmpt of first bodies spin in Eq. (6) */
86 const REAL8 LNhatx = y[5]; /* x-cmpt of orb plane normal in Eq. (7) */
87 const REAL8 LNhaty = y[6]; /* y-cmpt of orb plane normal in Eq. (7) */
88 const REAL8 LNhatz = y[7]; /* z-cmpt of orb plane normal in Eq. (7) */
89 const REAL8 e1x = y[8]; /* x-cmpt of orb plane basis vector 1 Eq.(13) */
90 const REAL8 e1y = y[9]; /* x-cmpt of orb plane basis vector 1 Eq.(13) */
91 const REAL8 e1z = y[10]; /* x-cmpt of orb plane basis vector 1 Eq.(13) */
92
93 /* powers of omega used in post-Newtonian expansion */
94 const REAL8 omega_1_3 = pow( omega, 1.0/3.0 );
95 const REAL8 omega_2_3 = omega_1_3 * omega_1_3;
96 const REAL8 omega_4_3 = omega * omega_1_3;
97 const REAL8 omega_5_3 = omega_4_3 * omega_1_3;
98 const REAL8 omega_7_3 = omega_5_3 * omega_2_3;
99 const REAL8 omega_6_3 = omega * omega;
100 const REAL8 omega_11_3 = omega_7_3 * omega_4_3;
101
102 /* coefficients of the cross products in Eqs. (6) and (7) */
103 const REAL8 S1_spin_orbit_coeff = omega_5_3 * pn_params->S1_spin_orbit;
104 const REAL8 LNhat_coeff = omega_1_3 * pn_params->LNhat;
105
106 /* compute the cross product of LNhat and S1 */
107 const REAL8 LNhat_cross_S1_x = LNhaty * S1z - LNhatz * S1y;
108 const REAL8 LNhat_cross_S1_y = LNhatz * S1x - LNhatx * S1z;
109 const REAL8 LNhat_cross_S1_z = LNhatx * S1y - LNhaty * S1x;
110
111 /* dot product of LNhat and S1 */
112 const REAL8 LNhat_dot_S1 = LNhatx * S1x + LNhaty * S1y + LNhatz * S1z;
113
114 /* OmegaL as defined in Eq. (7) */
115 const REAL8 OmegaLx = - LNhat_coeff * S1_spin_orbit_coeff * S1x;
116 const REAL8 OmegaLy = - LNhat_coeff * S1_spin_orbit_coeff * S1y;
117 const REAL8 OmegaLz = - LNhat_coeff * S1_spin_orbit_coeff * S1z;
118
119 /* dot product of OmegaL and LNhat needed in Eq. (14) */
120 const REAL8 OmegaL_dot_LNhat =
121 OmegaLx * LNhatx + OmegaLy * LNhaty + OmegaLz * LNhatz;
122
123 /* Omegae as defined by Eq. (14) */
124 const REAL8 Omegaex = OmegaLx - OmegaL_dot_LNhat * LNhatx;
125 const REAL8 Omegaey = OmegaLy - OmegaL_dot_LNhat * LNhaty;
126 const REAL8 Omegaez = OmegaLz - OmegaL_dot_LNhat * LNhatz;
127
128 /* compute the derivatives of the spin precession given by Eq. (6) */
129 const REAL8 dS1x_dt = S1_spin_orbit_coeff * LNhat_cross_S1_x;
130 const REAL8 dS1y_dt = S1_spin_orbit_coeff * LNhat_cross_S1_y;
131 const REAL8 dS1z_dt = S1_spin_orbit_coeff * LNhat_cross_S1_z;
132
133 /* compute the derivatives of the orbital precession given by Eq. (7) */
134 const REAL8 dLNhatx_dt = LNhat_coeff * dS1x_dt;
135 const REAL8 dLNhaty_dt = LNhat_coeff * dS1y_dt;
136 const REAL8 dLNhatz_dt = LNhat_coeff * dS1z_dt;
137
138 /* compute the of derivatives of the orbital plane basis given by Eq.(13) */
139 const REAL8 de1x_dt = Omegaey * e1z - Omegaez * e1y;
140 const REAL8 de1y_dt = Omegaez * e1x - Omegaex * e1z;
141 const REAL8 de1z_dt = Omegaex * e1y - Omegaey * e1x;
142
143 /* compute the derivative of the orbital phase given by Eq. (5) */
144 const REAL8 domega_dt = omega_11_3 * (
145 /* contribution due to purely orbital evolution */
146 + pn_params->orbital->data[0] /* 0 */
147 + pn_params->orbital->data[1] * omega_1_3 /* 0.5 */
148 + pn_params->orbital->data[2] * omega_2_3 /* 1.0 */
149 + pn_params->orbital->data[3] * omega /* 1.5 */
150 + pn_params->orbital->data[4] * omega_4_3 /* 2.0 */
151 + pn_params->orbital->data[5] * omega_5_3 /* 2.5 */
152 + pn_params->orbital->data[6] * omega_6_3 /* 3.0 */
153 + pn_params->orbital->data[7] * omega_6_3 * log( omega ) /* 3.0 */
154 + pn_params->orbital->data[8] * omega_7_3 /* 3.5 */
155 /* contribution at 1.5 pN due spin-orbit interaction */
156 + (pn_params->orbital->data[0]
157 * pn_params->spin->data[0] * LNhat_dot_S1) * omega
158 );
159
160 /* compute the derivative of the gravitational wave phase the gw */
161 /* phase evolution is purely orbital as we are working in the */
162 /* precessing converion: see the discussion after Eq. (14) */
163 const REAL8 dPhi_dt = omega;
164
165 /* pass LNhat_dot_back so we can check it's constant */
166 pn_params->LNhat_dot_S1 = LNhat_dot_S1;
167
168 /* copy derivatives into output array */
169 dydt[0] = dPhi_dt;
170 dydt[1] = domega_dt;
171 dydt[2] = dS1x_dt;
172 dydt[3] = dS1y_dt;
173 dydt[4] = dS1z_dt;
174 dydt[5] = dLNhatx_dt;
175 dydt[6] = dLNhaty_dt;
176 dydt[7] = dLNhatz_dt;
177 dydt[8] = de1x_dt;
178 dydt[9] = de1y_dt;
179 dydt[10] = de1z_dt;
180
181 return GSL_SUCCESS;
182}
183
184
187{
188 REAL4 m_total = m1 + m2;
189 REAL4 eta = (m1 * m2) / (m_total * m_total);
190 const UINT4 max_pn_order = 9;
191 REAL4Vector* c_vec = XLALCreateREAL4Vector( max_pn_order );
192 REAL4* c;
193
194 if ( ! c_vec )
196 else
197 c = c_vec->data;
198
199 /* 0 pN coefficient which multiplies all the other terms */
200 c[0] = (96.0/5.0) * eta;
201
202 /* 0.5 pN correction */
203 c[1] = 0;
204
205 /* 1 pN correction */
206 c[2] = c[0] * (-1.0/336.0) * (743.0 + 924.0 * eta);
207
208 /* 1.5 pN correction */
209 c[3] = c[0] * 4.0 * LAL_PI;
210
211 /* 2 pN correction */
212 c[4] = c[0] * (34103.0 + 122949.0 * eta + 59472.0 * eta * eta)
213 / 18144.0;
214
215 /* 2.5 pN correction */
216 c[5] = c[0] * (-1.0/672.0) * (4159.0 + 15876.0 * eta) * LAL_PI;
217
218 /* 3 pN correction excluding log((M omega)^2/3) term */
219 c[6] = c[0] * ( 16447322263.0/139708800.0
220 - 1712.0/105.0 * LAL_GAMMA
221 + 16.0/3.0 * LAL_PI * LAL_PI
222 + ( -273811877.0/1088640.0 + 451.0/48.0 * LAL_PI * LAL_PI
223 - (88.0 * 1039.0)/(3.0 * 4620.0) ) * eta
224 + 541.0/896.0 * eta * eta
225 - 5605.0/2592.0 * eta * eta * eta
226 - 856.0/105.0 * log(16.0) );
227
228 /* 3 pN correction of log((M omega)^2/3) term */
229 c[7] = c[0] * (-1712.0/315.0);
230
231 /* 3.5 pN correction */
232 c[8] = c[0] * (-13245.0 + 717350.0 * eta + 731960.0 * eta * eta)
233 * (LAL_PI/12096.0);
234
235 return c_vec;
236}
237
238
241 REAL4 chi1, REAL4 chi2,
242 REAL4 Q1, REAL4 Q2 )
243{
244 const REAL4 m_total = m1 + m2;
245 const REAL4 m1_5 = m1 * m1 * m1 * m1 * m1;
246 const REAL4 m2_5 = m2 * m2 * m2 * m2 * m2;
247 const UINT4 max_spin_order = 6;
248 REAL4Vector* c_vec = XLALCreateREAL4Vector( max_spin_order );
249 REAL4* c;
250
251 if ( ! c_vec )
253 else
254 c = c_vec->data;
255
256 /* 1.5 pN spin-orbit interaction from body 1 */
257 c[0] = (-1.0 / (12.0 * m_total * m_total)) * ( 113.0 + 75.0 * (m2/m1) );
258
259 /* 1.5 pN spin-orbit interaction from body 2 */
260 c[1] = (-1.0 / (12.0 * m_total * m_total)) * ( 113.0 + 75.0 * (m1/m2) );
261
262 /* 2 pN spin-spin interaction: coefficent of S_1 . S_2 */
263 c[2] = -247.0 / (48.0 * m_total * m_total * m1 * m2);
264
265 /* 2 pN spin-spin interaction: coefficent of (L . S_1)(L . S_2) */
266 c[3] = 721.0 / (48.0 * m_total * m_total * m1 * m2);
267
268 /* 2 pN Kerr quadrupole-monopole coupling for first body */
269 if ( chi1 )
270 c[4] = ( -5.0 * Q1 )
271 / ( 2.0 * m1_5 * chi1 * chi1 * m_total * m_total );
272 else
273 c[4] = 0;
274
275 /* 2 pN Kerr quadrupole-monopole coupling for second body */
276 if ( chi2 )
277 c[5] = ( -5.0 * Q2 )
278 / ( 2.0 * m2_5 * chi2 * chi2 * m_total * m_total );
279 else
280 c[5] = 0;
281
282 return c_vec;
283}
284
285
288 REAL4 chi1, REAL4 chi2,
289 REAL4 Q1, REAL4 Q2 )
290{
291 /* These coefficients are derived from Eqs. (11) and (12) and (13) of */
292 /* Buonanno, Chen and Vallisneri, Phys. Rev. D 67, 104025 (BCV2) */
293 const REAL4 m_total = m1 + m2;
294 const REAL4 mu = m1 * m2 / m_total;
295 const REAL4 eta = mu / m_total;
296 const REAL4 m1_5 = m1 * m1 * m1 * m1 * m1;
297 const REAL4 m2_5 = m2 * m2 * m2 * m2 * m2;
298 const UINT4 max_pn_order = 9;
299 REAL4Vector* c_vec = XLALCreateREAL4Vector( max_pn_order );
300 REAL4* c;
301
302 if ( ! c_vec )
304 else
305 c = c_vec->data;
306
307 /* 0 pN coefficient which multiplies all the other terms */
308 c[0] = -eta/3.0;
309
310 /* 0.5 pN correction */
311 c[1] = 0;
312
313 /* 1 pN correction */
314 c[2] = c[0] * (-1.0/6.0) * (9.0 + eta);
315
316 /* 1.5 pN correction */
317 c[3] = 0;
318
319 /* 2 pN correction */
320 c[4] = c[0] * (3.0/24.0) * (-81.0 + 57.0 * eta - eta * eta);
321
322 /* 2.5 pN correction */
323 c[5] = 0;
324
325 /* 3 pN correction */
326 c[6] = c[0] * 4.0
327 * ((-675.0/64.0)
328 + ( 34445.0/576.0 - 205*LAL_PI*LAL_PI/96.0 ) * eta
329 - 155.0/96.0 * eta * eta
330 - 35.0/5184.0 * eta * eta * eta);
331
332 /* 2.0 pN quadrupole-monopole coupling term from first body */
333 if ( chi1 )
334 c[7] = c[0] * (3.0 * Q1)
335 / (2.0 * m1_5 * chi1 * chi1 * m_total * m_total );
336 else
337 c[7] = 0;
338
339 /* 2.0 pN quadrupole-monopole coupling term from second body */
340 if ( chi2 )
341 c[8] = c[0] * (3.0 * Q2)
342 / (2.0 * m2_5 * chi2 * chi2 * m_total * m_total );
343 else
344 c[8] = 0;
345
346 return c_vec;
347}
348
349
350static REAL4
352{
353 REAL4 m_total = ma + mb;
354 REAL4 eta = (ma * mb) / (m_total * m_total);
355 return (eta/2.0) * ( 4.0 + 3.0 * ma/mb );
356}
357
358
359static REAL4
361{
362 REAL4 m_total = m1 + m2;
363 REAL4 eta = (m1 * m2) / (m_total * m_total);
364 return -1.0 / (eta * m_total * m_total);
365}
366
368 REAL8 LNhat_dot_S1, REAL8 LNhat_dot_S2, REAL8 S1_dot_S2,
369 REAL4 m1, REAL4 m2, REAL4 chi1, REAL4 chi2, REAL4Vector* pn_params )
370{
371 /* Function which computes the derivative of the orbital energy with */
372 /* respect to omega. This is algorithm here implements the (analytically */
373 /* computed) derivative of BCV2 Eq. (12) with respect to omega (i.e. it */
374 /* is the quantity on the left hand side of BCV2 Eq. (18). */
375
376 /* mass parameters */
377 const REAL8 m_total = m1 + m2;
378
379 /* magnitude of spin vectors needed for qm coupling term in energy */
380 const REAL8 mag_S1 = m1 * m1 * chi1;
381 const REAL8 mag_S2 = m2 * m2 * chi2;
382
383 /* LNhat dot S_effective defined in BCV2 Eq. (7) */
384 const REAL8 LNhat_dot_Seff
385 = ( 1.0 + (3.0 * m2) / (4.0 * m1) ) * LNhat_dot_S1
386 + ( 1.0 + (3.0 * m1) / (4.0 * m2) ) * LNhat_dot_S2;
387
388 /* powers of omega used in post-Newtonian expansion */
389 const REAL8 omega_1_3 = pow( omega, 1.0/3.0 );
390 const REAL8 omega_minus1_3 = 1.0 / omega_1_3;
391 const REAL8 omega_2_3 = omega_1_3 * omega_1_3;
392 const REAL8 omega_4_3 = omega * omega_1_3;
393 const REAL8 omega_5_3 = omega_4_3 * omega_1_3;
394
395 /* derivative of orbital energy with respect to time */
396 const REAL8 energy
397 /* contribution from non-spinning pN terms */
398 = pn_params->data[0] * omega_minus1_3 /* 0 */
399 + pn_params->data[1] /* 0.5 */
400 + pn_params->data[2] * omega_1_3 /* 1.0 */
401 + pn_params->data[3] * omega_2_3 /* 1.5 */
402 + pn_params->data[4] * omega /* 2.0 */
403 + pn_params->data[5] * omega_4_3 /* 2.5 */
404 + pn_params->data[6] * omega_5_3 /* 3.0 */
405 /* contribution from spin orbit terms at 1.5 pN order */
406 + pn_params->data[0]
407 * 20.0 * LNhat_dot_Seff * omega_2_3 / (3.0 * m_total * m_total)
408 /* XXX contribution from spin spin terms at 2.0 pN order */
409 + (-1.0/2.0) * ( S1_dot_S2 - 3.0 * LNhat_dot_S1 * LNhat_dot_S2 )
410 * omega_5_3 / (m_total * m_total)
411 /* contribution from first quadrupole-monopole coupling at 2.0 pN */
412 + pn_params->data[7] * omega
413 * ( 3.0 * LNhat_dot_S1 * LNhat_dot_S1 - mag_S1 * mag_S1 )
414 /* contribution from second quadrupole-monopole coupling at 2.0 pN */
415 + pn_params->data[8] * omega
416 * ( 3.0 * LNhat_dot_S2 * LNhat_dot_S2 - mag_S2 * mag_S2 );
417
418 return (REAL4) energy;
419}
420
421
422/* Function for the evaluation of the time evolution of the phase, the */
423/* frequency and the e_i basis vectors in the precessing convention */
424
425INT4
427 REAL4Vector *PTFphi,
428 REAL4Vector *PTFomega_2_3,
429 REAL4VectorSequence *PTFe1,
430 REAL4VectorSequence *PTFe2,
431 InspiralTemplate *InspTmplt,
432 REAL8 deltaT
433 )
434
435{
436 UINT4 i, len;
437 UINT4 N = PTFphi->length;
438 INT4 errcode = 0;
439 REAL8 f_min = InspTmplt->fLower;
440 REAL8 m1 = InspTmplt->mass1;
441 REAL8 m2 = InspTmplt->mass2;
442 REAL8 chi1 = InspTmplt->chi;
443 REAL8 kappa = InspTmplt->kappa;
444 REAL8 t, t_next;
445 REAL8 step_size;
446 REAL8 dE_dt, dE_dt_n_1=0, dE_dt_n_2=0;
447 REAL8 N_steps;
448
449 ptf_evolution_params_t pn_params;
450 ptf_evolution_params_t* pn_params_ptr = &pn_params;
451
452 const REAL8 m_total = m1 + m2;
453 const REAL8 geometrized_m_total = m_total * LAL_MTSUN_SI;
454 const REAL8 freq_step = geometrized_m_total * LAL_PI;
455 const REAL8 step = deltaT / geometrized_m_total;
456 const REAL8 omegam_to_hz = 1.0 / freq_step;
457 const INT4 num_evolution_variables = 11;
458 REAL8 y[11], dydt[11];
459
460 /* Dynamical evolution variables and their derivatives */
461 REAL8 Phi ; /* gravitational wave phase in BCV2 Eq. (18) */
462 REAL8 omega; /* omega as in Eq. (5) */
463 REAL8 UNUSED S1x; /* x-cmpt of first bodies spin in Eq. (6) */
464 REAL8 UNUSED S1y; /* y-cmpt of first bodies spin in Eq. (6) */
465 REAL8 UNUSED S1z; /* z-cmpt of first bodies spin in Eq. (6) */
466 REAL8 LNhatx; /* x-cmpt of orb plane normal in Eq. (7) */
467 REAL8 LNhaty; /* y-cmpt of orb plane normal in Eq. (7) */
468 REAL8 LNhatz; /* z-cmpt of orb plane normal in Eq. (7) */
469 REAL8 e1x; /* x-component of the basis vector e1 in Eq.(13) */
470 REAL8 e1y; /* y-component of the basis vector e1 in Eq.(13) */
471 REAL8 e1z; /* z-component of the basis vector e2 in Eq.(13) */
472 REAL8 e2x; /* x-component of the basis vector e2 in Eq.(13) */
473 REAL8 e2y; /* y-component of the basis vector e2 in Eq.(13) */
474 REAL8 e2z; /* z-component of the basis vector e2 in Eq.(13) */
475
476 /* orbital energy pn parameters and pn constants vector */
477 REAL4Vector* orbital_energy_coeffs;
478
479 /* create the differential equation solver */
480 const gsl_odeiv_step_type* solver_type
481 = gsl_odeiv_step_rkf45;
482 gsl_odeiv_step* solver_step
483 = gsl_odeiv_step_alloc( solver_type, num_evolution_variables );
484 gsl_odeiv_control* solver_control
485 = gsl_odeiv_control_standard_new( 1.0e-5, 1.0e-5, 1.0, 1.0 );
486 gsl_odeiv_evolve* solver_evolve
487 = gsl_odeiv_evolve_alloc( num_evolution_variables );
488 gsl_odeiv_system solver_system;
489
490 solver_system.function = XLALPTFWaveformDerivatives;
491 solver_system.jacobian = NULL;
492 solver_system.dimension = num_evolution_variables;
493 solver_system.params = (void*) pn_params_ptr;
494
495 /* set up orbital energy and post-Newtonian coefficents needed in evolution */
496 orbital_energy_coeffs = XLALPTFOmegaPNCoeffsEnergy( m1, m2, chi1, 0, 0, 0 );
497 pn_params.orbital = XLALPTFOmegaPNCoeffsOrbital( m1, m2 );
498 pn_params.spin = XLALPTFOmegaPNCoeffsSpin( m1, m2, chi1, 0, 0.0, 0 );
499 pn_params.S1_spin_orbit = spin_so_coeff( m2, m1 ); /* need m2/m1 */
500 pn_params.LNhat = orbital_coeff( m1, m2 );
501 pn_params.mag_S1 = m1 * m1 * chi1;
502
503 /* set up initial values for dynamical variables */
504 /* in the precessing convention */
505
506 Phi = y[0] = 0.0;
507 omega = y[1] = f_min / omegam_to_hz;
508 S1x = y[2] = sqrt( 1 - kappa * kappa ) * pn_params.mag_S1 ;
509 S1y = y[3] = 0;
510 S1z = y[4] = kappa * pn_params.mag_S1 ;
511 LNhatx = y[5] = 0.0;
512 LNhaty = y[6] = 0.0;
513 LNhatz = y[7] = 1.0;
514 e1x = y[8] = 1.0;
515 e1y = y[9] = 0.0;
516 e1z = y[10] = 0.0;
517 e2x = 0.0;
518 e2y = 1.0;
519 e2z = 0.0;
520
521 /* start computing the waveform we use a while() loop which we */
522 /* break out of when one of three possible temination conditions */
523 /* or two error conditions is reached */
524
525 /* Zero out the dynamical variables so they don't contain garbage */
526 memset ( PTFomega_2_3->data, 0, N * sizeof(REAL4));
527 memset ( PTFphi->data, 0, N * sizeof(REAL4));
528 memset ( PTFe1->data, 0, 3 * N * sizeof(REAL4));
529 memset ( PTFe2->data, 0, 3 * N * sizeof(REAL4));
530
531 i = 0;
532 t = 0;
533 while ( 1 )
534 {
535 /* if we have run out of memory for the waveform, break out of the loop */
536 if ( i >= N )
537 {
538 XLALPrintError( "XLAL Error: output too short for PTF waveform\n" );
539 errcode = XLAL_ENOMEM;
540 break;
541 }
542
543 /* compute the gravitational waveform from the dynamical */
544 /* variables and store it in the output structures */
545 PTFomega_2_3->data[i] = (REAL4) (pow( omega, 2.0/3.0 ));
546 PTFphi->data[i] = (REAL4) (Phi);
547 PTFe1->data[i] = (REAL4) (e1x);
548 PTFe1->data[N + i] = (REAL4) (e1y);
549 PTFe1->data[2 * N + i] = (REAL4) (e1z);
550 PTFe2->data[i] = (REAL4) (e2x);
551 PTFe2->data[N + i] = (REAL4) (e2y);
552 PTFe2->data[2 * N + i] = (REAL4) (e2z);
553
554 /* advance the time (which is in units of total mass) */
555 t = i * step;
556 t_next = ++i * step;
557 step_size = step;
558
559 /* call the solver to get the next timestep */
560 errcode = gsl_odeiv_evolve_apply(
561 solver_evolve, solver_control, solver_step, &solver_system,
562 &t, t_next, &step_size, y );
563
564 /* check for that the solver exited successfully */
565 if ( errcode != GSL_SUCCESS )
566 {
567 XLALPrintError( "XLAL Error: GSL ODE integrator failure\n" );
568 errcode = XLAL_EFAILED;
569 break;
570 }
571
572 /* copy the output variables necessary to compute the gw */
573 Phi = y[0];
574 omega = y[1];
575 LNhatx = y[5];
576 LNhaty = y[6];
577 LNhatz = y[7];
578 e1x = y[8];
579 e1y = y[9];
580 e1z = y[10];
581 e2x = LNhaty * e1z - LNhatz * e1y;
582 e2y = LNhatz * e1x - LNhatx * e1z;
583 e2z = LNhatx * e1y - LNhaty * e1x;
584
585 /* exit with an error if any of the dynamical variables contain NaN */
586 if ( isnan( Phi ) || isnan( omega ) || isnan( LNhatx ) ||
587 isnan( LNhaty ) || isnan( LNhatz ) || isnan( e1x ) ||
588 isnan( e1y ) || isnan( e1z ) )
589 {
590 /* check if we are close to the MECO */
591 N_steps = ((i-2) * dE_dt_n_1 - (i-1) * dE_dt_n_2) /
592 ( dE_dt_n_1 - dE_dt_n_2) - i + 1;
593
594 if ( N_steps > 5.0 )
595 {
596 fprintf(stderr,"cycle %d\n",i);
597 XLALPrintError( "XLAL Error: NaN in PTF dynamical variables\n" );
598 errcode = XLAL_EFAILED;
599 }
600 break;
601 }
602
603 /* Store the last two values of dE/dt so as to be able to estimate */
604 /* how far from the MECO condition we are in case the code is failing */
605 if ( i <= 1 )
606 {
607 dE_dt_n_1 = stpn_orbital_energy( omega, pn_params.LNhat_dot_S1,
608 0, 0, m1, m2, chi1, 0, orbital_energy_coeffs);
609 dE_dt_n_2 = dE_dt_n_1 * 1.01;
610 }
611 else if ( i > 1 )
612 {
613 dE_dt_n_2 = dE_dt_n_1;
614 dE_dt_n_1 = stpn_orbital_energy( omega, pn_params.LNhat_dot_S1,
615 0, 0, m1, m2, chi1, 0, orbital_energy_coeffs);
616 }
617
618 /* terminate if domega_dt is no longer positive as this means that */
619 /* the adiabatic approximation has probably broken down */
620 XLALPTFWaveformDerivatives( t, y, dydt, (void*) pn_params_ptr );
621 if ( dydt[1] <= 0 ) break;
622
623 /* terminate if the derivative of the orbital energy is zero or positive */
624 /* this is the MECO termination condition discessed in BCV2 Eq. (13) */
625 if ( (dE_dt = stpn_orbital_energy( omega, pn_params.LNhat_dot_S1,
626 0, 0, m1, m2, chi1, 0, orbital_energy_coeffs )) >= 0 ) break;
627
628 /* If all check are ok set the final frequency */
629 InspTmplt->fFinal = omega * omegam_to_hz;
630
631
632 } /* end of evolution while ( 1 ) loop */
633
634 /* free the memory used by the ode solver */
635 gsl_odeiv_evolve_free( solver_evolve );
636 gsl_odeiv_control_free( solver_control );
637 gsl_odeiv_step_free( solver_step );
638
639 /* free the memory used for the pn coefficients */
640 XLALDestroyREAL4Vector( orbital_energy_coeffs );
641 XLALDestroyREAL4Vector( pn_params.orbital );
642 XLALDestroyREAL4Vector( pn_params.spin);
643
644 /* Set the length of the template */
645 InspTmplt->tC = deltaT * (REAL8) i;
646
647 /* shift the waveform so that the coalescence time */
648 /* corresponds to the end of the segment */
649 len = N - i;
650
651 /* Move the waveform at the end of the segment */
652 memmove( PTFomega_2_3->data + len, PTFomega_2_3->data, i * sizeof(REAL4) );
653 memmove( PTFphi->data + len, PTFphi->data, i * sizeof(REAL4) );
654 memmove( PTFe1->data + len, PTFe1->data, (2 * N + i) * sizeof(REAL4) );
655 memmove( PTFe2->data + len, PTFe2->data, (2 * N + i) * sizeof(REAL4) );
656
657 /* Set the waveform to zero at the beginning of the segment */
658 memset ( PTFomega_2_3->data, 0, len * sizeof(REAL4));
659 memset ( PTFphi->data, 0, len * sizeof(REAL4));
660 memset ( PTFe1->data, 0, len * sizeof(REAL4));
661 memset ( PTFe2->data, 0, len * sizeof(REAL4));
662
663 /* the GSL success code is probably the same as LAL's but just in case... */
664 if ( errcode == GSL_SUCCESS )
665 errcode = XLAL_SUCCESS;
666 else
667 XLAL_ERROR(errcode);
668
669 return errcode;
670}
static REAL4 stpn_orbital_energy(REAL8 omega, REAL8 LNhat_dot_S1, REAL8 LNhat_dot_S2, REAL8 S1_dot_S2, REAL4 m1, REAL4 m2, REAL4 chi1, REAL4 chi2, REAL4Vector *pn_params)
static INT4 XLALPTFWaveformDerivatives(REAL8 UNUSED t, const REAL8 y[11], REAL8 dydt[11], void *params)
static REAL4 spin_so_coeff(REAL4 ma, REAL4 mb)
static REAL4 orbital_coeff(REAL4 m1, REAL4 m2)
#define fprintf
double i
INT4 XLALFindChirpPTFWaveform(REAL4Vector *PTFphi, REAL4Vector *PTFomega_2_3, REAL4VectorSequence *PTFe1, REAL4VectorSequence *PTFe2, InspiralTemplate *InspTmplt, REAL8 deltaT)
REAL4Vector * XLALPTFOmegaPNCoeffsSpin(REAL4 m1, REAL4 m2, REAL4 chi1, REAL4 chi2, REAL4 Q1, REAL4 Q2)
REAL4Vector * XLALPTFOmegaPNCoeffsEnergy(REAL4 m1, REAL4 m2, REAL4 chi1, REAL4 chi2, REAL4 Q1, REAL4 Q2)
REAL4Vector * XLALPTFOmegaPNCoeffsOrbital(REAL4 m1, REAL4 m2)
#define LAL_PI
#define LAL_MTSUN_SI
#define LAL_GAMMA
double REAL8
uint32_t UINT4
int32_t INT4
float REAL4
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
#define XLAL_ERROR_NULL(...)
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFAILED
list y
list mu
c
int N
The inspiral waveform parameter structure containing information about the waveform to be generated.
Definition: LALInspiral.h:205
REAL8 mass1
Mass of the primary in solar mass (input/output)
Definition: LALInspiral.h:211
REAL8 fFinal
final frequency reached, in units of Hz (output)
Definition: LALInspiral.h:293
REAL8 tC
total chirp time seconds (output)
Definition: LALInspiral.h:301
REAL8 mass2
Mass of the secondary in solar mass (mass1 need not be larger than mass2 (input/output)
Definition: LALInspiral.h:212
REAL8 fLower
lower frequency cutoff of the detector in Hz (input)
Definition: LALInspiral.h:217
REAL8 chi
dimensionless spin of black hole (ie mass1)
Definition: LALInspiral.h:274
REAL8 kappa
cosine of angle between spin of mass1 and orb ang mom
Definition: LALInspiral.h:275
REAL4 * data
double f_min
double deltaT