![]() |
Equation of State Sub-Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TOV_EOS_H 00024 #define O2SCL_TOV_EOS_H 00025 00026 #include <cmath> 00027 #include <iostream> 00028 #include <fstream> 00029 00030 #include <o2scl/constants.h> 00031 #include <o2scl/funct.h> 00032 #include <o2scl/multi_funct.h> 00033 #include <o2scl/mm_funct.h> 00034 #include <o2scl/lib_settings.h> 00035 #include <o2scl/table_units.h> 00036 00037 #include <o2scl/mroot.h> 00038 #include <o2scl/ode_step.h> 00039 #include <o2scl/minimize.h> 00040 #include <o2scl/gsl_min_brent.h> 00041 #include <o2scl/gsl_mroot_hybrids.h> 00042 #include <o2scl/ode_funct.h> 00043 #include <o2scl/gsl_astep.h> 00044 00045 #ifndef DOXYGENP 00046 namespace o2scl { 00047 #endif 00048 00049 /** \brief A EOS base class for the TOV solver 00050 00051 \todo Fix read_table_file and maybe set_low_density_eos(). 00052 */ 00053 class tov_eos { 00054 00055 protected: 00056 00057 /// To convert MeV to kilograms 00058 double mev_kg; 00059 00060 /// To convert \f$ MeV/fm{^3} \f$ to solar masses per cubic kilometer 00061 double mev_per_fm3_msun_km3; 00062 00063 public: 00064 00065 tov_eos() { 00066 baryon_column=false; 00067 verbose=1; 00068 mev_kg=1.0e3*gsl_cgs::electron_volt/gsl_cgs::speed_of_light/ 00069 gsl_cgs::speed_of_light; 00070 mev_per_fm3_msun_km3=mev_kg/gsl_mks::solar_mass*1.0e54; 00071 } 00072 00073 virtual ~tov_eos() {} 00074 00075 /// Control for output (default 1) 00076 int verbose; 00077 00078 /** \brief Given the pressure, produce the energy and number densities 00079 00080 The arguments \c P and \c e should always be in 00081 \f$ M_{\odot}/\mathrm{km}^3 \f$ . 00082 00083 If the baryon density is not specified, it should be set to 00084 zero or \ref baryon_column should be set to false. 00085 */ 00086 virtual int get_eden(double P, double &e, double &nb)=0; 00087 00088 /** \brief Given the pressure, produce all the remaining quantities 00089 00090 The argument \c P should always be in 00091 \f$ M_{\odot}/\mathrm{km}^3 \f$ . 00092 */ 00093 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00094 np=0; 00095 return 0; 00096 } 00097 00098 /** \brief Fill a list with strings for the names of the remaining 00099 quanities 00100 */ 00101 virtual int get_names_units(size_t &np, 00102 std::vector<std::string> &pnames, 00103 std::vector<std::string> &punits) { 00104 np=0; 00105 return 0; 00106 } 00107 00108 /** \brief Set to true if the baryon density is provided in the 00109 EOS (default false) 00110 */ 00111 bool baryon_column; 00112 00113 }; 00114 00115 /** \brief An EOS for the TOV solver using simple linear interpolation 00116 and a default low-density EOS 00117 00118 Internally, energy and pressure are stored in units of solar 00119 masses per cubic kilometer and baryon density is stored in units 00120 of fm^{-3}. The user-specified EOS table is left as is, and unit 00121 conversion is performed as needed in get_eden() and other 00122 functions so that results are returned in the units specified by 00123 set_units(). 00124 00125 \note This stores a pointer to the user-specified table, 00126 so if that pointer becomes invalid, the interpolation will 00127 fail. 00128 00129 The function set_units() needs to be called before either of the 00130 functions get_eden() or get_eden_ld() are called. The function 00131 set_units() may be called after calling either the read_table() 00132 functions or the set_low_density_eos() function. 00133 00134 \todo Warn that the pressure in the low-density eos is not 00135 strictly increasing! (see at P=4.3e-10) 00136 \todo It might be useful to exit more gracefully when non-finite 00137 values are obtained in interpolation, analogous to the 00138 err_nonconv mechanism elsewhere. 00139 00140 */ 00141 class tov_interp_eos : public tov_eos { 00142 00143 public: 00144 00145 tov_interp_eos(); 00146 00147 virtual ~tov_interp_eos() {} 00148 00149 /** \brief Given the pressure, produce the energy and number densities 00150 00151 The arguments \c P and \c e should always be in 00152 \f$ M_{\odot}/\mathrm{km}^3 \f$ . 00153 00154 If the baryon density is not specified, it should be set to 00155 zero or \ref baryon_column should be set to false. 00156 */ 00157 virtual int get_eden(double pres, double &ed, double &nb); 00158 00159 /** \brief Given the pressure, produce the energy and number 00160 densities from the user-specified EOS 00161 00162 The arguments \c pres, \c ed, and \c nb should be 00163 in the user-specified unit system. 00164 */ 00165 virtual int get_eden_user(double pres, double &ed, double &nb); 00166 00167 /** \brief Given the pressure, produce the energy and number 00168 densities from the low-density EOS 00169 00170 The arguments \c pres, \c ed, and \c nb should be 00171 in the user-specified unit system. 00172 */ 00173 virtual int get_eden_ld(double pres, double &ed, double &nb); 00174 00175 /** \brief Given the pressure, produce all the remaining quantities 00176 00177 The argument \c P should always be in 00178 \f$ M_{\odot}/\mathrm{km}^3 \f$ . 00179 */ 00180 virtual int get_aux(double P, size_t &nv, ovector_base &auxp); 00181 00182 /** \brief Fill a list with strings for the names of the remaining 00183 quanities 00184 */ 00185 virtual int get_names_units(size_t &np, 00186 std::vector<std::string> &pnames, 00187 std::vector<std::string> &punits); 00188 00189 /// Specify the EOS through a table 00190 int read_table(table_units &eosat, std::string s_cole, 00191 std::string s_colp, std::string s_colnb=""); 00192 00193 /** \brief Set the low-density EOS 00194 */ 00195 int set_low_density_eos(std::string s_nvpath, 00196 int s_nvcole=0, int s_nvcolp=1, int s_nvcolnb=2); 00197 00198 /// Default low-density EOS 00199 int default_low_dens_eos(); 00200 00201 /// Compute with no low-density EOS 00202 int no_low_dens_eos() { 00203 ldeos=false; 00204 return 0; 00205 } 00206 00207 /** \brief Set the units of the user-specified EOS 00208 */ 00209 int set_units(double s_efactor, double s_pfactor, 00210 double s_nfactor); 00211 00212 /** \brief Set the units of the user-specified EOS 00213 */ 00214 int set_units(std::string leunits="", 00215 std::string lpunits="", std::string lnunits=""); 00216 00217 /** \brief Return limiting and transition pressures 00218 00219 Returns, in order: 00220 - the highest pressure in the low-density EOS 00221 - the transition pressure 00222 - the lowest pressure in the high-density EOS 00223 */ 00224 int get_transition(double &plow, double &ptrans, double &phi); 00225 00226 /** \brief Set the transition pressure and "width" 00227 00228 Sets the transition pressure and the width (specified as a 00229 number greater than unity in \c pw) of the transition between 00230 the two EOSs. The transition is done smoothly using linear 00231 interpolation between \f$ P=\mathrm{ptrans}/pmathrm{pw} \f$ 00232 and \f$ P=\mathrm{ptrans} \times pmathrm{pw} \f$. 00233 */ 00234 int set_transition(double ptrans, double pw); 00235 00236 #ifndef DOXYGEN_INTERNAL 00237 00238 protected: 00239 00240 /// Check that the EOS is valid 00241 int check_eos(); 00242 00243 /// \name Low-density EOS 00244 //@{ 00245 00246 /// true if we are using the low-density eos (false) 00247 bool ldeos; 00248 00249 /** \brief Low-density EOS switch 00250 00251 This is \c true if the ldeos has been read by set_ldeos. This 00252 is useful, since then we know whether or not we need 00253 to free the memory for the LD EOS in the destructor 00254 */ 00255 bool ldeos_read; 00256 00257 /// the path to the low-density EOS 00258 std::string ldpath; 00259 /// column in low-density eos for energy density 00260 int ldcole; 00261 /// column in low-density eos for pressure 00262 int ldcolp; 00263 /// column in low-density eos for baryon density 00264 int ldcolnb; 00265 /// file containing low-density EOS 00266 table_units *ld_eos; 00267 00268 /** \brief Highest pressure in low-density EOS 00269 (in \f$ M_{\odot}/\mathrm{km}^3 \f$) 00270 */ 00271 double presld; 00272 /** \brief Highest energy density in low-density EOS 00273 (in \f$ M_{\odot}/\mathrm{km}^3 \f$) 00274 */ 00275 double eld; 00276 /** \brief Highest baryon density in low-density EOS 00277 (in \f$ M_{\odot}/\mathrm{km}^3 \f$) 00278 */ 00279 double nbld; 00280 00281 /** \brief Transition pressure 00282 (in \f$ M_{\odot}/\mathrm{km}^3 \f$) 00283 */ 00284 double prest; 00285 /// Transition width (unitless) 00286 double pwidth; 00287 //@} 00288 00289 /// \name User EOS 00290 //@{ 00291 00292 /// file containing eos 00293 table_units *eost; 00294 00295 /// number of lines in eos file 00296 int nfile; 00297 00298 /// column for energy density in eos file 00299 int cole; 00300 /// column for pressure in eos file 00301 int colp; 00302 /// column for baryon density in eos file 00303 int colnb; 00304 00305 /// True if an EOS has been specified 00306 bool eos_read; 00307 //@} 00308 00309 /// \name Units 00310 //@{ 00311 00312 /// Units for energy density 00313 std::string eunits; 00314 /// Units for pressure 00315 std::string punits; 00316 /// Units for baryon density 00317 std::string nunits; 00318 00319 /// unit conversion factor for energy density (default 1.0) 00320 double efactor; 00321 /// unit conversion factor for pressure (default 1.0) 00322 double pfactor; 00323 /// unit conversion factor for baryon density (default 1.0) 00324 double nfactor; 00325 00326 //@} 00327 00328 /// Linear EOS interpolation 00329 void interp(const ovector_base &x, const ovector_base &y, 00330 double xx, double &yy, int n1, int n2); 00331 00332 #endif 00333 00334 }; 00335 00336 /** \brief The Buchdahl EOS for the TOV solver 00337 00338 Given the eos 00339 \f[ 00340 \rho = 12 \sqrt{p_{*} P}- 5 P 00341 \f] 00342 the TOV equation has an analytical solution 00343 \f[ 00344 R=(1-\beta) \sqrt{\frac{\pi}{288 p_{*} G (1-2 \beta)}} 00345 \f] 00346 where \f$ \beta = GM/R \f$. 00347 00348 The central pressure and energy density are 00349 \f[ 00350 P_c = 36 p_{*} \beta^2 00351 \f] 00352 \f[ 00353 {\rho}_c = 72 p_{*} \beta (1-5 \beta/2) 00354 \f] 00355 00356 Physical solutions are obtained only for \f$ P< 25 p_{*}/144 \f$ 00357 and \f$ \beta<1/6 \f$ . 00358 00359 Based on \ref Lattimer01. 00360 00361 \future Figure out what to do with the buchfun() function 00362 */ 00363 class tov_buchdahl_eos : public tov_eos { 00364 00365 public: 00366 00367 tov_buchdahl_eos() { 00368 Pstar=3.2e-5; 00369 } 00370 00371 virtual ~tov_buchdahl_eos() {} 00372 00373 /** \brief The parameter with units of pressure in units of solar 00374 masses per km cubed (default value \f$ 3.2 \times 10^{-5} \f$ 00375 ) 00376 */ 00377 double Pstar; 00378 00379 /** \brief Given the pressure, produce the energy and number densities 00380 00381 If the baryon density is not specified, it should be set to 00382 zero or \ref baryon_column should be set to false 00383 */ 00384 virtual int get_eden(double P, double &e, double &nb) { 00385 e=12.0*sqrt(Pstar*P)-5.0*P; 00386 nb=0.0; 00387 return 0; 00388 } 00389 00390 /// Given the pressure, produce all the remaining quantities 00391 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00392 np=0; 00393 return 0; 00394 } 00395 00396 /** \brief Fill a list with strings for the names of the remaining 00397 quanities 00398 */ 00399 virtual int get_names(size_t &np, std::vector<std::string> &pnames) { 00400 np=0; 00401 return 0; 00402 } 00403 00404 #ifdef O2SCL_NEVER_DEFINED 00405 00406 int buchfun(size_t bv, const ovector_base &bx, ovector_base &by, 00407 int &pa) { 00408 double u, rp; 00409 u=bx[0]; 00410 rp=bx[1]; 00411 by[0]=rp*(1.0-beta+u)/(1.0-2.0*beta)-buchrad; 00412 by[1]=beta/biga/rp*sin(biga*rp); 00413 return gsl_success; 00414 } 00415 00416 #endif 00417 00418 }; 00419 00420 /** \brief Standard polytropic EOS \f$ p = K \rho^{1+1/n} \f$ 00421 00422 Any units are permissible, but if this is to be used with \ref 00423 tov_solve, then the units of \f$ K \f$ must be consistent with 00424 the units set in \ref tov_solve::set_units(). 00425 */ 00426 class tov_polytrope_eos : public tov_eos { 00427 00428 public: 00429 00430 tov_polytrope_eos() { 00431 K=1.0; 00432 n=3.0; 00433 } 00434 00435 virtual ~tov_polytrope_eos() {} 00436 00437 /** \brief Coefficient (default 1.0) 00438 */ 00439 double K; 00440 00441 /// Index (default 3.0) 00442 double n; 00443 00444 /** \brief Given the pressure, produce the energy and number densities 00445 00446 If the baryon density is not specified, it should be set to 00447 zero or \ref baryon_column should be set to false 00448 */ 00449 virtual int get_eden(double P, double &e, double &nb) { 00450 e=pow(P/K,1.0/(1.0+1.0/n)); 00451 nb=0.0; 00452 return 0; 00453 } 00454 00455 /// Given the pressure, produce all the remaining quantities 00456 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00457 np=0; 00458 return 0; 00459 } 00460 00461 /** \brief Fill a list with strings for the names of the remaining 00462 quanities 00463 */ 00464 virtual int get_names(size_t &np, std::vector<std::string> &pnames) { 00465 np=0; 00466 return 0; 00467 } 00468 00469 }; 00470 00471 #ifndef DOXYGENP 00472 } 00473 #endif 00474 00475 #endif 00476 00477
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).