Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALInspiral 5.0.3.1-ea7c608
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALInspiralEccentricity.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007
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/**
21 * \author Devanka Pathak and Thomas Cokelaer
22 * \file
23 *
24 * \brief The code \c LALInspiralEccentricity generates a time-domain inspiral waveform corresponding to the
25 * \c approximant \c Eccentricity as outlined PRD 60 for the Newtonian case.
26 *
27 * ### Prototypes ###
28 *
29 * <tt>LALInspiralEccentricity()</tt>
30 * <ul>
31 * <li> \c signalvec: Output containing the inspiral waveform.</li>
32 * <li> \c params: Input containing binary chirp parameters and eccentricity.</li>
33 * </ul>
34 *
35 * <tt>LALInspiralEccentricityTemplates()</tt>
36 * <ul>
37 * <li> \c signalvec1: Output containing the 0-phase inspiral waveform.</li>
38 * <li> \c signalvec2: Output containing the \f$\pi/2\f$-phase inspiral waveform.</li>
39 * <li> \c params: Input containing binary chirp parameters.</li>
40 * </ul>
41 *
42 * ### Description ###
43 *
44 * \c LALInspiralEccentricity is called if the user has specified the
45 * \c enum \c approximant to be
46 * either \c TaylorT1 or \c PadeT1.
47 * \c LALInspiralEccentricityTemplates is exactly the same as <tt>LALInspiralEccentricity,</tt> except that
48 * it generates two templates one for which the starting phase is
49 * <tt>params.startPhase</tt> and the other for which the phase is
50 * <tt>params.startPhase + \f$\pi/2\f$</tt>.
51 *
52 * ### Algorithm ###
53 *
54 * This code uses a fourth-order Runge-Kutta algorithm to solve the ODEs
55 * in \eqref{eq_ode2}.
56 *
57 * ### Uses ###
58 *
59 * \code
60 * LALInspiralSetup()
61 * LALInspiralChooseModel()
62 * LALInspiralVelocity()
63 * LALInspiralPhasing1()
64 * LALInspiralDerivatives()
65 * LALRungeKutta4()
66 * \endcode
67 *
68 * ### Notes ###
69 *
70 */
71
72/*
73 Interface routine needed to generate time-domain T- or a P-approximant
74 waveforms by solving the ODEs using a 4th order Runge-Kutta; April 5, 00.
75*/
76#include <math.h>
77#include <lal/LALInspiral.h>
78#include <lal/LALStdlib.h>
79#include <lal/Units.h>
80#include <lal/SeqFactories.h>
81
82#ifdef __GNUC__
83#define UNUSED __attribute__ ((unused))
84#else
85#define UNUSED
86#endif
87
88/* structure to provide M and eta. */
89typedef struct
90tagecc_CBC_ODE_Struct
91{
92 double totalMass; /* M=m1+m2 */
93 double eta; /* eta=m1 m2/M^2 */
94}
96
97
98void
100 REAL8Vector *values,
101 REAL8Vector *dvalues,
102 void *params
103 );
104
105static void
108 REAL4Vector *signalvec1,
109 REAL4Vector *signalvec2,
110 REAL4Vector *a,
111 REAL4Vector *ff,
112 REAL8Vector *phi,
113 INT4 *countback,
115 );
116
117void
120 REAL4Vector *signalvec,
122 )
123 {
124
125 INT4 count;
126
129
130 ASSERT(signalvec, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
131 ASSERT(signalvec->data, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
132
133
134 /* Initially the waveform is empty*/
135 memset(signalvec->data, 0, signalvec->length*sizeof(REAL4));
136
137 /*Call the engine function*/
138 LALInspiralEccentricityEngine(status->statusPtr, signalvec, NULL, NULL, NULL, NULL, &count, params);
140
142 RETURN (status);
143
144}
145
146
147
148/*
149 Interface routine needed to generate time-domain T- or a P-approximant
150 waveforms by solving the ODEs using a 4th order Runge-Kutta; April 5, 00.
151*/
152
153void
156 REAL4Vector *signalvec1,
157 REAL4Vector *signalvec2,
159 )
160 {
161
162 INT4 count;
163
166
167 ASSERT(signalvec1, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
168 ASSERT(signalvec2, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
169 ASSERT(signalvec1->data, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
170 ASSERT(signalvec2->data, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
171
172 /* Initially the waveforms are empty */
173 memset(signalvec1->data, 0, signalvec1->length * sizeof(REAL4));
174 memset(signalvec2->data, 0, signalvec2->length * sizeof(REAL4));
175
176 /* Call the engine function */
177 LALInspiralEccentricityEngine(status->statusPtr, signalvec1, signalvec2, NULL, NULL, NULL, &count, params);
179
181 RETURN (status);
182
183}
184
185/*
186 * Engine function for use by other LALInspiralEccentricity* functions
187 * Craig Robinson April 2005
188 */
189
190void
193 REAL4Vector *signalvec1,
194 REAL4Vector *signalvec2,
195 REAL4Vector *a,
196 REAL4Vector UNUSED *ff,
197 REAL8Vector UNUSED *phi,
198 INT4 *countback,
200{
201 INT4 number_of_diff_equations = 3;
202 INT4 count = 0;
204 REAL8 phase;
205 REAL8 orbital_element_p,orbital_element_e_squared;
206 REAL8 orbital_element_e;
207 REAL8 twoPhim2Beta = 0;
208 REAL8 threePhim2Beta = 0;
209 REAL8 phim2Beta = 0;
210 REAL8 twoBeta;
211 REAL8 rbyM=1e6, rbyMFlso=6.;
212 REAL8 sin2Beta,cos2Beta,iota,onepCosSqI, SinSqI, cosI, e0, f_min, beta, p0;
213
214
215
216 REAL8 amp, m, dt, t, h1, h2, f, fHigh, piM, fu;
217 REAL8Vector dummy, values, dvalues, valuesNew, yt, dym, dyt;
218 INT4 done=0;
219 rk4In in4;
220 rk4GSLIntegrator *integrator;
221 void *funcParams;
222 expnCoeffs ak;
223 expnFunc func;
224
225#if 0
226 REAL8 mTot = 0;
227 REAL8 unitHz = 0;
228 REAL8 f2a = 0;
229 REAL8 mu = 0;
230 REAL8 etab = 0;
231 REAL8 fFac = 0; /* SI normalization for f and t */
232 REAL8 f2aFac = 0;/* factor multiplying f in amplitude function */
233 REAL8 apFac = 0, acFac = 0;/* extra factor in plus and cross amplitudes */
234#endif
235
238
239 ASSERT (params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
240 ASSERT (params->nStartPad >= 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
241 ASSERT (params->nEndPad >= 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
242 ASSERT (params->fLower > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
243 ASSERT (params->tSampling > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
244
245 LALInspiralSetup (status->statusPtr, &ak, params);
247 LALInspiralChooseModel(status->statusPtr, &func, &ak, params);
249
250 m = ak.totalmass = params->mass1+params->mass2;
251
252 values.length = dvalues.length = valuesNew.length =
253 yt.length = dym.length = dyt.length = number_of_diff_equations;
254 dummy.length = number_of_diff_equations * 6;
255 if (!(dummy.data = (REAL8 * ) LALMalloc(sizeof(REAL8) * number_of_diff_equations * 6))) {
256 ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
257 }
258
259 values.data = &dummy.data[0];
260 dvalues.data = &dummy.data[number_of_diff_equations];
261 valuesNew.data = &dummy.data[2*number_of_diff_equations];
262 yt.data = &dummy.data[3*number_of_diff_equations];
263 dym.data = &dummy.data[4*number_of_diff_equations];
264 dyt.data = &dummy.data[5*number_of_diff_equations];
265
266/* m = ak.totalmass;*/
267 dt = 1./params->tSampling;
268
269 if (a)
270 {
271 /*to be implemented. */
272
273
274/* mTot = params->mass1 + params->mass2;
275 etab = params->mass1 * params->mass2;
276 etab /= mTot;
277 etab /= mTot;
278 unitHz = mTot *LAL_MTSUN_SI*(REAL8)LAL_PI;
279 cosI = cos( params->inclination );
280 mu = etab * mTot;
281 fFac = 1.0 / ( 4.0*LAL_TWOPI*LAL_MTSUN_SI*mTot );
282 f2aFac = LAL_PI*LAL_MTSUN_SI*mTot*fFac;
283 apFac = acFac = -2.0 * mu * LAL_MRSUN_SI/params->distance;
284 apFac *= 1.0 + cosI*cosI;
285 acFac *= 2.0*cosI;
286 params->nStartPad = 0;
287 */
288 }
289
290 ASSERT(ak.totalmass > 0, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
291
292 t = 0.0;
293
294
295
296 in3.totalMass = (params->mass1 + params->mass2) * LAL_MTSUN_SI ;
297 in3.eta = (params->mass1 * params->mass2) /(params->mass1 + params->mass2) / (params->mass1 + params->mass2);
298 funcParams = (void *) &in3;
299
300
301 piM = LAL_PI * m * LAL_MTSUN_SI;
302/* f = (v*v*v)/piM;
303
304 fu = params->fCutoff;
305 if (fu)
306 fHigh = (fu < ak.flso) ? fu : ak.flso;
307 else
308 fHigh = ak.flso;
309 f = (v*v*v)/(LAL_PI*m);
310
311 ASSERT(fHigh < 0.5/dt, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
312 ASSERT(fHigh > params->fLower, status, LALINSPIRALH_ESIZE, LALINSPIRALH_MSGESIZE);
313*/
314
315
316 /* e0 is set at f_min */
317 e0 = params->eccentricity;
318
319 /* the second harmonic will start at fLower*2/3 */
320 f_min = params->fLower;
321 iota = params->inclination; /*overwritten later */
322
323 beta = 0.;
324 twoBeta = 2.* beta;
325 cos2Beta = cos(twoBeta);
326 sin2Beta = sin(twoBeta);
327 iota = LAL_PI/4.;
328 onepCosSqI = 1. + cos(iota) * cos(iota);
329 SinSqI = sin(iota) * sin(iota);
330 cosI = cos(iota);
331
332 p0 = (1. - e0*e0)/pow(2. * LAL_PI * m * LAL_MTSUN_SI* f_min/3. , 2./3.);
333
334 *(values.data) = orbital_element_p = p0;
335 *(values.data+1) = phase = params->startPhase;
336 *(values.data+2) = orbital_element_e = e0;
337
338
339
340
342 in4.x = t;
343 in4.y = &values;
344 in4.h = dt;
345 in4.n = number_of_diff_equations;
346 in4.yt = &yt;
347 in4.dym = &dym;
348 in4.dyt = &dyt;
349
350 xlalErrno = 0;
351 /* Initialize GSL integrator */
352 if (!(integrator = XLALRungeKutta4Init(number_of_diff_equations, &in4)))
353 {
354 INT4 errNum = XLALClearErrno();
355 LALFree(dummy.data);
356
357 if (errNum == XLAL_ENOMEM)
358 ABORT(status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM);
359 else
360 ABORTXLAL( status );
361 }
362
363 count = 0;
364 if (signalvec2) {
365 params->nStartPad = 0;} /* for template generation, that value must be zero*/
366
367 else if (signalvec1) {
368 count = params->nStartPad;
369 }
370
371 t = 0.0;
372
373
374 fu = params->fCutoff;
375 if (fu)
376 fHigh = (fu < ak.flso) ? fu : ak.flso;
377 else
378 fHigh = ak.flso;
379
380 f = 1./(pow(orbital_element_p, 3./2.))/piM;
381
382
383 /*fprintf(stderr, "fFinal = %f %f %f %f\n", fu,fHigh,f,ak.flso);*/
384 done = 0;
385 do {
386 /* Free up memory and abort if writing beyond the end of vector*/
387 /*if ((signalvec1 && (UINT4)count >= signalvec1->length) || (ff && (UINT4)count >= ff->length))*/
388 if ((signalvec1 && (UINT4)count >= signalvec1->length))
389 {
390 XLALRungeKutta4Free( integrator );
391 LALFree(dummy.data);
392 ABORT(status, LALINSPIRALH_EVECTOR, LALINSPIRALH_MSGEVECTOR);
393 }
394
395 /* Non-injection case */
396 if (signalvec1)
397 {
398 twoPhim2Beta = 2.* phase - twoBeta;
399 phim2Beta = phase - twoBeta;
400 threePhim2Beta = 3.* phase - twoBeta;
401 orbital_element_e_squared = orbital_element_e * orbital_element_e;
402 amp = params->signalAmplitude / orbital_element_p;
403
404/* fprintf(stderr, "%e %e %e %e %e\n", twoBeta, twoPhim2Beta, phim2Beta, threePhim2Beta, orbital_element_e_squared);*/
405
406
407 h1 = amp * ( ( 2. * cos(twoPhim2Beta) + 2.5 * orbital_element_e * cos(phim2Beta)
408 + 0.5 * orbital_element_e * cos(threePhim2Beta) + orbital_element_e_squared * cos2Beta) * onepCosSqI +
409 + ( orbital_element_e * cos(orbital_element_p) + orbital_element_e_squared) * SinSqI);
410 if ((f >= params->fLower) && (done == 0))
411 {
412 /*fprintf(stderr, "freq=%e p=%e, e=%e, phase = %e\n", f,orbital_element_p, orbital_element_e, phase);fflush(stderr);
413*/
414 params->alpha1 = orbital_element_e;
415 done = 1;
416 }
417 /*if (f>=params->fLower)*/
418 {
419 *(signalvec1->data + count) = (REAL4) h1;
420 }
421
422 if (signalvec2)
423 {
424 h2 = amp * ( ( 4. * sin(twoPhim2Beta) + 5 * orbital_element_e * sin(phim2Beta)
425 + orbital_element_e * sin(threePhim2Beta) - 2. * orbital_element_e_squared * sin2Beta) * cosI);
426/* if (f>=params->fLower)*/
427 {
428 *(signalvec2->data + count) = (REAL4) h2;
429 }
430 }
431 }
432
433 /* Injection case */
434 else if (a)
435 {
436 /*to be done*/
437 /*
438 omega = v*v*v;
439
440 ff->data[count] = (REAL4)(omega/unitHz);
441 f2a = pow (f2aFac * omega, 2./3.);
442 a->data[2*count] = (REAL4)(4.*apFac * f2a);
443 a->data[2*count+1] = (REAL4)(4.*acFac * f2a);
444 phi->data[count] = (REAL8)(p);
445 */
446 }
447
448 LALInspiralEccentricityDerivatives(&values, &dvalues,funcParams);
450
451 in4.dydx = &dvalues;
452 in4.x=t;
453
454 LALRungeKutta4(status->statusPtr, &valuesNew, integrator, funcParams);
456
457 *(values.data) = orbital_element_p = *(valuesNew.data);
458 *(values.data+1) = phase = *(valuesNew.data+1);
459 *(values.data+2) = orbital_element_e = *(valuesNew.data+2);
460
461 t = (++count-params->nStartPad) * dt;
462 /* v^3 is equal to p^(3/2)*/
463 f = 1./(pow(orbital_element_p, 3./2.))/piM;
464/* fprintf(stderr, "p=%e, e=%e, phase = %e\n", orbital_element_p, orbital_element_e, phase);
465 fflush(stderr);*/
466 rbyM = orbital_element_p/(1.+orbital_element_e * cos(phase));
467 /*fprintf(stderr, "rbyM=%e rbyMFlso=%e t=%e, ak.tn=%e f=%e e=%e\n",rbyM, rbyMFlso, t, ak.tn,f,orbital_element_e);
468 fflush(stderr);*/
469
470 } while ( (t < ak.tn) && (rbyM>rbyMFlso) && (f<fHigh));
471
472
473 /*fprintf(stderr, "t=%e ak.tn=%e rbyM=%e rbyMFlso=%e f=%f fHigh=%f", t, ak.tn, rbyM, rbyMFlso, f, fHigh);*/
474
475 /*also need to add for the fupper nyquist frequency**/
476 params->vFinal = orbital_element_p;
477 params->fFinal = f;
478 params->tC = t;
479 *countback = count;
480
481 XLALRungeKutta4Free( integrator );
482 LALFree(dummy.data);
483
485 RETURN (status);
486
487}
488
489
490
491
492void
494 REAL8Vector *values,
495 REAL8Vector *dvalues,
496 void *params
497 )
498 {
499
501 double M, eta, mu, c1, e0, e2, UNUSED p0, p2, p3, p4, phi;
502 par = (ecc_CBC_ODE_Input *) params;
503
504 /* affectation */
505 M = par->totalMass; /* in MTSUN*/
506 eta = par->eta; /*dimensionless*/
507 mu = eta * M; /*therefore in MTSUN*/
508 phi = values->data[1];
509 e0 = values->data[2];
510 e2 = values->data[2] * values->data[2];
511 p0 = values->data[0];
512 p2 = values->data[0] * values->data[0];
513 p3 = p2 * values->data[0];
514 p4 = p3 * values->data[0];
515
516 c1 = pow(1. - e2, 1.5);
517
518 /* y[0] is p
519 y[1] is phase
520 * y[2] is e
521 */
522
523/* fprintf(stderr, "before=%e %e %e\n", p0, e0, phi);*/
524 /* Eq 6 */
525 dvalues->data[1] = 1./(M * sqrt (p3)) * ( 1. + e0 * cos(phi) ) * ( 1. + e0 * cos(phi) );
526
527 /* Eq 8 */
528 dvalues->data[0] = (-64./5.) * mu / M / M * c1 / p3 * (1 + 7./8. * e2);
529
530 /* Eq 9*/
531 dvalues->data[2] = (-304./15.) * mu / M / M / p4 * c1 * e0 * (1. + 121./304. * e2);
532
533/* fprintf(stderr, "new values p=%e, e=%e, phase = %e\n",
534 dvalues->data[0],
535 dvalues->data[2],
536 dvalues->data[1]);*/
537
538 return;
539}
void XLALRungeKutta4Free(rk4GSLIntegrator *integrator)
void LALInspiralSetup(LALStatus *status, expnCoeffs *ak, InspiralTemplate *params)
void LALInspiralChooseModel(LALStatus *status, expnFunc *func, expnCoeffs *ak, InspiralTemplate *params)
void LALRungeKutta4(LALStatus *, REAL8Vector *, rk4GSLIntegrator *, void *)
rk4GSLIntegrator * XLALRungeKutta4Init(INT4 n, rk4In *input)
static void LALInspiralEccentricityEngine(LALStatus *status, REAL4Vector *signalvec1, REAL4Vector *signalvec2, REAL4Vector *a, REAL4Vector *ff, REAL8Vector *phi, INT4 *countback, InspiralTemplate *params)
void LALInspiralEccentricityDerivatives(REAL8Vector *values, REAL8Vector *dvalues, void *params)
void LALInspiralEccentricity(LALStatus *status, REAL4Vector *signalvec, InspiralTemplate *params)
void LALInspiralEccentricityTemplates(LALStatus *status, REAL4Vector *signalvec1, REAL4Vector *signalvec2, InspiralTemplate *params)
#define LALMalloc(n)
#define LALFree(p)
const double c1
#define ABORT(statusptr, code, mesg)
#define CHECKSTATUSPTR(statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define ABORTXLAL(sp)
#define LAL_PI
#define LAL_MTSUN_SI
double REAL8
uint32_t UINT4
int32_t INT4
float REAL4
#define LALINSPIRALH_EVECTOR
Attempting to write beyond the end of vector.
Definition: LALInspiral.h:71
#define LALINSPIRALH_EMEM
Memory allocation error.
Definition: LALInspiral.h:57
#define LALINSPIRALH_ENULL
Arguments contained an unexpected null pointer.
Definition: LALInspiral.h:56
#define LALINSPIRALH_ESIZE
Invalid input range.
Definition: LALInspiral.h:59
static const INT4 m
static const INT4 a
#define xlalErrno
int XLALClearErrno(void)
XLAL_ENOMEM
M
list mu
The inspiral waveform parameter structure containing information about the waveform to be generated.
Definition: LALInspiral.h:205
REAL4 * data
REAL8 * data
This structure contains various post-Newtonian and P-approximant expansion coefficients; the meanings...
Definition: LALInspiral.h:399
REAL8 totalmass
Definition: LALInspiral.h:474
REAL8 flso
Definition: LALInspiral.h:487
Structure to hold the pointers to the generic functions defined above.
Definition: LALInspiral.h:546
double inclination
double eccentricity
Structure containing steps and controls for the GSL Runge-Kutta solver.
Definition: LALInspiral.h:637
Structure used as an input to Runge-Kutta solver.
Definition: LALInspiral.h:620
REAL8Vector * dym
Definition: LALInspiral.h:626
REAL8 x
Definition: LALInspiral.h:622
REAL8Vector * yt
Definition: LALInspiral.h:625
REAL8Vector * dydx
Definition: LALInspiral.h:624
REAL8 h
Definition: LALInspiral.h:628
REAL8Vector * dyt
Definition: LALInspiral.h:627
INT4 n
Definition: LALInspiral.h:629
REAL8Vector * y
Definition: LALInspiral.h:623
TestFunction * function
Definition: LALInspiral.h:621
double f_min