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.");
435 if (sym_mass_ratio <= 0.25){
436 x = 1.0 - 4.0 * sym_mass_ratio;
437 mass_ratio = 0.5 * (1. - pow(
x, 0.5)) / sym_mass_ratio - 1.0;
456 c = pow((chirp_mass / component_mass), 5);
457 x = 1.5 * pow((3.0/
c), 0.5);
459 mass_ratio = 3.0 * cos(acos(
x) / 3.0) /
x;
480 REAL8 sym_mass_ratio;
481 REAL8 mass_difference;
503 mass1 = mass2 / mass_ratio;
508 mass1 = mass2 / mass_ratio;
512 mass1 = mass2 + mass_difference;
516 mass1 = total_mass - mass2;
520 mass1 = reduced_mass * mass2 / (mass2 - reduced_mass);
525 mass1 = mass2 / mass_ratio;
532 mass1 = total_mass / (1. + mass_ratio);
537 mass1 = total_mass / (1. + mass_ratio);
541 mass1 = 0.5 * (total_mass + mass_difference);
545 if (total_mass < 4.0 * reduced_mass){
548 x = total_mass * (total_mass - 4.0 * reduced_mass);
549 mass_difference = pow(
x, 0.5);
550 mass1 = total_mass - 0.5 * (total_mass - mass_difference);
554 sym_mass_ratio = pow((chirp_mass / total_mass), 5.0/3.0);
556 mass1 = total_mass / (1.0 + mass_ratio);
563 mass1 = (1. + mass_ratio) * reduced_mass / mass_ratio;
568 mass1 = (1. + mass_ratio) * reduced_mass / mass_ratio;
572 x = 4.0 * pow(reduced_mass,2) + pow(mass_difference,2);
573 mass1 = reduced_mass + 0.5 * mass_difference + 0.5 * pow(
x, 0.5);
577 total_mass = pow(pow(chirp_mass, 5) / pow(reduced_mass, 3), 0.5);
578 x = total_mass * (total_mass - 4.0 * reduced_mass);
580 mass_difference = pow(
x, 0.5);
581 mass1 = total_mass - 0.5 * (total_mass - mass_difference);
590 XLAL_CHECK(fabs(mass_difference) > 0,
XLAL_EDOM,
"Mass difference cannot be zero if it is combined with a dimensionless mass parameter.");
593 mass1 = mass_difference / (1.0 - mass_ratio);
594 XLAL_CHECK(mass1 > 0,
XLAL_EDOM,
"Inconsistent values of mass_difference and mass_ratio.");
599 if (mass_difference < 0){
600 mass_ratio = 1./mass_ratio;
602 mass1 = mass_difference / (1.0 - mass_ratio);
611 double chirp_mass_5 = pow(chirp_mass, 5);
612 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 };
613 double complex m2[6];
615 gsl_poly_complex_workspace *
w = gsl_poly_complex_workspace_alloc(7);
616 gsl_poly_complex_solve(coefficients, 7,
w, (
double *)m2);
617 gsl_poly_complex_workspace_free(
w);
622 if(cimag(m2[
i]) == 0 && creal(m2[
i])>0){
623 mass1 = creal(m2[
i]) + mass_difference;
624 if (mass1 > 0)
break;
634 sym_mass_ratio = mass_ratio / pow((1.0 + mass_ratio), 2);
635 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
636 mass1 = total_mass / (1.0 + mass_ratio);
641 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
642 mass1 = total_mass / (1.0 + mass_ratio);
661 REAL8 sym_mass_ratio;
662 REAL8 mass_difference;
681 mass2 = mass1 * mass_ratio;
686 mass2 = mass1 * mass_ratio;
690 mass2 = mass1 - mass_difference;
694 mass2 = total_mass - mass1;
698 mass2 = reduced_mass * mass1 / (mass1 - reduced_mass);
703 mass2 = mass1 * mass_ratio;
711 mass2 = total_mass / (1. + mass_ratio) * mass_ratio;
716 mass2 = total_mass / (1. + mass_ratio) * mass_ratio;
720 mass2 = 0.5 * (total_mass - mass_difference);
724 if (total_mass < 4.0 * reduced_mass){
727 x = total_mass * (total_mass - 4.0 * reduced_mass);
728 mass_difference = pow(
x, 0.5);
729 mass2 = 0.5 * (total_mass - mass_difference);
733 sym_mass_ratio = pow((chirp_mass / total_mass), 5.0/3.0);
735 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
743 mass2 = (1. + mass_ratio) * reduced_mass;
748 mass2 = (1. + mass_ratio) * reduced_mass;
752 x = 4.0 * pow(reduced_mass,2) + pow(mass_difference,2);
753 mass2 = reduced_mass + 0.5 * mass_difference + 0.5 * pow(
x, 0.5) - mass_difference;
757 total_mass = pow(pow(chirp_mass, 5) / pow(reduced_mass, 3), 0.5);
758 x = total_mass * (total_mass - 4.0 * reduced_mass);
760 mass_difference = pow(
x, 0.5);
761 mass2 = 0.5 * (total_mass - mass_difference);
771 XLAL_CHECK(fabs(mass_difference) > 0,
XLAL_EDOM,
"Mass difference cannot be zero if it is combined with a dimensionless mass parameter.");
774 mass2 = mass_difference / (1.0 - mass_ratio) * mass_ratio;
775 XLAL_CHECK(mass2 > 0,
XLAL_EDOM,
"Inconsistent values of mass_difference and mass_ratio.");
780 if (mass_difference < 0){
781 mass_ratio = 1./mass_ratio;
783 mass2 = mass_ratio * mass_difference / (1.0 - mass_ratio);
792 double chirp_mass_5 = pow(chirp_mass, 5);
793 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 };
794 double complex m2[6];
796 gsl_poly_complex_workspace *
w = gsl_poly_complex_workspace_alloc(7);
797 gsl_poly_complex_solve(coefficients, 7,
w, (
double *)m2);
798 gsl_poly_complex_workspace_free(
w);
803 if(cimag(m2[
i]) == 0 && creal(m2[
i])>0){
804 mass1 = creal(m2[
i]) + mass_difference;
806 mass2 = creal(m2[
i]);
818 sym_mass_ratio = mass_ratio / pow((1.0 + mass_ratio), 2);
819 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
820 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
825 total_mass = chirp_mass / pow(sym_mass_ratio, 3.0/5.0);
826 mass2 = total_mass / (1.0 + mass_ratio) * mass_ratio;
848 total_mass = mass1 + mass2;
866 mass_ratio = mass2 / mass1;
875 REAL8 sym_mass_ratio;
879 XLAL_CHECK(sym_mass_ratio > 0 && sym_mass_ratio <= 0.25,
XLAL_EDOM,
"sym_mass_ratio must be between (0, 0.25]");
884 sym_mass_ratio = mass1 * mass2 / pow(mass1 + mass2, 2);
886 return sym_mass_ratio;
902 chirp_mass = pow(mass1 * mass2, 3.0 / 5.0) / pow(mass1 + mass2, 1.0 / 5.0);
911 REAL8 mass_difference;
919 mass_difference = mass1 - mass2;
921 return mass_difference;
937 reduced_mass = mass1 * mass2 / (mass1 + mass2);
950 spinx = spin_norm * sin(spin_tilt) * cos(spin_phi);
958 spiny = spin_norm * sin(spin_tilt) * sin(spin_phi);
965 spinz = spin_norm * cos(spin_tilt);
972 spin_norm = sqrt(spinx* spinx+ spiny* spiny+ spinz * spinz);
979 spin_tilt = acos(spinz / sqrt(spinx* spinx+ spiny* spiny+ spinz * spinz));
986 spin_phi = atan(spiny / spinz);
1014 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1x. Assuming zero as a default value. \n");
1037 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1y. Assuming zero as a default value. \n");
1057 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin1z. Assuming zero as a default value. \n");
1080 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2x. Assuming zero as a default value. \n");
1103 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2y. Assuming zero as a default value. \n");
1123 XLAL_PRINT_WARNING(
"Not enough information provided to determine spin2z. Assuming zero as a default value. \n");
1131 REAL8 spin1_norm = -1;
1152 REAL8 spin1_tilt = -1;
1174 REAL8 spin1_phi = -1;
1194 REAL8 spin2_norm = -1;
1215 REAL8 spin2_tilt = -1;
1236 REAL8 spin2_phi = -1;
1274 LALValue * value = NULL;
1286 LALValue * value = NULL;
1749LALDict*
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(...)