36 #ifndef _LALSIMIMREOBHYBRIDRINGDOWN_C
37 #define _LALSIMIMREOBHYBRIDRINGDOWN_C
41 #include <lal/LALStdlib.h>
42 #include <lal/AVFactories.h>
43 #include <lal/SeqFactories.h>
44 #include <gsl/gsl_linalg.h>
45 #include <gsl/gsl_interp.h>
46 #include <gsl/gsl_spline.h>
47 #include <gsl/gsl_matrix.h>
55 #define UNUSED __attribute__ ((unused))
82 A1coeff00[2][2] = 0.0830664;
83 A1coeff01[2][2] = -0.0196758;
84 A1coeff02[2][2] = -0.0136459;
85 A1coeff10[2][2] = 0.0612892;
86 A1coeff11[2][2] = 0.00146142;
87 A1coeff20[2][2] = -0.0893454;
89 A1coeff00[2][1] = 0.07780330893915006;
90 A1coeff01[2][1] = -0.05070638166864379;
91 A1coeff10[2][1] = 0.24091006920322164;
92 A1coeff11[2][1] = 0.38582622780596576;
93 A1coeff20[2][1] = -0.7456327888190485;
94 A1coeff21[2][1] = -0.9695534075470388;
96 A1coeff00[3][3] = 0.07638733045623343;
97 A1coeff01[3][3] = -0.030993441267953236;
98 A1coeff10[3][3] = 0.2543447497371546;
99 A1coeff11[3][3] = 0.2516879591102584;
100 A1coeff20[3][3] = -1.0892686061231245;
101 A1coeff21[3][3] = -0.7980907313033606;
103 A1coeff00[4][4] = -0.06392710223439678;
104 A1coeff01[4][4] = -0.03646167590514318;
105 A1coeff10[4][4] = 0.345195277237925;
106 A1coeff11[4][4] = 1.2777441574118558;
107 A1coeff20[4][4] = -1.764352185878576;
108 A1coeff21[4][4] = -14.825262897834696;
109 A1coeff31[4][4] = 40.67135475479875;
111 A1coeff00[5][5] = -0.06704614393611373;
112 A1coeff01[5][5] = 0.021905949257025503;
113 A1coeff10[5][5] = -0.24754936787743445;
114 A1coeff11[5][5] = -0.0943771022698497;
115 A1coeff20[5][5] = 0.7588042862093705;
116 A1coeff21[5][5] = 0.4357768883690394;
120 return A1coeff00[modeL][modeM] + A1coeff01[modeL][modeM] * chi + A1coeff02[modeL][modeM] * chi * chi + A1coeff10[modeL][modeM] * eta +
121 A1coeff11[modeL][modeM] * eta * chi + A1coeff20[modeL][modeM] * eta * eta + A1coeff21[modeL][modeM]*eta*eta*chi + A1coeff31[modeL][modeM]*eta*eta*eta*chi;
141 A2coeff00[2][2] = -0.623953;
142 A2coeff01[2][2] = -0.371365;
143 A2coeff10[2][2] = 1.39777;
144 A2coeff11[2][2] = 2.40203;
145 A2coeff20[2][2] = -1.82173;
146 A2coeff21[2][2] = -5.25339;
148 A2coeff00[2][1] = -1.2451852641667298;
149 A2coeff01[2][1] = -1.195786238319961;
150 A2coeff10[2][1] = 6.134202504312409;
151 A2coeff11[2][1] = 15.66696619631313;
152 A2coeff20[2][1] = -14.67251127485556;
153 A2coeff21[2][1] = -44.41982201432511;
155 A2coeff00[3][3] = -0.8325292359346013;
156 A2coeff01[3][3] = -0.598880303198448;
157 A2coeff10[3][3] = 2.767989795032018;
158 A2coeff11[3][3] = 5.904371617277156;
159 A2coeff20[3][3] = -7.028151926115957;
160 A2coeff21[3][3] = -18.232606706124482;
162 A2coeff00[4][4] = 0.7813275473485185;
163 A2coeff01[4][4] = 0.8094706044462984;
164 A2coeff10[4][4] = -5.18689829943586;
165 A2coeff11[4][4] = -5.38343327318501;
166 A2coeff20[4][4] = 14.026415859369477;
167 A2coeff21[4][4] = 0.1051625997942299;
168 A2coeff31[4][4] = 46.978434956814006;
170 A2coeff00[5][5] = 1.6763424265367357;
171 A2coeff01[5][5] = 0.4925695499534606;
172 A2coeff10[5][5] = -5.604559311983177;
173 A2coeff11[5][5] = -6.209095657439377;
174 A2coeff20[5][5] = 16.751319143123386;
175 A2coeff21[5][5] = 16.778452555342554;
177 return A2coeff00[modeL][modeM] + A2coeff01[modeL][modeM] * chi + A2coeff10[modeL][modeM] * eta +
178 A2coeff11[modeL][modeM] * eta * chi + A2coeff20[modeL][modeM] * eta * eta + A2coeff21[modeL][modeM] * eta * eta * chi + A2coeff31[modeL][modeM]*eta*eta*eta*chi;
197 P1coeff00[2][2] = 0.147584;
198 P1coeff01[2][2] = 0.00779176;
199 P1coeff02[2][2] = -0.0244358;
200 P1coeff10[2][2] = 0.263456;
201 P1coeff11[2][2] = -0.120853;
202 P1coeff20[2][2] = -0.808987;
204 P1coeff00[2][1] = 0.15601401627613815;
205 P1coeff01[2][1] = 0.10219957917717622;
206 P1coeff10[2][1] = 0.023346852452720928;
207 P1coeff11[2][1] = -0.9435308286367039;
208 P1coeff20[2][1] = 0.15326558178697175;
209 P1coeff21[2][1] = 1.7979082057513565;
211 P1coeff00[3][3] = 0.11085299117493969;
212 P1coeff01[3][3] = 0.018959099261813613;
213 P1coeff10[3][3] = 0.9999800463662053;
214 P1coeff11[3][3] = -0.729149797691242;
215 P1coeff20[3][3] = -3.3983315694441125;
216 P1coeff21[3][3] = 2.5192011762934037;
218 P1coeff00[4][4] = 0.11498976343440313;
219 P1coeff01[4][4] = 0.008389519706605305;
220 P1coeff10[4][4] = 1.6126522800609633;
221 P1coeff11[4][4] = -0.8069979888526699;
222 P1coeff20[4][4] = -6.255895564079467;
223 P1coeff21[4][4] = 7.595651881827078;
224 P1coeff31[4][4] = -19.32367406125053;
226 P1coeff00[5][5] = 0.16465380962882128;
227 P1coeff01[5][5] = -0.026574817803812007;
228 P1coeff10[5][5] = -0.19184523794508765;
229 P1coeff11[5][5] = -0.05519618962738479;
230 P1coeff20[5][5] = 0.33328424135336965;
231 P1coeff21[5][5] = 0.3194274548351241;
234 return P1coeff00[modeL][modeM] + P1coeff01[modeL][modeM] * chi + P1coeff02[modeL][modeM] * chi * chi + P1coeff10[modeL][modeM] * eta +
235 P1coeff11[modeL][modeM] * eta * chi + P1coeff20[modeL][modeM] * eta * eta + P1coeff21[modeL][modeM]*eta*eta*chi + P1coeff31[modeL][modeM]*eta*eta*eta*chi;
255 P2coeff00[2][2] = 2.46654;
256 P2coeff01[2][2] = 3.13067;
257 P2coeff02[2][2] = 0.581626;
258 P2coeff10[2][2] = -6.99396;
259 P2coeff11[2][2] = -9.61861;
260 P2coeff20[2][2] = 17.5646;
262 P2coeff00[2][1] = 2.7886287922318105;
263 P2coeff01[2][1] = 4.29290053494256;
264 P2coeff10[2][1] = -0.8145406685320334;
265 P2coeff11[2][1] = -15.93796979597706;
266 P2coeff20[2][1] = 5.549338798935832;
267 P2coeff21[2][1] = 12.649775582333442;
268 P2coeff02[2][1] = 2.5582321247274726;
269 P2coeff12[2][1] = -10.232928498772893;
271 P2coeff00[3][3] = 2.7825237371542735;
272 P2coeff01[3][3] = 2.8796835808075003;
273 P2coeff10[3][3] = -7.844741660437831;
274 P2coeff11[3][3] = -34.7670039322078;
275 P2coeff20[3][3] = 27.181024362399302;
276 P2coeff21[3][3] = 127.13948436435182;
278 P2coeff00[4][4] = 3.111817347262856;
279 P2coeff01[4][4] = 5.399341180960216;
280 P2coeff10[4][4] = 15.885333959709488;
281 P2coeff11[4][4] = -87.92421137153823;
282 P2coeff20[4][4] = -79.64931908155609;
283 P2coeff21[4][4] = 657.7156442271963;
284 P2coeff31[4][4] = -1555.2968529739226;
285 P2coeff02[4][4] = 2.3832321567874686;
286 P2coeff12[4][4] = -9.532928476043567;
288 P2coeff00[5][5] = 11.102447263357977;
289 P2coeff01[5][5] = 6.015112119742853;
290 P2coeff10[5][5] = -58.605776859097084;
291 P2coeff11[5][5] = -81.68032025902797;
292 P2coeff20[5][5] = 176.60643662729498;
293 P2coeff21[5][5] = 266.47345742836745;
296 return P2coeff00[modeL][modeM] + P2coeff01[modeL][modeM] * chi + P2coeff02[modeL][modeM] * chi * chi + P2coeff12[modeL][modeM] * chi * chi * eta + P2coeff10[modeL][modeM] * eta +
297 P2coeff11[modeL][modeM] * eta * chi + P2coeff20[modeL][modeM] * eta * eta + P2coeff21[modeL][modeM]*eta*eta*chi + P2coeff31[modeL][modeM]*eta*eta*eta*chi;
335 UINT4 i, j, k, nmodes = 8;
338 REAL8 t1, t2, t3, t4, t5, rt;
350 t5 = (matchrange->
data[0] - matchrange->
data[1]) *
m;
358 if (inspwave1->
length != 3 || inspwave2->
length != 3 || modefreqs->
length != nmodes) {
364 XLAL_CALLGSL(coef = (gsl_matrix *) gsl_matrix_alloc(2 * nmodes, 2 * nmodes));
365 XLAL_CALLGSL(hderivs = (gsl_vector *) gsl_vector_alloc(2 * nmodes));
366 XLAL_CALLGSL(
x = (gsl_vector *) gsl_vector_alloc(2 * nmodes));
367 XLAL_CALLGSL(
p = (gsl_permutation *) gsl_permutation_alloc(2 * nmodes));
370 if (!coef || !hderivs || !
x || !
p) {
372 gsl_matrix_free(coef);
374 gsl_vector_free(hderivs);
378 gsl_permutation_free(
p);
387 for (
i = 0;
i < nmodes; ++
i) {
388 gsl_matrix_set(coef, 0,
i, 1);
389 gsl_matrix_set(coef, 1,
i, -cimag(modefreqs->
data[
i]));
390 gsl_matrix_set(coef, 2,
i, exp(-cimag(modefreqs->
data[
i]) * t1) * cos(creal(modefreqs->
data[
i]) * t1));
391 gsl_matrix_set(coef, 3,
i, exp(-cimag(modefreqs->
data[
i]) * t2) * cos(creal(modefreqs->
data[
i]) * t2));
392 gsl_matrix_set(coef, 4,
i, exp(-cimag(modefreqs->
data[
i]) * t3) * cos(creal(modefreqs->
data[
i]) * t3));
393 gsl_matrix_set(coef, 5,
i, exp(-cimag(modefreqs->
data[
i]) * t4) * cos(creal(modefreqs->
data[
i]) * t4));
394 gsl_matrix_set(coef, 6,
i, exp(-cimag(modefreqs->
data[
i]) * t5) * cos(creal(modefreqs->
data[
i]) * t5));
395 gsl_matrix_set(coef, 7,
i, exp(-cimag(modefreqs->
data[
i]) * t5) * (-cimag(modefreqs->
data[
i]) * cos(creal(modefreqs->
data[
i]) * t5)
396 - creal(modefreqs->
data[
i]) * sin(creal(modefreqs->
data[
i]) * t5)));
397 gsl_matrix_set(coef, 8,
i, 0);
398 gsl_matrix_set(coef, 9,
i, -creal(modefreqs->
data[
i]));
399 gsl_matrix_set(coef, 10,
i, -exp(-cimag(modefreqs->
data[
i]) * t1) * sin(creal(modefreqs->
data[
i]) * t1));
400 gsl_matrix_set(coef, 11,
i, -exp(-cimag(modefreqs->
data[
i]) * t2) * sin(creal(modefreqs->
data[
i]) * t2));
401 gsl_matrix_set(coef, 12,
i, -exp(-cimag(modefreqs->
data[
i]) * t3) * sin(creal(modefreqs->
data[
i]) * t3));
402 gsl_matrix_set(coef, 13,
i, -exp(-cimag(modefreqs->
data[
i]) * t4) * sin(creal(modefreqs->
data[
i]) * t4));
403 gsl_matrix_set(coef, 14,
i, -exp(-cimag(modefreqs->
data[
i]) * t5) * sin(creal(modefreqs->
data[
i]) * t5));
404 gsl_matrix_set(coef, 15,
i, exp(-cimag(modefreqs->
data[
i]) * t5) * (cimag(modefreqs->
data[
i]) * sin(creal(modefreqs->
data[
i]) * t5)
405 - creal(modefreqs->
data[
i]) * cos(creal(modefreqs->
data[
i]) * t5)));
407 for (
i = 0;
i < 2; ++
i) {
409 gsl_vector_set(hderivs,
i + nmodes, inspwave2->
data[(
i + 1) * inspwave2->
vectorLength - 1]);
411 gsl_vector_set(hderivs,
i + 6 + nmodes, inspwave2->
data[
i * inspwave2->
vectorLength]);
413 gsl_vector_set(hderivs, 2, inspwave1->
data[4]);
414 gsl_vector_set(hderivs, 2 + nmodes, inspwave2->
data[4]);
415 gsl_vector_set(hderivs, 3, inspwave1->
data[3]);
416 gsl_vector_set(hderivs, 3 + nmodes, inspwave2->
data[3]);
417 gsl_vector_set(hderivs, 4, inspwave1->
data[2]);
418 gsl_vector_set(hderivs, 4 + nmodes, inspwave2->
data[2]);
419 gsl_vector_set(hderivs, 5, inspwave1->
data[1]);
420 gsl_vector_set(hderivs, 5 + nmodes, inspwave2->
data[1]);
423 for (
i = 0;
i < nmodes; ++
i) {
424 for (k = 0; k < nmodes; ++k) {
425 gsl_matrix_set(coef,
i, k + nmodes, -gsl_matrix_get(coef,
i + nmodes, k));
426 gsl_matrix_set(coef,
i + nmodes, k + nmodes, gsl_matrix_get(coef,
i, k));
432 printf(
"\nRingdown matching matrix:\n");
433 for (
i = 0;
i < 16; ++
i) {
434 for (j = 0; j < 16; ++j) {
435 printf(
"%.12e ", gsl_matrix_get(coef,
i, j));
440 for (
i = 0;
i < 16; ++
i) {
441 printf(
"%.12e ", gsl_vector_get(hderivs,
i));
448 if (gslStatus == GSL_SUCCESS) {
449 XLAL_CALLGSL(gslStatus = gsl_linalg_LU_solve(coef,
p, hderivs,
x));
451 if (gslStatus != GSL_SUCCESS) {
452 gsl_matrix_free(coef);
453 gsl_vector_free(hderivs);
455 gsl_permutation_free(
p);
463 gsl_matrix_free(coef);
464 gsl_vector_free(hderivs);
466 gsl_permutation_free(
p);
470 for (
i = 0;
i < nmodes; ++
i) {
471 modeamps->
data[
i] = gsl_vector_get(
x,
i);
472 modeamps->
data[
i + nmodes] = gsl_vector_get(
x,
i + nmodes);
476 gsl_matrix_free(coef);
477 gsl_vector_free(hderivs);
479 gsl_permutation_free(
p);
485 for (j = 0; j < rdwave1->
length; ++j) {
486 tj = j *
dt - timeOffset;
487 rdwave1->
data[j] = 0;
488 rdwave2->
data[j] = 0;
489 for (
i = 0;
i < nmodes; ++
i) {
490 rdwave1->
data[j] += exp(-tj * cimag(modefreqs->
data[
i]))
491 * (modeamps->
data[
i] * cos(tj * creal(modefreqs->
data[
i]))
492 + modeamps->
data[
i + nmodes] * sin(tj * creal(modefreqs->
data[
i])));
493 rdwave2->
data[j] += exp(-tj * cimag(modefreqs->
data[
i]))
494 * (-modeamps->
data[
i] * sin(tj * creal(modefreqs->
data[
i]))
495 + modeamps->
data[
i + nmodes] * cos(tj * creal(modefreqs->
data[
i])));
534 gsl_interp_accel *acc;
540 tlist = (
double *)
LALMalloc(6 *
sizeof(
double));
541 rt = (matchrange->
data[1] - matchrange->
data[0]) / 5.;
542 tlist[0] = matchrange->
data[0];
543 tlist[1] = tlist[0] + rt;
544 tlist[2] = tlist[1] + rt;
545 tlist[3] = tlist[2] + rt;
546 tlist[4] = tlist[3] + rt;
547 tlist[5] = matchrange->
data[1];
550 vecLength = (
m * matchrange->
data[2] /
dt) + 1;
554 y = (
double *)
LALMalloc(vecLength *
sizeof(
double));
560 for (j = 0; j < vecLength; ++j) {
561 y[j] = wave->
data[j];
564 XLAL_CALLGSL(acc = (gsl_interp_accel *) gsl_interp_accel_alloc());
565 XLAL_CALLGSL(spline = (gsl_spline *) gsl_spline_alloc(gsl_interp_cspline, vecLength));
566 if (!acc || !spline) {
568 gsl_interp_accel_free(acc);
570 gsl_spline_free(spline);
576 gslStatus = gsl_spline_init(spline, timeVec->
data,
y, vecLength);
577 if (gslStatus != GSL_SUCCESS) {
578 gsl_spline_free(spline);
579 gsl_interp_accel_free(acc);
585 for (j = 0; j < 6; ++j) {
586 gslStatus = gsl_spline_eval_e(spline, tlist[j], acc, &ry);
587 if (gslStatus == GSL_SUCCESS) {
588 gslStatus = gsl_spline_eval_deriv_e(spline, tlist[j], acc, &dy);
589 gslStatus = gsl_spline_eval_deriv2_e(spline, tlist[j], acc, &dy2);
591 if (gslStatus != GSL_SUCCESS) {
592 gsl_spline_free(spline);
593 gsl_interp_accel_free(acc);
604 gsl_spline_free(spline);
605 gsl_interp_accel_free(acc);
663 REAL8 eta,
a, chi, NRPeakOmega22;
664 REAL8 sh, kk, kt1, kt2;
666 REAL8 spin1[3] = { spin1x, spin1y, spin1z };
667 REAL8 spin2[3] = { spin2x, spin2y, spin2z };
668 REAL8 finalMass, finalSpin;
671 eta = mass1 * mass2 / ((mass1 + mass2) * (mass1 + mass2));
701 a = (spin1[2] + spin2[2]) / 2. * (1.0 - 2.0 * eta) + (spin1[2] - spin2[2]) / 2. * (mass1 - mass2) / (mass1 + mass2);
705 modefreqs->
data[7] = (NRPeakOmega22 / finalMass + creal(modefreqs->
data[0])) / 2.;
706 modefreqs->
data[7] += I * 10. / 3. * cimag(modefreqs->
data[0]);
714 a = (spin1[2] + spin2[2]) / 2. * (1.0 - 2.0 * eta) + (spin1[2] - spin2[2]) / 2. * (mass1 - mass2) / (mass1 + mass2);
718 chi = (spin1[2] + spin2[2]) / 2. + (spin1[2] - spin2[2]) / 2. * ((mass1 - mass2) / (mass1 + mass2)) / (1. - 2. * eta);
725 kk = 0.7 + 0.3 * exp(100. * (eta - 0.25));
726 kt1 = 0.5 * sqrt(1. + 800.0 * eta * eta / 3.0) - 0.125;
727 kt2 = 0.5 * pow(1. + 0.5 * eta * sqrt(eta) / 0.0225, 2. / 3.) - 0.2;
739 modefreqs->
data[7] = (2. / 3. * NRPeakOmega22 / finalMass) + (1. / 3. * creal(modefreqs->
data[0]));
740 modefreqs->
data[7] += I * 3.5 / 0.9 * cimag(modefreqs->
data[0]);
741 modefreqs->
data[6] = (3. / 4. * NRPeakOmega22 / finalMass) + (1. / 4. * creal(modefreqs->
data[0]));
742 modefreqs->
data[6] += I * 3.5 * cimag(modefreqs->
data[0]);
747 if (chi >= 0.7 && chi < 0.8) {
748 sh = -9. * (eta - 0.25);
750 if ((eta > 30. / 31. / 31. && eta <= 10. / 121. && chi >= 0.8) || (eta <= 30. / 31. / 31. && chi >= 0.8 && chi < 0.9)) {
751 sh = -9. * (eta - 0.25) * (1. + 2. * exp(-(chi - 0.85) * (chi - 0.85) / 0.05 / 0.05)) * (1. + 1. / (1. + exp((eta - 0.01) / 0.001)));
752 kk = 0.7 + 0.3 * exp(100. * (eta - 0.25));
753 kt1 = 0.5 * sqrt(1. + 800.0 * eta * eta / 3.0) - 0.125;
754 kt2 = 0.5 * pow(1. + 0.5 * eta * sqrt(eta) / 0.0225, 2. / 3.) - 0.2;
755 modefreqs->
data[4] = 0.4 * (1. + kk) * creal(modefreqs->
data[6])
756 + I * cimag(modefreqs->
data[6]) / (2.5 * kt2 * exp(-(eta - 0.005) / 0.03));
757 modefreqs->
data[5] = 0.4 * (1. + kk) * creal(modefreqs->
data[7])
758 + I * cimag(modefreqs->
data[7]) / (1.5 * kt1 * exp(-(eta - 0.005) / 0.03));
759 modefreqs->
data[6] = kk * creal(modefreqs->
data[6]) + I * cimag(modefreqs->
data[6]) / kt2;
760 modefreqs->
data[7] = kk * creal(modefreqs->
data[7]) + I * cimag(modefreqs->
data[7]) / kt1;
762 if (eta < 30. / 31. / 31. && chi >= 0.9) {
763 sh = 0.55 - 9. * (eta - 0.25) * (1. + 2. * exp(-(chi - 0.85) * (chi - 0.85) / 0.05 / 0.05)) * (1. + 1. / (1. + exp((eta - 0.01) / 0.001)));
764 kk = 0.7 + 0.3 * exp(100. * (eta - 0.25));
765 kt1 = 0.5 * sqrt(1. + 800.0 * eta * eta / 3.0) - 0.125;
766 kt2 = 0.5 * pow(1. + 0.5 * eta * sqrt(eta) / 0.0225, 2. / 3.) - 0.2;
767 modefreqs->
data[4] = 1.1 * 0.4 * (1. + kk) * creal(modefreqs->
data[6])
768 + I * cimag(modefreqs->
data[6]) / (1.05 * 2.5 * kt2 * exp(-(eta - 0.005) / 0.03));
769 modefreqs->
data[5] = 0.4 * (1. + kk) * creal(modefreqs->
data[7])
770 + I * cimag(modefreqs->
data[7]) / (1.05 * 1.5 * kt1 * exp(-(eta - 0.005) / 0.03));
771 modefreqs->
data[6] = kk * creal(modefreqs->
data[6]) + I * cimag(modefreqs->
data[6]) / kt2;
772 modefreqs->
data[7] = kk * creal(modefreqs->
data[7]) + I * cimag(modefreqs->
data[7]) / kt1;
774 if (eta > 10. / 121. && chi >= 0.8) {
775 sh = 1. - 9. * (eta - 0.25) * (1. + 2. * exp(-(chi - 0.85) * (chi - 0.85) / 0.05 / 0.05)) * (1. + 1. / (1. + exp((eta - 0.01) / 0.001)));
776 kk = 0.7 + 0.3 * exp(100. * (eta - 0.25));
777 kt1 = 0.45 * sqrt(1. + 200.0 * eta * eta / 3.0) - 0.125;
778 kt2 = 0.5 * pow(1. + 0.5 * eta * sqrt(eta) / 0.0225, 2. / 3.) - 0.2;
779 modefreqs->
data[6] = kk * creal(modefreqs->
data[6]) + I * cimag(modefreqs->
data[6]) / 0.95 / kt2;
780 modefreqs->
data[7] = kk * creal(modefreqs->
data[7]) + I * cimag(modefreqs->
data[7]) / kt1;
783 matchrange->
data[0] -= sh;
784 matchrange->
data[1] -= sh;
800 matchrange->
data[0] -= fmod(matchrange->
data[0],
dt / mTot);
801 matchrange->
data[1] -= fmod(matchrange->
data[1],
dt / mTot);
811 if (matchrange->
data[0] * mTot / dt < 5 || matchrange->
data[1] * mTot /
dt > matchrange->
data[2] * mTot /
dt - 2) {
812 XLALPrintError(
"More inspiral points needed for ringdown matching.\n");
813 printf(
"%.16e,%.16e,%.16e\n", matchrange->
data[0] * mTot /
dt, matchrange->
data[1] * mTot /
dt, matchrange->
data[2] * mTot /
dt - 2);
833 if (!rdwave1 || !rdwave2 || !rinspwave || !dinspwave || !ddinspwave || !inspwaves1 || !inspwaves2) {
872 for (j = 0; j < 6; j++) {
873 inspwaves1->
data[j] = rinspwave->
data[j];
874 inspwaves1->
data[j + 6] = dinspwave->
data[j];
875 inspwaves1->
data[j + 12] = ddinspwave->
data[j];
890 for (j = 0; j < 6; j++) {
891 inspwaves2->
data[j] = rinspwave->
data[j];
892 inspwaves2->
data[j + 6] = dinspwave->
data[j];
893 inspwaves2->
data[j + 12] = ddinspwave->
data[j];
919 UINT4 attachIdx = round(matchrange->
data[1] * mTot /
dt);
920 for (j = 1; j < Nrdwave; ++j) {
921 signal1->
data[j + attachIdx] = rdwave1->
data[j];
922 signal2->
data[j + attachIdx] = rdwave2->
data[j];
925 memset(signal1->
data + Nrdwave + attachIdx, 0, (signal1->
length - Nrdwave - attachIdx) *
sizeof(
REAL8));
926 memset(signal2->
data + Nrdwave + attachIdx, 0, (signal2->
length - Nrdwave - attachIdx) *
sizeof(
REAL8));
948 if ( indAmax == NULL || timeVec == NULL || ampWave == NULL || valAmax == NULL ) {
955 if (timeVec->
data[
i] == tofAmax) {
958 *valAmax = ampWave->
data[
i];
966 printf(
" found maximum times: %f, %f \n", timeVec->
data[*indAmax], tofAmax );
997 const REAL8 domega220,
999 const REAL8 domega210,
1000 const REAL8 dtau210,
1001 const REAL8 domega330,
1002 const REAL8 dtau330,
1003 const REAL8 domega440,
1004 const REAL8 dtau440,
1005 const REAL8 domega550,
1006 const REAL8 dtau550,
1007 const UINT2 TGRflag,
1015 if ( mass1 <= 0. || mass2 <= 0.
1016 || fabs(spin1x) > 1. || fabs(spin1y) > 1. || fabs(spin1z) > 1.
1017 || fabs(spin2x) > 1. || fabs(spin2y) > 1. || fabs(spin2z) > 1.
1018 || spin1x*spin1x + spin1y*spin1y + spin1z*spin1z > 1.
1019 || spin2x*spin2x + spin2y*spin2y + spin2z*spin2z > 1.
1025 UNUSED
INT4 phasecount;
1035 REAL8 mtot = mass1 + mass2;
1036 REAL8 eta = mass1 * mass2 / (mtot * mtot);
1040 REAL8 chi1 = spin1z;
1041 REAL8 chi2 = spin2z;
1042 REAL8 spin1[3] = { spin1x, spin1y, spin1z };
1043 REAL8 spin2[3] = { spin2x, spin2y, spin2z };
1048 gsl_spline *spline0 = NULL;
1049 gsl_interp_accel *acc0 = NULL;
1054 printf(
"RDfit: we use spin1 %f, spin2 %f, and it should be dimensionless [-1,1] \n", chi1, chi2);
1055 printf(
"We use approximant = %d \n", appr);
1057 REAL8 chi = 0.5 * (chi1 + chi2) + 0.5 * (chi1 - chi2) * (mass1 - mass2)/(mass1 + mass2) / (1.0 - 2.0 * eta);
1071 if ((
l == 2 ) && (
m == 2)){
1072 modefreqs->
data[0] = creal(modefreqs->
data[0])*(1. + domega220) + I*cimag(modefreqs->
data[0])/(1. + dtau220);
1074 if ((
l == 2 ) && (
m == 1)) {
1075 modefreqs->
data[0] = creal(modefreqs->
data[0])*(1. + domega210) + I*cimag(modefreqs->
data[0])/(1. + dtau210);
1077 if ((
l == 3 ) && (
m == 3)) {
1078 modefreqs->
data[0] = creal(modefreqs->
data[0])*(1. + domega330) + I*cimag(modefreqs->
data[0])/(1. + dtau330);
1080 if ((
l == 4 ) && (
m == 4)) {
1081 modefreqs->
data[0] = creal(modefreqs->
data[0])*(1. + domega440) + I*cimag(modefreqs->
data[0])/(1. + dtau440);
1083 if ((
l == 5 ) && (
m == 5)) {
1084 modefreqs->
data[0] = creal(modefreqs->
data[0])*(1. + domega550) + I*cimag(modefreqs->
data[0])/(1. + dtau550);
1095 sigmalm0 = (-cimag(modefreqs->
data[0]) - I * creal(modefreqs->
data[0])) * (mtot *
LAL_MTSUN_SI);
1099 printf(
"Mode %d %d \n",
l,
m);
1100 printf(
"matchpoints are: %.16f, %.16f, %.16f, %.16f\n", matchrange->
data[0], matchrange->
data[1], matchrange->
data[2], matchrange->
data[3]);
1101 printf(
"the 0-overtone is: %.16f + i %.16f \n", creal(sigmalm0), cimag(sigmalm0));
1113 ampWave->
data[
i] = 0.0;
1114 phWave->
data[
i] = 0.0;
1117 prev = atan2(signal2->
data[0], signal1->
data[0]);
1118 phWave->
data[0] = prev;
1127 phWave->
data[
i] = phWave->
data[
i - 1] + corph;
1134 char filename2[
sizeof "CheckStasAmplPhaseXX.dat"];
1135 sprintf(filename2,
"CheckStasAmplPhase%01d%01d.dat",
l,
m);
1136 fout = fopen(filename2,
"w");
1137 printf(
"Check the length: time %d, signal %d \n", timeVec->
length, signal1->
length);
1152 if (
l == 5 &&
m==5) {
1153 tofAmax = matchrange->
data[3];
1157 if((
l == 2 &&
m == 2) || (
l == 5 &&
m == 5)){
1165 *indAmpMax = indAmax;
1169 if(
l == 5 &&
m == 5){
1170 spline0 = gsl_spline_alloc (gsl_interp_cspline, timeVec->
length);
1171 acc0 = gsl_interp_accel_alloc ();
1172 gsl_spline_init (spline0, timeVec->
data, ampWave->
data, timeVec->
length);
1173 gsl_interp_accel_reset (acc0);
1174 valdAmax = gsl_spline_eval_deriv (spline0, tofAmax, acc0);
1178 indAmax = *indAmpMax;
1179 valAmax = ampWave->
data[indAmax];
1183 spline0 = gsl_spline_alloc (gsl_interp_cspline, timeVec->
length);
1184 acc0 = gsl_interp_accel_alloc ();
1185 gsl_spline_init (spline0, timeVec->
data, ampWave->
data, timeVec->
length);
1186 gsl_interp_accel_reset (acc0);
1187 valdAmax = gsl_spline_eval_deriv (spline0, tofAmax, acc0);
1194 printf(
"Check: The maximum of amplitude is %.16e found at t=%f, index = %d (out of %d) \n", valAmax, tofAmax, indAmax, timeVec->
length);
1195 printf(
"Amp@Attachment = %.16f \n", valAmax);
1196 printf(
"dAmp@Attachment = %.16f \n", valdAmax);
1197 FILE *indMax = NULL;
1198 char filename2[
sizeof "indexMaxXXHi.dat"];
1199 sprintf(filename2,
"indexMax%01d%01dHi.dat",
l,
m);
1200 indMax = fopen (filename2,
"w");
1201 fprintf(indMax,
"%d \n",indAmax);
1220 printf(
"ampcf1 = %.16f \n", ampcf1);
1230 printf(
"ampcf2 = %.16f \n", ampcf2);
1234 if(
l == 2 &&
m == 2){
1235 if (creal(sigmalm0) > 2. * ampcf1 * tanh(ampcf2)) {
1236 ampcf1 = creal(sigmalm0) / (2. * tanh(ampcf2));
1245 printf(
"phasecf1 = %.16f \n", phasecf1);
1254 printf(
"phasecf2 = %.16f \n", phasecf2);
1271 for (
i = 0;
i < Nrdwave;
i++) {
1272 rdtime->
data[
i] =
i * dtM;
1277 REAL8 Arescaledtcons = valAmax * exp(-creal(sigmalm0) * tcons) / eta;
1278 REAL8 dtArescaledtcons = (valdAmax - creal(sigmalm0) * valAmax) * exp(-creal(sigmalm0) * tcons) / eta;
1280 REAL8 ampcc1 = dtArescaledtcons * pow(
cosh(ampcf2), 2) / ampcf1;
1282 REAL8 ampcc2 = (Arescaledtcons * ampcf1 - dtArescaledtcons *
cosh(ampcf2) * sinh(ampcf2)) / ampcf1;
1292 for (
i = 0;
i < Nrdwave;
i++) {
1293 ampRD->
data[
i] = eta * exp(creal(sigmalm0) * rdtime->
data[
i]) * (ampcc1 * tanh(ampcf1 * rdtime->
data[
i] + ampcf2) + ampcc2);
1296 char filename[
sizeof "StasAmpRD_fullXX.dat"];
1297 sprintf(
filename,
"StasAmpRD_full%01d%01d.dat",
l,
m);
1302 for (
i = 1;
i < Nrdwave;
i++) {
1309 REAL8 omegarescaledtcons = (phWave->
data[indAmax] - phWave->
data[indAmax - 1]) / dtM - cimag(sigmalm0);
1315 printf(
"omega0 = %.16f\n", phWave->
data[0]);
1318 REAL8 phasecc1 = omegarescaledtcons * (phasecf2 + 1.0) / phasecf2 / phasecf1;
1325 printf(
"phi_0 = %.16f \n", phi0);
1327 REAL8 logargnum, logargden;
1329 for (
i = 0;
i < Nrdwave;
i++) {
1330 logargnum = 1. + phasecf2 * exp(-phasecf1 * rdtime->
data[
i]);
1331 logargden = 1. + phasecf2;
1332 phRD->
data[
i] = phi0 - phasecc1 * log(logargnum / logargden) + cimag(sigmalm0) * rdtime->
data[
i];
1335 char filename[
sizeof "StasPhRD_fullXX.dat"];
1336 sprintf(
filename,
"StasPhRD_full%01d%01d.dat",
l,
m);
1341 for (
i = 1;
i < Nrdwave;
i++) {
1347 UINT4 totSz = indAmax + Nrdwave;
1355 for (
i = 0;
i < indAmax;
i++) {
1359 for (
i = 0;
i < Nrdwave;
i++) {
1360 tFull->
data[
i + indAmax] = rdtime->
data[
i] + tofAmax;
1363 fout = fopen(
"StasPhRD_full2.dat",
"w");
1364 for (
i = 0;
i < totSz;
i++) {
1369 gsl_spline *spline = NULL;
1370 gsl_interp_accel *acc = NULL;
1371 spline = gsl_spline_alloc(gsl_interp_cspline, totSz);
1372 acc = gsl_interp_accel_alloc();
1373 gsl_spline_init(spline, tFull->
data, PhFull->
data, totSz);
1374 for (
i = 0;
i < totSz;
i++) {
1375 frFull->
data[
i] = gsl_spline_eval_deriv(spline, tFull->
data[
i], acc);
1377 fout = fopen(
"StasFrRD_full.dat",
"w");
1378 for (
i = 0;
i < totSz;
i++) {
1383 gsl_spline_free(spline);
1384 gsl_interp_accel_free(acc);
1393 for (
i = 0;
i < Nrdwave;
i++) {
1398 gsl_spline_free (spline0);
1399 gsl_interp_accel_free (acc0);
1433 if ( mass1 <= 0. || mass2 <= 0.
1434 || fabs(spin1x) > 1. || fabs(spin1y) > 1. || fabs(spin1z) > 1.
1435 || fabs(spin2x) > 1. || fabs(spin2y) > 1. || fabs(spin2z) > 1.
1436 || spin1x*spin1x + spin1y*spin1y + spin1z*spin1z > 1.
1437 || spin2x*spin2x + spin2y*spin2y + spin2z*spin2z > 1.
1443 UNUSED
INT4 phasecount;
1452 REAL8 mtot = mass1 + mass2;
1453 REAL8 eta = mass1 * mass2 / (mtot * mtot);
1457 REAL8 chi1 = spin1z;
1458 REAL8 chi2 = spin2z;
1459 REAL8 spin1[3] = { spin1x, spin1y, spin1z };
1460 REAL8 spin2[3] = { spin2x, spin2y, spin2z };
1466 printf(
"RDfit: we use spin1 %f, spin2 %f, and it should be dimensionless [-1,1] \n", chi1, chi2);
1467 printf(
"We use approximant = %d \n", appr);
1469 REAL8 chi = 0.5 * (chi1 + chi2) + 0.5 * (chi1 - chi2) * (mass1 - mass2)/(mass1 + mass2) / (1.0 - 2.0 * eta);
1485 sigma220 = (-cimag(modefreqs->
data[0]) - I * creal(modefreqs->
data[0])) * (mtot *
LAL_MTSUN_SI);
1488 printf(
"matchpoints are: %f, %f, %f \n", matchrange->
data[0], matchrange->
data[1], matchrange->
data[2]);
1489 printf(
"the 0-overtone is: %f + i %f \n", creal(sigma220), cimag(sigma220));
1501 ampWave->
data[
i] = 0.0;
1502 phWave->
data[
i] = 0.0;
1505 prev = atan2(signal2->
data[0], signal1->
data[0]);
1506 phWave->
data[0] = prev;
1515 phWave->
data[
i] = phWave->
data[
i - 1] + corph;
1522 fout = fopen(
"CheckStasAmplPhase.dat",
"w");
1523 printf(
"Check the length: time %d, signal %d \n", timeVec->
length, signal1->
length);
1536 if ( tofAmax != timeVec->
data[timeVec->
length-1] ) {
1545 indAmax = timeVec->
length-1;
1546 valAmax = ampWave->
data[indAmax];
1549 printf(
"Check: The maximum of amplitude is %.16e found at t=%f, index = %d (out of %d) \n", valAmax, tofAmax, indAmax, timeVec->
length);
1572 if (creal(sigma220) > 2. * ampcf1 * tanh(ampcf2)) {
1573 ampcf1 = creal(sigma220) / (2. * tanh(ampcf2));
1596 for (
i = 0;
i < Nrdwave;
i++) {
1597 rdtime->
data[
i] =
i * dtM;
1602 REAL8 Arescaledtcons = valAmax * exp(-creal(sigma220) * tcons) / eta;
1603 REAL8 dtArescaledtcons = (0. - creal(sigma220) * valAmax) * exp(-creal(sigma220) * tcons) / eta;
1604 REAL8 ampcc1 = dtArescaledtcons * pow(
cosh(ampcf2), 2) / ampcf1;
1605 REAL8 ampcc2 = (Arescaledtcons * ampcf1 - dtArescaledtcons *
cosh(ampcf2) * sinh(ampcf2)) / ampcf1;
1615 for (
i = 0;
i < Nrdwave;
i++) {
1616 ampRD->
data[
i] = eta * exp(creal(sigma220) * rdtime->
data[
i]) * (ampcc1 * tanh(ampcf1 * rdtime->
data[
i] + ampcf2) + ampcc2);
1621 fout = fopen(
"StasAmpRD_full.dat",
"w");
1622 for (
i = 0;
i < indAmax;
i++) {
1625 for (
i = 0;
i < Nrdwave;
i++) {
1632 REAL8 omegarescaledtcons = (phWave->
data[indAmax] - phWave->
data[indAmax - 1]) / dtM - cimag(sigma220);
1633 REAL8 phasecc1 = omegarescaledtcons * (phasecf2 + 1.0) / phasecf2 / phasecf1;
1635 REAL8 logargnum, logargden;
1637 for (
i = 0;
i < Nrdwave;
i++) {
1638 logargnum = 1. + phasecf2 * exp(-phasecf1 * rdtime->
data[
i]);
1639 logargden = 1. + phasecf2;
1640 phRD->
data[
i] = phi0 - phasecc1 * log(logargnum / logargden) + cimag(sigma220) * rdtime->
data[
i];
1641 phRD->
data[
i] = phi0 + ((phWave->
data[indAmax] - phWave->
data[indAmax - 1]) / dtM) * rdtime->
data[
i];
1645 fout = fopen(
"StasPhRD_full.dat",
"w");
1646 for (
i = 0;
i < indAmax;
i++) {
1649 for (
i = 0;
i < Nrdwave;
i++) {
1655 UINT4 totSz = indAmax + Nrdwave;
1663 for (
i = 0;
i < indAmax;
i++) {
1667 for (
i = 0;
i < Nrdwave;
i++) {
1668 tFull->
data[
i + indAmax] = rdtime->
data[
i] + tofAmax;
1671 fout = fopen(
"StasPhRD_full2.dat",
"w");
1672 for (
i = 0;
i < totSz;
i++) {
1677 gsl_spline *spline = NULL;
1678 gsl_interp_accel *acc = NULL;
1679 spline = gsl_spline_alloc(gsl_interp_cspline, totSz);
1680 acc = gsl_interp_accel_alloc();
1681 gsl_spline_init(spline, tFull->
data, PhFull->
data, totSz);
1682 for (
i = 0;
i < totSz;
i++) {
1683 frFull->
data[
i] = gsl_spline_eval_deriv(spline, tFull->
data[
i], acc);
1685 fout = fopen(
"StasFrRD_full.dat",
"w");
1686 for (
i = 0;
i < totSz;
i++) {
1691 gsl_spline_free(spline);
1692 gsl_interp_accel_free(acc);
1701 for (
i = 0;
i < Nrdwave;
i++) {
static REAL8 XLALCalculateRDPhaseCoefficient1(UINT4 modeL, UINT4 modeM, REAL8 eta, REAL8 chi)
static UNUSED INT4 XLALSimIMREOBAttachFitRingdown(REAL8Vector *signal1, REAL8Vector *signal2, const INT4 l, const INT4 m, const REAL8 dt, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1x, const REAL8 spin1y, const REAL8 spin1z, const REAL8 spin2x, const REAL8 spin2y, const REAL8 spin2z, const REAL8 domega220, const REAL8 dtau220, const REAL8 domega210, const REAL8 dtau210, const REAL8 domega330, const REAL8 dtau330, const REAL8 domega440, const REAL8 dtau440, const REAL8 domega550, const REAL8 dtau550, const UINT2 TGRflag, REAL8Vector *timeVec, REAL8Vector *matchrange, Approximant approximant, UINT4 *indAmpMax)
The main function for performing the ringdown attachment for SEOBNRv4 (and beyond) This is the functi...
static INT4 XLALSimIMREOBHybridRingdownWave(REAL8Vector *rdwave1, REAL8Vector *rdwave2, const REAL8 dt, const REAL8 mass1, const REAL8 mass2, REAL8VectorSequence *inspwave1, REAL8VectorSequence *inspwave2, COMPLEX16Vector *modefreqs, REAL8Vector *matchrange)
Generates the ringdown wave associated with the given real and imaginary parts of the inspiral wavefo...
static UNUSED INT4 XLALSimIMREOBTaper(REAL8Vector *signal1, REAL8Vector *signal2, const INT4 l, const INT4 m, const REAL8 dt, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1x, const REAL8 spin1y, const REAL8 spin1z, const REAL8 spin2x, const REAL8 spin2y, const REAL8 spin2z, REAL8Vector *timeVec, REAL8Vector *matchrange, Approximant approximant)
static REAL8 XLALCalculateRDPhaseCoefficient2(UINT4 modeL, UINT4 modeM, REAL8 eta, REAL8 chi)
static UNUSED INT4 XLALSimIMREOBHybridAttachRingdown(REAL8Vector *signal1, REAL8Vector *signal2, const INT4 l, const INT4 m, const REAL8 dt, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1x, const REAL8 spin1y, const REAL8 spin1z, const REAL8 spin2x, const REAL8 spin2y, const REAL8 spin2z, REAL8Vector *timeVec, REAL8Vector *matchrange, Approximant approximant)
The main workhorse function for performing the ringdown attachment for EOB models EOBNRv2 and SEOBNRv...
static INT4 XLALGenerateHybridWaveDerivatives(REAL8Vector *rwave, REAL8Vector *dwave, REAL8Vector *ddwave, REAL8Vector *timeVec, REAL8Vector *wave, REAL8Vector *matchrange, REAL8 dt, REAL8 mass1, REAL8 mass2)
Function which calculates the value of the waveform, plus its first and second derivatives,...
static INT4 XLALSimFindIndexMaxAmpli(UINT4 *indAmax, REAL8Vector *timeVec, REAL8Vector *ampWave, REAL8 *valAmax, REAL8 tofAmax)
static REAL8 XLALCalculateRDAmplitudeCoefficient2(UINT4 modeL, UINT4 modeM, REAL8 eta, REAL8 chi)
static REAL8 XLALCalculateRDAmplitudeCoefficient1(UINT4 modeL, UINT4 modeM, REAL8 eta, REAL8 chi)
static UNUSED REAL8 XLALSimIMREOBGetNRSpinPeakOmega(INT4 UNUSED l, INT4 UNUSED m, REAL8 UNUSED eta, REAL8 a)
Peak frequency predicted by fitting NR results (currently only 2,2 available).
static UNUSED REAL8 XLALSimIMREOBGetNRSpinPeakOmegav2(INT4 UNUSED l, INT4 UNUSED m, REAL8 UNUSED eta, REAL8 a)
Peak frequency predicted by fitting NR results (currently only 2,2 available).
static UNUSED REAL8 XLALSimIMREOBGetNRSpinPeakOmegaV4(INT4 modeL, INT4 modeM, REAL8 UNUSED eta, REAL8 a)
Peak frequency predicted by fitting NR results The coefficients for the (2,2) are in Eq.
#define XLAL_CALLGSL(statement)
REAL8VectorSequence * XLALCreateREAL8VectorSequence(UINT4 length, UINT4 veclen)
void XLALDestroyREAL8VectorSequence(REAL8VectorSequence *vecseq)
INT4 XLALSimIMREOBFinalMassSpin(REAL8 *finalMass, REAL8 *finalSpin, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], Approximant approximant)
Computes the final mass and spin of the black hole resulting from merger.
INT4 XLALSimIMREOBGenerateQNMFreqV2(COMPLEX16Vector *modefreqs, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], UINT4 l, INT4 m, UINT4 nmodes, Approximant approximant)
These functions generate the quasinormal mode frequencies for a black hole ringdown.
#define EOB_RD_EFOLDS
The number of e-folds of ringdown which should be attached for EOBNR models.
Approximant
Enum that specifies the PN approximant to be used in computing the waveform.
@ SEOBNRv2
Spin-aligned EOBNR model v2.
@ SEOBNRv1
Spin-aligned EOBNR model.
COMPLEX16Vector * XLALCreateCOMPLEX16Vector(UINT4 length)
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
void XLALDestroyCOMPLEX16Vector(COMPLEX16Vector *vector)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1