![]() |
Equation of State Sub-Library: Version 0.910
|
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_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 #include <o2scl/shared_ptr.h> 00030 00031 #ifndef DOXYGENP 00032 namespace o2scl { 00033 #endif 00034 00035 /** \brief Class to solve the Tolman-Oppenheimer-Volkov equations 00036 00037 \hline 00038 <b>Mathematical background:</b> 00039 00040 In units where \f$ c=1 \f$, the TOV equations (i.e. Einstein's 00041 equations for a static spherically symmetric object) are 00042 \f[ 00043 \frac{d m}{d r} = 4 \pi r^2 \varepsilon 00044 \f] 00045 \f[ 00046 \frac{d P}{d r} = - \frac{G \varepsilon m}{r^2} 00047 \left( 1+\frac{P}{\varepsilon}\right) 00048 \left( 1+\frac{4 \pi P r^3}{m} \right) 00049 \left( 1-\frac{2 G m}{r}\right)^{-1} 00050 \f] 00051 where \f$r\f$ is the radial coordinate, \f$m(r)\f$ is the 00052 gravitational mass enclosed within a radius \f$r\f$, and 00053 \f$\varepsilon(r)\f$ and \f$P(r)\f$ are the energy density and 00054 pressure at \f$r\f$, and \f$G\f$ is the gravitational constant. 00055 The boundary conditions are \f$m(r=0)=0\f$ the condition 00056 \f$P(r=R)=0\f$ for some fixed radius \f$R\f$. These boundary 00057 conditions give a series of solutions to the TOV equations as a 00058 function of the radius, although they do not necessarily have a 00059 solution for all radii. 00060 00061 The gravitational mass is given by 00062 \f[ 00063 M_G = \int_0^R 4 \pi r^2 \varepsilon d r 00064 \f] 00065 00066 The gravitational potential, \f$\Phi(r)\f$ can be determined from 00067 \f[ 00068 \frac{d \Phi}{d r} = - \frac{1}{\varepsilon} 00069 \frac{ d P}{d r} \left(1+\frac{P}{\varepsilon}\right)^{-1} 00070 \f] 00071 00072 The proper boundary condition for the gravitational potential 00073 is 00074 \f[ 00075 \Phi(r=R) = \frac{1}{2} \ln \left(1-\frac{2 G M}{R} \right) 00076 \f] 00077 which ensures that \f$ \phi(r) \rightarrow 0 \f$ as 00078 \f$ r \rightarrow \infty \f$ . 00079 00080 The surface gravity is 00081 \f[ 00082 g = \frac{G m}{r^2}\left(1-\frac{2 G m}{r}\right)^{-1/2} 00083 \f] 00084 which is given in inverse kilometers and the redshift is 00085 \f[ 00086 z = \left(1-\frac{2 G m}{r}\right)^{-1/2} - 1 00087 \f] 00088 which is unitless. 00089 00090 The baryonic mass is typically defined by 00091 \f[ 00092 M_B = \int_0^R 4 \pi r^2 n_B m_B 00093 \left(1-\frac{2 G m}{r}\right)^{-1/2} d r 00094 \f] 00095 where \f$ n_B(r) \f$ is the baryon number density at radius 00096 \f$ r \f$ and \f$ m_B \f$ is the mass of one baryon. Then the 00097 "binding energy" of the neutron star is defined to be \f$ M_B - 00098 M_G \f$ . If you can specify the product \f$ n_B m_B \f$ in the 00099 EOS (analogous to the rest mass energy density), it will compute 00100 the associated baryonic mass for you. 00101 00102 In the case of slow rigid rotation with angular velocity 00103 \f$ \Omega \f$, the moment of inertia is 00104 \f[ 00105 I = \frac{8 \pi}{3} \int_0^R dr~r^4\left(\varepsilon+P\right) 00106 e^{\Phi} \left(\frac{\bar{\omega}}{\Omega}\right) 00107 \left(1-\frac{2 G m}{r}\right)^{-1/2} 00108 \f] 00109 where the function \f$ \bar{\omega}(r) \f$ is the solution of 00110 \f[ 00111 \frac{d}{dr} \left( r^4 j \frac{d \bar{\omega}}{dr}\right) 00112 + 4 r^3 \frac{d j}{dr} \bar{\omega} = 0 00113 \f] 00114 and the function \f$ j(r) \f$ is defined by 00115 \f[ 00116 j = \left( 1-\frac{2 G m}{r} \right) e^{-\Phi} 00117 \f] 00118 The boundary conditions for \f$ \bar{\omega} \f$ are 00119 \f$ d \bar{\omega}/dr = 0 \f$ at \f$ r=0 \f$ and 00120 \f[ 00121 \bar{\omega}(R) = \Omega - \left(\frac{R}{3}\right) 00122 \left(\frac{d \bar{\omega}}{dr}\right)_{r=R} \, . 00123 \f] 00124 00125 \hline 00126 <b>General usage notes:</b> 00127 00128 The equation of state may be changed at any time, by specifying 00129 the appropriate tov_eos object 00130 00131 Screen output: 00132 - \c verbose=0 - Nothing 00133 - \c verbose=1 - Basic information 00134 - \c verbose=2 - For each profile computation, report solution 00135 information at every kilometer. 00136 - \c verbose=3 - Report profile information at every 20 grid points. A 00137 keypress is required after each profile. 00138 00139 \hline 00140 <b>Output tables:</b> 00141 00142 The functions fixed() and max() produce output tables which 00143 represent the profile of the neutron star of the requested mass. 00144 The columns are 00145 - \c gm, the enclosed gravitational mass in solar masses 00146 - \c r, the radial coordinate in \f$ \mathrm{km} \f$ 00147 - \c gp, the gravitational potential (unitless) when 00148 \ref calcgpot is true 00149 - \c bm, the baryonic mass in solar masses (when 00150 \ref tov_eos::baryon_column is true). 00151 - \c pr, the pressure 00152 - \c ed, the energy density 00153 - \c nb, the baryon density (if \ref tov_eos::baryon_column 00154 is true) 00155 - \c sg, the local surface gravity 00156 (in \f$ \mathrm{g}/\mathrm{cm}^{2} \f$ ) 00157 - \c rs, the local redshift (unitless), 00158 - \c dmdr, the derivative of the enclosed gravitational mass 00159 in \f$ \mathrm{M}_{\odot}/\mathrm{km} \f$ 00160 - \c dlogpdr, the derivative of the natural logarithm of the 00161 pressure 00162 - \c dgpdr, the derivative of the gravitational potential 00163 in \f$ 1/\mathrm{km} \f$ (if \ref calcgpot is true) 00164 - \c dbmdr, the derivative of the enclosed baryonic mass 00165 (if \ref tov_eos::baryon_column is true). \n 00166 The remaining columns are given by the user-defined columns from 00167 the equation of state as determined by \ref tov_eos::get_names_units() 00168 and \ref tov_eos::get_aux(). 00169 00170 The function mvsr() produces a different kind of output table 00171 corresponding to the mass versus radius curve. Some points on 00172 the curve may correspond to unstable branches. 00173 - \c gm, the total gravitational mass in solar masses 00174 - \c r, the radius in \f$ \mathrm{km} \f$ 00175 - \c gp, the gravitational potential at the surface (unitless) when 00176 \ref calcgpot is true 00177 - \c bm, total the baryonic mass in solar masses (when 00178 \ref tov_eos::baryon_column is true). 00179 - \c pr, the central pressure 00180 - \c ed, the central energy density 00181 - \c nb, the central baryon density (if \ref tov_eos::baryon_column 00182 is true) 00183 - \c sg, the surface gravity 00184 (in \f$ \mathrm{g}/\mathrm{cm}^{2} \f$ ) 00185 - \c rs, the redshift at the surface, 00186 - \c dmdr, the derivative of the gravitational mass 00187 - \c dlogpdr, the derivative of the natural logarithm of the 00188 pressure 00189 - \c dgpdr, the derivative of the gravitational potential 00190 in \f$ 1/\mathrm{km} \f$ (if \ref calcgpot is true) 00191 - \c dbmdr, the derivative of the enclosed baryonic mass 00192 (if \ref tov_eos::baryon_column is true). \n 00193 The remaining columns are given by the user-defined columns from 00194 the equation of state as determined by \ref tov_eos::get_names_units() 00195 and \ref tov_eos::get_aux(). 00196 00197 \hline 00198 <b>Accuracy:</b> 00199 00200 The present code, as demonstrated in the tests, gives the 00201 correct central pressure and energy density of the analytical 00202 solution by Buchdahl to within less than 1 \part in \f$ 10^8 \f$. 00203 00204 \hline 00205 <b>Other details and todos:</b> 00206 00207 \note The function star_fun() returns <tt>gsl_efailed</tt> 00208 without calling the error handler in the case that the solver 00209 can recover gracefully from, for example, a negative pressure. 00210 00211 \todo 00212 - baryon mass doesn't work for fixed() (This may be fixed. We should 00213 make sure it's tested.) 00214 - Combine maxoutsize and kmax? 00215 - Document column naming issues 00216 - Document surface gravity and redshift 00217 - Standardize \c xmev_kg, etc. 00218 - Use convert_units? 00219 - Double check that fixed() doesn't give a solution on the 00220 unstable branch 00221 - Ensure that this class copies over the units of the 00222 user-specified columns to the table 00223 00224 \comment 00225 To solve the calling of the error handler, I need to rewrite the 00226 adaptive stepper to simply stop if the base stepper makes a step 00227 which is too large. That demands creating a new version of 00228 gsl_astep::evolve_apply(). The question is how to communicate 00229 the information from the tov derivs() function to the new 00230 version of gsl_astep::evolve_apply(). An easy way would be to 00231 just create a new return value which indicates the step should 00232 be shortened, and just stop if the step becomes too short. 00233 Alternatively, instead of modifying evolve_apply(), we could 00234 just ensure the adaptive stepper bails out correctly if the 00235 stepper returns a nonzero value and then have the caller 00236 (starfun) take care of it. This would probably be better. We 00237 might have to make sure that gsl_astep does not set yout if the 00238 step fails. (3/27/09 - It looks like this might be fixed now?) 00239 \endcomment 00240 00241 \hline 00242 */ 00243 class tov_solve { 00244 00245 #ifndef DOXYGEN_INTERNAL 00246 00247 protected: 00248 00249 /// To convert MeV to kilograms 00250 double mev_kg; 00251 00252 /// To convert \f$ MeV/fm{^3} \f$ to solar masses per cubic kilometer 00253 double mev_per_fm3_msun_km3; 00254 00255 /** \brief Target mass 00256 00257 Negative values to indicate a mass measured relative to the 00258 maximum mass. For example, if the EOS has a maximum mass of 2.0, then 00259 -0.15 will give the profile of a 1.85 solar mass star. 00260 */ 00261 double tmass; 00262 00263 /** \brief Ensure \c col does not match strings in \c cnames 00264 00265 Underscores are added to \c col until it matches none of 00266 the strings in \c cnames. 00267 */ 00268 int make_unique_name(std::string &col, 00269 std::vector<std::string> &cnames); 00270 00271 /// The EOS 00272 tov_eos *te; 00273 00274 /// True if the EOS has been set 00275 bool eos_set; 00276 00277 /// \name User EOS units 00278 //@{ 00279 /// Units for energy density 00280 std::string eunits; 00281 /// Units for pressure 00282 std::string punits; 00283 /// Units for baryon density 00284 std::string nunits; 00285 /// unit conversion factor for energy density (default 1.0) 00286 double efactor; 00287 /// unit conversion factor for pressure (default 1.0) 00288 double pfactor; 00289 /// unit conversion factor for baryon density (default 1.0) 00290 double nfactor; 00291 //@} 00292 00293 /// maximum storage size (default 40000) 00294 int kmax; 00295 /// maximum size of output file (default 400) 00296 int maxoutsize; 00297 00298 /** \brief Smallest allowed pressure for integration (default: -100) 00299 00300 This quantity can't be much smaller than -100 since we need to 00301 compute numbers near \f$ e^{-presmin} \f$ 00302 */ 00303 double presmin; 00304 00305 /// \name Integration storage 00306 //@{ 00307 /** \brief ODE functions 00308 00309 The vector \c rky[0] is the gravitational mass in solar 00310 masses, and the vector \c rky[1] is the natural logarithm of 00311 the pressure in solar masses per cubic kilometer. When \ref 00312 calcgpot is true, the next vector in this list is the 00313 gravitational potential (which is unitless), and when \ref 00314 tov_eos::baryon_column is true, the next vector in this 00315 list is the baryonic mass in solar masses. 00316 */ 00317 ovector rky[6]; 00318 /// Radial coordinate (in kilometers) 00319 ovector rkx; 00320 /// The derivatives of the ODE functions 00321 ovector rkdydx[6]; 00322 //@} 00323 00324 /// Compute the angular velocity 00325 int ang_vel(); 00326 00327 /// Interpolation object for derivs_ang_vel() 00328 sm_interp smi; 00329 00330 /// The output table 00331 o2_shared_ptr<table_units>::type out_table; 00332 00333 /// The solver 00334 mroot<mm_funct<> > *mroot_ptr; 00335 00336 /// The minimizer 00337 minimize<funct> *min_ptr; 00338 00339 /// The adaptive stepper 00340 adapt_step<ode_funct<> > *as_ptr; 00341 00342 /// The ODE step function 00343 virtual int derivs(double x, size_t nv, const ovector_base &y, 00344 ovector_base &dydx); 00345 00346 /// The ODE step function for the angular velocity 00347 virtual int derivs_ang_vel(double x, size_t nv, const ovector_base &y, 00348 ovector_base &dydx); 00349 00350 /** \brief Construct a stellar profile 00351 00352 This function constructs a stellar profile in \ref out_table 00353 from the information in \ref rkx and \ref rky. 00354 */ 00355 virtual int profile_out(double xx); 00356 00357 /// The minimizer function to compute the maximum mass 00358 virtual double maxfun(double maxx); 00359 00360 /** \brief The solver function to compute the stellar profile 00361 */ 00362 virtual int starfun(size_t ndvar, const ovector_base &ndx, 00363 ovector_base &ndy); 00364 00365 /// The schwarzchild radius in km 00366 double schwarz_km; 00367 00368 #endif 00369 00370 public: 00371 00372 tov_solve(); 00373 00374 virtual ~tov_solve(); 00375 00376 /// \name Basic properties 00377 //@{ 00378 /// mass 00379 double mass; 00380 /// radius 00381 double rad; 00382 /// baryonic mass 00383 double bmass; 00384 /// gravitational potential 00385 double gpot; 00386 //@} 00387 00388 /** \name Solution parameters 00389 00390 These parameters can be changed at any time. 00391 */ 00392 //@{ 00393 /// Use general relativistic version (default true) 00394 bool generel; 00395 /** \brief calculate the gravitational potential and the enclosed 00396 baryon mass (default false) 00397 */ 00398 bool calcgpot; 00399 /// smallest allowed radial stepsize (default 1.0e-4) 00400 double hmin; 00401 /// largest allowed radial stepsize (default 0.05) 00402 double hmax; 00403 /// initial radial stepsize (default 4.0e-3) 00404 double hstart; 00405 /// control for output (default 1) 00406 int verbose; 00407 /// maximum radius for integration in km (default 60) 00408 double maxradius; 00409 //@} 00410 00411 /// \name Mass versus radius parameters 00412 00413 //@{ 00414 /// Beginning pressure (default 7.0e-7) 00415 double prbegin; 00416 /// Ending pressure (default 8.0e-3) 00417 double prend; 00418 /// Increment for pressure (default 1.1) 00419 double princ; 00420 /// Use 'princ' as a multiplier, not an additive increment (default true) 00421 bool logmode; 00422 /** \brief Guess for central pressure in solar masses per km3 00423 (default \f$ 5.2 \times 10^{-5} \f$) 00424 00425 This guess is used in the function fixed(). 00426 */ 00427 double prguess; 00428 /// Beginning pressure for maximum mass guess (default 7.0e-5) 00429 double max_begin; 00430 /// Ending pressure for maximum mass guess (default 5.0e-3) 00431 double max_end; 00432 /// Increment for pressure for maximum mass guess (default 1.3) 00433 double max_inc; 00434 //@} 00435 00436 /// \name Basic operation 00437 //@{ 00438 /// Set the EOS to use 00439 int set_eos(tov_eos &ter) { 00440 te=&ter; 00441 eos_set=true; 00442 return 0; 00443 } 00444 00445 /// Set units 00446 int set_units(double s_efactor=1.0, double s_pfactor=1.0, 00447 double s_nbfactor=1.0); 00448 00449 /** \brief Set units 00450 00451 Valid entries for the units of energy density and pressure are: 00452 - "g/cm^3" 00453 - "erg/cm^3" 00454 - "MeV/fm^3" 00455 - "1/fm^4" 00456 - "Msun/km^3" (i.e. solar masses per cubic kilometer) 00457 00458 Valid entries for the units of baryon density are: 00459 - "1/m^3" 00460 - "1/cm^3" 00461 - "1/fm^3" 00462 */ 00463 int set_units(std::string eunits="", std::string punits="", 00464 std::string nunits=""); 00465 00466 /// Calculate the mass vs. radius curve 00467 virtual int mvsr(); 00468 00469 /// Calculate the profile of a star with fixed mass 00470 virtual int fixed(double d_tmass); 00471 00472 /// Calculate the profile of the maximum mass star 00473 virtual int max(); 00474 00475 /** \brief Return the results data table 00476 */ 00477 o2_shared_ptr<table_units>::type get_results() { 00478 return out_table; 00479 } 00480 00481 /** \brief Check the solution (unfinished) 00482 */ 00483 int solution_check(); 00484 //@} 00485 00486 /// \name Control numerical methods 00487 //@{ 00488 /** \brief Set maximum storage for integration 00489 00490 The variable \c s_kmax is the maximum number of radial 00491 integration stepsk while \c s_maxoutsize is the maximum number 00492 of points that will be output for any profile. 00493 00494 If \c s_kmax is less than zero, there is no limit on 00495 the number of radial steps. 00496 */ 00497 int set_kmax(int s_maxoutsize=400, int s_kmax=80000); 00498 00499 /** \brief Set solver 00500 */ 00501 int set_mroot(mroot<mm_funct<> > &s_mrp) 00502 {mroot_ptr=&s_mrp; return 0;}; 00503 00504 /** \brief Set minimizer 00505 */ 00506 int set_minimize(minimize<funct > &s_mp) 00507 {min_ptr=&s_mp; return 0;}; 00508 00509 /** \brief Set the adaptive stepper 00510 */ 00511 int set_stepper(adapt_step<ode_funct<> > &sap) 00512 {as_ptr=&sap; return 0;}; 00513 //@} 00514 00515 /// The default minimizer 00516 gsl_min_brent<funct > def_min; 00517 00518 /// The default solver 00519 gsl_mroot_hybrids<mm_funct<> > def_solver; 00520 00521 /// The default adaptive stepper 00522 gsl_astep<ode_funct<> > def_stepper; 00523 00524 /// If true, compute the angular velocity (default false) 00525 bool compute_ang_vel; 00526 00527 /// The angular velocity 00528 double cap_omega; 00529 00530 }; 00531 00532 #ifndef DOXYGENP 00533 } 00534 #endif 00535 00536 #endif 00537 00538
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).