25 #define UNUSED __attribute__ ((unused))
37 #include <gsl/gsl_const.h>
38 #include <gsl/gsl_errno.h>
39 #include <gsl/gsl_math.h>
40 #include <gsl/gsl_odeiv.h>
53 nu =
q/((
q+1.)*(
q+1.));
60 return 0.5*(1.+sqrt(1.-4.*nu));
68 if ((
m>0) & (
m<8)) logm =
Logm[
m];
78 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
79 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, n);
80 gsl_spline_init (spline, t,
y, n);
83 for (
INT4 k = 0; k < ni; k++)
85 yi[k] = (
REAL8) gsl_spline_eval (spline, ti[k], acc);
87 gsl_spline_free (spline);
88 gsl_interp_accel_free (acc);
95 INT4 i0 = o-1, i1 = n-o;
101 if (
x <= xp[i0])
return 0;
102 if (
x > xp[i1])
return n-2*o;
106 if (
x < xp[
i]) i1 =
i;
else i0 =
i;
117 REAL8 o, num, den, div, ci;
119 for (
i = 0;
i < n;
i++)
121 if (fabs(xx -
x[
i]) <=
tiny)
return f[
i];
123 for (j = 0; j < n; j++)
133 for (
i = 0;
i < n;
i++)
149 for (
i = 0;
i < n;
i++)
152 for (j = 0; j < n; j++)
168 REAL8 num, den, div, ci;
170 for (
i = 0;
i < n;
i++)
173 if (fabs(div) <=
tiny)
return f[
i];
188 ff =
baryc_f(xx, ox, &f[ix], &
x[ix]);
195 const INT4 i = (n-1)/2;
197 REAL8 d1f = 0., d2f = 0.;
200 d1f = 0.5*(f[
i+1]-f[
i-1]);
201 d2f = (f[
i-1]-2*f[
i]+f[
i+1]);
205 d1f = (8.*(f[
i+1]-f[
i-1]) - f[
i+2] + f[
i-2]);
206 d2f = (-30*f[
i]+16*(f[
i+1]+f[
i-1])-(f[
i+2]+f[
i-2]));
210 d1f = ( 45.0*(f[
i+1]-f[
i-1]) - 9.0*(f[
i+2] - f[
i-2]) + f[
i+3] - f[
i-3] )/(60.0);
211 d2f = ( -490.0*f[
i]+270.0*(f[
i+1]+f[
i-1])-27.0*(f[
i+2]+f[
i-2])+2.0*(f[
i+3]+f[
i-3]) )/(180.0);
224 *fmax = ( -((dx + x0 - xmax)*(-x0 + xmax)*f[-1 +
i])
225 + (dx - x0 + xmax)*(2*(dx + x0 - xmax)*f[
i] + (-x0 + xmax)*f[1 +
i]) );
226 *fmax /= (2.*
SQ(dx));
230 *fmax = ((dx + x0 - xmax)*(2*dx + x0 - xmax)*(-x0 + xmax)*(dx - x0 + xmax)*f[-2 +
i]
231 + (2*dx - x0 + xmax)*(-4*(dx + x0 - xmax)*(2*dx + x0 - xmax)*(-x0 + xmax)*f[-1 +
i]+(dx - x0 + xmax)*(6*(dx + x0 - xmax)*(2*dx + x0 - xmax)*f[
i] + (-x0 + xmax)*(4*(2*dx + x0 - xmax)*f[1 +
i]- (dx + x0 - xmax)*f[2 +
i]))));
232 *fmax /= (24.*pow(dx,4));
337 for (
INT4 EMM = 0; EMM <= (
INT4) ELL; EMM++)
344 /* Make sure that for non-BNS systems, only \f$(2,\pm 2)\f$ modes are active */
345 if (!use_tidal) XLAL_CHECK((ELL==2) && (abs(EMM)==2), XLAL_EDOM, "Modes beyond (2,\\pm 2) are only available
for BNS in
TEOBResumS.
");
347 /* Make sure (l,-m) mode is activated if (l,m) is active. Does not
348 * exit with error but silently adds the symmetric mode if not present.
349 * Bitwise operation in implementation ensures that no check is necessary.
351 XLALSimInspiralModeArrayActivateMode(ModeArray, ELL, -EMM);
353 else if (XLALSimInspiralModeArrayIsModeActive(ModeArray, ELL, -EMM))
355 /* Make sure (l,m) mode is active if (l,-m) is active */
356 XLAL_CHECK(XLALSimInspiralModeArrayIsModeActive(ModeArray, ELL, EMM), XLAL_EDOM, "Symmetric (
l,-
m) mode cannot be included without the (
l,
m) mode being active.
");
364 /* (h+, hx) polarizations from the multipolar waveform in the source frame */
365 void XLALSimIMRComputePolarisations(REAL8Sequence *hplus_out,
366 REAL8Sequence *hcross_out,
367 SphHarmTimeSeries *hlm,
369 REAL8 amplitude_prefactor,
373 INT4 mneg = 1; /* m>0 modes only, add m<0 modes afterwards */
374 COMPLEX16 Y, Ym=0.0, hpc;
377 SphHarmTimeSeries *this_mode = hlm;
383 if (!XLALSimInspiralModeArrayIsModeActive(modeArray, l, m))
385 this_mode = this_mode->next;
388 mneg = XLALSimInspiralModeArrayIsModeActive(modeArray, l, - m);
390 Y = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, m);
391 if ( (mneg) && (m != 0) )
393 Ym = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, - m);
394 if ( l % 2 ) Ym = -Ym; /* l is odd */
397 for (UINT4 i=0; i < this_mode->mode->data->length; i++)
400 hpc += this_mode->mode->data->data[i] * Y;
402 if ( (mneg) && (m != 0) )
403 hpc += conj(this_mode->mode->data->data[i]) * Ym;
405 hpc *= amplitude_prefactor;
406 hplus_out->data[i] += creal(hpc);
407 hcross_out->data[i] -= cimag(hpc);
410 this_mode = this_mode->next;
416 /* (h+, hx) polarizations from the multipolar waveform in the source frame;
417 polar representation of time series */
418 void XLALSimIMRComputePolarisationsPolar(REAL8Sequence *hplus_out,
419 REAL8Sequence *hcross_out,
420 SphHarmPolarTimeSeries *hlm,
422 REAL8 amplitude_prefactor,
426 INT4 mneg = 1; /* m>0 modes only, add m<0 modes afterwards */
427 COMPLEX16 Y, Ym = 0.0, hpc;
430 SphHarmPolarTimeSeries *this_mode = hlm;
436 if (!XLALSimInspiralModeArrayIsModeActive(modeArray, l, m))
438 this_mode = this_mode->next;
441 mneg = XLALSimInspiralModeArrayIsModeActive(modeArray, l, - m);
442 //#pragma omp parallel
444 /* Convention (master) theta = (-)incl and phi = pi/2 - phiRef */
445 Y = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, m);
446 if ( (mneg) && (m != 0) )
448 Ym = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, l, -m);
449 if ( l % 2 ) Ym = -Ym; /* l is odd */
452 for (UINT4 i=0; i < this_mode->ampl->data->length; i++)
454 hpc = cpolar(this_mode->ampl->data->data[i], -this_mode->phase->data->data[i]) * Y;
457 if ( (mneg) && (m != 0) )
458 hpc += cpolar(this_mode->ampl->data->data[i], this_mode->phase->data->data[i]) * Ym;
460 hpc *= amplitude_prefactor;
461 hplus_out->data[i] += creal(hpc);
462 hcross_out->data[i] -= cimag(hpc);
465 this_mode = this_mode->next;
472 /* 4th order centered stencil first derivative, uniform grids */
473 INT4 D0(REAL8 *f, REAL8 dx, INT4 n, REAL8 *df)
475 const REAL8 oo12dx = 1./(12*dx);
477 for (i=2; i<n-2; i++)
479 df[i] = (8.*(f[i+1]-f[i-1]) - f[i+2] + f[i-2])*oo12dx;
482 df[i] = (-25.*f[i] + 48.*f[i+1] - 36.*f[i+2] + 16.*f[i+3] - 3.*f[i+4])*oo12dx;
484 df[i] = (-3.*f[i-1] - 10.*f[i] + 18.*f[i+1] - 6.*f[i+2] + f[i+3])*oo12dx;
486 df[i] = - (-3.*f[i+1] - 10.*f[i] + 18.*f[i-1] - 6.*f[i-2] + f[i-3])*oo12dx;
488 df[i] = - (-25.*f[i] + 48.*f[i-1] - 36.*f[i-2] + 16.*f[i-3] - 3.*f[i-4])*oo12dx;
492 /* 4th order centered stencil second derivative, uniform grids */
493 INT4 D2(REAL8 *f, REAL8 dx, INT4 n, REAL8 *d2f)
495 const REAL8 oo12dx2 = 1./(dx*dx*12);
497 for (i=2; i<n-2; i++)
499 d2f[i] = (-30*f[i]+16*(f[i+1]+f[i-1])-(f[i+2]+f[i-2]))*oo12dx2;
502 d2f[i] = (45*f[i]-154*f[i+1]+214*f[i+2]-156*f[i+3]+61*f[i+4]-10*f[i+5])*oo12dx2;
504 d2f[i] = (10*f[i-1]-15*f[i]-4*f[i+1]+14*f[i+2]-6*f[i+3]+f[i+4])*oo12dx2;
506 d2f[i] = (10*f[i+1]-15*f[i]-4*f[i-1]+14*f[i-2]-6*f[i-3]+f[i-4])*oo12dx2;
508 d2f[i] = (45*f[i]-154*f[i-1]+214*f[i-2]-156*f[i-3]+61*f[i-4]-10*f[i-5])*oo12dx2;
512 /* Third-order polynomial integration */
513 REAL8 cumint3(REAL8 *f, REAL8 *x, const INT4 n, REAL8 *sum)
515 REAL8 xe[n+2], fe[n+2];
516 REAL8 *x0,*x1,*x2,*x3;
517 REAL8 *f0,*f1,*f2,*f3;
518 REAL8 a,b,c,d,e,h,g,z;
519 const REAL8 oo12 = 0.08333333333333333;
521 for (INT4 i=1; i < n+1; i++)
542 for (INT4 i=0; i < n-1; i++)
550 g = 0.5*(f1[i]+f2[i]);
551 z = b*g + oo12*b*b*(c*b*(2*c+b)*(c+b)*d-a*c*(c-a)*(2*c+2*a+3*b)*e-a*b*(2*a+b)*(a+b)*h)/(a*c*(a+b)*(c+b)*(c+a+b));
552 sum[i+1] = sum[i] + z;
558 /* Simple unwrap for phase angles */ // Do NOT mess with it
559 void unwrap(REAL8 *p, const INT4 size)
561 if (size < 1) return;
563 INT4 fact = 0; // For making the initial negative phase angles positive
569 if( p[0] < 0 ) fact = 1;
573 for (j = 1; j < size; j++)
575 p[j] += fact*LAL_TWOPI;
580 p[j] += corr - fact*LAL_TWOPI;
586 /* Unwrap unsign number of cycles from reference phase as proxy */
587 void unwrap_proxy(REAL8 *p, REAL8 *r, const INT4 size, const INT4 shift0)
589 if (size < 1) return;
591 INT4 *n = (INT4 *) calloc(size, sizeof(INT4));
592 XLAL_CHECK_VOID(n, XLAL_ENOMEM, "Out of memory
");
594 const REAL8 ooTwoPi = 1.0/(LAL_TWOPI);
595 const REAL8 r0 = r[0];
597 /* no cycles from reference phase, r>0 */
598 for (INT4 i = 0; i < size; i++)
599 n[i] = floor ( (r[i] - r0) * ooTwoPi );
603 /* shift phase : p(0) = r(0) */
604 const REAL8 dp = (r0 - p[0]);
605 for (INT4 i = 0; i < size; i++)
609 /* unwrap based on no cycles */
610 const REAL8 p0 = p[0];
612 for (INT4 i = 0; i < size; i++)
614 p[i] += n[i]*LAL_TWOPI;
615 /* correct cases p = - Pi + epsilon */
616 np = floor ( ( p[i] - p0 )*ooTwoPi );
617 p[i] += (n[i]-np)*LAL_TWOPI;
623 /* Compute size of a uniform grid t0:dt:tf */
624 INT4 get_uniform_size(const REAL8 tN, const REAL8 t0, const REAL8 dt)
626 return ((INT4)((tN - t0)/dt + 1));
629 /* Compute optimized timestep after merger */
630 REAL8 get_mrg_timestep(REAL8 q, REAL8 chi1, REAL8 chi2)
632 REAL8 dt = q+chi1+chi2; // MA: just to get rid of UNUSED errors
638 /* Multipolar waveform at time point (complex) */
639 void Waveform_lm_t_alloc (LALTEOBResumSWaveformModeSingleTime **wav)
641 *wav = (LALTEOBResumSWaveformModeSingleTime *) calloc(1, sizeof(LALTEOBResumSWaveformModeSingleTime));
642 XLAL_CHECK_VOID(wav, XLAL_ENOMEM, "Could not allocate mode instance.\n
");
648 void Waveform_lm_t_free (LALTEOBResumSWaveformModeSingleTime *wav)
655 void NQCdata_alloc (NQCdata **nqc)
657 *nqc = (NQCdata *) calloc(1, sizeof(NQCdata));
658 XLAL_CHECK_VOID(nqc, XLAL_ENOMEM, "Out of memory
");
659 (*nqc)->flx = (NQCcoefs *) calloc(1, sizeof(NQCcoefs));
660 XLAL_CHECK_VOID((*nqc)->flx, XLAL_ENOMEM, "Out of memory
");
661 (*nqc)->hlm = (NQCcoefs *) calloc(1, sizeof(NQCcoefs));
662 XLAL_CHECK_VOID((*nqc)->hlm, XLAL_ENOMEM, "Out of memory
");
665 void NQCdata_free (NQCdata *nqc)
667 if(nqc->flx) free (nqc->flx);
668 if(nqc->hlm) free (nqc->hlm);
674 void XLALTEOBDynamicsInit (LALTEOBResumSDynamics **dyn, INT4 size, const char *name)
676 (*dyn) = calloc(1, sizeof(LALTEOBResumSDynamics));
677 XLAL_CHECK_VOID(dyn, XLAL_ENOMEM, "Could not allocate TEOB Dynamics.\n
");
679 strcpy((*dyn)->name,name);
681 (*dyn)->time = calloc ((size_t) size, sizeof(REAL8) ); // TODO: speedup: calloc < malloc+memset
683 for (INT4 v = 0; v < TEOB_DYNAMICS_NVARS; v++)
685 (*dyn)->data[v] = calloc ((size_t) size, sizeof(REAL8) );
687 NQCdata_alloc(&(*dyn)->NQC);
691 void XLALTEOBDynamicsPush (LALTEOBResumSDynamics **dyn, INT4 size)
693 (*dyn)->time = realloc( (*dyn)->time, size * sizeof(REAL8) );
694 for (INT4 v = 0; v < TEOB_DYNAMICS_NVARS; v++)
696 (*dyn)->data[v] = realloc ( (*dyn)->data[v], size * sizeof(REAL8) );
697 if ((*dyn)->data[v] == NULL) XLAL_ERROR_VOID(XLAL_ENOMEM, "Could not allocate TEOB Dynamics.\n
");
698 /* if (dn>0) memset( (*dyn)->data[v] + n, 0, dn * sizeof(REAL8) ); */ // TODO: MA: use this?
703 /* Interp and overwrite a multipolar waveform */
704 void XLALTEOBDynamicsInterp (LALTEOBResumSDynamics *dyn, const INT4 size, const REAL8 t0, const REAL8 dt, const char *name)
706 /* Alloc and init aux memory */
707 LALTEOBResumSDynamics *dyn_aux;
708 const INT4 oldsize = dyn->size;
709 XLALTEOBDynamicsInit(&dyn_aux, oldsize, "");
710 memcpy(dyn_aux->time, dyn->time, oldsize * sizeof(REAL8));
711 for (int v = 0; v < TEOB_DYNAMICS_NVARS; v++)
712 memcpy(dyn_aux->data[v], dyn->data[v], oldsize * sizeof(REAL8));
714 /* Overwrite and realloc arrays */
718 if (strcmp(name, "")) strcpy(dyn->name, name);
719 if(dyn->time) free(dyn->time);
721 dyn->time = malloc ( size * sizeof(REAL8) );
723 for (int v = 0; v < TEOB_DYNAMICS_NVARS; v++)
725 if (dyn->data[v]) free(dyn->data[v]);
726 dyn->data[v] = malloc ( size * sizeof(REAL8) );
727 /* memset(dyn->data[v], 0., size*sizeof(double)); */
730 /* Fill new time array */
731 for (int i = 0; i < size; i++)
732 dyn->time[i] = i*dt + t0;
735 for (int k = 0; k < TEOB_DYNAMICS_NVARS; k++)
736 interp_spline(dyn_aux->time, dyn_aux->data[k], dyn_aux->size, dyn->time, size, dyn->data[k]);
738 /* Free aux memory */
739 XLALFreeTEOBDynamics (dyn_aux);
742 /* Extract Dynamics at times t >= to and t < tn, Alloc a new Dynamics var */
743 void XLALTEOBDynamicsExtract (LALTEOBResumSDynamics *dyna, const REAL8 to, const REAL8 tn, LALTEOBResumSDynamics **dynb, const char *name)
747 XLAL_ERROR_VOID(XLAL_EINVAL, "Bad choice of times: tn < to
");
748 if (to > dyna->time[dyna->size-1])
749 XLAL_ERROR_VOID(XLAL_EINVAL, "Nothing to extract, to > time[size-1]
");
750 if (tn < dyna->time[0])
751 XLAL_ERROR_VOID(XLAL_EINVAL, "Nothing to extract, tn < time[0]
");
753 /* Find indexes of closest elements to (to, tn) */
755 INT4 in = dyna->size-1;
756 if (to > dyna->time[0])
757 io = find_point_bisection(to, dyna->size, dyna->time, 1);
758 if (tn < dyna->time[dyna->size-1])
759 in = find_point_bisection(tn, dyna->size, dyna->time, 0);
761 /* Calculate the new size */
762 const INT4 N = in-io;
765 /* Alloc output waveform b */
766 XLALTEOBDynamicsInit (dynb, N, name);
768 /* TODO: Parameters are not copied in the new wf !*/
770 (*dynb) = (Dynamics *) calloc(1, sizeof(Dynamics));
772 errorexit("Out of memory
");
773 strcpy((*dynb)->name,name);
775 memcpy(*dynb, dyna, sizeof(Dynamics)); // copy parameters
776 (*dynb)->time = malloc ( N * sizeof(double) );
777 for (int v = 0; v < TEOB_DYNAMICS_NVARS; v++)
778 (*dynb)->data[v] = malloc ( N * sizeof(double) );
781 /* Copy the relevant part of a into b */
782 for (int i = 0; i < N; i++)
783 (*dynb)->time[i] = dyna->time[io + i];
784 for (int v = 0; v < TEOB_DYNAMICS_NVARS; v++)
786 for (int i = 0; i < N; i++)
788 (*dynb)->data[v][i] = dyna->data[v][io + i];
794 /* Join two dynamics time series at t = to */
795 void XLALTEOBDynamicsJoin (LALTEOBResumSDynamics *dyna, LALTEOBResumSDynamics *dynb, REAL8 to)
797 /* Time arrays are suppose to be ordered as
798 dyna->time: x x x x x x x x x
799 dynb->time: o o o o o o o o o
801 But they do not need to overlap or be uniformly spaced.
803 to > dyna->time[hlma->size-1] => extend the dynamics data
804 to < dynb->time[0] => join the whole b dynamics
805 Following checks enforce the above structure, if possible.
807 if (dyna->time[0] > dynb->time[0]) SWAPTRS( dyna, dynb );
808 XLAL_CHECK_VOID (to <= dynb->time[dynb->size-1], XLAL_EINVAL, "Joining time outside range. Dynamics not joined.
");
809 XLAL_CHECK_VOID (to > dyna->time[0], XLAL_EINVAL, "Joining time outside range. Dynamics not joined.
");
811 /* Find indexes of closest elements to to */
812 const INT4 ioa = find_point_bisection(to, dyna->size, dyna->time, 1);
813 INT4 iob = find_point_bisection(to, dynb->size, dynb->time, 1);
814 if ( DEQUAL(dyna->time[ioa], dynb->time[iob], 1e-10) ) iob++;
816 /* Calculate the new size */
817 const INT4 Nb = dynb->size - iob;
818 const INT4 N = ioa + Nb;
821 XLALTEOBDynamicsPush (&dyna, N);
823 /* Copy the relevant part of b into a */
824 for (int i = 0; i < Nb; i++)
825 dyna->time[ioa + i] = dynb->time[iob + i];
826 for (int v = 0; v < TEOB_DYNAMICS_NVARS; v++)
828 for (int i = 0; i < Nb; i++)
830 dyna->data[v][ioa + i] = dynb->data[v][iob + i];
836 void XLALFreeTEOBDynamics (LALTEOBResumSDynamics *dyn)
838 if(dyn->time) free(dyn->time);
839 for (INT4 v = 0; v < TEOB_DYNAMICS_NVARS; v++)
840 if (dyn->data[v]) free(dyn->data[v]);
841 NQCdata_free(dyn->NQC);
847 /* Sync some quick access parameters in dyn with parameter database
848 to be used carefully */
849 void XLALTEOBDynamicsSetParams(LALTEOBResumSDynamics *dyn, /*< pointer to LALTEOBResumSDynamics struct to be filled in */
850 UNUSED LALValue **pModeArray, /*< Mode array to be returned */
851 const REAL8 m1, /*< mass of companion 1 (kg) */
852 const REAL8 m2, /*< mass of companion 2 (kg) */
853 const REAL8 UNUSED S1x, /*< x-component of the dimensionless spin of object 1 */
854 const REAL8 UNUSED S1y, /*< y-component of the dimensionless spin of object 1 */
855 const REAL8 S1z, /*< z-component of the dimensionless spin of object 1 */
856 const REAL8 UNUSED S2x, /*< x-component of the dimensionless spin of object 2 */
857 const REAL8 UNUSED S2y, /*< y-component of the dimensionless spin of object 2 */
858 const REAL8 S2z, /*< z-component of the dimensionless spin of object 2 */
859 const REAL8 dt, /*< sampling interval (s) */
860 const REAL8 lambda1, /*< l=2 tidal polarizability for m1 */
861 const REAL8 lambda2, /*< l=2 tidal polarizability for m2 */
862 const REAL8 lambda1oct, /*< l=3 tidal polarizability for m1 */
863 const REAL8 lambda2oct, /*< l=3 tidal polarizability for m2 */
864 const REAL8 lambda1hex, /*< l=4 tidal polarizability for m1 */
865 const REAL8 lambda2hex, /*< l=4 tidal polarizability for m2 */
866 LALDict *LALparams /*< LALDict dictionary for extra waveform options */
869 LALSimInspiralSpinOrder spinO = XLALSimInspiralWaveformParamsLookupPNSpinOrder(LALparams);
870 LALSimInspiralTidalOrder tidalO = XLALSimInspiralWaveformParamsLookupPNTidalOrder(LALparams);
871 LALSimInspiralGETides geTides = TEOB_GE_TIDES_DEFAULT;
872 LALSimInspiralGMTides gmTides = TEOB_GM_TIDES_DEFAULT;
873 if (XLALDictContains(LALparams, "GEtideO
"))
874 geTides = XLALSimInspiralWaveformParamsLookupGETides(LALparams);
875 if (XLALDictContains(LALparams, "GMtideO
"))
876 gmTides = XLALSimInspiralWaveformParamsLookupGMTides(LALparams);
879 /* Set auxiliary parameters */
881 dyn->M = (m1+m2)/LAL_MSUN_SI; /* Msun */
883 dyn->nu = q_to_nu(dyn->q);
884 dyn->X1 = nu_to_X1(dyn->nu);
885 dyn->X2 = 1. - dyn->X1;
889 dyn->S1 = SQ(dyn->X1) * dyn->chi1;
890 dyn->S2 = SQ(dyn->X2) * dyn->chi2;
891 dyn->a1 = dyn->X1*dyn->chi1;
892 dyn->a2 = dyn->X2*dyn->chi2;
893 REAL8 aK = dyn->a1 + dyn->a2;
895 dyn->S = dyn->S1 + dyn->S2; /* in the EMRL this becomes the spin of the BH */
896 dyn->Sstar = dyn->X2*dyn->a1 + dyn->X1*dyn->a2; /* in the EMRL this becomes the spin of the particle */
901 INT4 teobModeChoice = TEOB_MODES_NOPT; /* initialize to unavailable value */
904 /* Reading tidal order, spin order and GM tides from LALDict */
906 if (geTides > LAL_SIM_INSPIRAL_GETIDES_NOPT) XLAL_ERROR_VOID(XLAL_EDATA, "Gravitoelectric tides option not supported.
");
910 case LAL_SIM_INSPIRAL_TIDAL_ORDER_ALL:
911 dyn->use_tidal = geTides;
913 case LAL_SIM_INSPIRAL_TIDAL_ORDER_0PN:
914 dyn->use_tidal = LAL_SIM_INSPIRAL_GETIDES_OFF;
917 XLAL_ERROR_VOID(XLAL_EDATA, "Tidal order not supported.
");
920 /* Determine the type of binary based on lambda being 0 */
922 if (lambda1 == 0.0 && lambda2 ==0.0) dyn->use_tidal = LAL_SIM_INSPIRAL_GETIDES_OFF;
923 else if (lambda1 == 0.0) dyn->bhns = 1;
924 else if (lambda2 == 0.0) dyn->bhns = 2;
926 INT4 use_Yagi_fits = 1;
927 if (XLALDictContains(LALparams, "use_Yagi_fits
"))
928 use_Yagi_fits = XLALDictLookupINT4Value(LALparams, "use_Yagi_fits
");
930 if ((dyn->use_tidal != LAL_SIM_INSPIRAL_GETIDES_OFF) && (!use_Yagi_fits))
933 XLAL_CHECK_VOID(lambda1 != 0 && lambda2 != 0 && lambda1oct != 0 && lambda2oct != 0 && lambda1hex != 0 && lambda2hex != 0, XLAL_EDOM, "If Yagi fits are not used, then all tidal parameters (quad, oct, hex) need to be positive!
");
936 if (gmTides > LAL_SIM_INSPIRAL_GMTIDES_NOPT) XLAL_ERROR_VOID(XLAL_EDATA, "Gravitomagnetic tides option not supported.
");
937 dyn->use_tidal_gravitomagnetic = gmTides;
941 case LAL_SIM_INSPIRAL_SPIN_ORDER_ALL:
944 case LAL_SIM_INSPIRAL_SPIN_ORDER_0PN:
948 XLAL_ERROR_VOID(XLAL_EDATA, "Spin order not supported.
");
952 if (dyn->use_tidal!=LAL_SIM_INSPIRAL_GETIDES_OFF)
954 REAL8 LambdaAl2 = lambda1;
955 REAL8 LambdaBl2 = lambda2;
956 REAL8 LambdaAl3, LambdaAl4, LambdaBl3, LambdaBl4, SigmaAl2, SigmaBl2;
957 LambdaAl3 = lambda1oct;
958 LambdaAl4 = lambda1hex;
959 LambdaBl3 = lambda2oct;
960 LambdaBl4 = lambda2hex;
961 SigmaAl2 = SigmaBl2 = 0.0;
965 /* Allow for manual override of oct and hex Lambdas */
966 if (LambdaAl3==0.0) LambdaAl3 = Yagi13_fit_barlamdel(LambdaAl2, 3);
967 if (LambdaBl3==0.0) LambdaBl3 = Yagi13_fit_barlamdel(LambdaBl2, 3);
968 if (LambdaAl4==0.0) LambdaAl4 = Yagi13_fit_barlamdel(LambdaAl2, 4);
969 if (LambdaBl4==0.0) LambdaBl4 = Yagi13_fit_barlamdel(LambdaBl2, 4);
971 /* Write new values to LALDict so that they are globally accessible */
972 XLALSimInspiralWaveformParamsInsertTidalOctupolarLambda1(LALparams, LambdaAl3);
973 XLALSimInspiralWaveformParamsInsertTidalOctupolarLambda2(LALparams, LambdaBl3);
974 XLALSimInspiralWaveformParamsInsertTidalHexadecapolarLambda1(LALparams, LambdaAl4);
975 XLALSimInspiralWaveformParamsInsertTidalHexadecapolarLambda2(LALparams, LambdaBl4);
978 // dyn->SigmaAl2 = Yagi13_fit_barsigmalambda(dyn->LambdaAl2);
979 // dyn->SigmaBl2 = Yagi13_fit_barsigmalambda(dyn->LambdaBl2);
982 SigmaAl2 = JFAPG_fit_Sigma_Irrotational(LambdaAl2);
983 SigmaBl2 = JFAPG_fit_Sigma_Irrotational(LambdaBl2);
986 if (dyn->use_tidal_gravitomagnetic != LAL_SIM_INSPIRAL_GMTIDES_OFF)
988 SigmaAl2 = JFAPG_fit_Sigma_Irrotational(LambdaAl2);
989 SigmaBl2 = JFAPG_fit_Sigma_Irrotational(LambdaBl2);
992 /* Tidal coupling constants */
995 dyn->kapA2 = 3. * LambdaAl2 * XA*XA*XA*XA*XA / dyn->q;
996 dyn->kapA3 = 15. * LambdaAl3 * XA*XA*XA*XA*XA*XA*XA / dyn->q;
997 dyn->kapA4 = 105. * LambdaAl4 * XA*XA*XA*XA*XA*XA*XA*XA*XA / dyn->q;
999 dyn->kapB2 = 3. * LambdaBl2 * XB*XB*XB*XB*XB * dyn->q;
1000 dyn->kapB3 = 15. * LambdaBl3 * XB*XB*XB*XB*XB*XB*XB * dyn->q;
1001 dyn->kapB4 = 105. * LambdaBl4 * XB*XB*XB*XB*XB*XB*XB*XB*XB * dyn->q;
1003 /* gravitomagnetic tidal coupling constants el = 2 only */
1004 dyn->kapA2j = 24. * SigmaAl2 * XA*XA*XA*XA*XA / dyn->q;
1005 dyn->kapB2j = 24. * SigmaBl2 * XB*XB*XB*XB*XB * dyn->q;
1007 dyn->kapT2 = dyn->kapA2 + dyn->kapB2;
1008 dyn->kapT3 = dyn->kapA3 + dyn->kapB3;
1009 dyn->kapT4 = dyn->kapA4 + dyn->kapB4;
1010 dyn->kapT2j = dyn->kapA2j + dyn->kapB2j;
1012 XLAL_CHECK_VOID(dyn->kapT2 > 0., XLAL_EDOM, "kappaT2 must be >= 0
");
1013 XLAL_CHECK_VOID(dyn->kapT3 > 0., XLAL_EDOM, "kappaT3 must be >= 0
");
1014 XLAL_CHECK_VOID(dyn->kapT4 > 0., XLAL_EDOM, "kappaT4 must be >= 0
");
1016 /* Tidal coefficients cons dynamics
1017 \f$\bar{\alpha}_n^{(\ell)}\f$, Eq.(37) of Damour&Nagar, PRD 81, 084016 (2010) */
1018 dyn->bar_alph2_1 = (5./2.*XA*dyn->kapA2 + 5./2.*XB*dyn->kapB2)/dyn->kapT2;
1019 dyn->bar_alph2_2 = ((3.+XA/8.+ 337./28.*XA*XA)*dyn->kapA2 + (3.+XB/8.+ 337./28.*XB*XB)*dyn->kapB2)/dyn->kapT2;
1020 dyn->bar_alph3_1 = ((-2.+15./2.*XA)*dyn->kapA3 + (-2.+15./2.*XB)*dyn->kapB3)/dyn->kapT3;
1021 dyn->bar_alph3_2 = ((8./3.-311./24.*XA+110./3.*XA*XA)*dyn->kapA3 + (8./3.-311./24.*XB+110./3.*XB*XB)*dyn->kapB3)/dyn->kapT3;
1022 /* Gravitomagnetic term, see Eq.(6.27) if Bini-Damour-Faye 2012 */
1023 dyn->bar_alph2j_1 = ( dyn->kapA2j*(1. + (11./6.)*XA + XA*XA) + dyn->kapB2j*(1. + (11./6.)*XB + XB*XB) )/dyn->kapT2j;
1025 /* Tidal coefficients for the amplitude */
1026 dyn->khatA2 = 3./2. * LambdaAl2 * XB/XA * (REAL8) gsl_pow_int((double) XA,5);
1027 dyn->khatB2 = 3./2. * LambdaBl2 * XA/XB * (REAL8) gsl_pow_int((double) XB,5);
1029 /* Self-spin coefficients */
1038 REAL8 logC_Q1 = logQ(log(LambdaAl2));
1039 dyn->C_Q1 = exp(logC_Q1);
1040 dyn->C_Oct1 = Yagi14_fit_Coct(dyn->C_Q1);
1041 dyn->C_Hex1 = Yagi14_fit_Chex(dyn->C_Q1);
1045 REAL8 logC_Q2 = logQ(log(LambdaBl2));
1046 dyn->C_Q2 = exp(logC_Q2);
1047 dyn->C_Oct2 = Yagi14_fit_Coct(dyn->C_Q2);
1048 dyn->C_Hex2 = Yagi14_fit_Chex(dyn->C_Q2);
1051 /* Set more as needed ... */
1056 /* Use default modes for BNS */
1057 teobModeChoice = TEOB_MODES_BNS_DEFAULT;
1063 c3 = eob_c3_fit_global(dyn->nu, dyn->chi1, dyn->chi2, dyn->X1, dyn->X2, dyn->a1, dyn->a2);
1064 /* Use default modes for BBH */
1065 teobModeChoice = TEOB_MODES_BBH_DEFAULT;
1069 if (*pModeArray == NULL)
1071 *pModeArray = XLALSimInspiralCreateModeArray();
1072 XLALSetup_TEOB_mode_array(*pModeArray, teobModeChoice);
1074 XLALCheck_TEOB_mode_array(*pModeArray, dyn->use_tidal);
1076 /* Default NQC settings:
1077 * - if tides are on no NQC for flux and hlm (BNS/BHNS)
1078 * - if tides are off and spins are on, calculate NQC for hlm but not for flux (BBH spins)
1079 * - if tides and spins are off, then calculate NQC for flux and hlm using nrfit_nospin201602 (BBH no spins)
1080 * TODO: parse optional flags in LALDict
1086 dyn->nqc_coeffs_hlm = NQC_OFF;
1087 dyn->nqc_coeffs_flx = NQC_OFF;
1093 /* BBH spins setup */
1094 dyn->nqc_coeffs_hlm = NQC_COMPUTE;
1095 dyn->nqc_coeffs_flx = NQC_OFF;
1099 /* BBH no spins setup */
1100 dyn->nqc_coeffs_hlm = NQC_NR_NOSPIN;
1101 dyn->nqc_coeffs_flx = NQC_NR_NOSPIN;
1106 eob_nqc_setcoefs(dyn);
1111 INT4 utidal_tmp, uspin_tmp;
1112 utidal_tmp = dyn->use_tidal;
1113 uspin_tmp = dyn->use_spins;
1115 /* Temporarily set tidal to NNLO and switch off spin for LR estimation */
1116 dyn->use_tidal = LAL_SIM_INSPIRAL_GETIDES_NNLO;
1120 // TODO: tidesFlag usage?
1121 XLAL_CHECK_VOID((status = eob_dyn_adiabLR(dyn, &(dyn->rLR_tidal), utidal_tmp))==XLAL_SUCCESS, status, "Light ring not found! Exiting...
");
1124 dyn->use_tidal = utidal_tmp;
1125 dyn->use_spins = uspin_tmp;
1128 /* p-order 2GSF pole in the tidal interaction.
1130 See Eq.(29) of TEOBResumS paper
1131 A. Nagar et al. Phys. Rev. D 98, 104052 (2018), arXiv:1806.01772 [gr-qc]
1132 originating from calculations in
1133 D. Bini and T. Damour, Phys.Rev. D90, 124037 (2014), arXiv:1409.6933 [gr-qc]
1135 S. R. Dolan, P. Nolan, A. C. Ottewill, N. Warburton, and B. Wardell,
1136 Phys. Rev. D91, 023009 (2015), arXiv:1406.4890 [gr-qc]
1138 The interested user may set a custom value
1139 AT THEIR OWN RISK by passing the appropriate
1140 REAL8 parameter "pGSF_tidal
" through LALDict.
1142 dyn->pGSF_tidal = 4.0;
1143 if (XLALDictContains(LALparams, "pGSF_tidal
"))
1144 dyn->pGSF_tidal = XLALDictLookupREAL8Value(LALparams, "pGSF_tidal
");
1146 if (!(dyn->use_tidal))
1148 HealyBBHFitRemnant(S1z, S2z, dyn->q, &(dyn->Mbhf), &(dyn->abhf));
1149 dyn->abhf = JimenezFortezaRemnantSpin(dyn->nu, dyn->X1, dyn->X2, S1z, S2z);
1152 dyn->ode_timestep = ODE_TSTEP_ADAPTIVE;
1153 dyn->t_stop = 1e10; // HARDCODED
1154 dyn->r_stop = 1.0; // HARDCODED
1156 /* Function pointers */
1157 EOBWavFlmSFunc eob_wav_flm_s;
1158 EOBDynSGetRCFunc eob_dyn_s_get_rc;
1160 /* Set f_lm fun pointer */
1161 if (ssorder==SS_LO) {
1162 /* eob_wav_flm_s = &eob_wav_flm_s_old; */
1163 eob_wav_flm_s = &eob_wav_flm_s_SSLO;
1164 } else if (ssorder==SS_NLO) {
1165 eob_wav_flm_s = &eob_wav_flm_s_SSNLO;
1166 } else XLAL_ERROR_VOID(XLAL_EINVAL, "SS order not recognized.\n
");
1167 dyn->eob_wav_flm_s = eob_wav_flm_s;
1169 /* Set rc fun pointer */
1170 if (rc_order==RC_LO)
1172 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_LO;
1174 else if (rc_order==RC_NLO)
1176 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_NLO;
1178 else if (rc_order==RC_NNLO)
1180 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_NNLO;
1182 else if (rc_order==RC_NNLOS4)
1184 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_NNLO_S4;
1186 else if (rc_order==RC_NOSPIN)
1188 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_NOSPIN;
1190 else if (rc_order==RC_NOTIDES)
1192 eob_dyn_s_get_rc = &eob_dyn_s_get_rc_NOTIDES;
1194 else XLAL_ERROR_VOID(XLAL_EINVAL, "Centrifugal radius option not recognized.\n
");
1195 dyn->eob_dyn_s_get_rc = eob_dyn_s_get_rc;
1197 /* Pre-compute coefficients for resummed amplitudes */
1198 eob_wav_flm_coeffs(dyn->nu, dyn->clm);
1203 /* Convert time in sec to dimensionless and mass-rescaled units */
1204 REAL8 time_units_factor(REAL8 M)
1206 return 1./(M*LAL_MTSUN_SI);
1209 REAL8 time_units_conversion(REAL8 M, REAL8 t)
1211 return t/(M*LAL_MTSUN_SI);
1214 /* Convert frequency in Hz to dimensionless radius */
1215 REAL8 radius0(REAL8 M, REAL8 fHz)
1217 REAL8 x = (M*LAL_MTSUN_SI*fHz*2.*LAL_PI)/2.;
1218 return cbrt(1/(x*x));
1221 /* Mass and angular momentum of the final black hole
1222 Healey, Lousto and Zochlower (HLZ),
1223 arXiv: 1406.7295, published as PRD 90, 104004 (2014)
1224 WARNING: the formula uses the convention that M2 > M1, so that
1225 chi2 should refer to the black hole with the largest
1226 mass. In the EOB code, this is given by chi1, since
1227 in EOB code we use the convention that M1 > M2
1229 Here it is q=M2/M1, with M2>M1
1231 Improved with (Eisco, Jisco) + iterative procedure 23/02/2016
1232 parameters (TABLE VI)
1234 void HealyBBHFitRemnant(REAL8 chi1, REAL8 chi2, REAL8 q, REAL8 *mass, REAL8 *spin)
1237 /* Final mass: Angular momentum: */
1239 REAL8 M0 = 0.951507; REAL8 L0 = 0.686710;
1240 REAL8 K1 = -0.051379; REAL8 L1 = 0.613247;
1241 REAL8 K2a = -0.004804; REAL8 L2a = -0.145427;
1242 REAL8 K2b = -0.054522; REAL8 L2b = -0.115689;
1243 REAL8 K2c = -0.000022; REAL8 L2c = -0.005254;
1244 REAL8 K2d = 1.995246; REAL8 L2d = 0.801838;
1245 REAL8 K3a = 0.007064; REAL8 L3a = -0.073839;
1246 REAL8 K3b = -0.017599; REAL8 L3b = 0.004759;
1247 REAL8 K3c = -0.119175; REAL8 L3c = -0.078377;
1248 REAL8 K3d = 0.025000; REAL8 L3d = 1.585809;
1249 REAL8 K4a = -0.068981; REAL8 L4a = -0.003050;
1250 REAL8 K4b = -0.011383; REAL8 L4b = -0.002968;
1251 REAL8 K4c = -0.002284; REAL8 L4c = 0.004364;
1252 REAL8 K4d = -0.165658; REAL8 L4d = -0.047204;
1253 REAL8 K4e = 0.019403; REAL8 L4e = -0.053099;
1254 REAL8 K4f = 2.980990; REAL8 L4f = 0.953458;
1255 REAL8 K4g = 0.020250; REAL8 L4g = -0.067998;
1256 REAL8 K4h = -0.004091; REAL8 L4h = 0.001629;
1257 REAL8 K4i = 0.078441; REAL8 L4i = -0.066693;
1260 REAL8 nu = q/((1.+q)*(1.+q));
1262 /* Masses: convention here is that m2>m1 */
1263 REAL8 X2 = 0.5*(1.+sqrt(1.-4*nu));
1266 /* Spin variables */
1267 REAL8 s1 = X1*X1*chi1;
1268 REAL8 s2 = X2*X2*chi2;
1273 REAL8 Delta = X1/X2*s2 - X2/X1*s1 + s2 - s1;
1274 REAL8 Delta2 = Delta*Delta;
1275 REAL8 Delta3 = Delta*Delta2;
1276 REAL8 Delta4 = Delta2*Delta2;
1278 /* Mass ratio variables */
1279 REAL8 deltam = -sqrt(1-4*nu); // X1 - X2
1280 REAL8 deltam2 = deltam*deltam;
1281 REAL8 deltam3 = deltam*deltam2;
1282 REAL8 deltam4 = deltam*deltam3;
1283 REAL8 deltam6 = deltam2*deltam4;
1285 /* Initialize the angular momentum */
1300 /* Set-up an interative procedure to compute properly the "isco
" quantities */
1315 Z1 = 1 + cbrt(1-a2)*(cbrt(1+a0) + cbrt(1-a0));
1316 Z2 = sqrt(3*a2 + Z1*Z1);
1317 risco = 3 + Z2 - a0_sign*sqrt((3-Z1)*(3+Z1+2.*Z2));
1319 Eisco = (1 - 2.*uisco + a0*sqrt(uisco*uisco*uisco))/sqrt(1-3*uisco + 2*a0*sqrt(uisco*uisco*uisco));
1320 Jisco = 2./(sqrt(3.*risco))*(3.*sqrt(risco)-2.*a0);
1322 /* Dimensionless spin: J/Mbh^2 */
1323 abh = (4*nu)*(4*nu)*(L0 + L1*S + L2a*Delta*deltam + L2b*S2 + L2c*Delta2 + L2d*deltam2 + L3a*Delta*S*deltam + L3b*S*Delta2 + L3c*S3 + L3d*S*deltam2 + L4a*Delta*S2*deltam + L4b*Delta3*deltam + L4c*Delta4 + L4d*S4 + L4e*Delta2*S2 + L4f*deltam4 + L4g*Delta*deltam3 + L4h*Delta2*deltam2 + L4i*S2*deltam2) + S*(1+8*nu)*deltam4 + nu*Jisco*deltam6;
1325 Mbh = (4*nu)*(4*nu)*(M0 + K1*S + K2a*Delta*deltam + K2b*S2 + K2c*Delta2 + K2d*deltam2 + K3a*Delta*S*deltam + K3b*S*Delta2 + K3c*S3 + K3d*S*deltam2 + K4a*Delta*S2*deltam + K4b*Delta3*deltam + K4c*Delta4 + K4d*S4 + K4e*Delta2*S2 + K4f*deltam4 + K4g*Delta*deltam3 + K4h*Delta2*deltam2 + K4i*S2*deltam2) + (1 + nu*(Eisco + 11))*deltam6;
1334 /* Final spin fit of */
1335 // TODO: Refs needed
1336 REAL8 JimenezFortezaRemnantSpin(REAL8 nu, REAL8 X1, REAL8 X2, REAL8 chi1, REAL8 chi2)
1339 const REAL8 xnu = sqrt(1.0-4.0*nu);
1340 const REAL8 Dchi = chi1-chi2;
1341 const REAL8 S = (X1*X1*chi1+X2*X2*chi2)/(X1*X1+X2*X2);
1342 const REAL8 a2 = 3.833;
1343 const REAL8 a3 = -9.49;
1344 const REAL8 a5 = 2.513;
1346 /* The functional form is taken from eq. (7), page 5. */
1347 REAL8 Lorb_spin_zero = (1.3*a3*nu*nu*nu + 5.24*a2*nu*nu + 2.*sqrt(3)*nu)/(2.88*a5*nu + 1);
1349 /* Coeffcients taken from Table II, page 6: */
1355 /* These values are taken from Table III, page 7: */
1359 REAL8 f11 = 0.345225*f21 + 0.0321306*f31 - 3.66556*f50 + 7.5397;
1361 /* These values are taken from Table IV, page 10 */
1367 /* The following quantities were taken from the relation given in eq. (11), */
1368 /* page 7: fi3 = 64 - 64.*fi0 - 16.*fi1 - 4.*fi2; */
1369 REAL8 f13 = 64 - 16.*f11 - 4.*f12;
1370 REAL8 f23 = 64 - 16.*f21 - 4.*f22;
1371 REAL8 f33 = 64 - 16.*f31 - 4.*f32;
1372 REAL8 f53 = 64 - 64.*f50 - 16.*f51;
1374 /* this transformation is given in eq. (9), page (7) */
1375 REAL8 b1t = b1*(f11*nu + f12*nu*nu + f13*nu*nu*nu);
1376 REAL8 b2t = b2*(f21*nu + f22*nu*nu + f23*nu*nu*nu);
1377 REAL8 b3t = b3*(f31*nu + f32*nu*nu + f33*nu*nu*nu);
1378 REAL8 b5t = b5*(f50 + f51*nu + f53*nu*nu*nu);
1380 /* The functional form is taken from eq. (8), page 6. */
1381 REAL8 Lorb_eq_spin = (0.00954*b3t*S*S*S + 0.0851*b2t*S*S - 0.194*b1t*S)/(1 - 0.579*b5t*S);
1383 /* These values are taken from Table IV, page 10: */
1386 REAL8 d20 = -0.0598;
1390 /* The functional form is taken from eq. (19a-c), page 10.*/
1391 REAL8 A1 = d10*xnu*nu*nu*(d11*nu+1);
1392 REAL8 A2 = d20*nu*nu*nu;
1393 REAL8 A3 = d30*xnu*nu*nu*nu*(d31*nu+1);
1395 /* The functional form is taken from eq. (15), page 9. */
1396 REAL8 Lorb_uneq_mass = A1*Dchi + A2*Dchi*Dchi + A3*S*Dchi;
1398 return X1*X1*chi1+X2*X2*chi2 + Lorb_spin_zero + Lorb_eq_spin + Lorb_uneq_mass;
1401 /* logQ-vs-log(lambda) fit of Table I of Yunes-Yagi
1402 here x = log(lambda) and the output is the log of the coefficient
1403 that describes the quadrupole deformation due to spin. */
1406 const REAL8 ai = 0.194;
1407 const REAL8 bi = 0.0936;
1408 const REAL8 ci = 0.0474;
1409 const REAL8 di = -4.21e-3;
1410 const REAL8 ei = 1.23e-4;
1411 const REAL8 x2 = x*x;
1412 const REAL8 x3 = x*x2;
1413 const REAL8 x4 = x*x3;
1414 return ai + bi*x + ci*x2 + di*x3 + ei*x4;
1417 /* Yagi 2013 fits for NS multipolar
1418 \f$\bar{\lambda}_\ell = 2 k_\ell/(C^{2\ell+1} (2\ell-1)!!)\f$
1419 Eq.(9,10),(61); Tab.I; Fig.8 http://arxiv.org/abs/1311.0872 */
1420 REAL8 Yagi13_fit_barlamdel(REAL8 barlam2, int ell)
1422 if (barlam2<=0.) return 0.;
1423 REAL8 lnx = log(barlam2);
1427 coeffs[0] = 2.52e-5;
1428 coeffs[1] = -1.31e-3;
1429 coeffs[2] = 2.51e-2;
1436 coeffs[1] = -1.81e-3;
1437 coeffs[2] = 3.95e-2;
1442 XLAL_ERROR_REAL8(XLAL_EINVAL, "Yagi fits are
for ell=3,4.
");
1443 REAL8 lny = coeffs[0]*lnx*lnx*lnx*lnx+coeffs[1]*lnx*lnx*lnx+coeffs[2]*lnx*lnx+coeffs[3]*lnx+coeffs[4];
1447 /* Yagi 2013 fits for NS multipolar
1448 \f$\bar{\sigma_2}( \bar{\lambda}_2 )\f$
1449 Eq.(9,11),(61); Tab.I; Fig.9 http://arxiv.org/abs/1311.0872
1450 See also later erratum */
1451 REAL8 Yagi13_fit_barsigmalambda(REAL8 barlam2)
1453 if (barlam2<=0.) return 0.;
1454 REAL8 lnx = log(barlam2);
1459 coeffs[2] = 2.81e-2;
1460 coeffs[1] = 3.59e-4;
1461 coeffs[0] = -3.61e-5;
1465 coeffs[2] = 1.68e-2;
1466 coeffs[1] = -1.58e-4;
1467 coeffs[0] = -6.03e-6;
1468 REAL8 lny = coeffs[0]*lnx*lnx*lnx*lnx+coeffs[1]*lnx*lnx*lnx+coeffs[2]*lnx*lnx+coeffs[3]*lnx+coeffs[4];
1470 return -1.0*exp(lny);
1473 /* Yagi et al. fits for C_Oct
1474 Eq. (90) and Table I of https://arxiv.org/abs/1403.6243 */
1475 REAL8 Yagi14_fit_Coct(REAL8 C_Q)
1481 REAL8 cubrootCoct = A0 + B1*pow(C_Q,nu1);
1483 return cubrootCoct*cubrootCoct*cubrootCoct;
1486 /* Yagi et al. fits for C_Hex
1487 Eq. (90) and Table I of https://arxiv.org/abs/1403.6243 */
1488 REAL8 Yagi14_fit_Chex(REAL8 C_Q)
1494 REAL8 fourthrootChex = A0 + B1*pow(C_Q,nu1);
1496 return SQ(SQ(fourthrootChex));
1499 // TODO: Refs needed
1500 REAL8 JFAPG_fit_Sigma_Irrotational(REAL8 barlam2)
1502 if (barlam2<=0.) return 0.;
1503 REAL8 lnx = log(barlam2);
1508 coeffs[3] = 9.69e-3;
1509 coeffs[2] = 1.03e-3;
1510 coeffs[1] = -9.37e-5;
1511 coeffs[0] = 2.24e-6;
1512 REAL8 lny = coeffs[0]*lnx*lnx*lnx*lnx*lnx+coeffs[1]*lnx*lnx*lnx*lnx+coeffs[2]*lnx*lnx*lnx+coeffs[3]*lnx*lnx+coeffs[4]*lnx+coeffs[5];
1514 return -1.0*exp(lny);
1517 // TODO: Refs needed
1518 REAL8 JFAPG_fit_Sigma_Static(REAL8 barlam2)
1520 if (barlam2<=0.) return 0.;
1521 REAL8 lnx = log(barlam2);
1527 coeffs[2] = 1.28e-3;
1528 coeffs[1] = -6.37e-5;
1529 coeffs[0] = 1.18e-6;
1530 REAL8 lny = coeffs[0]*lnx*lnx*lnx*lnx*lnx+coeffs[1]*lnx*lnx*lnx*lnx+coeffs[2]*lnx*lnx*lnx+coeffs[3]*lnx*lnx+coeffs[4]*lnx+coeffs[5];
1535 /* Join two multipolar waveforms at t = to */
1536 void XLALSphHarmPolarJoin (SphHarmPolarTimeSeries *hlma, SphHarmPolarTimeSeries *hlmb, REAL8 to)
1538 /* Time arrays are suppose to be ordered as
1539 hlma->tdata->data: x x x x x x x x x
1540 hlmb->tdata->data: o o o o o o o o o
1542 But they do not need to overlap or be uniformly spaced.
1544 t0 > hlma->time[hlma->size-1] => extend the a waveform
1545 t0 < hlmb->time[0] => join the whole b waveform
1546 Following checks enforce the above structure, if possible.
1548 if (hlma->tdata->data[0] > hlmb->tdata->data[0])
1550 SWAPTRS( hlma, hlmb );
1552 if ((to > hlmb->tdata->data[hlmb->tdata->length-1]) || (to <= hlma->tdata->data[0])) return;
1554 /* Find indexes of closest elements to "to
"
1555 If the two arrays exactly overlap at "to
" this should give:
1556 time_a[ioa] = time_b[iob] */
1557 const int ioa = find_point_bisection(to, hlma->tdata->length, hlma->tdata->data, 1);
1558 int iob = find_point_bisection(to, hlmb->tdata->length, hlmb->tdata->data, 1);
1560 if ( DEQUAL(hlma->tdata->data[ioa], hlmb->tdata->data[iob], 1e-10) ) iob++;
1562 /* Calculate the new size N */
1563 const int N = ioa + hlmb->tdata->length - iob;
1566 XLALResizeSphHarmPolarTimeSeries(hlma, 0, N);
1567 XLALResizeREAL8Sequence(hlma->tdata, 0, N);
1569 /* Copy the relevant part of b into a */
1570 for (int i = ioa; i < N; i++)
1572 hlma->tdata->data[i] = hlmb->tdata->data[iob + i - ioa];
1574 SphHarmPolarTimeSeries *this = hlma;
1575 SphHarmPolarTimeSeries *that = hlmb;
1576 while (this && that)
1578 for (int i = ioa; i < N; i++)
1580 XLAL_CHECK_VOID((this->l==that->l) && (this->m==that->m), XLAL_EFAULT, "Mismatch of
l and
m when joining modes.
");
1581 this->ampl->data->data[i] = that->ampl->data->data[iob + i - ioa];
1582 this->phase->data->data[i] = that->phase->data->data[iob + i - ioa];
1587 XLAL_CHECK_VOID(!this && !that, XLAL_EFAULT, "SphHarmTimeSeries to be joined must have the same set of modes
");
INT4 find_point_bisection(REAL8 x, INT4 n, REAL8 *xp, INT4 o)
void baryc_weights(INT4 n, REAL8 *x, REAL8 *omega)
void interp_spline(double *t, double *y, int n, double *ti, int ni, REAL8 *yi)
INT4 XLALSetup_TEOB_mode_array(LALValue *ModeArray, INT4 modeType)
Should not be needed in LAL (all parameters passed to interface function)
REAL8 baryc_f_weights(REAL8 xx, INT4 n, REAL8 *f, REAL8 *x, REAL8 *omega)
REAL8 q_to_nu(const REAL8 q)
REAL8 baryc_f(REAL8 xx, INT4 n, REAL8 *f, REAL8 *x)
REAL8 Eulerlog(const REAL8 x, const INT4 m)
static const REAL8 Logm[]
REAL8 nu_to_X1(const REAL8 nu)
REAL8 interp1d(const INT4 order, REAL8 xx, INT4 nx, REAL8 *f, REAL8 *x)
INT4 XLALCheck_TEOB_mode_array(LALValue *ModeArray, UINT4 use_tidal)
REAL8 find_max(const INT4 n, REAL8 dx, REAL8 x0, REAL8 *f, REAL8 *fmax)
This file is part of TEOBResumS.
#define LAL_SIM_L_MAX_MODE_ARRAY
Maximum L spherical harmonic mode that is supported in Mode Array.
@ TEOBResumS
Resummed Spin-aligned Tidal EOB.
#define XLAL_ERROR_REAL8(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_CHECK_REAL8(assertion,...)