tov_solve.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_SOLVE_H
00024 #define O2SCL_TOV_SOLVE_H
00025 
00026 #include <o2scl/tov_eos.h>
00027 #include <o2scl/smart_interp.h>
00028 
00029 #ifndef DOXYGENP
00030 namespace o2scl {
00031 #endif
00032 
00033   /** 
00034       \brief Class to solve the Tolman-Oppenheimer-Volkov equations
00035 
00036       Integrate Tolman-Oppenheimer-Volkov (TOV) equations
00037 
00038       The present code, as demonstrated in the tests, gives the
00039       correct central pressure and energy density of the analytical
00040       solution by Buchdahl to within less than 1 part in \f$ 10^5 \f$.
00041 
00042       The TOV equations (i.e. Einstein's equations for a 
00043       static spherically symmetric object) are
00044       \f[
00045       \frac{d m}{d r} = 4 \pi r^2 \varepsilon
00046       \f]
00047       \f[
00048       \frac{d P}{d r} = - \frac{G \varepsilon m}{r^2}
00049       \left( 1+\frac{P}{\varepsilon}\right)
00050       \left( 1+\frac{4 \pi P r^3}{m} \right)
00051       \left( 1-\frac{2 G m}{r}\right)^{-1}
00052       \f]
00053       where \f$r\f$ is the radial coordinate, \f$m(r)\f$ is the mass
00054       enclosed within a radius \f$r\f$, and \f$\varepsilon(r)\f$ and
00055       \f$P(r)\f$ are the energy density and pressure at \f$r\f$, and
00056       \f$G\f$ is the gravitational constant. The boundary conditions
00057       are \f$m(r=0)=0\f$ the condition \f$P(r=R)=0\f$ for some fixed
00058       radius \f$R\f$. These boundary conditions give a series of
00059       solutions to the TOV equations as a function of the radius,
00060       although they do not necessarily have a solution for all radii.
00061 
00062       The gravitational mass is given by
00063       \f[
00064       M_G = \int_0^R 4 \pi r^2 \varepsilon d r
00065       \f]
00066       while the baryonic mass is given by
00067       \f[
00068       M_B = \int_0^R 4 \pi r^2 n_B m_B 
00069       \left(1-\frac{G m}{r}\right)^{-1/2} d r
00070       \f]
00071       where \f$n_B(r)\f$ is the baryon number density at radius
00072       \f$r\f$ and \f$m_B\f$ is the mass of one baryon.
00073 
00074       The gravitational potential, \f$\Phi(r)\f$ can be determined from
00075       \f[
00076       \frac{d \Phi}{d r} = - \frac{1}{\varepsilon}
00077       \frac{ d P}{d r} \left(1+\frac{P}{\varepsilon}\right)^{-1}
00078       \f]
00079 
00080       The proper boundary condition for the gravitational potential
00081       is 
00082       \f[
00083       \Phi(r=R) = \frac{1}{2} \ln \left(1-\frac{2 G M}{R} \right)
00084       \f]
00085 
00086       The equation of state may be changed at any time.
00087       
00088       Note that the pressure in the low-density eos is not 
00089       strictly increasing! (see at P=4.3e-10)
00090 
00091       <b>Screen output</b>
00092       - \c verbose=0 - Nothing (even if an error occurs).
00093       - \c verbose=1 - Some basic information and any errors or
00094       warnings.
00095       - \c verbose=2 - For each profile computation, information
00096       at every kilometer.
00097       - \c verbose=3 - Profile information every 20 grid points. A 
00098       keypress is required after each profile.
00099       
00100       \todo
00101       - baryon mass doesn't work for fixed() (This may be fixed. We should
00102       make sure it's tested.)
00103       - Combine maxoutsize and kmax?
00104       - Document column naming issues
00105 
00106   */
00107   class tov_solve {
00108   public:
00109 
00110     /// \name Basic properties
00111     //@{
00112     /// mass
00113     double mass;
00114     /// radius
00115     double rad;
00116     /// baryonic mass
00117     double bmass;
00118     /// gravitational potential
00119     double gpot;
00120     //@}
00121 
00122     /// \name Solution parameters
00123     /**
00124        These parameters can be changed at any time.
00125     */
00126     //@{
00127     /// Use general relativistic version (default true)
00128     bool generel;
00129     /** \brief calculate the gravitational potential and the enclosed 
00130         baryon mass (default false)
00131     */
00132     bool calcgpot;
00133     /// smallest allowed radial stepsize (default 1.0e-4)
00134     double hmin;
00135     /// largest allowed radial stepsize (default 0.05)
00136     double hmax;
00137     /// initial radial stepsize (default 4.0e-3)
00138     double hstart;
00139     /// control for output (default 1)
00140     int verbose;
00141     /// maximum radius for integration in km (default 60)
00142     double maxradius;
00143     //@}
00144 
00145     /// \name Mass versus radius parameters
00146 
00147     //@{
00148     /// Beginning pressure (default 7.0e-7)
00149     double prbegin;
00150     /// Ending pressure (default 8.0e-3)
00151     double prend;
00152     /// Increment for pressure (default 1.1)
00153     double princ;
00154     /// Use 'princ' as a multiplier, not an additive increment (default true)
00155     bool logmode;
00156     /** \brief Guess for central pressure in solar masses per km3 
00157         (default \f$ 5.2 \times 10^{-5} \f$)
00158 
00159         This guess is used in the function fixed().
00160     */
00161     double prguess;
00162     //@}
00163 
00164     /// \name Fixed mass parameters
00165 
00166     //@{
00167     /** 
00168         \brief Target mass
00169       
00170         Use negative values to indicate a mass measured relative to the
00171         maximum mass. For example, if the EOS has a maximum mass of 2.0, then
00172         -0.15 will give the profile of a 1.85 solar mass star.
00173     */
00174     double tmass;
00175     //@}
00176 
00177     /// \name Results
00178 
00179     //@{
00180     /** \brief Return the results data table
00181      */
00182     table &get_results() {return out_table;}
00183     //@}
00184   
00185     //--------------------------------------------
00186     // Function prototypes
00187 
00188     tov_solve();
00189 
00190     ~tov_solve();
00191     
00192     /// \name Actual solution of equations
00193     //@{
00194     /// Calculate the mass vs. radius curve
00195     int mvsr();
00196     /// Calculate the profile of a star with fixed mass
00197     int fixed(double d_tmass);
00198     /// Calculate the profile of the maximum mass star
00199     int max();
00200     //@}
00201 
00202     /** 
00203         \brief Check the solution (unfinished)
00204     */
00205     int solution_check();
00206 
00207     /// Set units
00208     int set_units(double s_efactor=1.0, double s_pfactor=1.0, 
00209                   double s_nbfactor=1.0);
00210 
00211     /** 
00212         \brief Set units
00213         
00214         Valid entries for the units of energy density and pressure are:
00215         - "g/cm^3"
00216         - "erg/cm^3"
00217         - "MeV/fm^3"
00218         - "fm^-4"
00219         - "Msun/kg^3" (i.e. solar masses per cubic kilometer)
00220         
00221         Valid entries for the units of baryon density are:
00222         - "m^-3"
00223         - "cm^-3"
00224         - "fm^-3"
00225     */
00226     int set_units(std::string eunits="", std::string punits="", 
00227                   std::string nunits="");
00228 
00229     /** 
00230         \brief Set maximum storage for integration
00231         
00232         The variable \c s_kmax is the maximum number of radial
00233         integration stepsk while \c s_maxoutsize is the maximum number
00234         of points that will be output for any profile.
00235         
00236         If \c s_kmax is less than zero, there is no limit on
00237         the number of radial steps.
00238     */
00239     int set_kmax(int s_maxoutsize=400, int s_kmax=40000);
00240 
00241     /// Set the EOS to use
00242     int set_eos(tov_eos &ter) {
00243       te=&ter;
00244       eos_set=true;
00245       return 0;
00246     }
00247 
00248     /** 
00249         \brief Set solver
00250     */
00251     int set_mroot(mroot<void *,mm_funct<void *> > &s_mrp) 
00252     {mroot_ptr=&s_mrp; return 0;};
00253 
00254     /** 
00255         \brief Set minimizer
00256     */
00257     int set_minimize(minimize<void *,funct<void *> > &s_mp) 
00258     {min_ptr=&s_mp; return 0;};
00259 
00260     /** 
00261         \brief Set the adaptive stepper
00262     */
00263     int set_stepper(adapt_step<void *,ode_funct<void *> > &sap)
00264     {as_ptr=&sap; return 0;};
00265 
00266     /// The default minimizer
00267     gsl_min_brent<void *,funct<void *> > def_min;
00268     
00269     /// The default solver
00270     gsl_mroot_hybrids<void *,mm_funct<void *> > def_solver;
00271 
00272     /// The default adaptive stepper
00273     gsl_astep<void *,ode_funct<void *> > def_stepper;
00274 
00275     /// If true, compute the angular velocity (default false)
00276     bool compute_ang_vel;
00277     
00278     /// The angular velocity
00279     double cap_omega;
00280 
00281     /// The schwarzchild radius in km
00282     double schwarz_km;
00283     
00284 #ifndef DOXYGEN_INTERNAL
00285 
00286     friend class io_tlate<tov_solve>;
00287 
00288   protected:
00289     
00290     /** 
00291         \brief Ensure \c col does not match strings in \c cnames
00292     */
00293     int make_unique_name(std::string &col, 
00294                          std::vector<std::string> &cnames);
00295     
00296     /// The EOS
00297     tov_eos *te;
00298 
00299     /// True if the EOS has been set
00300     bool eos_set;
00301 
00302     /// Define some necessary I/O objects
00303     base_ioc bio;
00304 
00305     /// \name User EOS
00306     //@{
00307     /// Units for energy density
00308     std::string eunits;
00309     /// Units for pressure
00310     std::string punits;
00311     /// Units for baryon density
00312     std::string nunits;
00313     /// unit conversion factor for energy density (default 1.0)
00314     double efactor;
00315     /// unit conversion factor for pressure (default 1.0)
00316     double pfactor;
00317     /// unit conversion factor for baryon density (default 1.0)
00318     double nfactor;
00319     //@}
00320     
00321     /// maximum storage size (default 40000)
00322     int kmax;
00323     /// maximum size of output file (default 400)
00324     int maxoutsize;
00325 
00326     /** 
00327         \brief Smallest allowed pressure for integration (default: -100)
00328    
00329         This can't be much
00330         smaller since we need to compute numbers near exp(-presmin)
00331     */
00332     double presmin;
00333 
00334     /// \name Integration storage
00335     //@{
00336     ovector rky[6], rkx, rkdydx[6];
00337     //@}
00338     
00339     /// The output table
00340     table out_table;
00341 
00342     /// The solver
00343     mroot<void *,mm_funct<void *> > *mroot_ptr;
00344 
00345     /// The minimizer
00346     minimize<void *,funct<void *> > *min_ptr;
00347     
00348     /// The default adaptive stepper
00349     adapt_step<void *,ode_funct<void *> > *as_ptr;
00350 
00351     /// The ODE step function
00352     int derivs(double x, size_t nv, const ovector_view &y,
00353                ovector_view &dydx, void *&pa);
00354 
00355     /// The ODE step function for the angular velocity
00356     int derivs_ang_vel(double x, size_t nv, const ovector_view &y,
00357                        ovector_view &dydx, void *&pa);
00358 
00359     /// Output a stellar profile
00360     int profile_out(double xx);
00361 
00362     /// The minimizer function to compute the maximum mass
00363     double maxfun(double maxx, void *&pa);
00364 
00365     /** 
00366         \brief The solver function to compute the stellar profile
00367 
00368      */
00369     int starfun(size_t ndvar, const ovector_view &ndx, ovector_view &ndy, 
00370                 void *&pa);
00371 
00372     /// Compute the angular velocity
00373     int ang_vel();
00374 
00375     /// Interpolation object for derivs_ang_vel()
00376     smart_interp<> smi;
00377 
00378 #endif
00379 
00380   };
00381 
00382 #ifndef DOXYGENP
00383 }
00384 #endif
00385 
00386 #endif
00387 
00388 

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