Processing math: 0%
LALInspiral 5.0.3.1-ea7c608
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALInspiralWave2.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2007 Stas Babak, David Churches, Jolien Creighton, B.S. Sathyaprakash, Craig Robinson , Thomas Cokelaer, Drew Keppel
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 Sathyaprakash, B. S.
22 * \file
23 * \ingroup LALInspiral_h
24 *
25 * \brief These modules generate a time-domain chirp waveform of type #TaylorT2.
26 *
27 * ### Prototypes ###
28 *
29 * <tt>XLALInspiralWave2()</tt>
30 * <ul>
31 * <li> \c output: Output containing the inspiral waveform.</li>
32 * <li> \c params: Input containing binary chirp parameters.</li>
33 * </ul>
34 *
35 * <tt>XLALInspiralWave2Templates()</tt>
36 * <ul>
37 * <li> \c output1: Output containing the 0-phase inspiral waveform.</li>
38 * <li> \c output2: 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 * XLALInspiralWave2() generates #TaylorT2 approximant wherein
45 * the phase of the waveform is given as an implicit function of time
46 * as in \eqref{eq_InspiralWavePhase2}. A template is required
47 * to be sampled at equal intervals of time. Thus, first of the equations
48 * in \eqref{eq_InspiralWavePhase2} is solved for \f$v\f$ at equally
49 * spaced values of the time steps
50 * \f$t_k\f$ and the resulting value of \f$v_k\f$ is used in the second equation to
51 * obtain the phase \f$\phi_k\f$.
52 *
53 * XLALInspiralWave2Templates() is exactly the same as XLALInspiralWave2()
54 * except that it generates two waveforms that differ in phase by \f$\pi/2.\f$
55 *
56 * ### Uses ###
57 *
58 * \code
59 * LALInspiralParameterCalc()
60 * LALDBisectionFindRoot()
61 * LALInspiralPhasing2()
62 * \endcode
63 *
64 */
65
66#include <math.h>
67#include <lal/LALStdlib.h>
68#include <lal/LALInspiral.h>
69#include <lal/FindRoot.h>
70#include <lal/Units.h>
71#include <lal/SeqFactories.h>
72
73static int
75 REAL4Vector *output1,
76 REAL4Vector *output2,
77 REAL4Vector *h,
79 REAL4Vector *ff,
80 REAL8Vector *phi,
82 InspiralInit *paramsInit
83 );
84
85int
87 REAL4Vector *output,
89 )
90{
91
92 INT4 count;
93 InspiralInit paramsInit;
94
95 if (output == NULL)
97 if (output->data == NULL)
99 if (params == NULL)
101 if (params->nStartPad < 0)
103 if (params->fLower <= 0)
105 if (params->tSampling <= 0)
107
110 if (XLALInspiralSetup(&(paramsInit.ak), params))
112 if (XLALInspiralChooseModel(&(paramsInit.func), &(paramsInit.ak), params))
114
115 if (params->totalMass <= 0.)
117 if (params->eta < 0.)
119
120 memset( output->data, 0, output->length * sizeof(REAL4) );
121
122 /* Call the engine function */
123 count = XLALInspiralWave2Engine(output, NULL, NULL, NULL,
124 NULL, NULL, params, &paramsInit);
125 if (count < 0)
127
128 return XLAL_SUCCESS;
129}
130
131int
133 REAL4Vector *output1,
134 REAL4Vector *output2,
136 )
137{
138 INT4 count;
139 InspiralInit paramsInit;
140
141 if (output1 == NULL)
143 if (output2 == NULL)
145 if (output1->data == NULL)
147 if (output2->data == NULL)
149 if (params == NULL)
151 if (params->nStartPad < 0)
153 if (params->fLower <= 0)
155 if (params->tSampling <= 0)
157
160 if (XLALInspiralSetup(&(paramsInit.ak), params))
162 if (XLALInspiralChooseModel(&(paramsInit.func), &(paramsInit.ak), params))
164
165 if (params->totalMass <= 0.)
167 if (params->eta < 0.)
169
170 /* Initialise the waveforms to zero */
171 memset(output1->data, 0, output1->length * sizeof(REAL4));
172 memset(output2->data, 0, output2->length * sizeof(REAL4));
173
174 /* Call the engine function */
175 count = XLALInspiralWave2Engine(output1, output2, NULL, NULL,
176 NULL, NULL, params, &paramsInit);
177
178 if (count < 0)
180
181 return XLAL_SUCCESS;
182}
183
184int
186 CoherentGW *waveform,
188 PPNParamStruc *ppnParams
189 )
190{
191 INT4 count;
192 UINT4 i;
193 REAL4Vector *a = NULL;/* pointers to generated amplitude data */
194 REAL4Vector *h = NULL;/* pointers to generated polarizations */
195 REAL4Vector *ff = NULL;/* pointers to generated frequency data */
196 REAL8Vector *phi = NULL;/* pointer to generated phase data */
197
198 REAL8 phiC;/* phase at coalescence */
199 CHAR message[256];
200
201 InspiralInit paramsInit;
202
203 /* Make sure parameter and waveform structures exist. */
204 if (params == NULL)
206 if (waveform == NULL)
208 if (waveform->h != NULL)
210 if (waveform->a != NULL)
212 if (waveform->f != NULL)
214 if (waveform->phi != NULL)
216 if (waveform->shift != NULL)
218
219
220 params->ampOrder = (LALPNOrder) 0;
221 sprintf(message, "WARNING: Amp Order has been reset to %d", params->ampOrder);
222 XLALPrintInfo("%s", message);
223 /* Compute some parameters*/
224 if (XLALInspiralInit(params, &paramsInit))
226
227 if (paramsInit.nbins == 0)
228 {
229 /* FIXME: is this the correct thing to return? */
230 return XLAL_SUCCESS;
231 }
232
233 /* Now we can allocate memory and vector for coherentGW structure*/
234 ff = XLALCreateREAL4Vector(paramsInit.nbins);
235 if (ff == NULL)
237 a = XLALCreateREAL4Vector(2*paramsInit.nbins);
238 if (a == NULL)
240 phi = XLALCreateREAL8Vector(paramsInit.nbins);
241 if (phi == NULL)
243
244 /* By default the waveform is empty */
245 memset(ff->data, 0, paramsInit.nbins * sizeof(REAL4));
246 memset(a->data, 0, 2 * paramsInit.nbins * sizeof(REAL4));
247 memset(phi->data, 0, paramsInit.nbins * sizeof(REAL8));
248
249 if( params->ampOrder )
250 {
251 h = XLALCreateREAL4Vector(2*paramsInit.nbins);
252 if (h == NULL)
254 memset(h->data, 0, h->length * sizeof(REAL4));
255 }
256
257 /* Call the engine function */
258 count = XLALInspiralWave2Engine(NULL, NULL, h, a, ff,
259 phi, params, &paramsInit);
260 if (count < 0)
261 {
265 if( h )
266 {
268 }
270 }
271
272 if ( fabs(phi->data[count-1]/2.)/LAL_PI < 2. ){
273 sprintf(message, "The waveform has only %f cycles; we don't keep waveform with less than 2 cycles.",
274 (double)(fabs(phi->data[count-1]/2.)/LAL_PI) );
275 XLALPrintWarning("%s", message);
276 }
277 else
278 {
279 /*wrap the phase vector*/
280 phiC = phi->data[count-1] ;
281 for (i=0; i<(UINT4)count;i++)
282 {
283 phi->data[i] = phi->data[i] -phiC + ppnParams->phi;
284 }
285 /* Allocate the waveform structures. */
286 waveform->a = (REAL4TimeVectorSeries *) XLALMalloc( sizeof(REAL4TimeVectorSeries) );
287 if ( waveform->a == NULL )
289 memset( waveform->a, 0, sizeof(REAL4TimeVectorSeries) );
290
291 waveform->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) );
292 if ( waveform->f == NULL )
293 {
294 XLALFree( waveform->a );
295 waveform->a = NULL;
297 }
298 memset( waveform->f, 0, sizeof(REAL4TimeSeries) );
299
300 waveform->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) );
301 if ( waveform->phi == NULL )
302 {
303 XLALFree( waveform->a );
304 waveform->a = NULL;
305 XLALFree( waveform->f );
306 waveform->f = NULL;
308 }
309 memset( waveform->phi, 0, sizeof(REAL8TimeSeries) );
310
311 waveform->a->data = XLALCreateREAL4VectorSequence(count, 2);
312 if (waveform->a->data == NULL)
314 waveform->f->data = XLALCreateREAL4Vector(count);
315 if (waveform->f->data == NULL)
317 waveform->phi->data = XLALCreateREAL8Vector(count);
318 if (waveform->phi->data == NULL)
320
321 memcpy(waveform->f->data->data , ff->data, count*(sizeof(REAL4)));
322 memcpy(waveform->a->data->data , a->data, 2*count*(sizeof(REAL4)));
323 memcpy(waveform->phi->data->data ,phi->data, count*(sizeof(REAL8)));
324
325 waveform->a->deltaT = waveform->f->deltaT = waveform->phi->deltaT = ppnParams->deltaT;
326
327 waveform->a->sampleUnits = lalStrainUnit;
328 waveform->f->sampleUnits = lalHertzUnit;
330 waveform->position = ppnParams->position;
331 waveform->psi = ppnParams->psi;
332
333 snprintf( waveform->a->name, LALNameLength, "T2 inspiral amplitude" );
334 snprintf( waveform->f->name, LALNameLength, "T2 inspiral frequency" );
335 snprintf( waveform->phi->name, LALNameLength, "T2 inspiral phase" );
336
337
338 /* --- fill some output ---*/
339 ppnParams->tc = (double)(count-1) / params->tSampling ;
340 ppnParams->length = count;
341 ppnParams->dfdt = ((REAL4)(waveform->f->data->data[count-1] - waveform->f->data->data[count-2])) * ppnParams->deltaT;
342 ppnParams->fStop = params->fFinal;
344 ppnParams->termDescription = GENERATEPPNINSPIRALH_MSGEFSTOP;
345
346 ppnParams->fStart = ppnParams->fStartIn;
347
348 if( params->ampOrder )
349 {
350 waveform->h = (REAL4TimeVectorSeries *) XLALMalloc( sizeof(REAL4TimeVectorSeries) );
351 if ( waveform->h == NULL )
353 memset( waveform->h, 0, sizeof(REAL4TimeVectorSeries) );
354
355 waveform->h->data = XLALCreateREAL4VectorSequence(count, 2);
356 if ( waveform->h->data == NULL )
358 memcpy(waveform->h->data->data , h->data, 2*count*(sizeof(REAL4)));
359 waveform->h->deltaT = 1./params->tSampling;
360 waveform->h->sampleUnits = lalStrainUnit;
361 snprintf( waveform->h->name, LALNameLength, "T3 inspiral polarizations" );
363 h = NULL;
364 }
365 } /*end of coherentGW storage */
366
367
368 /* --- free memory --- */
372
373 return XLAL_SUCCESS;
374}
375
376/* 'Engine' function upon which all the other functions invoke
377 Craig Robinson 04/05 */
378
379
380
381static int
383 REAL4Vector *output1,
384 REAL4Vector *output2,
385 REAL4Vector *h,
386 REAL4Vector *a,
387 REAL4Vector *ff,
388 REAL8Vector *phi,
390 InspiralInit *paramsInit
391 )
392{
393
394 REAL8 amp, dt, fs, fu, fHigh, phase0, phase1, tC;
395 REAL8 phase, v, totalMass, fLso, freq, fOld;
396 INT4 i, startShift, count;
397 REAL8 xmin,xmax,xacc;
398 REAL8 (*timing2)(REAL8, void *);
399 InspiralToffInput toffIn;
400 void *funcParams;
401 expnCoeffs ak;
402 expnFunc func;
403
404 /* Variables only used in injection case.. */
405 REAL8 omega;
406 REAL8 unitHz = 0;
407 REAL8 f2a = 0;
408 REAL8 mu = 0;
409 REAL8 mTot = 0;
410 REAL8 cosI = 0;/* cosine of system inclination */
411 REAL8 etab =0;
412 REAL8 fFac = 0; /* SI normalization for f and t */
413 REAL8 f2aFac = 0;/* factor multiplying f in amplitude function */
414 REAL8 apFac = 0, acFac = 0;/* extra factor in plus and cross amplitudes */
415
416
417 ak = paramsInit->ak;
418 func = paramsInit->func;
419
420 if (output2 || a)
421 params->nStartPad = 0; /* that value must be zero for template generation */
422 dt = 1.0/(params->tSampling); /* sampling interval */
423 fs = params->fLower; /* lower frequency cutoff */
424 fu = params->fCutoff; /* upper frequency cutoff */
425 startShift = params->nStartPad; /* number of bins to pad at the beginning */
426 phase0 = params->startPhase; /* initial phasea */
427 phase1 = phase0 + LAL_PI_2;
428
429 timing2 = func.timing2; /* function to solve for v, given t:*/
430
431 if (a || h) /* Only used in injection case */
432 {
433 mTot = params->mass1 + params->mass2;
434 etab = params->mass1 * params->mass2;
435 etab /= mTot;
436 etab /= mTot;
437 unitHz = (mTot) *LAL_MTSUN_SI*(REAL8)LAL_PI;
438 cosI = cos( params->inclination );
439 mu = etab * mTot;
440 fFac = 1.0 / ( 4.0*LAL_TWOPI*LAL_MTSUN_SI*mTot );
441 f2aFac = LAL_PI*LAL_MTSUN_SI*mTot*fFac;
442 apFac = acFac = -2.0 * mu * LAL_MRSUN_SI/params->distance;
443 apFac *= 1.0 + cosI*cosI;
444 acFac *= 2.0 * cosI;
445 }
446
447 if (params->totalMass <= 0)
449 if (params->eta < 0 || params->eta > 0.25)
451
452 totalMass = params->totalMass*LAL_MTSUN_SI; /* convert from solar masses to seconds */
453
454 toffIn.tN = ak.tvaN;
455 toffIn.t2 = ak.tva2;
456 toffIn.t3 = ak.tva3;
457 toffIn.t4 = ak.tva4;
458 toffIn.t5 = ak.tva5;
459 toffIn.t6 = ak.tva6;
460 toffIn.t7 = ak.tva7;
461 toffIn.tl6 = ak.tvl6;
462 toffIn.piM = ak.totalmass * LAL_PI;
463
464 /* Determine the total chirp-time tC: the total chirp time is
465 timing2(v0;tC,t) with t=tc=0*/
466
467 toffIn.t = 0.;
468 toffIn.tc = 0.;
469 funcParams = (void *) &toffIn;
470 tC = func.timing2(fs, funcParams);
473 /* Reset chirp time in toffIn structure */
474 toffIn.tc = -tC;
475
476 /* Determine the initial phase: it is phasing2(v0) with ak.phiC=0 */
477 v = pow(fs * LAL_PI * totalMass, (1./3.));
478 ak.phiC = 0.0;
479 phase = func.phasing2(v, &ak);
480 if (XLAL_IS_REAL8_FAIL_NAN(phase))
482 ak.phiC = -phase;
483
484 /*
485 If flso is less than the user inputted upper frequency cutoff fu,
486 */
487
488 fLso = ak.fn;
489 if (fu)
490 fHigh = (fu < fLso) ? fu : fLso;
491 else
492 fHigh = fLso;
493
494 /* Is the sampling rate large enough? */
495
496 if (fHigh >= 0.5/dt)
498 if (fHigh <= params->fLower)
500
501 xmax = 1.2*fu;
502 xacc = 1.0e-8;
503 xmin = 0.999999*fs;
504
505 i = startShift;
506
507 /* Now cast the input structure to argument 4 of BisectionFindRoot so that it
508 of type void * rather than InspiralToffInput */
509
510 funcParams = (void *) &toffIn;
511
512 toffIn.t = 0.0;
513 freq = fs;
514 count=0;
515 do
516 {
517 /*
518 Check we're not writing past the end of the vector
519 */
520 if ((output1 && ((UINT4)i >= output1->length)) || (ff && ((UINT4)count >= ff->length)))
521 {
523 }
524
525 fOld = freq;
526 v = pow(freq*toffIn.piM, (1./3.));
527 phase = func.phasing2(v, &ak); /* phase at given v */
528 if (XLAL_IS_REAL8_FAIL_NAN(phase))
530
531 amp = params->signalAmplitude*v*v;
532
533 if (output1)
534 {
535 output1->data[i]=(REAL4)(amp*cos(phase+phase0));
536 if (output2)
537 output2->data[i]=(REAL4)(amp*cos(phase+phase1));
538 }
539 else
540 {
541 int ice, ico;
542 ice = 2*count;
543 ico = ice + 1;
544 omega = v*v*v;
545
546 ff->data[count]= (REAL4)(omega/unitHz);
547 f2a = pow (f2aFac * omega, 2./3.);
548 a->data[ice] = (REAL4)(4.*apFac * f2a);
549 a->data[ico] = (REAL4)(4.*acFac * f2a);
550 phi->data[count] = (REAL8)(phase);
551
552 if(h)
553 {
554 h->data[ice] = LALInspiralHPlusPolarization( phase, v, params );
555 h->data[ico] = LALInspiralHCrossPolarization( phase, v, params );
556 }
557 }
558 i++;
559 ++count;
560 toffIn.t=count*dt;
561 /*
562 Determine the frequency at the current time by solving timing2(v;tC,t)=0
563 */
564 xmin = 0.8*freq;
565 freq = XLALDBisectionFindRoot(timing2, xmin, xmax, xacc, funcParams);
566 if (XLAL_IS_REAL8_FAIL_NAN(freq))
568 } while (freq < fHigh && freq > fOld && toffIn.t < -tC);
569 params->fFinal = fOld;
570 if (output1 && !(output2)) params->tC = toffIn.t;
571
572 return count;
573}
int XLALInspiralParameterCalc(InspiralTemplate *params)
REAL4 LALInspiralHCrossPolarization(REAL8 phase, REAL8 v, InspiralTemplate *params)
int XLALInspiralSetup(expnCoeffs *ak, InspiralTemplate *params)
int XLALInspiralInit(InspiralTemplate *params, InspiralInit *paramsInit)
int XLALInspiralChooseModel(expnFunc *func, expnCoeffs *ak, InspiralTemplate *params)
REAL4 LALInspiralHPlusPolarization(REAL8 phase, REAL8 v, InspiralTemplate *params)
int XLALInspiralWave2(REAL4Vector *output, InspiralTemplate *params)
int XLALInspiralWave2ForInjection(CoherentGW *waveform, InspiralTemplate *params, PPNParamStruc *ppnParams)
int XLALInspiralWave2Templates(REAL4Vector *output1, REAL4Vector *output2, InspiralTemplate *params)
static int XLALInspiralWave2Engine(REAL4Vector *output1, REAL4Vector *output2, REAL4Vector *h, REAL4Vector *a, REAL4Vector *ff, REAL8Vector *phi, InspiralTemplate *params, InspiralInit *paramsInit)
#define LALMalloc(n)
double i
REAL4VectorSequence * XLALCreateREAL4VectorSequence(UINT4 length, UINT4 veclen)
REAL8 XLALDBisectionFindRoot(REAL8(*y)(REAL8, void *), REAL8 xmin, REAL8 xmax, REAL8 xacc, void *params)
#define GENERATEPPNINSPIRALH_EFSTOP
Reached requested termination frequency.
#define LAL_PI_2
#define LAL_PI
#define LAL_TWOPI
#define LAL_MTSUN_SI
#define LAL_MRSUN_SI
double REAL8
char CHAR
uint32_t UINT4
int32_t INT4
float REAL4
LALNameLength
void * XLALMalloc(size_t n)
void XLALFree(void *p)
LALPNOrder
static const INT4 a
const LALUnit lalStrainUnit
const LALUnit lalHertzUnit
const LALUnit lalDimensionlessUnit
REAL4Vector * XLALCreateREAL4Vector(UINT4 length)
void XLALDestroyREAL4Vector(REAL4Vector *vector)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_ERROR(...)
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_IS_REAL8_FAIL_NAN(val)
XLAL_EBADLEN
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EDOM
list mu
REAL4TimeSeries * shift
SkyPosition position
REAL4TimeVectorSeries * a
REAL8TimeSeries * phi
REAL4TimeVectorSeries * h
REAL4TimeSeries * f
expnFunc func
Definition: LALInspiral.h:680
expnCoeffs ak
Definition: LALInspiral.h:679
The inspiral waveform parameter structure containing information about the waveform to be generated.
Definition: LALInspiral.h:205
This is a structure needed by the inner workings of the inspiral wave generation code.
Definition: LALInspiral.h:357
This structure stores the parameters for constructing a restricted post-Newtonian waveform.
const CHAR * termDescription
The termination code description (above)
INT4 termCode
The termination condition (above) that stopped computation of the waveform.
REAL4 dfdt
The maximum value of encountered over any timestep used in generating the waveform.
REAL4 phi
The phase at coalescence (or arbitrary reference phase for a post -Newtonian approximation),...
REAL4 psi
polarization angle (radians)
REAL4 fStart
The actual starting frequency of the waveform, in Hz (normally close but not identical to fStartIn)
SkyPosition position
location of source on sky
UINT4 length
The length of the generated waveform.
REAL4 fStop
The frequency at the termination of the waveform, in Hz.
REAL8 tc
The time from the start of the waveform to coalescence (in the point-mass approximation),...
REAL4 fStartIn
The requested starting frequency of the waveform, in Hz.
REAL8 deltaT
The requested sampling interval of the waveform, in s.
CHAR name[LALNameLength]
REAL4Sequence * data
LALUnit sampleUnits
CHAR name[LALNameLength]
REAL4VectorSequence * data
REAL4 * data
REAL8Sequence * data
LALUnit sampleUnits
CHAR name[LALNameLength]
REAL8 * data
This structure contains various post-Newtonian and P-approximant expansion coefficients; the meanings...
Definition: LALInspiral.h:399
REAL8 tvl6
Definition: LALInspiral.h:439
REAL8 tva2
Definition: LALInspiral.h:439
REAL8 tva6
Definition: LALInspiral.h:439
REAL8 tva5
Definition: LALInspiral.h:439
REAL8 totalmass
Definition: LALInspiral.h:474
REAL8 tva3
Definition: LALInspiral.h:439
REAL8 tvaN
Definition: LALInspiral.h:439
REAL8 tva4
Definition: LALInspiral.h:439
REAL8 tva7
Definition: LALInspiral.h:439
REAL8 phiC
Definition: LALInspiral.h:487
Structure to hold the pointers to the generic functions defined above.
Definition: LALInspiral.h:546
InspiralPhasing2 * phasing2
Definition: LALInspiral.h:550
InspiralTiming2 * timing2
Definition: LALInspiral.h:549
double inclination
double distance
char output[FILENAME_MAX]