Equation of State Sub-Library: Version 0.910
tov_eos.h
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Friends

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.