1#include <lal/LALStdio.h>
2#include <lal/LALDict.h>
3#include <lal/LALSimInspiral.h>
4#include <lal/LALSimInspiralWaveformFlags.h>
5#include <lal/LALSimInspiralWaveformParams.h>
7#include <gsl/gsl_poly.h>
16#define UNREVIEWED_CODE_WARNING \
17 int debug_level = XLALGetDebugLevel(); \
18 XLALClobberDebugLevel(2); \
19 XLAL_PRINT_WARNING("This code is currently UNREVIEWED, use with caution!"); \
20 XLALClobberDebugLevel(debug_level);
24#define DEFINE_INSERT_FUNC(NAME, TYPE, KEY, DEFAULT) \
25 int XLALSimInspiralWaveformParamsInsert ## NAME(LALDict *params, TYPE value) \
27 return XLALDictInsert ## TYPE ## Value(params, KEY, value); \
30#define DEFINE_LOOKUP_FUNC(NAME, TYPE, KEY, DEFAULT) \
31 TYPE XLALSimInspiralWaveformParamsLookup ## NAME(LALDict *params) \
33 TYPE value = DEFAULT; \
34 if (params && XLALDictContains(params, KEY)) \
35 value = XLALDictLookup ## TYPE ## Value(params, KEY); \
39#define DEFINE_ISDEFAULT_FUNC(NAME, TYPE, KEY, DEFAULT) \
40 int XLALSimInspiralWaveformParams ## NAME ## IsDefault(LALDict *params) \
42 return XLALSimInspiralWaveformParamsLookup ## NAME(params) == DEFAULT; \
47#define DEFINE_INSERT_FUNC(NAME, TYPE, KEY, DEFAULT) \
48 int XLALSimInspiralWaveformParamsInsert ## NAME(LALDict *params, TYPE value);
50#define DEFINE_LOOKUP_FUNC(NAME, TYPE, KEY, DEFAULT) \
51 TYPE XLALSimInspiralWaveformParamsLookup ## NAME(LALDict *params);
53#define DEFINE_ISDEFAULT_FUNC(NAME, TYPE, KEY, DEFAULT) \
54 int XLALSimInspiralWaveformParams ## NAME ## IsDefault(LALDict *params);
62#define String const char *
74 for(
size_t i = 0;
i < num_par;
i++) {
90 UINT2 nodim_number = 0;
92 const char *dimensionful_masses[6] = {
"mass1",
"mass2",
"total_mass", \
93 "chirp_mass",
"mass_difference",
"reduced_mass"};
94 const char *dimensionless_masses[2] = {
"mass_ratio",
"sym_mass_ratio"};
95 const char *symetric_masses[6] = {
"mass1",
"mass2",
"total_mass",
"chirp_mass",
"sym_mass_ratio",
"reduced_mass"};
97 for (
size_t j = 0; j <
sizeof(dimensionful_masses)/
sizeof(*dimensionful_masses); ++j){
102 for (
size_t j = 0; j <
sizeof(dimensionless_masses)/
sizeof(*dimensionless_masses); ++j){
107 for (
size_t j = 0; j <
sizeof(symetric_masses)/
sizeof(*symetric_masses); ++j){
116 if ((dim_number == 2 && nodim_number == 0) || (dim_number == 1 && nodim_number == 1)){
122 else if ((dim_number == 1 && nodim_number == 0) || dim_number == 0){
124 " one dimensionless and one dimensionful mass parameters, or two dimensionful masses.");
128 " one dimensionless and one dimensionful mass parameters, or two dimensionful masses.");
431 if (sym_mass_ratio <= 0.25){
432 x = 1.0 - 4.0 * sym_mass_ratio;
433 mass_ratio = 0.5 * (1. - pow(
x, 0.5)) / sym_mass_ratio - 1.0;
452 c = pow((chirp_mass / component_mass), 5);
453 x = 1.5 * pow((3.0/
c), 0.5);
455 mass_ratio = 3.0 * cos(acos(
x) / 3.0) /
x;
476 REAL8 sym_mass_ratio;
477 REAL8 mass_difference;
499 mass1 = mass2 / mass_ratio;
504 mass1 = mass2 / mass_ratio;
508 mass1 = mass2 + mass_difference;
512 mass1 = total_mass - mass2;
516 mass1 = reduced_mass * mass2 / (mass2 - reduced_mass);
521 mass1 = mass2 / mass_ratio;
528 mass1 = total_mass / (1. + mass_ratio);
533 mass1 = total_mass / (1. + mass_ratio);
537 mass1 = 0.5 * (total_mass + mass_difference);
541 if (total_mass < 4.0 * reduced_mass){
544 x = total_mass * (total_mass - 4.0 * reduced_mass);
545 mass_difference = pow(
x, 0.5);
546 mass1 = total_mass - 0.5 * (total_mass - mass_difference);
550 sym_mass_ratio = pow((chirp_mass / total_mass), 5.0/3.0);
552 mass1 = total_mass / (1.0 + mass_ratio);
559 mass1 = (1. + mass_ratio) * reduced_mass / mass_ratio;
564 mass1 = (1. + mass_ratio) * reduced_mass / mass_ratio;
568 x = 4.0 * pow(reduced_mass,2) + pow(mass_difference,2);
569 mass1 = reduced_mass + 0.5 * mass_difference + 0.5 * pow(
x, 0.5);
573 total_mass = pow(pow(chirp_mass, 5) / pow(reduced_mass, 3), 0.5);
574 x = total_mass * (total_mass - 4.0 * reduced_mass);
576 mass_difference = pow(
x, 0.5);
577 mass1 = total_mass - 0.5 * (total_mass - mass_difference);
586 XLAL_CHECK(fabs(mass_difference) > 0,
XLAL_EDOM,
"Mass difference cannot be zero if it is combined with a dimensionless mass parameter.");
589 mass1 = mass_difference / (1.0 - mass_ratio);
590 XLAL_CHECK(mass1 > 0,
XLAL_EDOM,
"Inconsistent values of mass_difference and mass_ratio.");
595 if (mass_difference < 0){
596 mass_ratio = 1./mass_ratio;
598 mass1 = mass_difference / (1.0 - mass_ratio);
607 double chirp_mass_5 = pow(chirp_mass, 5);
608 double coefficients[7] = { -mass_difference * chirp_mass_5, -2 * chirp_mass_5, 0, pow(mass_difference, 3), 3 * pow(mass_difference, 2), 3 * mass_difference, 1 };
609 double complex m2[6];
611 gsl_poly_complex_workspace *
w = gsl_poly_complex_workspace_alloc(7);
612 gsl_poly_complex_solve(coefficients, 7,
w, (
double *)m2);
613 gsl_poly_complex_workspace_free(
w);
618 if(cimag(m2[
i]) == 0 && creal(m2[
i])>0){
619 mass1 = creal(m2[
i]) + mass_difference;
620 if (mass1 > 0)
break;
630 sym_mass_ratio = mass_ratio / pow((1.0 + mass_ratio), 2);
631 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
632 mass1 = total_mass / (1.0 + mass_ratio);
637 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
638 mass1 = total_mass / (1.0 + mass_ratio);
657 REAL8 sym_mass_ratio;
658 REAL8 mass_difference;
677 mass2 = mass1 * mass_ratio;
682 mass2 = mass1 * mass_ratio;
686 mass2 = mass1 - mass_difference;
690 mass2 = total_mass - mass1;
694 mass2 = reduced_mass * mass1 / (mass1 - reduced_mass);
699 mass2 = mass1 * mass_ratio;
707 mass2 = total_mass / (1. + mass_ratio) * mass_ratio;
712 mass2 = total_mass / (1. + mass_ratio) * mass_ratio;
716 mass2 = 0.5 * (total_mass - mass_difference);
720 if (total_mass < 4.0 * reduced_mass){
723 x = total_mass * (total_mass - 4.0 * reduced_mass);
724 mass_difference = pow(
x, 0.5);
725 mass2 = 0.5 * (total_mass - mass_difference);
729 sym_mass_ratio = pow((chirp_mass / total_mass), 5.0/3.0);
731 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
739 mass2 = (1. + mass_ratio) * reduced_mass;
744 mass2 = (1. + mass_ratio) * reduced_mass;
748 x = 4.0 * pow(reduced_mass,2) + pow(mass_difference,2);
749 mass2 = reduced_mass + 0.5 * mass_difference + 0.5 * pow(
x, 0.5) - mass_difference;
753 total_mass = pow(pow(chirp_mass, 5) / pow(reduced_mass, 3), 0.5);
754 x = total_mass * (total_mass - 4.0 * reduced_mass);
756 mass_difference = pow(
x, 0.5);
757 mass2 = 0.5 * (total_mass - mass_difference);
767 XLAL_CHECK(fabs(mass_difference) > 0,
XLAL_EDOM,
"Mass difference cannot be zero if it is combined with a dimensionless mass parameter.");
770 mass2 = mass_difference / (1.0 - mass_ratio) * mass_ratio;
771 XLAL_CHECK(mass2 > 0,
XLAL_EDOM,
"Inconsistent values of mass_difference and mass_ratio.");
776 if (mass_difference < 0){
777 mass_ratio = 1./mass_ratio;
779 mass2 = mass_ratio * mass_difference / (1.0 - mass_ratio);
788 double chirp_mass_5 = pow(chirp_mass, 5);
789 double coefficients[7] = { -mass_difference * chirp_mass_5, -2 * chirp_mass_5, 0, pow(mass_difference, 3), 3 * pow(mass_difference, 2), 3 * mass_difference, 1 };
790 double complex m2[6];
792 gsl_poly_complex_workspace *
w = gsl_poly_complex_workspace_alloc(7);
793 gsl_poly_complex_solve(coefficients, 7,
w, (
double *)m2);
794 gsl_poly_complex_workspace_free(
w);
799 if(cimag(m2[
i]) == 0 && creal(m2[
i])>0){
800 mass1 = creal(m2[
i]) + mass_difference;
802 mass2 = creal(m2[
i]);
814 sym_mass_ratio = mass_ratio / pow((1.0 + mass_ratio), 2);
815 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
816 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
821 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
822 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
844 total_mass = mass1 + mass2;
862 mass_ratio = mass2 / mass1;
871 REAL8 sym_mass_ratio;
875 XLAL_CHECK(sym_mass_ratio > 0 && sym_mass_ratio <= 0.25,
XLAL_EDOM,
"sym_mass_ratio must be between (0, 0.25]");
880 sym_mass_ratio = mass1 * mass2 / pow(mass1 + mass2, 2);
882 return sym_mass_ratio;
898 chirp_mass = pow(mass1 * mass2, 3.0 / 5.0) / pow(mass1 + mass2, 1.0 / 5.0);
907 REAL8 mass_difference;
915 mass_difference = mass1 - mass2;
917 return mass_difference;
933 reduced_mass = mass1 * mass2 / (mass1 + mass2);
946 spinx = spin_norm * sin(spin_tilt) * cos(spin_phi);
954 spiny = spin_norm * sin(spin_tilt) * sin(spin_phi);
961 spinz = spin_norm * cos(spin_tilt);
968 spin_norm = sqrt(spinx* spinx+ spiny* spiny+ spinz * spinz);
975 spin_tilt = acos(spinz / sqrt(spinx* spinx+ spiny* spiny+ spinz * spinz));
982 spin_phi = atan(spiny / spinz);
1010 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1x. Assuming zero as a default value. \n");
1033 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1y. Assuming zero as a default value. \n");
1053 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1z. Assuming zero as a default value. \n");
1076 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2x. Assuming zero as a default value. \n");
1099 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2y. Assuming zero as a default value. \n");
1119 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2z. Assuming zero as a default value. \n");
1127 REAL8 spin1_norm = -1;
1148 REAL8 spin1_tilt = -1;
1170 REAL8 spin1_phi = -1;
1190 REAL8 spin2_norm = -1;
1211 REAL8 spin2_tilt = -1;
1232 REAL8 spin2_phi = -1;
1270 LALValue * value = NULL;
1282 LALValue * value = NULL;
1737LALDict*
XLALSimInspiralParamsDict(const
REAL8 m1, const
REAL8 m2, const
REAL8 S1x, const
REAL8 S1y, const
REAL8 S1z, const
REAL8 S2x, const
REAL8 S2y, const
REAL8 S2z, const
REAL8 distance, const
REAL8 inclination, const
REAL8 phiRef, const
REAL8 longAscNodes, const
REAL8 eccentricity, const
REAL8 f_ref, LALDict *LALparams)
int XLALDictContains(const LALDict *dict, const char *key)
LALDictEntry * XLALDictLookup(const LALDict *dict, const char *key)
LALDict * XLALDictDuplicate(const LALDict *orig)
int XLALDictInsertValue(LALDict *dict, const char *key, const LALValue *value)
const LALValue * XLALDictEntryGetValue(const LALDictEntry *entry)
REAL8 XLALDictLookupREAL8Value(const LALDict *dict, const char *key)
LALValue * XLALValueDuplicate(const LALValue *value)
#define LAL_DEFAULT_F_ECC
@ LAL_SIM_INSPIRAL_MODES_CHOICE_ALL
Include all available modes.
@ LAL_SIM_INSPIRAL_GETIDES_GSF23
@ LAL_SIM_INSPIRAL_FRAME_AXIS_ORBITAL_L
Set z-axis along the initial orbital angular momentum.
@ LAL_SIM_INSPIRAL_GMTIDES_PN
@ Eccentricity
UNDOCUMENTED.
#define XLAL_ERROR_REAL8(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_PRINT_WARNING(...)