tov_eos.h

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

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page