00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #if 0
00021 <lalVerbatim file="LALInspiralRingdownWaveCV">
00022 Author: Yi Pan
00023 $Id: LALInspiralRingdownWave.c,v 1.9 2008/04/30 14:34:28 spxcar Exp $
00024 </lalVerbatim>
00025
00026 <lalLaTeX>
00027 \subsection{Module \texttt{LALInspiralRingdownWave.c}}
00028
00029 Module to compute the ring-down waveform as linear combination
00030 of quasi-normal-modes decaying waveforms, which can be attached to
00031 the inspiral part of the compat binary coalescing waveform.
00032
00033 \subsubsection*{Prototypes}
00034 \vspace{0.1in}
00035 \input{XLALXLALInspiralRingdownWaveCP}
00036 \idx{XLALXLALInspiralRingdownWave()}
00037 \begin{itemize}
00038 \item \texttt{rdwave1,} Output, the real part of the ring-down waveform
00039 \item \texttt{rdwave2,} Output, the imaginary part of the ring-down waveform
00040 \item \texttt{params,} Input, the parameters where ring-down waveforms are computed
00041 \item \texttt{inspwave1,} Input, the real part of the ring-down waveform
00042 \item \texttt{inspwave2,} Input, the real part of the ring-down waveform
00043 \item \texttt{modefreqs,} Input, the frequencies of the quasi-normal-modes
00044 \item \texttt{nmode,} Input, the number of quasi-normal-modes to be combined.
00045 \end{itemize}
00046
00047 \input{XLALGenerateWaveDerivativesCP}
00048 \idx{XLALGenerateWaveDerivatives()}
00049 \begin{itemize}
00050 \item \texttt{dwave,} Output, time derivative of the input waveform
00051 \item \texttt{ddwave,} Output, two time derivative of the input waveform
00052 \item \texttt{wave,} Input, waveform to be differentiated in time
00053 \item \texttt{params,} Input, the parameters of the input waveform.
00054 \end{itemize}
00055
00056 \input{XLALGenerateQNMFreqCP}
00057 \idx{XLALGenerateQNMFreq()}
00058 \begin{itemize}
00059 \item \texttt{ptfwave,} Output, the frequencies of the quasi-normal-modes
00060 \item \texttt{params,} Input, the parameters of the binary system
00061 \item \texttt{l,} Input, the l of the modes
00062 \item \texttt{m,} Input, the m of the modes
00063 \item \texttt{nmodes,} Input, the number of overtones considered.
00064 \end{itemize}
00065
00066 \input{XLALFinalMassSpinCP}
00067 \idx{XLALFinalMassSpin()}
00068 \begin{itemize}
00069 \item \texttt{finalMass,} Output, the mass of the final Kerr black hole
00070 \item \texttt{finalSpin,} Input, the spin of the final Kerr balck hole
00071 \item \texttt{params,} Input, the parameters of the binary system.
00072 \end{itemize}
00073
00074 \subsubsection*{Description}
00075 Generating ring-down waveforms.
00076
00077 \subsubsection*{Algorithm}
00078
00079 \subsubsection*{Uses}
00080
00081 \begin{verbatim}
00082 LALMalloc
00083 LALFree
00084 \end{verbatim}
00085
00086 \subsubsection*{Notes}
00087
00088 \vfill{\footnotesize\input{LALInspiralRingdownWaveCV}}
00089
00090 </lalLaTeX>
00091 #endif
00092
00093 #include <stdlib.h>
00094 #include <lal/LALStdlib.h>
00095 #include <lal/AVFactories.h>
00096 #include <lal/SeqFactories.h>
00097 #include <lal/LALInspiralBank.h>
00098 #include <lal/LALNoiseModels.h>
00099 #include <lal/LALConstants.h>
00100 #include <gsl/gsl_linalg.h>
00101 #include <gsl/gsl_interp.h>
00102 #include <gsl/gsl_spline.h>
00103
00104
00105 INT4 XLALInspiralRingdownWave (
00106 REAL4Vector *rdwave1,
00107 REAL4Vector *rdwave2,
00108 InspiralTemplate *params,
00109 REAL4VectorSequence *inspwave1,
00110 REAL4VectorSequence *inspwave2,
00111 COMPLEX8Vector *modefreqs,
00112 UINT4 nmodes
00113 )
00114
00115 {
00116
00117 static const char *func = "XLALInspiralRingdownWave";
00118
00119
00120 INT4 errcode = XLAL_SUCCESS;
00121
00122
00123 INT4 gslStatus;
00124
00125 UINT4 i, j, k;
00126
00127
00128 REAL8 dt;
00129 gsl_matrix *coef;
00130 gsl_vector *hderivs;
00131 gsl_vector *x;
00132 gsl_permutation *p;
00133 REAL8Vector *modeamps;
00134 int s;
00135 REAL8 tj;
00136
00137 dt = 1.0 / params -> tSampling;
00138
00139 if ( inspwave1->length != nmodes || inspwave2->length != nmodes ||
00140 modefreqs->length != nmodes )
00141 {
00142 XLAL_ERROR( func, XLAL_EBADLEN );
00143 }
00144
00145
00146
00147 XLAL_CALLGSL( coef = (gsl_matrix *) gsl_matrix_alloc(2 * nmodes, 2 * nmodes) );
00148 XLAL_CALLGSL( hderivs = (gsl_vector *) gsl_vector_alloc(2 * nmodes) );
00149 XLAL_CALLGSL( x = (gsl_vector *) gsl_vector_alloc(2 * nmodes) );
00150 XLAL_CALLGSL( p = (gsl_permutation *) gsl_permutation_alloc(2 * nmodes) );
00151
00152
00153 if ( !coef || !hderivs || !x || !p )
00154 {
00155 if (coef) gsl_matrix_free(coef);
00156 if (hderivs) gsl_vector_free(hderivs);
00157 if (x) gsl_vector_free(x);
00158 if (p) gsl_permutation_free(p);
00159
00160 XLAL_ERROR( func, XLAL_ENOMEM );
00161 }
00162
00163
00164
00165
00166 for (i = 0; i < nmodes; ++i)
00167 {
00168 gsl_matrix_set(coef, 0, i, 1);
00169 gsl_matrix_set(coef, 1, i, - modefreqs->data[i].im);
00170 gsl_matrix_set(coef, 2, i, modefreqs->data[i].im * modefreqs->data[i].im
00171 - modefreqs->data[i].re * modefreqs->data[i].re);
00172 gsl_matrix_set(coef, 3, i, 0);
00173 gsl_matrix_set(coef, 4, i, - modefreqs->data[i].re);
00174 gsl_matrix_set(coef, 5, i, 2 * modefreqs->data[i].re * modefreqs->data[i].im);
00175
00176 gsl_vector_set(hderivs, i, inspwave1->data[(i + 1) * inspwave1->vectorLength - 1]);
00177 gsl_vector_set(hderivs, i + nmodes, inspwave2->data[(i + 1) * inspwave2->vectorLength - 1]);
00178 }
00179
00180 for (i = 0; i < nmodes; ++i)
00181 {
00182 for (k = 0; k < nmodes; ++k)
00183 {
00184 gsl_matrix_set(coef, i, k + nmodes, - gsl_matrix_get(coef, i + nmodes, k));
00185 gsl_matrix_set(coef, i + nmodes, k + nmodes, gsl_matrix_get(coef, i, k));
00186 }
00187 }
00188
00189
00190 XLAL_CALLGSL( gslStatus = gsl_linalg_LU_decomp(coef, p, &s) );
00191 if ( gslStatus == GSL_SUCCESS )
00192 {
00193 XLAL_CALLGSL( gslStatus = gsl_linalg_LU_solve(coef, p, hderivs, x) );
00194 }
00195
00196 if ( gslStatus != GSL_SUCCESS )
00197 {
00198 gsl_matrix_free(coef);
00199 gsl_vector_free(hderivs);
00200 gsl_vector_free(x);
00201 gsl_permutation_free(p);
00202 XLAL_ERROR( func, XLAL_EFUNC );
00203 }
00204
00205
00206 modeamps = XLALCreateREAL8Vector(2 * nmodes);
00207
00208 if ( !modeamps )
00209 {
00210 gsl_matrix_free(coef);
00211 gsl_vector_free(hderivs);
00212 gsl_vector_free(x);
00213 gsl_permutation_free(p);
00214 XLAL_ERROR( func, XLAL_ENOMEM );
00215 }
00216
00217 for (i = 0; i < nmodes; ++i)
00218 {
00219 modeamps->data[i] = gsl_vector_get(x, i);
00220 modeamps->data[i + nmodes] = gsl_vector_get(x, i + nmodes);
00221 }
00222
00223
00224 gsl_matrix_free(coef);
00225 gsl_vector_free(hderivs);
00226 gsl_vector_free(x);
00227 gsl_permutation_free(p);
00228
00229
00230 for (j = 0; j < rdwave1->length; ++j)
00231 {
00232 tj = j * dt;
00233 rdwave1->data[j] = 0;
00234 rdwave2->data[j] = 0;
00235 for (i = 0; i < nmodes; ++i)
00236 {
00237 rdwave1->data[j] += exp(- tj * modefreqs->data[i].im)
00238 * ( modeamps->data[i] * cos(tj * modefreqs->data[i].re)
00239 + modeamps->data[i + nmodes] * sin(tj * modefreqs->data[i].re) );
00240 rdwave2->data[j] += exp(- tj * modefreqs->data[i].im)
00241 * (- modeamps->data[i] * sin(tj * modefreqs->data[i].re)
00242 + modeamps->data[i + nmodes] * cos(tj * modefreqs->data[i].re) );
00243 }
00244 }
00245
00246 XLALDestroyREAL8Vector(modeamps);
00247 return errcode;
00248 }
00249
00250
00251 INT4 XLALGenerateWaveDerivatives (
00252 REAL4Vector *dwave,
00253 REAL4Vector *ddwave,
00254 REAL4Vector *wave,
00255 InspiralTemplate *params
00256 )
00257
00258 {
00259 static const char *func = "XLALGenerateWaveDerivatives";
00260
00261
00262 INT4 errcode = XLAL_SUCCESS;
00263
00264
00265 INT4 gslStatus;
00266
00267 UINT4 j;
00268 REAL8 dt;
00269 double *x, *y;
00270 double dy, dy2;
00271 gsl_interp_accel *acc;
00272 gsl_spline *spline;
00273
00274
00275 dt = 1.0 / params -> tSampling;
00276
00277
00278
00279 x = (double *) LALMalloc(wave->length * sizeof(double));
00280 y = (double *) LALMalloc(wave->length * sizeof(double));
00281
00282 if ( !x || !y )
00283 {
00284 if ( x ) LALFree (x);
00285 if ( y ) LALFree (y);
00286 XLAL_ERROR( func, XLAL_ENOMEM );
00287 }
00288
00289 for (j = 0; j < wave->length; ++j)
00290 {
00291 x[j] = j;
00292 y[j] = wave->data[j];
00293 }
00294
00295 XLAL_CALLGSL( acc = (gsl_interp_accel*) gsl_interp_accel_alloc() );
00296 XLAL_CALLGSL( spline = (gsl_spline*) gsl_spline_alloc(gsl_interp_cspline, wave->length) );
00297 if ( !acc || !spline )
00298 {
00299 if ( acc ) gsl_interp_accel_free(acc);
00300 if ( spline ) gsl_spline_free(spline);
00301 LALFree( x );
00302 LALFree( y );
00303 XLAL_ERROR( func, XLAL_ENOMEM );
00304 }
00305
00306
00307 XLAL_CALLGSL( gslStatus = gsl_spline_init(spline, x, y, wave->length) );
00308 if ( gslStatus != GSL_SUCCESS )
00309 {
00310 gsl_spline_free(spline);
00311 gsl_interp_accel_free(acc);
00312 LALFree( x );
00313 LALFree( y );
00314 XLAL_ERROR( func, XLAL_EFUNC );
00315 }
00316
00317
00318 for (j = 0; j < wave->length; ++j)
00319 {
00320 XLAL_CALLGSL(gslStatus = gsl_spline_eval_deriv_e( spline, j, acc, &dy ) );
00321 if ( gslStatus == GSL_SUCCESS )
00322 {
00323 XLAL_CALLGSL(gslStatus = gsl_spline_eval_deriv2_e(spline, j, acc, &dy2 ) );
00324 }
00325 if (gslStatus != GSL_SUCCESS )
00326 {
00327 gsl_spline_free(spline);
00328 gsl_interp_accel_free(acc);
00329 LALFree( x );
00330 LALFree( y );
00331 XLAL_ERROR( func, XLAL_EFUNC );
00332 }
00333 dwave->data[j] = (REAL4)(dy / dt);
00334 ddwave->data[j] = (REAL4)(dy2 / dt / dt);
00335
00336 }
00337
00338
00339 gsl_spline_free(spline);
00340 gsl_interp_accel_free(acc);
00341 LALFree(x);
00342 LALFree(y);
00343
00344 return errcode;
00345 }
00346
00347
00348 INT4 XLALGenerateQNMFreq(
00349 COMPLEX8Vector *modefreqs,
00350 InspiralTemplate *params,
00351 UINT4 l,
00352 UINT4 m,
00353 UINT4 nmodes
00354 )
00355
00356 {
00357
00358 INT4 errcode = XLAL_SUCCESS;
00359 UINT4 i;
00360 REAL8 totalMass, finalMass, finalSpin;
00361
00362 REAL4 BCWre[3][3] = { {1.5251, -1.1568, 0.1292}, {1.3673, -1.0260, 0.1628}, { 1.3223, -1.0257, 0.1860} };
00363 REAL4 BCWim[3][3] = { {0.7000, 1.4187, -0.4990}, {0.1000, 0.5436, -0.4731}, {-0.1000, 0.4206, -0.4256} };
00364
00365
00366
00367 totalMass = params->totalMass;
00368 finalMass = 0;
00369 finalSpin = 0;
00370
00371
00372 errcode = XLALFinalMassSpin(&finalMass, &finalSpin, params);
00373 if ( errcode != XLAL_SUCCESS )
00374 {
00375 XLAL_ERROR( "XLALGenerateQNMFreq", XLAL_EFUNC );
00376 }
00377
00378
00379 for (i = 0; i < nmodes; ++i)
00380 {
00381 modefreqs->data[i].re = BCWre[i][0] + BCWre[i][1] * pow(1.- finalSpin, BCWre[i][2]);
00382 modefreqs->data[i].im = modefreqs->data[i].re / 2
00383 / (BCWim[i][0] + BCWim[i][1] * pow(1.- finalSpin, BCWim[i][2]));
00384 modefreqs->data[i].re *= 1./ finalMass / (totalMass * LAL_MTSUN_SI);
00385 modefreqs->data[i].im *= 1./ finalMass / (totalMass * LAL_MTSUN_SI);
00386 }
00387 return errcode;
00388 }
00389
00390
00391 INT4 XLALFinalMassSpin(
00392 REAL8 *finalMass,
00393 REAL8 *finalSpin,
00394 InspiralTemplate *params
00395 )
00396
00397 {
00398
00399 INT4 errcode = XLAL_SUCCESS;
00400 REAL8 eta, eta2;
00401
00402
00403 eta = params->eta;
00404 eta2 = eta * eta;
00405
00406
00407 *finalMass = 1 - 0.057191 * eta - 0.498 * eta2;
00408 *finalSpin = 3.464102 * eta - 2.9 * eta2;
00409
00410 return errcode;
00411 }
00412
00413
00414 INT4 XLALInspiralAttachRingdownWave (
00415 REAL4Vector *Omega,
00416 REAL4Vector *signal1,
00417 REAL4Vector *signal2,
00418 InspiralTemplate *params)
00419 {
00420
00421 static const char *func = "XLALInspiralAttachRingdownWave";
00422
00423 COMPLEX8Vector *modefreqs;
00424 UINT4 Nrdwave, Npatch;
00425 UINT4 attpos = 0;
00426 UINT4 j;
00427 INT4 errcode;
00428
00429 UINT4 nmodes;
00430 INT4 l, m;
00431 REAL4Vector *rdwave1;
00432 REAL4Vector *rdwave2;
00433 REAL4Vector *inspwave;
00434 REAL4Vector *dinspwave;
00435 REAL4Vector *ddinspwave;
00436 REAL4VectorSequence *inspwaves1;
00437 REAL4VectorSequence *inspwaves2;
00438 REAL8 omegamatch, dt, c1;
00439
00440
00441
00442
00443
00444 dt = 1./params->tSampling;
00445 omegamatch = -0.01 + 0.133 + 0.183 * params->eta + 0.161 * params->eta * params->eta;
00446
00447 for (j = 0; j < Omega->length; ++j)
00448 {
00449
00450 if(Omega->data[j] > omegamatch)
00451 {
00452 attpos = j - 1;
00453 break;
00454 }
00455
00456 }
00457 c1 = 1./(LAL_PI*LAL_MTSUN_SI*params->totalMass);
00458
00459
00460 nmodes = 3;
00461 l = 2;
00462 m = 2;
00463 modefreqs = XLALCreateCOMPLEX8Vector( nmodes );
00464 if ( !modefreqs )
00465 {
00466 XLAL_ERROR( func, XLAL_ENOMEM );
00467 }
00468
00469 errcode = XLALGenerateQNMFreq( modefreqs, params, l, m, nmodes );
00470 if ( errcode != XLAL_SUCCESS )
00471 {
00472 XLALDestroyCOMPLEX8Vector( modefreqs );
00473 XLAL_ERROR( func, XLAL_EFUNC );
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 Nrdwave = (INT4) (10 / modefreqs->data[0].im / dt);
00485
00486 Npatch = 11;
00487
00488
00489 if ( attpos < ( Npatch + 1 ) / 2 || attpos + (Npatch - 1) / 2 >= signal1->length )
00490 {
00491 XLALPrintError( "Value of attpos inconsistent with given value of Npatch.\n" );
00492 XLALDestroyCOMPLEX8Vector( modefreqs );
00493 XLAL_ERROR( func, XLAL_EFAILED );
00494 }
00495
00496
00497
00498 rdwave1 = XLALCreateREAL4Vector( Nrdwave );
00499 rdwave2 = XLALCreateREAL4Vector( Nrdwave );
00500 inspwave = XLALCreateREAL4Vector( Npatch );
00501 dinspwave = XLALCreateREAL4Vector( Npatch );
00502 ddinspwave = XLALCreateREAL4Vector( Npatch );
00503 inspwaves1 = XLALCreateREAL4VectorSequence( 3, (Npatch + 1) / 2 );
00504 inspwaves2 = XLALCreateREAL4VectorSequence( 3, (Npatch + 1) / 2 );
00505
00506
00507 if ( !rdwave1 || !rdwave2 || !inspwave || !dinspwave || !ddinspwave
00508 || !inspwaves1 || !inspwaves2 )
00509 {
00510 XLALDestroyCOMPLEX8Vector( modefreqs );
00511 if (rdwave1) XLALDestroyREAL4Vector( rdwave1 );
00512 if (rdwave2) XLALDestroyREAL4Vector( rdwave2 );
00513 if (inspwave) XLALDestroyREAL4Vector( inspwave );
00514 if (dinspwave) XLALDestroyREAL4Vector( dinspwave );
00515 if (ddinspwave) XLALDestroyREAL4Vector( ddinspwave );
00516 if (inspwaves1) XLALDestroyREAL4VectorSequence( inspwaves1 );
00517 if (inspwaves2) XLALDestroyREAL4VectorSequence( inspwaves2 );
00518 XLAL_ERROR( func, XLAL_ENOMEM );
00519 }
00520
00521
00522
00523 for (j = 0; j < Npatch; j++)
00524 {
00525 inspwave->data[j] = signal1->data[attpos - (Npatch + 1) / 2 + j];
00526 }
00527
00528 errcode = XLALGenerateWaveDerivatives( dinspwave, ddinspwave, inspwave, params );
00529 if ( errcode != XLAL_SUCCESS )
00530 {
00531 XLALDestroyCOMPLEX8Vector( modefreqs );
00532 XLALDestroyREAL4Vector( rdwave1 );
00533 XLALDestroyREAL4Vector( rdwave2 );
00534 XLALDestroyREAL4Vector( inspwave );
00535 XLALDestroyREAL4Vector( dinspwave );
00536 XLALDestroyREAL4Vector( ddinspwave );
00537 XLALDestroyREAL4VectorSequence( inspwaves1 );
00538 XLALDestroyREAL4VectorSequence( inspwaves2 );
00539 XLAL_ERROR( func, XLAL_EFUNC );
00540 }
00541 for (j = 0; j < (Npatch + 1) / 2; j++)
00542 {
00543 inspwaves1->data[j] = inspwave->data[j];
00544 inspwaves1->data[j + (Npatch + 1) / 2] = dinspwave->data[j];
00545 inspwaves1->data[j + 2 * (Npatch + 1) / 2] = ddinspwave->data[j];
00546 }
00547
00548
00549 for (j = 0; j < Npatch; j++)
00550 {
00551 inspwave->data[j] = signal2->data[attpos - (Npatch + 1) / 2 + j];
00552 }
00553
00554 errcode = XLALGenerateWaveDerivatives( dinspwave, ddinspwave, inspwave, params );
00555 if ( errcode != XLAL_SUCCESS )
00556 {
00557 XLALDestroyCOMPLEX8Vector( modefreqs );
00558 XLALDestroyREAL4Vector( rdwave1 );
00559 XLALDestroyREAL4Vector( rdwave2 );
00560 XLALDestroyREAL4Vector( inspwave );
00561 XLALDestroyREAL4Vector( dinspwave );
00562 XLALDestroyREAL4Vector( ddinspwave );
00563 XLALDestroyREAL4VectorSequence( inspwaves1 );
00564 XLALDestroyREAL4VectorSequence( inspwaves2 );
00565 XLAL_ERROR( func, XLAL_EFUNC );
00566 }
00567 for (j = 0; j < (Npatch + 1) / 2; j++)
00568 {
00569 inspwaves2->data[j] = inspwave->data[j];
00570 inspwaves2->data[j + (Npatch + 1) / 2] = dinspwave->data[j];
00571 inspwaves2->data[j + 2 * (Npatch + 1) / 2] = ddinspwave->data[j];
00572 }
00573
00574
00575
00576 errcode = XLALInspiralRingdownWave( rdwave1, rdwave2, params, inspwaves1, inspwaves2,
00577 modefreqs, nmodes );
00578 if ( errcode != XLAL_SUCCESS )
00579 {
00580 XLALDestroyCOMPLEX8Vector( modefreqs );
00581 XLALDestroyREAL4Vector( rdwave1 );
00582 XLALDestroyREAL4Vector( rdwave2 );
00583 XLALDestroyREAL4Vector( inspwave );
00584 XLALDestroyREAL4Vector( dinspwave );
00585 XLALDestroyREAL4Vector( ddinspwave );
00586 XLALDestroyREAL4VectorSequence( inspwaves1 );
00587 XLALDestroyREAL4VectorSequence( inspwaves2 );
00588 XLAL_ERROR( func, XLAL_EFUNC );
00589 }
00590
00591 for (j = 1; j < Nrdwave; ++j)
00592 {
00593 signal1->data[j + attpos - 1] = rdwave1->data[j];
00594 signal2->data[j + attpos - 1] = rdwave2->data[j];
00595 }
00596
00597
00598 XLALDestroyCOMPLEX8Vector( modefreqs );
00599 XLALDestroyREAL4Vector( rdwave1 );
00600 XLALDestroyREAL4Vector( rdwave2 );
00601 XLALDestroyREAL4Vector( inspwave );
00602 XLALDestroyREAL4Vector( dinspwave );
00603 XLALDestroyREAL4Vector( ddinspwave );
00604 XLALDestroyREAL4VectorSequence( inspwaves1 );
00605 XLALDestroyREAL4VectorSequence( inspwaves2 );
00606
00607 return errcode;
00608 }