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