LALSimulation  5.4.0.1-fe68b98
LALSimNeutronStarFamily.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 J. Creighton
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with with program; see the file COPYING. If not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA 02110-1301 USA
18  */
19 /**
20  * @author Jolien Creighton
21  * @addtogroup LALSimNeutronStarFamily_c
22  * @brief Provides routines for one-parameter families of neutron stars of
23  * a given equation of state.
24  * @{
25  */
26 
27 #include <math.h>
28 #include <gsl/gsl_errno.h>
29 #include <gsl/gsl_interp.h>
30 #include <gsl/gsl_min.h>
31 GSL_VAR const gsl_interp_type * lal_gsl_interp_steffen;
32 
33 #include <lal/LALStdlib.h>
34 #include <lal/LALSimNeutronStar.h>
35 
36 /** @cond */
37 
38 /* Contents of the neutron star family structure. */
39 struct tagLALSimNeutronStarFamily {
40  double *pdat;
41  double *mdat;
42  double *rdat;
43  double *kdat;
44  size_t ndat;
45  gsl_interp *p_of_m_interp;
46  gsl_interp *r_of_m_interp;
47  gsl_interp *k_of_m_interp;
48  gsl_interp_accel *p_of_m_acc;
49  gsl_interp_accel *r_of_m_acc;
50  gsl_interp_accel *k_of_m_acc;
51 };
52 
53 /* gsl function for use in finding the maximum neutron star mass */
54 static double fminimizer_gslfunction(double x, void * params);
55 static double fminimizer_gslfunction(double x, void * params)
56 {
58  double r, m, k;
59  XLALSimNeutronStarTOVODEIntegrate(&r, &m, &k, x, eos);
60  return -m; /* maximum mass is minimum negative mass */
61 }
62 
63 /** @endcond */
64 
65 /**
66  * @brief Frees the memory associated with a pointer to a neutron star family.
67  * @param fam Pointer to the neutron star family structure to be freed.
68  */
70 {
71  if (fam) {
72  gsl_interp_accel_free(fam->k_of_m_acc);
73  gsl_interp_accel_free(fam->r_of_m_acc);
74  gsl_interp_accel_free(fam->p_of_m_acc);
75  gsl_interp_free(fam->k_of_m_interp);
76  gsl_interp_free(fam->r_of_m_interp);
77  gsl_interp_free(fam->p_of_m_interp);
78  LALFree(fam->kdat);
79  LALFree(fam->rdat);
80  LALFree(fam->mdat);
81  LALFree(fam->pdat);
82  LALFree(fam);
83  }
84  return;
85 }
86 
87 /**
88  * @brief Creates a neutron star family structure for a given equation of state.
89  * @details
90  * A neutron star family is a one-parameter family of neturon stars for a
91  * fixed equation of state. The one parameter is the neutron star central
92  * pressure, or, equivalently, the mass of the neutron star. The family
93  * is terminated at the maximum neutron star mass for the specified equation
94  * of state, so the mass can be used as the family parameter.
95  * @param eos Pointer to the Equation of State structure.
96  * @return A pointer to the neutron star family structure.
97  */
100 {
102  const size_t ndatmax = 100;
103  const double logpmin = 75.5;
104  double logpmax;
105  double dlogp;
106  size_t ndat = ndatmax;
107  size_t i;
108 
109  /* allocate memory */
110  fam = LALMalloc(sizeof(*fam));
111  if (!fam)
113  fam->pdat = LALMalloc(ndat * sizeof(*fam->pdat));
114  fam->mdat = LALMalloc(ndat * sizeof(*fam->mdat));
115  fam->rdat = LALMalloc(ndat * sizeof(*fam->rdat));
116  fam->kdat = LALMalloc(ndat * sizeof(*fam->kdat));
117  if (!fam->mdat || !fam->rdat || !fam->kdat)
119 
120  /* compute data tables */
121  logpmax = log(XLALSimNeutronStarEOSMaxPressure(eos));
122  dlogp = (logpmax - logpmin) / ndat;
123  for (i = 0; i < ndat; ++i) {
124  fam->pdat[i] = exp(logpmin + i * dlogp);
125  XLALSimNeutronStarTOVODEIntegrate(&fam->rdat[i], &fam->mdat[i],
126  &fam->kdat[i], fam->pdat[i], eos);
127  /* determine if maximum mass has been found */
128  if (i > 0 && fam->mdat[i] <= fam->mdat[i-1])
129  break;
130  }
131 
132  if (i < ndat) {
133  /* replace the ith point with the maximum mass */
134  const double epsabs = 0.0, epsrel = 1e-6;
135  double a = fam->pdat[i - 2];
136  double x = fam->pdat[i - 1];
137  double b = fam->pdat[i];
138  double fa = -fam->mdat[i - 2];
139  double fx = -fam->mdat[i - 1];
140  double fb = -fam->mdat[i];
141  int status;
142  gsl_function F;
143  gsl_min_fminimizer * s;
144  F.function = &fminimizer_gslfunction;
145  F.params = eos;
146  s = gsl_min_fminimizer_alloc(gsl_min_fminimizer_brent);
147  gsl_min_fminimizer_set_with_values(s, &F, x, fx, a, fa, b, fb);
148  do {
149  status = gsl_min_fminimizer_iterate(s);
150  x = gsl_min_fminimizer_x_minimum(s);
151  a = gsl_min_fminimizer_x_lower(s);
152  b = gsl_min_fminimizer_x_upper(s);
153  status = gsl_min_test_interval(a, b, epsabs, epsrel);
154  } while (status == GSL_CONTINUE);
155  gsl_min_fminimizer_free(s);
156  fam->pdat[i] = x;
157  XLALSimNeutronStarTOVODEIntegrate(&fam->rdat[i], &fam->mdat[i],
158  &fam->kdat[i], fam->pdat[i], eos);
159 
160  /* resize arrays */
161  if(fam->pdat[i] <= fam->pdat[i-1]){
162  fam->pdat[i-1] = fam->pdat[i];
163  ndat = i;
164  }
165  else{
166  ndat = i + 1;
167  }
168 
169  fam->pdat = LALRealloc(fam->pdat, ndat * sizeof(*fam->pdat));
170  fam->mdat = LALRealloc(fam->mdat, ndat * sizeof(*fam->mdat));
171  fam->rdat = LALRealloc(fam->rdat, ndat * sizeof(*fam->rdat));
172  fam->kdat = LALRealloc(fam->kdat, ndat * sizeof(*fam->kdat));
173  }
174  fam->ndat = ndat;
175 
176  /* setup interpolators */
177 
178  fam->p_of_m_acc = gsl_interp_accel_alloc();
179  fam->r_of_m_acc = gsl_interp_accel_alloc();
180  fam->k_of_m_acc = gsl_interp_accel_alloc();
181 
182  fam->p_of_m_interp = gsl_interp_alloc(gsl_interp_cspline, ndat);
183  fam->r_of_m_interp = gsl_interp_alloc(lal_gsl_interp_steffen, ndat);
184  fam->k_of_m_interp = gsl_interp_alloc(lal_gsl_interp_steffen, ndat);
185 
186  gsl_interp_init(fam->p_of_m_interp, fam->mdat, fam->pdat, ndat);
187  gsl_interp_init(fam->r_of_m_interp, fam->mdat, fam->rdat, ndat);
188  gsl_interp_init(fam->k_of_m_interp, fam->mdat, fam->kdat, ndat);
189 
190  return fam;
191 }
192 
193 /**
194  * @brief Returns the minimum mass of a neutron star family.
195  * @param fam Pointer to the neutron star family structure.
196  * @return The maximum mass of the neutron star family (kg).
197  */
199 {
200  return fam->mdat[0];
201 }
202 
203 /**
204  * @brief Returns the maximum mass of a neutron star family.
205  * @param fam Pointer to the neutron star family structure.
206  * @return The maximum mass of the neutron star family (kg).
207  */
209 {
210  return fam->mdat[fam->ndat - 1];
211 }
212 
213 /**
214  * @brief Returns the central pressure of a neutron star of mass @a m.
215  * @param m The mass of the neutron star (kg).
216  * @param fam Pointer to the neutron star family structure.
217  * @return The central pressure of the neutron star (Pa).
218  */
221 {
222  double p;
223  p = gsl_interp_eval(fam->p_of_m_interp, fam->mdat, fam->pdat, m,
224  fam->p_of_m_acc);
225  return p;
226 }
227 
228 /**
229  * @brief Returns the radius of a neutron star of mass @a m.
230  * @param m The mass of the neutron star (kg).
231  * @param fam Pointer to the neutron star family structure.
232  * @return The radius of the neutron star (m).
233  */
235 {
236  double r;
237  r = gsl_interp_eval(fam->r_of_m_interp, fam->mdat, fam->rdat, m,
238  fam->r_of_m_acc);
239  return r;
240 }
241 
242 /**
243  * @brief Returns the tidal Love number k2 of a neutron star of mass @a m.
244  * @param m The mass of the neutron star (kg).
245  * @param fam Pointer to the neutron star family structure.
246  * @return The dimensionless tidal Love number k2.
247  */
249 {
250  double k;
251  k = gsl_interp_eval(fam->k_of_m_interp, fam->mdat, fam->kdat, m,
252  fam->k_of_m_acc);
253  return k;
254 }
255 
256 /** @} */
#define LALRealloc(p, n)
#define LALMalloc(n)
#define LALFree(p)
struct tagLALSimNeutronStarFamily LALSimNeutronStarFamily
Incomplete type for a neutron star family having a particular EOS.
struct tagLALSimNeutronStarEOS LALSimNeutronStarEOS
Incomplete type for the neutron star Equation of State (EOS).
int s
Definition: bh_qnmode.c:137
double i
Definition: bh_ringdown.c:118
double e
Definition: bh_ringdown.c:117
double XLALSimNeutronStarEOSMaxPressure(LALSimNeutronStarEOS *eos)
Returns the maximum pressure of the EOS in Pa.
double XLALSimNeutronStarLoveNumberK2(double m, LALSimNeutronStarFamily *fam)
Returns the tidal Love number k2 of a neutron star of mass m.
void XLALDestroySimNeutronStarFamily(LALSimNeutronStarFamily *fam)
Frees the memory associated with a pointer to a neutron star family.
double XLALSimNeutronStarRadius(double m, LALSimNeutronStarFamily *fam)
Returns the radius of a neutron star of mass m.
GSL_VAR const gsl_interp_type * lal_gsl_interp_steffen
double XLALSimNeutronStarFamMinimumMass(LALSimNeutronStarFamily *fam)
Returns the minimum mass of a neutron star family.
double XLALSimNeutronStarCentralPressure(double m, LALSimNeutronStarFamily *fam)
Returns the central pressure of a neutron star of mass m.
LALSimNeutronStarFamily * XLALCreateSimNeutronStarFamily(LALSimNeutronStarEOS *eos)
Creates a neutron star family structure for a given equation of state.
double XLALSimNeutronStarMaximumMass(LALSimNeutronStarFamily *fam)
Returns the maximum mass of a neutron star family.
int XLALSimNeutronStarTOVODEIntegrate(double *radius, double *mass, double *love_number_k2, double central_pressure_si, LALSimNeutronStarEOS *eos)
static const INT4 r
static const INT4 m
static const INT4 a
#define XLAL_ERROR_NULL(...)
XLAL_ENOMEM
list x
list p
string status
Definition: burst.c:245