00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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/collection.h> 00036 #include <o2scl/table_units.h> 00037 #include <o2scl/base_ioc.h> 00038 00039 #include <o2scl/mroot.h> 00040 #include <o2scl/odestep.h> 00041 #include <o2scl/minimize.h> 00042 #include <o2scl/gsl_min_brent.h> 00043 #include <o2scl/gsl_mroot_hybrids.h> 00044 #include <o2scl/ode_funct.h> 00045 #include <o2scl/gsl_astep.h> 00046 00047 #ifndef DOXYGENP 00048 namespace o2scl { 00049 #endif 00050 00051 /** 00052 \brief A EOS base class for the TOV solver 00053 */ 00054 class tov_eos { 00055 00056 public: 00057 00058 tov_eos() { 00059 baryon_column=false; 00060 verbose=1; 00061 } 00062 00063 virtual ~tov_eos() {} 00064 00065 /// control for output (default 1) 00066 int verbose; 00067 00068 /** 00069 \brief Given the pressure, produce the energy and number densities 00070 00071 If the baryon density is not specified, it should be set to 00072 zero or \ref baryon_column should be set to false 00073 */ 00074 virtual int get_eden(double P, double &e, double &nb) { 00075 return 0; 00076 } 00077 00078 /// Given the pressure, produce all the remaining quantities 00079 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00080 np=0; 00081 return 0; 00082 } 00083 00084 /** 00085 \brief Fill a list with strings for the names of the remaining 00086 quanities 00087 */ 00088 virtual int get_names(size_t &np, std::vector<std::string> &pnames) { 00089 np=0; 00090 return 0; 00091 } 00092 00093 /** 00094 \brief Set to true if the baryon density is provided in the 00095 EOS (default false) 00096 */ 00097 bool baryon_column; 00098 00099 }; 00100 00101 /** 00102 \brief An EOS for the TOV solver using simple linear interpolation 00103 and a default low-density EOS 00104 00105 Internally, energy and pressure are stored in units of solar 00106 masses per cubic kilometer and baryon density is stored in units 00107 of fm^{-3}. The user-specified EOS table is left as is, and unit 00108 conversion is performed as needed in get_eden() and other 00109 functions so that results are returned in the units specified by 00110 set_units(). 00111 00112 The function set_units() needs to be called before either of the 00113 functions get_eden() or get_eden_ld() are called. The function 00114 set_units() may be called after calling either the read_table() 00115 functions or the set_low_density_eos() function. 00116 00117 \todo Warn that the pressure in the low-density eos is not 00118 strictly increasing! (see at P=4.3e-10) 00119 00120 */ 00121 class tov_interp_eos : public tov_eos { 00122 00123 public: 00124 00125 tov_interp_eos(); 00126 00127 virtual ~tov_interp_eos() {} 00128 00129 /// Given the pressure, produce the energy and number densities 00130 virtual int get_eden(double pres, double &ed, double &nb); 00131 00132 /** 00133 \brief Given the pressure, produce the energy and number 00134 densities from the user-specified EOS 00135 */ 00136 virtual int get_eden_user(double pres, double &ed, double &nb); 00137 00138 /** 00139 \brief Given the pressure, produce the energy and number 00140 densities from the low-density EOS 00141 */ 00142 virtual int get_eden_ld(double pres, double &ed, double &nb); 00143 00144 /// Given the pressure, produce all the remaining quantities 00145 virtual int get_aux(double P, size_t &nv, ovector_base &auxp); 00146 00147 /** 00148 \brief Fill a list with strings for the names of the remaining 00149 quanities 00150 */ 00151 virtual int get_names(size_t &np, std::vector<std::string> &pnames); 00152 00153 /// Specify the EOS through a table 00154 int read_table(table &eosat, std::string s_cole="ed", 00155 std::string s_colp="pr", std::string s_colnb="nb"); 00156 00157 /// Specify the EOS through a table in a file 00158 int read_table_file(std::string eosfn, std::string s_cole="ed", 00159 std::string s_colp="pr", std::string s_colnb="nb"); 00160 00161 /** 00162 \brief Set the low-density EOS 00163 */ 00164 int set_low_density_eos(bool s_ldeos, std::string s_nvpath, 00165 int s_nvcole=0, int s_nvcolp=1, int s_nvcolnb=2); 00166 00167 /** \brief Set the units of the user-specified EOS 00168 */ 00169 int set_units(double s_efactor, double s_pfactor, 00170 double s_nfactor); 00171 00172 /** \brief Set the units of the user-specified EOS 00173 */ 00174 int set_units(std::string leunits="", 00175 std::string lpunits="", std::string lnunits=""); 00176 00177 /** 00178 \brief Return limiting and transition pressures 00179 00180 Returns, in order: 00181 - the highest pressure in the low-density EOS 00182 - the transition pressure 00183 - the lowest pressure in the high-density EOS 00184 */ 00185 int get_transition(double &plow, double &ptrans, double &phi); 00186 00187 /** 00188 \brief Set the transition pressure and "width" 00189 00190 Sets the transition pressure and the width (specified as a 00191 number greater than unity in \c pw) of the transition between 00192 the two EOSs. The transition is done smoothly using linear 00193 interpolation between \f$ P=\mathrm{ptrans}/pmathrm{pw} \f$ 00194 and \f$ P=\mathrm{ptrans} \times pmathrm{pw} \f$. 00195 */ 00196 int set_transition(double ptrans, double pw); 00197 00198 #ifndef DOXYGEN_INTERNAL 00199 00200 protected: 00201 00202 /// A base I/O object for reading EOSs 00203 base_ioc bio; 00204 00205 /// For reading the table 00206 table_units_io_type table_units_io; 00207 00208 /// Check that the EOS is valid 00209 int check_eos(); 00210 00211 /// \name Low-density EOS 00212 //@{ 00213 00214 /// true if we are using the low-density eos (false) 00215 bool ldeos; 00216 00217 /** 00218 \brief Low-density EOS switch 00219 00220 This is \c true if the ldeos has been read by set_ldeos. This 00221 is useful, since then we know whether or not we need 00222 to free the memory for the LD EOS in the destructor 00223 */ 00224 bool ldeos_read; 00225 00226 /// the path to the low-density EOS 00227 std::string ldpath; 00228 /// column in low-density eos for energy density 00229 int ldcole; 00230 /// column in low-density eos for pressure 00231 int ldcolp; 00232 /// column in low-density eos for baryon density 00233 int ldcolnb; 00234 /// file containing low-density EOS 00235 table_units *ld_eos; 00236 00237 /// highest pressure in low-density EOS 00238 double presld; 00239 /// highest energy density in low-density EOS 00240 double eld; 00241 /// highest baryon density in low-density EOS 00242 double nbld; 00243 00244 /// Transition pressure 00245 double prest; 00246 /// Transition width 00247 double pwidth; 00248 //@} 00249 00250 /// \name User EOS 00251 //@{ 00252 00253 /// file containing eos 00254 table *eost; 00255 00256 /// number of lines in eos file 00257 int nfile; 00258 00259 /// column for energy density in eos file 00260 int cole; 00261 /// column for pressure in eos file 00262 int colp; 00263 /// column for baryon density in eos file 00264 int colnb; 00265 00266 /// True if an EOS has been specified 00267 bool eos_read; 00268 //@} 00269 00270 /// \name Units 00271 //@{ 00272 00273 /// Units for energy density 00274 std::string eunits; 00275 /// Units for pressure 00276 std::string punits; 00277 /// Units for baryon density 00278 std::string nunits; 00279 00280 /// unit conversion factor for energy density (default 1.0) 00281 double efactor; 00282 /// unit conversion factor for pressure (default 1.0) 00283 double pfactor; 00284 /// unit conversion factor for baryon density (default 1.0) 00285 double nfactor; 00286 00287 //@} 00288 00289 /// Linear EOS interpolation 00290 void interp(const ovector_base &x, const ovector_base &y, 00291 double xx, double &yy, int n1, int n2); 00292 00293 #endif 00294 00295 }; 00296 00297 /** 00298 \brief The Buchdahl EOS for the TOV solver 00299 00300 Given the eos 00301 \f[ 00302 \rho = 12 \sqrt{p_{*} P}- 5 P 00303 \f] 00304 the TOV equation has an analytical solution 00305 \f[ 00306 R=(1-\beta) \sqrt{\frac{\pi}{288 p_{*} G (1-2 \beta)}} 00307 \f] 00308 where \f$ \beta = GM/R \f$. 00309 00310 The central pressure and energy density are 00311 \f[ 00312 P_c = 36 p_{*} \beta^2 00313 \f] 00314 \f[ 00315 {\rho}_c = 72 p_{*} \beta (1-5 \beta/2) 00316 \f] 00317 00318 Physical solutions are obtained only for \f$ P< 25 p_{*}/144 \f$ 00319 and \f$ \beta<1/6 \f$ . 00320 00321 Based on \ref Lattimer01. 00322 00323 \future Figure out what to do with the buchfun() function 00324 */ 00325 class tov_buchdahl_eos : public tov_eos { 00326 00327 public: 00328 00329 tov_buchdahl_eos() { 00330 Pstar=3.2e-5; 00331 } 00332 00333 virtual ~tov_buchdahl_eos() {} 00334 00335 /** 00336 \brief The parameter with units of pressure in units of solar 00337 masses per km cubed (default value \f$ 3.2 \times 10^{-5} \f$ 00338 ) 00339 */ 00340 double Pstar; 00341 00342 /** 00343 \brief Given the pressure, produce the energy and number densities 00344 00345 If the baryon density is not specified, it should be set to 00346 zero or \ref baryon_column should be set to false 00347 */ 00348 virtual int get_eden(double P, double &e, double &nb) { 00349 e=12.0*sqrt(Pstar*P)-5.0*P; 00350 nb=0.0; 00351 return 0; 00352 } 00353 00354 /// Given the pressure, produce all the remaining quantities 00355 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00356 np=0; 00357 return 0; 00358 } 00359 00360 /** 00361 \brief Fill a list with strings for the names of the remaining 00362 quanities 00363 */ 00364 virtual int get_names(size_t &np, std::vector<std::string> &pnames) { 00365 np=0; 00366 return 0; 00367 } 00368 00369 #ifdef O2SCL_NEVER_DEFINED 00370 00371 int buchfun(size_t bv, const ovector_base &bx, ovector_base &by, 00372 int &pa) { 00373 double u, rp; 00374 u=bx[0]; 00375 rp=bx[1]; 00376 by[0]=rp*(1.0-beta+u)/(1.0-2.0*beta)-buchrad; 00377 by[1]=beta/biga/rp*sin(biga*rp); 00378 return gsl_success; 00379 } 00380 00381 #endif 00382 00383 }; 00384 00385 /** 00386 \brief Standard polytropic EOS \f$ p = K \rho^{1+1/n} \f$ 00387 00388 Any units are permissible, but if this is to be used with \ref 00389 tov_solve, then the units of \f$ K \f$ must be consistent with 00390 the units set in \ref tov_solve::set_units(). 00391 */ 00392 class tov_polytrope_eos : public tov_eos { 00393 00394 public: 00395 00396 tov_polytrope_eos() { 00397 K=1.0; 00398 n=3.0; 00399 } 00400 00401 virtual ~tov_polytrope_eos() {} 00402 00403 /** 00404 \brief Coefficient (default 1.0) 00405 */ 00406 double K; 00407 00408 /// Index (default 3.0) 00409 double n; 00410 00411 /** 00412 \brief Given the pressure, produce the energy and number densities 00413 00414 If the baryon density is not specified, it should be set to 00415 zero or \ref baryon_column should be set to false 00416 */ 00417 virtual int get_eden(double P, double &e, double &nb) { 00418 e=pow(P/K,1.0/(1.0+1.0/n)); 00419 nb=0.0; 00420 return 0; 00421 } 00422 00423 /// Given the pressure, produce all the remaining quantities 00424 virtual int get_aux(double P, size_t &np, ovector_base &auxp) { 00425 np=0; 00426 return 0; 00427 } 00428 00429 /** 00430 \brief Fill a list with strings for the names of the remaining 00431 quanities 00432 */ 00433 virtual int get_names(size_t &np, std::vector<std::string> &pnames) { 00434 np=0; 00435 return 0; 00436 } 00437 00438 }; 00439 00440 #ifndef DOXYGENP 00441 } 00442 #endif 00443 00444 #endif 00445 00446
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page