33 enum {N_POLY_MAX = 100};
34 struct tagLALSimNeutronStarEOSDataPiecewisePolytrope {
36 double rhoTab[N_POLY_MAX];
37 double epsilonTab[N_POLY_MAX];
38 double pTab[N_POLY_MAX];
39 double kTab[N_POLY_MAX];
40 double gammaTab[N_POLY_MAX];
41 double nTab[N_POLY_MAX];
42 double aTab[N_POLY_MAX];
43 double hTab[N_POLY_MAX];
52 int i = eos->data.piecewisePolytrope->nPoly - 1;
54 while (h <= eos->
data.piecewisePolytrope->hTab[
i] &&
i > 0)
61 static double eos_rho_of_h_piecewise_polytrope(
double h,
64 int i = polytrope_index_of_h(h, eos);
65 double enthalpy = exp(h);
66 double k_i = eos->data.piecewisePolytrope->kTab[
i];
67 double n_i = eos->data.piecewisePolytrope->nTab[
i];
68 double a_i = eos->data.piecewisePolytrope->aTab[
i];
71 num = enthalpy - 1.0 - a_i;
72 den = (n_i + 1.0) * k_i;
74 return pow(num / den, n_i);
78 static double eos_p_of_h_piecewise_polytrope(
double h,
81 int i = polytrope_index_of_h(h, eos);
82 double enthalpy = exp(h);
83 double k_i = eos->data.piecewisePolytrope->kTab[
i];
84 double n_i = eos->data.piecewisePolytrope->nTab[
i];
85 double a_i = eos->data.piecewisePolytrope->aTab[
i];
88 num = enthalpy - 1.0 - a_i;
89 den = (n_i + 1.0) * k_i;
91 return k_i * pow(num / den, n_i + 1.0);
95 static double eos_e_of_h_piecewise_polytrope(
double h,
98 int i = polytrope_index_of_h(h, eos);
99 double n_i = eos->data.piecewisePolytrope->nTab[
i];
100 double a_i = eos->data.piecewisePolytrope->aTab[
i];
101 double enthalpy = exp(h);
102 double rho = eos_rho_of_h_piecewise_polytrope(h, eos);
104 double num = 1.0 + a_i + n_i * enthalpy;
105 double den = n_i + 1.0;
107 return rho * num / den;
122 static double eos_v_of_h_piecewise_polytrope(
double h,
125 int i = polytrope_index_of_h(h, eos);
126 double enthalpy = exp(h);
127 double n_i = eos->data.piecewisePolytrope->nTab[
i];
128 double a_i = eos->data.piecewisePolytrope->aTab[
i];
130 return sqrt((enthalpy - 1.0 - a_i) / (n_i * enthalpy));
139 int i = eos->data.piecewisePolytrope->nPoly - 1;
141 while (p <= eos->
data.piecewisePolytrope->pTab[
i] &&
i > 0)
147 static double eos_h_of_p_piecewise_polytrope(
double p,
150 int i = polytrope_index_of_p(p, eos);
151 double k_i = eos->data.piecewisePolytrope->kTab[
i];
152 double n_i = eos->data.piecewisePolytrope->nTab[
i];
153 double a_i = eos->data.piecewisePolytrope->aTab[
i];
156 1.0 + a_i + (n_i + 1.0) * k_i * pow(p / k_i, 1.0 / (n_i + 1.0));
160 return log(enthalpy);
172 static double eos_e_of_p_piecewise_polytrope(
double p,
176 int i = polytrope_index_of_p(p, eos);
177 double k_i = eos->data.piecewisePolytrope->kTab[
i];
178 double n_i = eos->data.piecewisePolytrope->nTab[
i];
179 double a_i = eos->data.piecewisePolytrope->aTab[
i];
181 rho = pow(p / k_i, n_i / (n_i + 1.0));
183 return (1.0 + a_i) * rho + n_i *
p;
187 static double eos_dedp_of_p_piecewise_polytrope(
double p,
191 int i = polytrope_index_of_p(p, eos);
192 double gamma_i = eos->data.piecewisePolytrope->gammaTab[
i];
194 epsilon = eos_e_of_p_piecewise_polytrope(p, eos);
196 return (epsilon + p) / (gamma_i *
p);
215 LALFree(eos->data.piecewisePolytrope);
223 static double eos_min_acausal_pseudo_enthalpy_piecewise_polytrope(
double hmax,
227 int nPoly = eos->data.piecewisePolytrope->nPoly;
228 double n_i, a_i, h_i, h_ip1;
230 double enthalpyMinAcausal;
231 double hMinAcausal = hmax;
238 for (
i = 0;
i < nPoly;
i++) {
239 n_i = eos->data.piecewisePolytrope->nTab[
i];
240 a_i = eos->data.piecewisePolytrope->aTab[
i];
241 h_i = eos->data.piecewisePolytrope->hTab[
i];
247 vSound = eos_v_of_h_piecewise_polytrope(h_i, eos);
254 if (
i == nPoly - 1) {
257 h_ip1 = eos->data.piecewisePolytrope->hTab[
i + 1];
258 vSound = eos_v_of_h_piecewise_polytrope(h_ip1, eos);
261 enthalpyMinAcausal = (1 + a_i) / (1 - n_i);
262 hMinAcausal = log(enthalpyMinAcausal);
274 print_piecewise_polytrope_data(LALSimNeutronStarEOSDataPiecewisePolytrope *
279 printf(
"nPoly = %d\n",
data->nPoly);
282 for (
i = 0;
i <
data->nPoly;
i++)
286 printf(
"rhoTab[i] =\t");
287 for (
i = 0;
i <
data->nPoly;
i++)
288 printf(
"%e\t",
data->rhoTab[
i]);
291 printf(
"epsilonTab[i] =\t");
292 for (
i = 0;
i <
data->nPoly;
i++)
293 printf(
"%e\t",
data->epsilonTab[
i]);
296 printf(
"pTab[i] =\t");
297 for (
i = 0;
i <
data->nPoly;
i++)
298 printf(
"%e\t",
data->pTab[
i]);
301 printf(
"kTab[i] =\t");
302 for (
i = 0;
i <
data->nPoly;
i++)
303 printf(
"%e\t",
data->kTab[
i]);
306 printf(
"gammaTab[i] =\t");
307 for (
i = 0;
i <
data->nPoly;
i++)
308 printf(
"%e\t",
data->gammaTab[
i]);
311 printf(
"nTab[i] =\t");
312 for (
i = 0;
i <
data->nPoly;
i++)
313 printf(
"%e\t",
data->nTab[
i]);
316 printf(
"aTab[i] =\t");
317 for (
i = 0;
i <
data->nPoly;
i++)
318 printf(
"%e\t",
data->aTab[
i]);
321 printf(
"hTab[i] =\t");
322 for (
i = 0;
i <
data->nPoly;
i++)
323 printf(
"%e\t",
data->hTab[
i]);
340 double reference_pressure_si,
double reference_density_si)
343 LALSimNeutronStarEOSDataPiecewisePolytrope *
data;
352 eos->datatype = LALSIM_NEUTRON_STAR_EOS_DATA_TYPE_PIECEWISE_POLYTROPE;
353 eos->data.piecewisePolytrope =
data;
354 if(snprintf(eos->name,
sizeof(eos->name),
355 "Gamma=%g Polytrope (p=%g Pa @ rho=%g kg/m^3)", Gamma,
356 reference_pressure_si, reference_density_si) >= (
signed)
sizeof(eos->name))
360 eos->free = eos_free_piecewise_polytrope;
361 eos->e_of_p = eos_e_of_p_piecewise_polytrope;
362 eos->h_of_p = eos_h_of_p_piecewise_polytrope;
363 eos->e_of_h = eos_e_of_h_piecewise_polytrope;
364 eos->rho_of_h = eos_rho_of_h_piecewise_polytrope;
365 eos->p_of_h = eos_p_of_h_piecewise_polytrope;
366 eos->dedp_of_p = eos_dedp_of_p_piecewise_polytrope;
367 eos->v_of_h = eos_v_of_h_piecewise_polytrope;
370 eos->data.piecewisePolytrope->nPoly = 1;
371 eos->data.piecewisePolytrope->rhoTab[0] = 0.0;
372 eos->data.piecewisePolytrope->epsilonTab[0] = 0.0;
373 eos->data.piecewisePolytrope->pTab[0] = 0.0;
374 eos->data.piecewisePolytrope->kTab[0] =
p / pow(rho, Gamma);
375 eos->data.piecewisePolytrope->gammaTab[0] = Gamma;
376 eos->data.piecewisePolytrope->nTab[0] = 1.0 / (Gamma - 1.0);
377 eos->data.piecewisePolytrope->aTab[0] = 0.0;
378 eos->data.piecewisePolytrope->hTab[0] = 0.0;
382 eos->hmax = eos_h_of_p_piecewise_polytrope(eos->pmax, eos);
385 eos_min_acausal_pseudo_enthalpy_piecewise_polytrope(eos->hmax, eos);
388 print_piecewise_polytrope_data(eos->data.piecewisePolytrope);
389 printf(
"datatype = %d\n", eos->datatype);
390 printf(
"pmax = %e\n", eos->pmax);
391 printf(
"hmax = %e\n", eos->hmax);
392 printf(
"hMinAcausal = %e\n", eos->hMinAcausal);
418 logp1_si,
double gamma1,
double gamma2,
double gamma3)
421 LALSimNeutronStarEOSDataPiecewisePolytrope *
data;
427 double rhoLow[] = { 0, 2.44033979e10, 3.78358138e14, 2.62780487e15 };
429 { 1.0801158752700761e7, 1.311359898998385e10, 6.507604807550857e19,
430 3.053461077133694e8 };
431 double gammaLow[] = { 1.58424999, 1.28732904, 0.62223344, 1.35692395 };
440 double rho0, rho1,
rho2;
444 double rhoJoin1, rhoJoin2, pJoin1, pJoin2, gammaJoin, kJoin;
446 double k_i, rho_i, gamma_i, p_i, n_i, a_i, a_im1, n_im1, epsilon_i,
449 if (gamma1 <= 1.0 || gamma2 <= 1.0 || gamma3 <= 1.0)
451 "Adiabatic indices gamma1=%g, gamma2=%g, and gamma3=%g "
452 "must all be greater than 1", gamma1, gamma2, gamma3);
455 rho1 = pow(10, 17.7);
456 rho2 = pow(10, 18.0);
459 p1 = pow(10, logp1_si);
462 k1 = p1 / pow(rho1, gamma1);
463 k2 = p1 / pow(rho1, gamma2);
464 k3 =
k2 * pow(
rho2, gamma2 - gamma3);
468 rho0 = pow(kLow[3] /
k1, 1.0 / (gamma1 - gammaLow[3]));
470 p1min = kLow[3] * pow(rho1, gammaLow[3]);
471 if (logp1_si < log10(p1min) || logp1_si > 34.5)
473 "logp1_si=%g should be between %g and 34.5", logp1_si,
480 eos->datatype = LALSIM_NEUTRON_STAR_EOS_DATA_TYPE_PIECEWISE_POLYTROPE;
481 eos->data.piecewisePolytrope =
data;
483 if(snprintf(eos->name,
sizeof(eos->name),
"4-Piece Poly (p1=10^%.4g Pa,"
484 "G1=%.4g,G2=%.4g,G3=%.4g)", logp1_si, gamma1, gamma2, gamma3) >= (
int)
sizeof(eos->name))
488 eos->free = eos_free_piecewise_polytrope;
489 eos->e_of_p = eos_e_of_p_piecewise_polytrope;
490 eos->h_of_p = eos_h_of_p_piecewise_polytrope;
491 eos->e_of_h = eos_e_of_h_piecewise_polytrope;
492 eos->rho_of_h = eos_rho_of_h_piecewise_polytrope;
493 eos->p_of_h = eos_p_of_h_piecewise_polytrope;
494 eos->dedp_of_p = eos_dedp_of_p_piecewise_polytrope;
495 eos->v_of_h = eos_v_of_h_piecewise_polytrope;
501 if ((rho0 > rhoLow[3]) && (rho0 < rho1)) {
504 eos->data.piecewisePolytrope->kTab[0] = kLow[0];
505 eos->data.piecewisePolytrope->kTab[1] = kLow[1];
506 eos->data.piecewisePolytrope->kTab[2] = kLow[2];
507 eos->data.piecewisePolytrope->kTab[3] = kLow[3];
508 eos->data.piecewisePolytrope->kTab[4] =
k1;
509 eos->data.piecewisePolytrope->kTab[5] =
k2;
510 eos->data.piecewisePolytrope->kTab[6] =
k3;
512 eos->data.piecewisePolytrope->gammaTab[0] = gammaLow[0];
513 eos->data.piecewisePolytrope->gammaTab[1] = gammaLow[1];
514 eos->data.piecewisePolytrope->gammaTab[2] = gammaLow[2];
515 eos->data.piecewisePolytrope->gammaTab[3] = gammaLow[3];
516 eos->data.piecewisePolytrope->gammaTab[4] = gamma1;
517 eos->data.piecewisePolytrope->gammaTab[5] = gamma2;
518 eos->data.piecewisePolytrope->gammaTab[6] = gamma3;
520 eos->data.piecewisePolytrope->rhoTab[0] = rhoLow[0];
521 eos->data.piecewisePolytrope->rhoTab[1] = rhoLow[1];
522 eos->data.piecewisePolytrope->rhoTab[2] = rhoLow[2];
523 eos->data.piecewisePolytrope->rhoTab[3] = rhoLow[3];
524 eos->data.piecewisePolytrope->rhoTab[4] = rho0;
525 eos->data.piecewisePolytrope->rhoTab[5] = rho1;
526 eos->data.piecewisePolytrope->rhoTab[6] =
rho2;
528 eos->data.piecewisePolytrope->nPoly = 7;
537 pJoin1 = kLow[3] * pow(rhoJoin1, gammaLow[3]);
538 pJoin2 =
k1 * pow(rhoJoin2, gamma1);
541 gammaJoin = log(pJoin2 / pJoin1) / log(rhoJoin2 / rhoJoin1);
543 kJoin = pJoin1 / pow(rhoJoin1, gammaJoin);
546 eos->data.piecewisePolytrope->kTab[0] = kLow[0];
547 eos->data.piecewisePolytrope->kTab[1] = kLow[1];
548 eos->data.piecewisePolytrope->kTab[2] = kLow[2];
549 eos->data.piecewisePolytrope->kTab[3] = kLow[3];
550 eos->data.piecewisePolytrope->kTab[4] = kJoin;
551 eos->data.piecewisePolytrope->kTab[5] =
k1;
552 eos->data.piecewisePolytrope->kTab[6] =
k2;
553 eos->data.piecewisePolytrope->kTab[7] =
k3;
555 eos->data.piecewisePolytrope->gammaTab[0] = gammaLow[0];
556 eos->data.piecewisePolytrope->gammaTab[1] = gammaLow[1];
557 eos->data.piecewisePolytrope->gammaTab[2] = gammaLow[2];
558 eos->data.piecewisePolytrope->gammaTab[3] = gammaLow[3];
559 eos->data.piecewisePolytrope->gammaTab[4] = gammaJoin;
560 eos->data.piecewisePolytrope->gammaTab[5] = gamma1;
561 eos->data.piecewisePolytrope->gammaTab[6] = gamma2;
562 eos->data.piecewisePolytrope->gammaTab[7] = gamma3;
564 eos->data.piecewisePolytrope->rhoTab[0] = rhoLow[0];
565 eos->data.piecewisePolytrope->rhoTab[1] = rhoLow[1];
566 eos->data.piecewisePolytrope->rhoTab[2] = rhoLow[2];
567 eos->data.piecewisePolytrope->rhoTab[3] = rhoLow[3];
568 eos->data.piecewisePolytrope->rhoTab[4] = rhoJoin1;
569 eos->data.piecewisePolytrope->rhoTab[5] = rhoJoin2;
570 eos->data.piecewisePolytrope->rhoTab[6] = rho1;
571 eos->data.piecewisePolytrope->rhoTab[7] =
rho2;
573 eos->data.piecewisePolytrope->nPoly = 8;
575 XLAL_PRINT_INFO(
"An extra polytrope was used to join the low and high density regions.");
579 for (
i = 0;
i < eos->data.piecewisePolytrope->nPoly;
i++) {
581 gamma_i = eos->data.piecewisePolytrope->gammaTab[
i];
582 eos->data.piecewisePolytrope->kTab[
i] *=
584 2.0 * gamma_i - 4.0);
588 for (
i = 0;
i < eos->data.piecewisePolytrope->nPoly;
i++) {
589 k_i = eos->data.piecewisePolytrope->kTab[
i];
590 rho_i = eos->data.piecewisePolytrope->rhoTab[
i];
591 gamma_i = eos->data.piecewisePolytrope->gammaTab[
i];
593 p_i = k_i * pow(rho_i, gamma_i);
594 n_i = 1.0 / (gamma_i - 1.0);
599 a_im1 = eos->data.piecewisePolytrope->aTab[
i - 1];
600 n_im1 = eos->data.piecewisePolytrope->nTab[
i - 1];
601 a_i = a_im1 + (n_im1 - n_i) * p_i / rho_i;
604 epsilon_i = (1.0 + a_i) * rho_i + n_i * p_i;
609 enthalpy_i = 1.0 + a_i + (n_i + 1) * p_i / rho_i;
611 h_i = log(enthalpy_i);
613 eos->data.piecewisePolytrope->pTab[
i] = p_i;
614 eos->data.piecewisePolytrope->nTab[
i] = n_i;
615 eos->data.piecewisePolytrope->aTab[
i] = a_i;
616 eos->data.piecewisePolytrope->epsilonTab[
i] = epsilon_i;
617 eos->data.piecewisePolytrope->hTab[
i] = h_i;
621 eos->hmax = eos_h_of_p_piecewise_polytrope(eos->pmax, eos);
623 eos_min_acausal_pseudo_enthalpy_piecewise_polytrope(eos->hmax, eos);
626 print_piecewise_polytrope_data(eos->data.piecewisePolytrope);
627 printf(
"datatype = %d\n", eos->datatype);
628 printf(
"pmax = %e\n", eos->pmax);
629 printf(
"hmax = %e\n", eos->hmax);
630 printf(
"hMinAcausal = %e\n", eos->hMinAcausal);
#define LAL_G_C2_SI
Factor to convert density in kg/m^3 to geometerized units of m^-2.
#define LAL_NUCLEAR_DENSITY_GEOM_SI
Nuclear density in geometrized units of m^-2.
struct tagLALSimNeutronStarEOS LALSimNeutronStarEOS
Incomplete type for the neutron star Equation of State (EOS).
#define LAL_G_C4_SI
Factor to convert pressure in Pa to geometerized units of m^-2.
LALSimNeutronStarEOS * XLALSimNeutronStarEOSPolytrope(double Gamma, double reference_pressure_si, double reference_density_si)
Creates a polytrope Equation of State defined by p = K rho^Gamma.
LALSimNeutronStarEOS * XLALSimNeutronStarEOS4ParameterPiecewisePolytrope(double logp1_si, double gamma1, double gamma2, double gamma3)
Creates a 4-parameter piecewise-polytrope Equation of State.
#define XLAL_PRINT_INFO(...)
#define XLAL_ERROR_NULL(...)
#define XLAL_PRINT_WARNING(...)