28 #include <lal/LALSimReadData.h>
29 #include <gsl/gsl_interp.h>
30 #include <lal/LALSimNeutronStar.h>
35 struct tagLALSimNeutronStarEOSDataTabular {
48 gsl_interp *log_e_of_log_p_interp;
49 gsl_interp *log_h_of_log_p_interp;
50 gsl_interp *log_e_of_log_h_interp;
51 gsl_interp *log_p_of_log_h_interp;
52 gsl_interp *log_rho_of_log_h_interp;
53 gsl_interp *log_p_of_log_e_interp;
54 gsl_interp *log_p_of_log_rho_interp;
55 gsl_interp *log_cs2_of_log_h_interp;
56 gsl_interp_accel *log_e_of_log_p_acc;
57 gsl_interp_accel *log_h_of_log_p_acc;
58 gsl_interp_accel *log_e_of_log_h_acc;
59 gsl_interp_accel *log_p_of_log_h_acc;
60 gsl_interp_accel *log_rho_of_log_h_acc;
61 gsl_interp_accel *log_p_of_log_e_acc;
62 gsl_interp_accel *log_p_of_log_rho_acc;
63 gsl_interp_accel *log_cs2_of_log_h_acc;
73 if (log_e < eos->
data.tabular->log_edat[0])
75 return exp(eos->data.tabular->log_pdat[0] + (5.0 / 3.0) * (log_e - eos->data.tabular->log_edat[0]));
76 log_p = gsl_interp_eval(eos->data.tabular->log_p_of_log_e_interp,
77 eos->data.tabular->log_edat, eos->data.tabular->log_pdat, log_e,
78 eos->data.tabular->log_p_of_log_e_acc);
89 if (log_rho < eos->
data.tabular->log_rhodat[0])
91 return exp(eos->data.tabular->log_pdat[0] + (5.0 / 3.0) * (log_rho - eos->data.tabular->log_rhodat[0]));
92 log_p = gsl_interp_eval(eos->data.tabular->log_p_of_log_rho_interp,
93 eos->data.tabular->log_rhodat, eos->data.tabular->log_pdat, log_rho,
94 eos->data.tabular->log_p_of_log_rho_acc);
105 if (log_p < eos->
data.tabular->log_pdat[0])
107 return exp(eos->data.tabular->log_edat[0] + (3.0 / 5.0) * (log_p - eos->data.tabular->log_pdat[0]));
108 log_e = gsl_interp_eval(eos->data.tabular->log_e_of_log_p_interp,
109 eos->data.tabular->log_pdat, eos->data.tabular->log_edat, log_p,
110 eos->data.tabular->log_e_of_log_p_acc);
121 if (log_h < eos->
data.tabular->log_hdat[0])
123 return exp(eos->data.tabular->log_edat[0] + 1.5 * (log_h - eos->data.tabular->log_hdat[0]));
124 log_e = gsl_interp_eval(eos->data.tabular->log_e_of_log_h_interp,
125 eos->data.tabular->log_hdat, eos->data.tabular->log_edat, log_h,
126 eos->data.tabular->log_e_of_log_h_acc);
137 if (log_h < eos->
data.tabular->log_hdat[0])
139 return exp(eos->data.tabular->log_pdat[0] + 2.5 * (log_h - eos->data.tabular->log_hdat[0]));
140 log_p = gsl_interp_eval(eos->data.tabular->log_p_of_log_h_interp,
141 eos->data.tabular->log_hdat, eos->data.tabular->log_pdat, log_h,
142 eos->data.tabular->log_p_of_log_h_acc);
153 if (log_h < eos->
data.tabular->log_hdat[0])
155 return exp(eos->data.tabular->log_rhodat[0] + 1.5 * (log_h - eos->data.tabular->log_hdat[0]));
156 log_rho = gsl_interp_eval(eos->data.tabular->log_rho_of_log_h_interp,
157 eos->data.tabular->log_hdat, eos->data.tabular->log_rhodat, log_h,
158 eos->data.tabular->log_rho_of_log_h_acc);
169 if (log_p < eos->
data.tabular->log_pdat[0])
171 return exp(eos->data.tabular->log_hdat[0] + 0.4 * (log_p - eos->data.tabular->log_pdat[0]));
172 log_h = gsl_interp_eval(eos->data.tabular->log_h_of_log_p_interp,
173 eos->data.tabular->log_pdat, eos->data.tabular->log_hdat, log_p,
174 eos->data.tabular->log_h_of_log_p_acc);
182 double d_log_e_d_log_p;
183 if (p == 0 || (log_p = log(p)) < eos->data.tabular->log_pdat[0])
185 return (3.0 / 5.0) * exp(eos->data.tabular->log_edat[0] - eos->data.tabular->log_pdat[0]);
186 log_e = gsl_interp_eval(eos->data.tabular->log_e_of_log_p_interp,
187 eos->data.tabular->log_pdat, eos->data.tabular->log_edat, log_p,
188 eos->data.tabular->log_e_of_log_p_acc);
189 d_log_e_d_log_p = gsl_interp_eval_deriv(eos->data.tabular->log_e_of_log_p_interp,
190 eos->data.tabular->log_pdat, eos->data.tabular->log_edat, log_p,
191 eos->data.tabular->log_e_of_log_p_acc);
192 return d_log_e_d_log_p * exp(log_e - log_p);
197 double p, dedp, log_cs2, log_h;
198 if (eos->data.tabular->ncol == 2)
200 p = eos_p_of_h_tabular(h, eos);
201 dedp = eos_dedp_of_p_tabular(p, eos);
202 return pow(dedp, -0.5);
205 log_cs2 = gsl_interp_eval(eos->data.tabular->log_cs2_of_log_h_interp,
206 eos->data.tabular->log_hdat, eos->data.tabular->log_cs2dat, log_h,
207 eos->data.tabular->log_cs2_of_log_h_acc);
209 return pow(exp(log_cs2), -0.5);
222 static void eos_free_tabular_data(LALSimNeutronStarEOSDataTabular *
data)
225 gsl_interp_free(
data->log_e_of_log_p_interp);
226 gsl_interp_free(
data->log_e_of_log_h_interp);
227 gsl_interp_free(
data->log_p_of_log_h_interp);
228 gsl_interp_free(
data->log_h_of_log_p_interp);
229 gsl_interp_free(
data->log_rho_of_log_h_interp);
230 gsl_interp_free(
data->log_p_of_log_e_interp);
231 gsl_interp_free(
data->log_p_of_log_rho_interp);
232 gsl_interp_free(
data->log_cs2_of_log_h_interp);
233 gsl_interp_accel_free(
data->log_e_of_log_p_acc);
234 gsl_interp_accel_free(
data->log_e_of_log_h_acc);
235 gsl_interp_accel_free(
data->log_p_of_log_h_acc);
236 gsl_interp_accel_free(
data->log_h_of_log_p_acc);
237 gsl_interp_accel_free(
data->log_rho_of_log_h_acc);
238 gsl_interp_accel_free(
data->log_p_of_log_e_acc);
239 gsl_interp_accel_free(
data->log_p_of_log_rho_acc);
240 gsl_interp_accel_free(
data->log_cs2_of_log_h_acc);
257 eos_free_tabular_data(eos->data.tabular);
273 static double eos_min_acausal_pseudo_enthalpy_tabular(
double hmax,
280 double hMinAcausal = hmax;
282 h_im1 = exp(eos->data.tabular->log_hdat[0]);
283 v_im1 = eos_v_of_h_tabular(h_im1, eos);
284 for (
i = 1;
i < eos->data.tabular->ndat;
i++) {
285 h_i = exp(eos->data.tabular->log_hdat[
i]);
286 v_i = eos_v_of_h_tabular(h_i, eos);
289 m = (v_i - v_im1) / (h_i - h_im1);
290 hMinAcausal = h_im1 + (1.0 - v_im1) /
m;
304 double *mubdat,
double *muedat,
double *hdat,
double *yedat,
double *cs2dat,
size_t ndat,
size_t ncol)
307 LALSimNeutronStarEOSDataTabular *
data;
313 eos->datatype = LALSIM_NEUTRON_STAR_EOS_DATA_TYPE_TABULAR;
314 eos->data.tabular =
data;
317 eos->free = eos_free_tabular;
318 eos->e_of_p = eos_e_of_p_tabular;
319 eos->h_of_p = eos_h_of_p_tabular;
320 eos->e_of_h = eos_e_of_h_tabular;
321 eos->p_of_h = eos_p_of_h_tabular;
322 eos->rho_of_h = eos_rho_of_h_tabular;
323 eos->p_of_e = eos_p_of_e_tabular;
324 eos->p_of_rho = eos_p_of_rho_tabular;
325 eos->dedp_of_p = eos_dedp_of_p_tabular;
326 eos->v_of_h = eos_v_of_h_tabular;
332 while (*pdat == 0.0 || *edat == 0.0) {
345 for (
i = 0;
i < ndat; ++
i) {
346 data->log_pdat[
i] = log(pdat[
i]);
347 data->log_edat[
i] = log(edat[
i]);
358 integrand =
LALMalloc(ndat *
sizeof(*integrand));
359 for (
i = 0;
i < ndat; ++
i)
360 integrand[
i] = exp(
data->log_pdat[
i] + log(1.0 / (edat[
i] + pdat[
i])));
362 gsl_interp_accel * dhdp_of_p_acc_temp = gsl_interp_accel_alloc();
363 gsl_interp * dhdp_of_p_interp_temp = gsl_interp_alloc(gsl_interp_linear, ndat);
364 gsl_interp_init(dhdp_of_p_interp_temp,
data->log_pdat, integrand, ndat);
366 data->log_hdat[0] = log(pdat[0] / (edat[0] + pdat[0]));
367 for (
i = 1;
i < ndat; ++
i)
368 data->log_hdat[
i] = log(exp(
data->log_hdat[0]) + gsl_interp_eval_integ(dhdp_of_p_interp_temp,
data->log_pdat, integrand,
data->log_pdat[0],
data->log_pdat[
i], dhdp_of_p_acc_temp));
370 gsl_interp_free(dhdp_of_p_interp_temp);
371 gsl_interp_accel_free(dhdp_of_p_acc_temp);
376 while (*pdat == 0.0 || *edat == 0.0 || *hdat == 0.0) {
384 data->ncol = ncol - 1;
395 for (
i = 0;
i < ndat; ++
i) {
396 data->nbdat[
i] = nbdat[
i];
397 data->log_pdat[
i] = log(pdat[
i]);
398 data->log_edat[
i] = log(edat[
i]);
399 data->mubdat[
i] = mubdat[
i];
400 data->muedat[
i] = muedat[
i];
401 data->log_hdat[
i] = log(hdat[
i]);
402 data->yedat[
i] = yedat[
i];
403 data->log_cs2dat[
i] = log(cs2dat[
i]);
407 data->log_cs2_of_log_h_acc = gsl_interp_accel_alloc();
408 data->log_cs2_of_log_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
409 gsl_interp_init(
data->log_cs2_of_log_h_interp,
data->log_hdat,
data->log_cs2dat, ndat);
413 for (
i = 0;
i < ndat;
i++)
414 data->log_rhodat[
i] = log(edat[
i] + pdat[
i]) - exp(
data->log_hdat[
i]);
416 eos->pmax = exp(
data->log_pdat[ndat - 1]);
417 eos->hmax = exp(
data->log_hdat[ndat - 1]);
421 data->log_e_of_log_p_acc = gsl_interp_accel_alloc();
422 data->log_h_of_log_p_acc = gsl_interp_accel_alloc();
423 data->log_e_of_log_h_acc = gsl_interp_accel_alloc();
424 data->log_p_of_log_h_acc = gsl_interp_accel_alloc();
425 data->log_rho_of_log_h_acc = gsl_interp_accel_alloc();
426 data->log_p_of_log_e_acc = gsl_interp_accel_alloc();
427 data->log_p_of_log_rho_acc = gsl_interp_accel_alloc();
429 data->log_e_of_log_p_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
430 data->log_h_of_log_p_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
431 data->log_e_of_log_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
432 data->log_p_of_log_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
433 data->log_rho_of_log_h_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
434 data->log_p_of_log_e_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
435 data->log_p_of_log_rho_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
437 gsl_interp_init(
data->log_e_of_log_p_interp,
data->log_pdat,
data->log_edat, ndat);
438 gsl_interp_init(
data->log_h_of_log_p_interp,
data->log_pdat,
data->log_hdat, ndat);
439 gsl_interp_init(
data->log_e_of_log_h_interp,
data->log_hdat,
data->log_edat, ndat);
440 gsl_interp_init(
data->log_p_of_log_h_interp,
data->log_hdat,
data->log_pdat, ndat);
441 gsl_interp_init(
data->log_rho_of_log_h_interp,
data->log_hdat,
data->log_rhodat, ndat);
442 gsl_interp_init(
data->log_p_of_log_e_interp,
data->log_edat,
data->log_pdat, ndat);
443 gsl_interp_init(
data->log_p_of_log_rho_interp,
data->log_rhodat,
data->log_pdat, ndat);
446 eos_min_acausal_pseudo_enthalpy_tabular(eos->hmax, eos);
497 if (ndat == (
size_t) (-1))
500 nbdat =
LALMalloc(ndat *
sizeof(*nbdat));
503 mubdat =
LALMalloc(ndat *
sizeof(*mubdat));
504 muedat =
LALMalloc(ndat *
sizeof(*muedat));
506 yedat =
LALMalloc(ndat *
sizeof(*yedat));
507 cs2dat =
LALMalloc(ndat *
sizeof(*cs2dat));
512 for (
size_t i = 0 ;
i < ndat ;
i++) {
513 nbdat[
i] = f_dat[
i * ncol + 1];
516 mubdat[
i] = f_dat[
i * ncol + 4];
517 muedat[
i] = f_dat[
i * ncol + 5];
518 hdat[
i] = f_dat[
i * ncol + 6];
519 yedat[
i] = f_dat[
i * ncol + 7];
520 cs2dat[
i] = f_dat[
i * ncol + 8];
525 for (
size_t i = 0 ;
i < ndat ;
i++) {
526 pdat[
i] = f_dat[
i * ncol];
527 edat[
i] = f_dat[
i * ncol + 1];
538 fprintf(stderr,
"error: equation of state files must have at least 2 columns, ncol >= 2\n");
543 eos = eos_alloc_tabular(nbdat, edat, pdat, mubdat, muedat, hdat, yedat, cs2dat, ndat, ncol);
555 snprintf(eos->name,
sizeof(eos->name),
"%s", fname);
644 static const char fname_base[] =
"LALSimNeutronStarEOS_";
645 static const char fname_extn[] =
".dat";
649 char fname[FILENAME_MAX];
651 for (
i = 0;
i < n ; ++
i)
665 for (
i = 1;
i < n ; ++
i)
#define LAL_G_C2_SI
Factor to convert density in kg/m^3 to geometerized 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.
size_t XLALSimReadDataFileNCol(double **data, size_t *ncol, LALFILE *fp)
Read a multi-column data file.
LALFILE * XLALSimReadDataFileOpen(const char *fname)
Opens a specified data file, searching default path if necessary.
int XLALFileClose(LALFILE *file)
void * XLALMalloc(size_t n)
const char *const lalSimNeutronStarEOSNames[111]
Recognised names of equations of state.
LALSimNeutronStarEOS * XLALSimNeutronStarEOSByName(const char *name)
Creates an equation of state structure from tabulated equation of state data of a known name.
LALSimNeutronStarEOS * XLALSimNeutronStarEOSFromFile(const char *fname)
Reads a data file containing a tabulated equation of state.
int XLALStringCaseCompare(const char *s1, const char *s2)
#define XLAL_ERROR_NULL(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_PRINT_ERROR(...)