hadronic_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_HADRONIC_EOS_H
00024 #define O2SCL_HADRONIC_EOS_H
00025 
00026 #include <iostream>
00027 #include <string>
00028 #include <o2scl/eos.h>
00029 #include <o2scl/part.h>
00030 #include <o2scl/deriv.h>
00031 #include <o2scl/gsl_deriv.h>
00032 #include <o2scl/mroot.h>
00033 #include <o2scl/gsl_mroot_hybrids.h>
00034 #include <o2scl/collection.h>
00035 #include <o2scl/fermion.h>
00036 #include <o2scl/mm_funct.h>
00037 
00038 #ifndef DOXYGENP
00039 namespace o2scl {
00040 #endif
00041 
00042   /** 
00043       \brief Hadronic equation of state
00044 
00045       In the method documentation below, \f$ n \f$ is baryon number density, 
00046       \f$ \epsilon \f$ is energy density, and \f$ P \f$ is pressure.
00047     
00048       \htmlonly
00049       See more about Svprime in the Mathematica notebook at 
00050       <a href="hadronic_eos.nb">
00051       hadronic_eos.nb</a>, and
00052       <a href="hadronic_eos.ps">
00053       hadronic_eos.ps</a>.
00054       \endhtmlonly
00055       \latexonly
00056       See more about Svprime in the Mathematica notebook at 
00057       \begin{verbatim}
00058       doc/o2scl/extras/hadronic_eos.nb
00059       doc/o2scl/extras/hadronic_eos.ps
00060       \end{verbatim}
00061       \endlatexonly
00062 
00063       \todo Need to consider using denpar versus n_baryon and proton_frac. 
00064       Maybe some of this can be simplified or improved?
00065 
00066   */
00067   class hadronic_eos : public eos {
00068   public:
00069     
00070     hadronic_eos();
00071 
00072     virtual ~hadronic_eos() {};
00073 
00074     /// Binding energy
00075     double eoa;
00076 
00077     /// Compressibility
00078     double comp;
00079 
00080     /// Symmetry energy
00081     double esym;
00082   
00083     /// Saturation density
00084     double n0;
00085 
00086     /// Effective mass
00087     double msom;
00088 
00089     /// Skewness
00090     double kprime;
00091     
00092     /// Symmetry energy derivative
00093     double sprime;
00094 
00095     /// \name Equation of state
00096     //@{
00097     /** 
00098         \brief Equation of state as a function of the chemical potentials
00099     */
00100     virtual int calc_p(fermion &n, fermion &p, thermo &th);
00101 
00102     /** 
00103         \brief Equation of state as a function of the chemical potentials
00104         at finite temperature
00105     */
00106     virtual int calc_temp_p(fermion &n, fermion &p, const double T, 
00107                             thermo &th);
00108     
00109     /** 
00110         \brief Equation of state as a function of density
00111     */
00112     virtual int calc_e(fermion &n, fermion &p, thermo &th);
00113 
00114     /** 
00115         \brief Equation of state as a function of densities at 
00116         finite temperature
00117     */
00118     virtual int calc_temp_e(fermion &n, fermion &p, const double T, 
00119                             thermo &th);
00120     //@}
00121 
00122     /// \name Physical properties
00123     //@{
00124     /** 
00125         \brief Calculate compressibility of nuclear matter using calc_e()
00126 
00127         The compression modulus is defined here by: \f$ \chi = -1/V
00128         (dV/dP) = 1/n (dP/dn)^{-1} \f$ It is customary to use the
00129         incompressibility modulus \f$ K=9/(n \chi) \f$ .  This is the value
00130         denoted \c comp  in the code and can be written: \f$ K = 9 n d^2
00131         \epsilon /(d n^2) = 9 d P / (d n) \f$ .  It is often referred to as
00132         the "compressibility" and is about 220 MeV at saturation
00133         density. (Taken from Chabanat, et.  al. NPA 627 (1997) 710.) Note
00134         that this differs from \f$ K_2 = 9 n^2 d^2(\epsilon/n) / (d n^2)
00135          \f$ by \f$ 18 P/n \f$ at any density except the saturation
00136         density.  
00137     */
00138     virtual double fcomp(const double nb);
00139 
00140     /** 
00141         \brief Calculate binding energy using calc_e()
00142 
00143         \c eoa = (energy density/baryon number density-nucleon mass) at 
00144          \f$ n=n_0 \f$ . \f$ E_b \approx -16/(\hbar c) \f$ 
00145     */
00146     virtual double feoa(const double nb, const double pf=0.5);
00147 
00148     /** 
00149         \brief Calculate symmetry energy of matter using calc_e()
00150 
00151         \c esym = 
00152         \f[
00153         \left(\frac{1}{2 n}\frac{d^2 \epsilon}{d \delta^2}
00154         \right)_{n=n_B,\delta=\delta_0}
00155         \f]
00156 
00157         where \f$ \delta=1-2 x \f$ , \f$ \delta_0=1-2 x \f$ 
00158         and \f$ x \f$ is the proton fraction
00159         (for x=0.5 at saturation density, esym \f$ \approx 32/ \hbar c \f$ )
00160     */
00161     virtual double fesym(const double nb, const double pf=0.5);
00162     
00163     /** 
00164         \brief The symmetry energy slope parameter
00165         
00166         This returns the value of the "slope parameter" 
00167         of the symmetry energy
00168         \f[
00169         L=3 n_{B} \left(\frac{\partial E_{sym}}{n_{B}}\right)
00170         \f]
00171         in inverse Fermis. 
00172 
00173         where \f$ n_B \f$ is the baryon density. This ranges 
00174         between about zero and 200 MeV for many EOSs. If \c alt_sym
00175         is false (the default), then \ref fesym() is used to
00176         compute the symmetry energy, otherwise \ref fesym_diff()
00177         is used.
00178     */
00179     virtual double fesym_slope(const double nb, bool alt_sym=false);
00180 
00181     /** \brief Calculate symmetry energy of matter as energy of 
00182         neutron matter minus the energy of nuclear matter
00183 
00184         This function returns the energy per baryon of neutron matter
00185         minus the energy per baryon of nuclear matter. This will
00186         deviate significantly from the results from fesym() only if
00187         the dependence of the symmetry energy on \f$ \delta \f$ is not
00188         quadratic.
00189     */
00190     virtual double fesym_diff(const double nb);
00191 
00192     /** 
00193         \brief Calculate \f$ S^{\prime} \f$ in matter using calc_e()
00194 
00195         \c sprime = 
00196         \f[
00197         \left[n \frac{d}{d n}
00198         \left(\frac{1}{2 n}\frac{d^2 \epsilon}{d \delta^2}
00199         \right)\right]_{n=n_B,\delta=\delta_0}
00200         \f]
00201 
00202         where \f$ \delta=1-2 x \f$ , \f$ \delta_0=1-2 (\mathrm{pf}) \f$ 
00203         and \f$ x \f$ is the proton fraction
00204     */
00205     virtual double fsprime(const double nb, const double pf=0.5);
00206 
00207     /** 
00208         \brief Calculate skewness of nuclear matter using calc_e()
00209 
00210         The skewness is defined to be 
00211         \f$ 27 n^3 d^3 (\epsilon/n)/(d n^3) = 
00212         27 n^3 d^2 (P/n^2) / (d n^2) \f$ 
00213 
00214         and is denoted 'kprime'.
00215         This definition seems to be ambiguous for densities other than the 
00216         saturation density and is not quite analogous to the compressibility.
00217     */
00218     virtual double fkprime(const double nb);
00219 
00220     /** 
00221         \brief Calculate reduced neutron effective mass using calc_e()
00222 
00223         Neutron effective mass (n.ms) divided by vacuum mass (n.m) in
00224         nuclear matter at saturation density.  Note that this simply uses
00225         the value of n.ms from calc_e(), so that this effective mass could
00226         be either the Landau or Dirac mass depending on the context. Note
00227         that this may not be equal to the reduced proton effective mass.  
00228     */
00229     virtual double fmsom(const double nb, const double pf=0.5);
00230 
00231     /** 
00232         \brief Calculate saturation density using calc_e()
00233 
00234         This function finds the density for which the pressure vanishes
00235         in matter with \f$ n_n=n_p \f$ .
00236 
00237         \f$ n_0 \f$ = baryon number density at which 
00238         \f$ P=0, n_0 \approx 0.16 \f$ 
00239     */
00240     virtual double fn0(const double protfrac, double &leoa);
00241 
00242     /// Calculates all of the properties at the saturation density
00243     virtual int saturation();
00244     //@}
00245 
00246     /** 
00247         \brief Calculate coefficients for gradient part of Hamiltonian
00248 
00249         \note This is still somewhat experimental.
00250 
00251         We want the gradient part of the Hamiltonian in the form
00252         \f[
00253         {\cal H}_{\mathrm{grad}} = \frac{1}{2} \sum_{i=n,p}
00254         \sum_{j=n,p} Q_{ij}
00255         \vec{\nabla} n_i \cdot \vec{\nabla} n_j
00256         \f]
00257 
00258         The expression for the gradient terms from \ref Pethick95 is 
00259         \f{eqnarray*}
00260         {\cal H}_{\mathrm{grad}}&=&-\frac{1}{4}
00261         \left(2 P_1 + P_{1;f}-P_{2;f}\right) 
00262         \nonumber \\
00263         && +\frac{1}{2} \left( Q_1+Q_2 \right) 
00264         \left(n_n \nabla^2 n_n+n_p \nabla^2 n_p\right) \nonumber \\
00265         && + \frac{1}{4}\left( Q_1-Q_2 \right) 
00266         \left[\left(\nabla n_n\right)^2+\left(\nabla n_p\right)^2
00267         \right] \nonumber \\
00268         && + \frac{1}{2} \frac{d Q_2}{d n} 
00269         \left( n_n \nabla n_n + n_p \nabla n_p \right) \cdot \nabla n
00270         \f}
00271         This can be rewritten
00272         \f{eqnarray*}
00273         {\cal H}_{\mathrm{grad}}&=&\frac{1}{2}\left(\nabla n\right)^2
00274         \left[ \frac{3}{2} P_1+n \frac{d P_1}{d n}\right] \nonumber \\
00275         && - \frac{3}{4} \left[ \left( \nabla n_n\right)^2 + 
00276         \left( \nabla n_p \right)^2 \right] \nonumber \\
00277         && -\frac{1}{2} \left[ \right] \cdot \nabla n \frac{d Q_1}{d n}
00278         \nonumber \\ && - \frac{1}{4} \left( \nabla n\right)^2 P_2
00279         - \frac{1}{4} \left[ \left( \nabla n_n\right)^2 +
00280         \left( \nabla n_p \right)^2 \right] Q_2
00281         \f}
00282         or
00283         \f{eqnarray*}
00284         {\cal H}_{\mathrm{grad}}&=&\frac{1}{4} \left( \nabla n\right)^2
00285         \left[3 P_1 + 2 n \frac{d P_1}{d n}-P_2\right] \nonumber \\
00286         && - \frac{1}{4} \left( 3 Q_1+Q_2 \right)
00287         \left[ \left( \nabla n_n\right)^2 + 
00288         \left( \nabla n_p \right)^2 \right] \nonumber \\
00289         && - \frac{1}{2} \frac{d Q_1}{d n}
00290         \left[ n_n \nabla n_n + n_p \nabla n_p \right]
00291         \cdot \nabla n 
00292         \f}
00293         or
00294         \f{eqnarray*}
00295         {\cal H}_{\mathrm{grad}}&=&\frac{1}{4} \left( \nabla n\right)^2
00296         \left[3 P_1 + 2 n \frac{d P_1}{d n}-P_2\right] \nonumber \\
00297         && - \frac{1}{4} \left( 3 Q_1+Q_2 \right)
00298         \left[ \left( \nabla n_n\right)^2 + 
00299         \left( \nabla n_p \right)^2 \right] \nonumber \\
00300         && - \frac{1}{2} \frac{d Q_1}{d n}
00301         \left[ n_n \left( \nabla n_n \right)^2 +
00302         n_p \left( \nabla n_p \right)^2 + n \nabla n_n \cdot
00303         \nabla n_p \right]
00304         \f}
00305 
00306         Generally, for Skyrme-like interactions
00307         \f{eqnarray*}
00308         P_i &=& \frac{1}{4} t_i \left(1+\frac{1}{2} x_i \right) \nonumber \\
00309         Q_i &=& \frac{1}{4} t_i \left(\frac{1}{2} + x_i \right) \, .
00310         \f}
00311         for \f$ i=1,2 \f$ .
00312 
00313         This function uses the assumption \f$ x_1=x_2=0 \f$ to 
00314         calculate \f$ t_1 \f$ and \f$ t_2 \f$ from the neutron
00315         and proton effective masses assuming the Skyrme form. The
00316         values of \f$ Q_{ij} \f$ and their derivatives are then computed.
00317 
00318         The functions set_n_and_p() and set_thermo() will be called by
00319         gradient_qij(), to facilitate the use of the \c n, \c p, and
00320         \c th parameters.
00321        
00322     */
00323     int gradient_qij(fermion &n, fermion &p, thermo &th, 
00324                      double &qnn, double &qnp, double &qpp, 
00325                      double &dqnndnn, double &dqnndnp,
00326                      double &dqnpdnn, double &dqnpdnp,
00327                      double &dqppdnn, double &dqppdnp);
00328     
00329     /// \name Functions for calculating physical properties
00330     //@{
00331     /** 
00332         \brief Calculate pressure as a function of baryon density
00333 
00334         Used by fcomp().
00335     */
00336     double calc_pressure(double nb, void *&pa);
00337 
00338     /** \brief Calculate pressure / baryon density squared as a function
00339         of baryon density
00340         
00341         Used by fkprime().
00342     */
00343     double calc_press_on2(double nb, void *&pa);
00344 
00345     /** 
00346         \brief Calculate energy density as a function of 'delta' 
00347 
00348         Used by fesym().
00349     */
00350     double calc_edensity(double delta, void *&pa);
00351 
00352     /** 
00353         \brief Calculate symmetry energy as a function of 'delta'
00354 
00355         Used by fsprime().
00356     */
00357     double calc_esym(double delta, void *&pa);
00358 
00359     /** 
00360         \brief Solve for zero pressure as a function of baryon density
00361      
00362         Used by fn0().
00363     */
00364     int saturation_matter_e(double x, double &y, void *&pa);
00365     //@}
00366 
00367     /// \name Other functions
00368     //@{
00369     /** 
00370         \brief Nucleonic matter from calc_p()
00371     */
00372     int nuc_matter_p(size_t nv, const ovector_view &x, ovector_view &y, 
00373                      void *&pa);
00374     
00375     /** 
00376         \brief Nucleonic matter from calc_e()
00377     */
00378     int nuc_matter_e(size_t nv, const ovector_view &x, ovector_view &y, 
00379                      void *&pa);
00380     //@}
00381 
00382     /// \name Set auxilliary objects
00383     //@{
00384     /** \brief Set class mroot object for use in calculating chemical
00385         potentials from densities 
00386     */
00387     virtual int set_mroot(mroot<void *,mm_funct<void *> > &mr);
00388 
00389     /** \brief Set class mroot object for use calculating saturation density
00390      */
00391     virtual int set_sat_root(root<void *,funct<void *> > &mr);
00392 
00393     /// Set \ref deriv object to use to find saturation properties
00394     virtual int set_sat_deriv(deriv<void *,funct<void *> > &de);
00395 
00396     /// Set \ref deriv object to use to find saturation properties
00397     virtual int set_sat_deriv2(deriv<bool,funct<bool> > &de);
00398     
00399     /// Set neutron and proton 
00400     virtual int set_n_and_p(fermion &n, fermion &p);
00401     //@}
00402 
00403     /** 
00404         \brief The default object for derivatives
00405         
00406         The value of gsl_deriv::h is set to \f$ 10^{-3} \f$ in 
00407         the hadronic_eos constructor.
00408     */
00409     gsl_deriv<void *,funct<void *> > def_deriv;
00410     
00411     /** 
00412         \brief The second default object for derivatives
00413         
00414         The value of gsl_deriv::h is set to \f$ 10^{-3} \f$ in 
00415         the hadronic_eos constructor.
00416     */
00417     gsl_deriv<bool,funct<bool> > def_deriv2;
00418 
00419     /// The defaut neutron
00420     fermion def_neutron;
00421 
00422     /// The defaut proton
00423     fermion def_proton;
00424 
00425     /** 
00426         \brief The default solver
00427 
00428         Used by calc_e() and calc_temp_e() to solve nuc_matter_p() (2
00429         variables) and by calc_p() and calc_temp_p() to solve
00430         nuc_matter_e() (2 variables).
00431     */
00432     gsl_mroot_hybrids<void *,mm_funct<void *> > def_mroot;
00433     
00434     /** \brief The default solver for calculating the saturation 
00435         density
00436 
00437         Used by fn0() (which is called by saturation()) to solve
00438         saturation_matter_e() (1 variable).
00439     */
00440     cern_mroot_root<void *,funct<void *> > def_sat_root;
00441     
00442     /// Return string denoting type ("hadronic_eos")
00443     virtual const char *type() { return "hadronic_eos"; }
00444 
00445 #ifndef DOXYGEN_INTERNAL
00446 
00447   protected:
00448 
00449     /** 
00450         \name Switch for overloading [protected]
00451 
00452         The integer \c 'provides' needs to be set by children
00453         corresponding to which calc() functions are overloaded. Use
00454         the above integers in combination with the bitwise or '|'
00455         operator. For example, in the constructor of a descendant, you
00456         might set
00457         \code
00458         provides=(provides_calc_e | provides_calc_temp_e);
00459         \endcode 
00460         for a class which does both zero and finite temperature
00461         calculations as a function of density.
00462     */
00463     //@{
00464     int provides;
00465     static const int provides_calc_e=1;
00466     static const int provides_calc_p=2;
00467     static const int provides_calc_temp_e=4;
00468     static const int provides_calc_temp_p=8;
00469     //@}
00470     
00471     /// Compute t1 for gradient_qij().
00472     double t1_fun(double barn, void *&vp);
00473     
00474     /// Compute t2 for gradient_qij().
00475     double t2_fun(double barn, void *&vp);
00476     
00477     friend class io_tlate<hadronic_eos>;
00478 
00479     /// The EOS solver
00480     mroot<void *,mm_funct<void *> > *eos_mroot;
00481     
00482     /// The solver to compute saturation properties
00483     root<void *,funct<void *> > *sat_root;
00484 
00485     /// The derivative object for saturation properties
00486     deriv<void *,funct<void *> > *sat_deriv;
00487 
00488     /// The second derivative object for saturation properties
00489     deriv<bool,funct<bool> > *sat_deriv2;
00490 
00491     /// The neutron object
00492     fermion *neutron;
00493 
00494     /// The proton object
00495     fermion *proton;
00496 
00497     /// Temporary proton fraction
00498     double proton_frac;
00499     
00500     /// Temporary baryon number
00501     double n_baryon;
00502     
00503     /** 
00504         \brief Return the symmetry energy at density \c nb.
00505         
00506         Used by fesym_slope().
00507     */
00508     double calc_esym(double nb, bool &alt);
00509 
00510     /// Chemical potential parameters [protected]
00511     typedef struct mupar_s { 
00512       double mun, mup;
00513       double T;
00514     } mupar;
00515 
00516     /// Density parameters [protected]
00517     typedef struct denpar_s {
00518       double nn, np;
00519       double T;
00520     } denpar;
00521     
00522 #endif
00523     
00524   };
00525 
00526   template<> int io_tlate<hadronic_eos>::input
00527     (cinput *co, in_file_format *ins, hadronic_eos *he);
00528   template<> int io_tlate<hadronic_eos>::output
00529     (coutput *co, out_file_format *outs, hadronic_eos *he);
00530   template<> const char *io_tlate<hadronic_eos>::type();
00531 
00532   typedef io_tlate<hadronic_eos> hadronic_eos_io_type;
00533 
00534 #ifndef DOXYGENP
00535 }
00536 #endif
00537 
00538 #endif
00539 

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