Equation of State Sub-Library: Version 0.910
ex_apr_eos.cpp
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 
00024 /* Example: ex_apr_eos.cpp
00025    -------------------------------------------------------------------
00026 */
00027 #include <iostream>
00028 #include <cmath>
00029 #include <o2scl/apr_eos.h>
00030 #include <o2scl/table.h>
00031 #include <o2scl/constants.h>
00032 #include <o2scl/nonrel_fermion.h>
00033 #include <o2scl/tov_solve.h>
00034 #include <o2scl/cern_deriv.h>
00035 #include <o2scl/cern_mroot.h>
00036 #include <o2scl/hdf_io.h>
00037 #include <o2scl/test_mgr.h>
00038 
00039 using namespace std;
00040 using namespace o2scl;
00041 using namespace o2scl_hdf;
00042 using namespace o2scl_const;
00043 using namespace gsl_cgs;
00044 
00045 /** \brief Compute the APR EOS with a Gibbs construction and
00046     the mass versus radius curve [Example class]
00047     
00048     In succession, calculates nuclear matter, neutron matter, and
00049     then neutron star matter with Maxwell and Gibbs constructions.
00050     
00051     We could use the more accurate masses in <o2scl/constants.h> here,
00052     but APR appears to have been designed to be used with m_n = m_p =
00053     939 MeV.
00054 */
00055 class ex_apr_eos {
00056   
00057 protected:
00058   
00059   /// Neutron for low-density phase
00060   fermion n;
00061   /// Proton for low-density phase
00062   fermion p;
00063   /// Neutron for high-density phase
00064   fermion n2;
00065   /// Proton for high-density phase
00066   fermion p2;
00067   /// Compute zero-temperature thermodynamics
00068   fermion_zerot fzt;
00069   /// Electron for low-density phase
00070   fermion e;
00071   /// Muon for low-density phase
00072   fermion mu;
00073   /// Electron for high-density phase
00074   fermion e2;
00075   /// Muon for high-density phase
00076   fermion mu2;
00077   /// Baryon thermodynamics for low-density phase
00078   thermo hb;
00079   /// Leptonic thermodynamics for low-density phase
00080   thermo l;
00081   /// Baryon thermodynamics for high-density phase
00082   thermo hb2;
00083   /// Total thermodynamics
00084   thermo tot;
00085   /// Leptonic thermodynamics for high-density phase
00086   thermo l2;
00087   /// Solver
00088   gsl_mroot_hybrids<> nd;
00089   /// Solver
00090   gsl_mroot_hybrids<> nd2;
00091   /// Solver for saturation properties
00092   gsl_mroot_hybrids<> sat_solver;
00093   /// Baryon density
00094   double nb;
00095   /// Volume fraction of low-density phase
00096   double chi;
00097   /// Baryon chemical potential
00098   double mub;
00099   /// Charge chemical potential
00100   double muq;
00101   /// Proton fraction for Fig. 7
00102   double f7x;
00103   /// Choice of model from APR
00104   int choice;
00105   /// \name Phase specification
00106   //@{
00107   int phase;
00108   static const int low_phase=1;
00109   static const int mixed_phase=2;
00110   static const int high_phase=3;
00111   //@}
00112   /// Base APR EOS
00113   apr_eos ap;
00114   /// Table for output
00115   table_units at;
00116   /// Derivative object
00117   cern_deriv<funct> cd;
00118   /// HDF file for output
00119   hdf_file hf;
00120 
00121   /// Function for the Maxwell construction in Fig. 7
00122   int maxwell_fig7(size_t nv, const ovector_base &x, ovector_base &y) {
00123 
00124     n.n=x[0];
00125     p.n=x[1];
00126     n2.n=x[2];
00127     p2.n=x[3];
00128 
00129     if (x[0]<0.0 || x[1]<0.0 || x[2]<0.0 || x[3]<0.0) return 1;
00130 
00131     ap.pion=1;
00132     ap.calc_e(n,p,hb);
00133 
00134     e.mu=n.mu-p.mu;
00135     mu.mu=e.mu;
00136     fzt.calc_mu_zerot(e);
00137     fzt.calc_mu_zerot(mu);
00138     l.ed=e.ed+mu.ed;
00139     l.pr=e.pr+mu.pr;
00140     l.en=e.en+mu.en;
00141 
00142     ap.pion=2;
00143     ap.calc_e(n2,p2,hb2);
00144 
00145     e2.mu=n2.mu-p2.mu;
00146     mu2.mu=e2.mu;
00147     fzt.calc_mu_zerot(e2);
00148     fzt.calc_mu_zerot(mu2);
00149     l2.ed=e2.ed+mu2.ed;
00150     l2.pr=e2.pr+mu2.pr;
00151     l2.en=e2.en+mu2.en;
00152 
00153     y[0]=p.n-e.n-mu.n;
00154     y[1]=n.mu-n2.mu;
00155     y[2]=hb.pr-hb2.pr;
00156     y[3]=p2.n-e2.n-mu2.n;
00157 
00158     return 0;
00159   }
00160 
00161   /// Maxwell construction of the nuclear matter mixed phase 
00162   int mixedmaxwell(size_t nv, const ovector_base &x, ovector_base &y) {
00163     n.n=x[0];
00164     p.n=x[1];
00165     n2.n=x[2];
00166     p2.n=x[3];
00167     chi=x[4];
00168   
00169     ap.pion=1;
00170     ap.calc_e(n,p,hb);
00171 
00172     e.mu=n.mu-p.mu;
00173     mu.mu=e.mu;
00174     fzt.calc_mu_zerot(e);
00175     fzt.calc_mu_zerot(mu);
00176     l.ed=e.ed+mu.ed;
00177     l.pr=e.pr+mu.pr;
00178     l.en=e.en+mu.en;
00179 
00180     ap.pion=2;
00181     ap.calc_e(n2,p2,hb2);
00182 
00183     e2.mu=n2.mu-p2.mu;
00184     mu2.mu=e2.mu;
00185     fzt.calc_mu_zerot(e2);
00186     fzt.calc_mu_zerot(mu2);
00187     l2.ed=e2.ed+mu2.ed;
00188     l2.pr=e2.pr+mu2.pr;
00189     l2.en=e2.en+mu2.en;
00190 
00191     y[0]=nb-chi*(n.n+p.n)-(1.0-chi)*(n2.n+p2.n);
00192     y[1]=n.mu-n2.mu;
00193     y[2]=hb.pr-hb2.pr;
00194     y[3]=p.n-e.n-mu.n;
00195     y[4]=p2.n-e2.n-mu2.n;
00196   
00197     return 0;
00198   }
00199 
00200   /// Function to construct Fig. 7
00201   int fig7fun(size_t nv, const ovector_base &x, ovector_base &y) {
00202 
00203     nb=x[0];
00204     p.n=f7x*nb;
00205     n.n=nb-p.n;
00206 
00207     p2.n=f7x*nb;
00208     n2.n=nb-p2.n;
00209   
00210     ap.pion=1;
00211     ap.calc_e(n,p,hb);
00212 
00213     ap.pion=2;
00214     ap.calc_e(n2,p2,hb2);
00215 
00216     y[0]=hb.ed-hb2.ed;
00217 
00218     return 0;
00219   }
00220 
00221   /// Solve for neutron star matter (low-density phase)
00222   int nstar(size_t nv, const ovector_base &x, ovector_base &y) {
00223   
00224     n.n=x[0];
00225     p.n=nb-n.n;
00226   
00227     if (n.n<0.0 || p.n<0.0) {
00228       return 1;
00229     }
00230 
00231     ap.pion=1;
00232     ap.calc_e(n,p,hb);
00233 
00234     e.mu=n.mu-p.mu;
00235     mu.mu=e.mu;
00236     fzt.calc_mu_zerot(e);
00237     fzt.calc_mu_zerot(mu);
00238     l.ed=e.ed+mu.ed;
00239     l.pr=e.pr+mu.pr;
00240     l.en=e.en+mu.en;
00241   
00242     y[0]=p.n-e.n-mu.n;
00243 
00244     tot.pr=hb.pr+l.pr;
00245     tot.ed=hb.ed+l.ed;
00246 
00247     return 0;
00248   }
00249 
00250   /// Solve for neutron star matter (high-density phase)
00251   int nstar2(size_t nv, const ovector_base &x, ovector_base &y) {
00252 
00253     n2.n=x[0];
00254     p2.n=nb-n2.n;
00255     
00256     if (n2.n<0.0 || p2.n<0.0) return 1;
00257 
00258     ap.pion=2;
00259     ap.calc_e(n2,p2,hb2);
00260 
00261     e.mu=n2.mu-p2.mu;
00262     mu.mu=e.mu;
00263     fzt.calc_mu_zerot(e);
00264     fzt.calc_mu_zerot(mu);
00265     l.ed=e.ed+mu.ed;
00266     l.pr=e.pr+mu.pr;
00267     l.en=e.en+mu.en;
00268   
00269     y[0]=p2.n-e.n-mu.n;
00270 
00271     tot.pr=hb2.pr+l.pr;
00272     tot.ed=hb2.ed+l.ed;
00273   
00274     return 0;
00275   }
00276 
00277   /// Solve for neutron star matter (mixed phase)
00278   int nstarmixed(size_t nv, const ovector_base &x, ovector_base &y) {
00279 
00280     n.n=x[0];
00281     p.n=x[1];
00282     e.mu=x[2];
00283     n2.n=x[3];
00284     p2.n=x[4];
00285     mu.mu=e.mu;
00286 
00287     if (phase==low_phase) chi=1.0;
00288     else if (phase==high_phase) chi=0.0;
00289     else chi=x[5];
00290 
00291     if (n.n<0.0 || n2.n<0.0) return 1;
00292     if (p.n<0.0 || p2.n<0.0) return 1;
00293 
00294     ap.pion=1;
00295     ap.calc_e(n,p,hb);
00296   
00297     ap.pion=2;
00298     ap.calc_e(n2,p2,hb2);
00299 
00300     fzt.calc_mu_zerot(e);
00301     fzt.calc_mu_zerot(mu);
00302     l.ed=e.ed+mu.ed;
00303     l.pr=e.pr+mu.pr;
00304     l.en=e.en+mu.en;
00305   
00306     y[0]=nb-chi*(n.n+p.n)-(1.0-chi)*(n2.n+p2.n);
00307     y[1]=chi*p.n+(1.0-chi)*p2.n-e.n-mu.n;
00308     y[2]=n.mu-p.mu-e.mu;
00309     y[3]=p2.mu-p.mu;
00310     y[4]=n.mu-n2.mu;
00311 
00312     if (phase==mixed_phase) y[5]=hb.pr-hb2.pr;
00313 
00314     if (phase==low_phase) {
00315       tot.pr=hb.pr+l.pr;
00316       tot.ed=hb.ed+l.ed;
00317     } else if (phase==mixed_phase) {
00318       tot.pr=hb.pr+l.pr;
00319       tot.ed=hb.ed*chi+hb2.ed*(1.0-chi)+l.ed;
00320     } else {
00321       tot.pr=hb2.pr+l.pr;
00322       tot.ed=hb2.ed+l.ed;
00323     }
00324 
00325     return 0;
00326   }
00327 
00328   /// Write a line of data to the table
00329   void store_data() {
00330 
00331     ovector line;
00332     line.push_back(tot.ed);
00333     line.push_back(tot.pr);
00334     line.push_back(nb);
00335     line.push_back((chi*n.n+(1.0-chi)*n2.n));
00336     line.push_back((chi*p.n+(1.0-chi)*p2.n));
00337     line.push_back(n.n);
00338     line.push_back(p.n);
00339     line.push_back(n2.n);
00340     line.push_back(p2.n);
00341     line.push_back(chi);
00342     line.push_back(e.n);
00343     line.push_back(mu.n);
00344     line.push_back(n.mu);
00345     line.push_back(p.mu);
00346     line.push_back(e.mu);
00347     line.push_back(mu.mu);
00348     line.push_back(n.ms);
00349     line.push_back(p.ms);
00350     line.push_back(n2.ms);
00351     line.push_back(p2.ms);
00352     line.push_back(n.kf);
00353     line.push_back(p.kf);
00354     line.push_back(n2.kf);
00355     line.push_back(p2.kf);
00356     line.push_back(e.kf);
00357     line.push_back(mu.kf);
00358     if (line.size()!=at.get_ncolumns()) {
00359       O2SCL_ERR("Table misaligned.",gsl_efailed);
00360     }
00361   
00362     at.line_of_data(line.size(),line);
00363     return;
00364   }
00365 
00366   /// Solve for nuclear matter (mixed phase)
00367   int nucmixed(size_t nv, const ovector_base &x, ovector_base &y) {
00368 
00369     n.n=x[0];
00370     n2.n=x[1];
00371 
00372     if (phase==low_phase) chi=1.0;
00373     else if (phase==high_phase) chi=0.0;
00374     else chi=x[2];
00375 
00376     if (n.n<0.0 || n2.n<0.0) return 1;
00377 
00378     p.n=n.n;
00379     p2.n=n2.n;
00380 
00381     ap.pion=1;
00382     ap.calc_e(n,p,hb);
00383   
00384     ap.pion=2;
00385     ap.calc_e(n2,p2,hb2);
00386   
00387     y[0]=n.mu-n2.mu;
00388     y[1]=nb-chi*(n.n+p.n)-(1.0-chi)*(n2.n+p2.n);
00389 
00390     if (phase==mixed_phase) y[2]=hb.pr-hb2.pr;
00391 
00392     if (phase==low_phase) {
00393       tot.pr=hb.pr;
00394       tot.ed=hb.ed;
00395     } else if (phase==mixed_phase) {
00396       tot.pr=hb.pr;
00397       tot.ed=hb.ed*chi+hb2.ed*(1.0-chi);
00398     } else {
00399       tot.pr=hb2.pr;
00400       tot.ed=hb2.ed;
00401     }
00402  
00403 
00404     return 0;
00405   }
00406 
00407   /// Solve for neutron matter (mixed phase)
00408   int neutmixed(size_t nv, const ovector_base &x, ovector_base &y) {
00409 
00410     n.n=x[0];
00411     n2.n=x[1];
00412 
00413     if (phase==low_phase) chi=1.0;
00414     else if (phase==high_phase) chi=0.0;
00415     else chi=x[2];
00416 
00417     if (n.n<0.0 || n2.n<0.0) return 1;
00418 
00419     p.n=0.0;
00420     p2.n=0.0;
00421 
00422     ap.pion=1;
00423     ap.calc_e(n,p,hb);
00424   
00425     ap.pion=2;
00426     ap.calc_e(n2,p2,hb2);
00427   
00428     y[0]=n.mu-n2.mu;
00429     y[1]=nb-chi*(n.n+p.n)-(1.0-chi)*(n2.n+p2.n);
00430 
00431     if (phase==mixed_phase) y[2]=hb.pr-hb2.pr;
00432 
00433     if (phase==low_phase) {
00434       tot.pr=hb.pr;
00435       tot.ed=hb.ed;
00436     } else if (phase==mixed_phase) {
00437       tot.pr=hb.pr;
00438       tot.ed=hb.ed*chi+hb2.ed*(1.0-chi);
00439     } else {
00440       tot.pr=hb2.pr;
00441       tot.ed=hb2.ed;
00442     }
00443  
00444     return 0;
00445   }
00446 
00447   /// Solve for phase transition to nuclei
00448   int nucleimat(size_t nv, const ovector_base &ex, ovector_base &ey) {
00449 
00450     double nn1,np1,mun1,mup1;
00451     double nn2,np2,mun2,mup2;
00452     double u=0.0;
00453     thermo th1, th2;
00454 
00455     n.n=ex[0];
00456     p.n=ex[1];
00457     ap.pion=1;
00458     ap.calc_e(n,p,th1);
00459     nn1=n.n;
00460     np1=p.n;
00461     mun1=n.mu;
00462     mup1=p.mu;
00463   
00464     n.n=ex[2];
00465     p.n=0.0;
00466     ap.pion=1;
00467     ap.calc_e(n,p,th2);
00468     nn2=n.n;
00469     np2=p.n;
00470     mun2=n.mu;
00471     mup2=p.mu;
00472   
00473     e.mu=mun1-mup1;
00474     fzt.calc_mu_zerot(e);
00475     l.ed=e.ed;
00476     l.pr=e.pr;
00477     l.en=e.en;
00478     if (nv>3) u=ex[3];
00479     else u=1.0;
00480   
00481     ey[0]=(mun1-mun2)/1.0; 
00482     ey[1]=(th1.pr-th2.pr)/1.0; 
00483     ey[2]=u*np1-e.n;
00484     if (nv>3)ey[3]= barn-u*(np1+nn1)-(1.0-u)*nn2;
00485   
00486     tot.pr=th1.pr+e.pr;
00487     hb.ed=u*th1.ed+(1.0-u)*th2.ed;
00488     tot.ed=u*th1.ed+(1.0-u)*th2.ed+e.ed;
00489 
00490     n.n=ex[0];
00491     p.n=ex[1];
00492     ap.pion=1;
00493     ap.calc_e(n,p,th1);
00494   
00495     return 0;
00496   }
00497 
00498   /// Solve for phase transition to nuclei with a proton drip
00499   int nucleimat_pdrip(size_t nv, const ovector_base &ex, ovector_base &ey) {
00500 
00501     double nn1,np1,mun1,mup1;
00502     double nn2,np2,mun2,mup2;
00503     double u=0.0;
00504     thermo th1, th2;
00505 
00506     if (ex[0]<0.0 || ex[1]<0.0 || ex[2]<0.0 || ex[3]<0.0) {
00507       return 1;
00508     }
00509 
00510     n.n=ex[0];
00511     p.n=ex[1];
00512     ap.pion=1;
00513     ap.calc_e(n,p,th1);
00514     nn1=n.n;
00515     np1=p.n;
00516     mun1=n.mu;
00517     mup1=p.mu;
00518   
00519     n.n=ex[2];
00520     p.n=ex[3];
00521     ap.pion=1;
00522     ap.calc_e(n,p,th2);
00523     nn2=n.n;
00524     np2=p.n;
00525     mun2=n.mu;
00526     mup2=p.mu;
00527   
00528     e.mu=mun1-mup1;
00529     fzt.calc_mu_zerot(e);
00530     l.ed=e.ed;
00531     l.pr=e.pr;
00532     l.en=e.en;
00533     if (nv>4) u=ex[4];
00534     else u=1.0;
00535   
00536     ey[0]=(mun1-mun2)/1.0; 
00537     ey[1]=(th1.pr-th2.pr)/1.0; 
00538     ey[2]=e.n-u*np1-(1.0-u)*np2;
00539     ey[3]=(mup1-mup2)/1.0;
00540     if (nv>4) ey[4]=barn-u*(np1+nn1)-(1.0-u)*(nn2+np2);
00541   
00542     tot.pr=th1.pr+e.pr;
00543     hb.ed=u*th1.ed+(1.0-u)*th2.ed;
00544     tot.ed=u*th1.ed+(1.0-u)*th2.ed+e.ed;
00545 
00546     n.n=ex[0];
00547     p.n=ex[1];
00548     ap.pion=1;
00549     ap.calc_e(n,p,th1);
00550   
00551     return 0;
00552   }
00553 
00554 public:
00555 
00556   ex_apr_eos() {
00557 
00558     n.init(939.0/hc_mev_fm,2.0);
00559     p.init(939.0/hc_mev_fm,2.0);
00560     n2.init(939.0/hc_mev_fm,2.0);
00561     p2.init(939.0/hc_mev_fm,2.0);
00562     e.init(o2scl_fm::mass_electron,2.0);
00563     mu.init(o2scl_fm::mass_muon,2.0);
00564     e2.init(o2scl_fm::mass_electron,2.0);
00565     mu2.init(o2scl_fm::mass_muon,2.0);
00566     n.non_interacting=false;
00567     p.non_interacting=false;
00568     n2.non_interacting=false;
00569     p2.non_interacting=false;
00570 
00571     at.inc_maxlines(2000);
00572   }
00573 
00574   /// Main driver, computing the APR EOS and the associated M vs. R curve
00575   void run() {
00576 
00577     test_mgr t;
00578     t.set_output_level(1);
00579 
00580     // Output directory
00581     std::string prefix="ex_apr_";
00582     cout << "Set output prefix to '" << prefix << "' ." << endl;
00583     cout << endl;
00584 
00585     // Density grid
00586     double nbstart, nb_end, dnb;
00587 
00588     // Density at which to start looking for a mixed phase
00589     double nb_switch;
00590 
00591     // Temporary filename
00592     string filenm;
00593 
00594     // Error code value
00595     int ret;
00596 
00597     // Output file stream
00598     ofstream fout;
00599 
00600     // Variables and function values for solvers
00601     ovector x(7), y(7), xx(3), yy(3);
00602   
00603     // Function objects
00604     mm_funct_mfptr<ex_apr_eos> f_nucmixed(this,&ex_apr_eos::nucmixed);
00605     mm_funct_mfptr<ex_apr_eos> f_neutmixed(this,&ex_apr_eos::neutmixed);
00606     mm_funct_mfptr<ex_apr_eos> f_nstarmixed(this,&ex_apr_eos::nstarmixed);
00607     mm_funct_mfptr<ex_apr_eos> f_nstar(this,&ex_apr_eos::nstar);
00608     mm_funct_mfptr<ex_apr_eos> f_nstar2(this,&ex_apr_eos::nstar2);
00609     mm_funct_mfptr<ex_apr_eos> f_fig7fun(this,&ex_apr_eos::fig7fun);
00610     mm_funct_mfptr<ex_apr_eos> f_maxwell_fig7(this,&ex_apr_eos::maxwell_fig7);
00611     mm_funct_mfptr<ex_apr_eos> f_mixedmaxwell(this,&ex_apr_eos::mixedmaxwell);
00612 
00613     // Init density grid
00614     nbstart=0.005;
00615     dnb=0.002;
00616     nb_end=2.0;
00617 
00618     // Select APR EOS
00619     choice=1;
00620     ap.select(choice);
00621 
00622     // Init solver tolerances
00623     nd.tol_abs=1.0e-10;
00624     nd.tol_rel=1.0e-12;
00625     nd2.tol_abs=1.0e-10;
00626     nd2.tol_rel=1.0e-12;
00627     sat_solver.tol_abs=1.0e-10;
00628     sat_solver.tol_rel=1.0e-12;
00629 
00630     // Initialize table
00631     at.line_of_names(((string)("ed pr nb "))+
00632                      "nn np nn1 np1 nn2 np2 chi ne nmu "+
00633                      "mun mup mue mumu "+
00634                      "msn msp msn2 msp2 kfn kfp kfn2 kfp2 kfe kfmu");
00635     at.set_unit("ed","1/fm^4");
00636     at.set_unit("pr","1/fm^4");
00637     at.set_unit("nb","1/fm^3");
00638     at.set_unit("nn","1/fm^3");
00639     at.set_unit("np","1/fm^3");
00640     at.set_unit("nn1","1/fm^3");
00641     at.set_unit("np1","1/fm^3");
00642     at.set_unit("nn2","1/fm^3");
00643     at.set_unit("np2","1/fm^3");
00644     at.set_unit("ne","1/fm^3");
00645     at.set_unit("nmu","1/fm^3");
00646     at.set_unit("mun","1/fm");
00647     at.set_unit("mup","1/fm");
00648     at.set_unit("mue","1/fm");
00649     at.set_unit("mumu","1/fm");
00650     at.set_unit("msn","1/fm");
00651     at.set_unit("msp","1/fm");
00652     at.set_unit("msn2","1/fm");
00653     at.set_unit("msp2","1/fm");
00654     at.set_unit("kfn","1/fm");
00655     at.set_unit("kfp","1/fm");
00656     at.set_unit("kfn2","1/fm");
00657     at.set_unit("kfp2","1/fm");
00658     at.set_unit("kfe","1/fm");
00659     at.set_unit("kfmu","1/fm");
00660     
00661     //--------------------------------------------------------------------
00662     // Saturation properties
00663 
00664     ap.set_thermo(hb);
00665     ap.set_mroot(sat_solver);
00666     ap.set_n_and_p(n,p);
00667     if (ap.saturation()!=0) {
00668       O2SCL_ERR("Calculation of saturation properties failed.",
00669                 gsl_efailed);
00670     }
00671 
00672     cout << "--------- Saturation -------------------------------\n" << endl;
00673     cout << "n_0: " << ap.n0 << " fm^{-3}\nE_B: " << ap.eoa*hc_mev_fm 
00674          << " MeV\nK: " << ap.comp*hc_mev_fm << " MeV\nS: " 
00675          << ap.esym*hc_mev_fm << " MeV\nM^{*}/M: " << ap.msom << endl;
00676     cout << endl;
00677     
00678     //--------------------------------------------------------------------
00679     // Nuclear matter
00680 
00681     cout << "--------- Nuclear matter ---------------------------\n" << endl;
00682 
00683     // Begin with just the low density phase
00684 
00685     nb_switch=0.19;
00686 
00687     ap.pion=1;
00688     chi=1.0;
00689     at.clear_data();
00690     for(nb=nbstart;nb<nb_switch;nb+=dnb) {
00691     
00692       n.n=nb/2.0;
00693       p.n=n.n;
00694       
00695       ret=ap.calc_e(n,p,hb);
00696       if (ret!=0) {
00697         O2SCL_ERR("Failed to compute nuclear matter.",gsl_efailed);
00698       }
00699       tot.pr=hb.pr;
00700       tot.ed=hb.ed;
00701       
00702       store_data();
00703     }
00704   
00705     phase=low_phase;
00706     x[0]=nb_switch/2.0;
00707     x[1]=x[0];
00708 
00709     // Now start searching for the mixed phase
00710   
00711     for(nb=nb_switch;nb<=nb_end;nb+=dnb) {
00712     
00713       if (phase!=2) ret=nd.msolve(2,x,f_nucmixed);
00714       else ret=nd.msolve(3,x,f_nucmixed);
00715       if (ret!=0) {
00716         cout << nb << endl;
00717         O2SCL_ERR("Solving nuclear matter failed.",
00718                   gsl_efailed);
00719       }
00720     
00721       if (hb.pr<hb2.pr && phase==low_phase) {
00722         cout << "Mixed phase begins near nb=" << nb << "." << endl;
00723         phase=mixed_phase;
00724         // Pick a value of chi close to, but less than, one
00725         x[2]=0.90;
00726         nb-=dnb;
00727       } else if (phase==mixed_phase && x[2]<0.0) {
00728         cout << "Mixed phase ends near nb=" << nb << "." << endl;
00729         phase=high_phase;
00730         nb-=dnb;
00731       } else {
00732         store_data();
00733       }
00734     }
00735     
00736     string fn1=((string)prefix)+"nuc.o2";
00737     hf.open(fn1);
00738     hdf_output(hf,at,"nuc");
00739     hf.close();
00740     cout << "Generated nuc.o2." << endl;
00741 
00742     cout << endl;
00743     
00744     //--------------------------------------------------------------------
00745     // Neutron matter
00746 
00747     cout << "--------- Neutron matter ---------------------------\n" << endl;
00748 
00749     ap.pion=1;
00750     chi=1.0;
00751     at.clear_data();
00752 
00753     nb_switch=0.16;
00754 
00755     // Begin with just the low density phase
00756 
00757     for(nb=nbstart;nb<nb_switch;nb+=dnb) {
00758     
00759       n.n=nb;
00760       p.n=0.0;
00761 
00762       ret=ap.calc_e(n,p,hb);
00763       if (ret!=0) {
00764         O2SCL_ERR("Failed to compute neutron matter.",gsl_efailed);
00765       }
00766 
00767       tot.pr=hb.pr;
00768       tot.ed=hb.ed;
00769     
00770       store_data();
00771     }
00772 
00773     phase=low_phase;
00774     x[0]=nb_switch;
00775     x[1]=nb_switch;
00776   
00777     // Now start searching for the mixed phase
00778   
00779     for(nb=nb_switch;nb<=nb_end;nb+=dnb) {
00780 
00781       if (phase!=2) {
00782         ret=nd.msolve(2,x,f_neutmixed);
00783       } else {
00784         ret=nd.msolve(3,x,f_neutmixed);
00785       }
00786       if (ret!=0) {
00787         cout << nb << endl;
00788         O2SCL_ERR("Solving neutron matter failed.",
00789                   gsl_efailed);
00790       }
00791 
00792       if (hb.pr<hb2.pr && phase==low_phase) {
00793         cout << "Mixed phase begins near nb=" << nb << "." << endl;
00794         phase=mixed_phase;
00795         // Pick a value of chi close to, but less than, one
00796         x[2]=0.90;
00797         nb-=dnb;
00798       } else if (phase==mixed_phase && x[2]<0.0) {
00799         cout << "Mixed phase ends near nb=" << nb << "." << endl;
00800         phase=high_phase;
00801         nb-=dnb;
00802       } else {
00803         store_data();
00804       }
00805     }
00806 
00807     string fn2=((string)prefix)+"neut.o2";
00808     hf.open(fn2);
00809     hdf_output(hf,at,"neut");
00810     hf.close();
00811     cout << "Generated neut.o2." << endl;
00812 
00813     cout << endl;
00814 
00815     //--------------------------------------------------------------------
00816     // Neutron star matter - Maxwell construction
00817 
00818     cout << "--------- Neutron star matter ----------------------\n" << endl;
00819 
00820     cout << "Maxwell construction:" << endl;
00821   
00822     // Verify Figure 7
00823 
00824     filenm=prefix;
00825     filenm+="apr_fig7.1.o2";
00826     fout.open(filenm.c_str());
00827     fout.setf(ios::scientific);
00828     x[0]=0.32;
00829     for(f7x=0.5;f7x>=-0.001;f7x-=0.025) {
00830       ret=nd.msolve(1,x,f_fig7fun);
00831       if (ret!=0) {
00832         O2SCL_ERR("Failed to perform maxwell.",gsl_efailed);
00833       }
00834       fout << f7x << " " << x[0] << endl;
00835     }
00836     fout.close();
00837     cout << "Generated apr_fig7.1.o2." << endl;
00838 
00839     // Compute the beginning and ending densities
00840     // for the Maxwell construction
00841 
00842     x[0]=0.94*0.2;
00843     x[1]=0.06*0.2;
00844     x[2]=0.95*0.24;
00845     x[3]=0.05*0.24;
00846     nd.msolve(4,x,f_maxwell_fig7);
00847 
00848     double nb_low=x[0]+x[1], nb_high=x[2]+x[3];
00849     cout << "Mixed phase begins at nb=" << nb_low << "." << endl;
00850     cout << "Mixed phase ends at nb=" << nb_high << "." << endl;
00851     x[0]=nbstart/1.1;
00852 
00853     filenm=prefix; 
00854     filenm+="apr_fig7.2.o2";
00855     fout.open(filenm.c_str());
00856     
00857     /// Compute matter at densities below the maxwell construction
00858 
00859     for(nb=0.02;nb<nb_low*1.00001;nb+=(nb_low-nbstart)/20.0) {
00860       ret=nd.msolve(1,x,f_nstar);
00861       if (ret!=0) {
00862         cout << nb << endl;
00863         f_nstar(1,x,y);
00864         cout << x[0] << " " << y[0] << endl;
00865         O2SCL_ERR("Solving Maxwell construction failed.",
00866                   gsl_efailed);
00867       }
00868       fout << p.n/nb << " " << nb << endl;
00869     }
00870 
00871     // Compute matter at densities inside the Maxwell construction
00872 
00873     x[0]=(1.0-0.07)*nb_low;
00874     x[1]=0.07*nb_low;
00875     x[2]=(1.0-0.06)*nb_high;
00876     x[3]=0.06*nb_high;
00877     x[4]=1.0;
00878     dnb=(nb_high-nb_low)/20.0;
00879     for(nb=nb_low+dnb;nb<=nb_high*1.00001;nb+=dnb) {
00880       ret=nd.msolve(5,x,f_mixedmaxwell);
00881       if (ret!=0) {
00882         cout << nb << endl;
00883         O2SCL_ERR("Solving Maxwell construction (part 2) failed.",
00884                   gsl_efailed);
00885       }
00886       fout << (chi*p.n+(1.0-chi)*p2.n)/nb << " " << nb << endl;
00887     }
00888     
00889     // Compute matter at densities above the Maxwell construction
00890     
00891     x[0]=0.23;
00892     for(nb=nb_high;nb<nb_end;nb+=(nb_end-nb_high)/40.0) {
00893       ret=nd.msolve(1,x,f_nstar2);
00894       if (ret!=0) {
00895         cout << nb << endl;
00896         O2SCL_ERR("Solving Maxwell construction (part 3) failed.",
00897                   gsl_efailed);
00898       }
00899       fout << p2.n/nb << " " << nb << endl;
00900     }
00901     fout.close();
00902     cout << "Generated apr_fig7.2.o2." << endl;
00903     
00904     //--------------------------------------------------------------------
00905     // Neutron star matter - Gibbs construction
00906 
00907     cout << "\nGibbs construction." << endl;
00908   
00909     dnb=0.002;
00910     ap.pion=1;
00911     chi=1.0;
00912     at.clear_data();
00913 
00914     x[0]=nbstart/1.1;
00915     for(nb=nbstart;nb<=0.1701;nb+=dnb) {
00916       ret=nd.msolve(1,x,f_nstar);
00917       if (ret!=0) {
00918         cout << nb << endl;
00919         O2SCL_ERR("Solving Gibbs construction failed.",
00920                   gsl_efailed);
00921       }
00922       store_data();
00923     }
00924     nb-=dnb;
00925   
00926     phase=low_phase;
00927     x[0]=n.n;
00928     x[1]=p.n;
00929     x[2]=n.mu-p.mu;
00930     x[3]=n.n;
00931     x[4]=p.n;
00932   
00933     for(nb=0.17;nb<=nb_end;nb+=dnb) {
00934     
00935       if (phase!=2) {
00936         ret=nd.msolve(5,x,f_nstarmixed);
00937         nstarmixed(5,x,y);
00938       } else {
00939         ret=nd.msolve(6,x,f_nstarmixed);
00940       }
00941       if (ret!=0) {
00942         cout << "Solving Gibbs construction (part 2) failed." << endl;
00943         cout << nb << endl;
00944         cout << err_hnd->get_str() << endl;
00945         exit(-1);
00946       }
00947     
00948       if (hb.pr<hb2.pr && phase==low_phase) {
00949         cout << "Mixed phase begins at nb=" << nb << "." << endl;
00950         phase=mixed_phase;
00951         x[5]=0.90;
00952         nb-=dnb;
00953       } else if (phase==mixed_phase && x[5]<0.0) {
00954         cout << "Mixed phase ends at nb=" << nb << "." << endl;
00955         phase=high_phase;
00956         nb-=dnb;
00957       } else {
00958         store_data();
00959       }
00960     }
00961   
00962     //--------------------------------------------------------------------
00963     // Estimate transition density 
00964     
00965     cout << "\nEstimate of transition density:" << endl;
00966   
00967     ovector newx(12), newy(12);
00968     mm_funct_mfptr<ex_apr_eos> nuclei_f(this,&ex_apr_eos::nucleimat);
00969     mm_funct_mfptr<ex_apr_eos> nucleip_f(this,&ex_apr_eos::nucleimat_pdrip);
00970     nd2.tol_abs/=1.0e4;
00971     nd2.tol_rel/=1.0e4;
00972   
00973     newx[0]=0.1;
00974     newx[1]=0.001;
00975     newx[2]=0.1;
00976     ret=nd2.msolve(3,newx,nuclei_f);
00977     if (ret!=0) {
00978       nucleimat(3,newx,newy);
00979       if (fabs(newy[0])>1.0e-8 || fabs(newy[1])>1.0e-8 ||
00980           fabs(newy[2])>1.0e-8) {
00981         cout << endl;
00982         cout << "Problem in transition density (1)." << endl;
00983         cout << err_hnd->get_str() << endl;
00984         cout << newx[0] << " " << newy[0] << endl;
00985         cout << newx[1] << " " << newy[1] << endl;
00986         cout << newx[2] << " " << newy[2] << endl;
00987         cout << endl;
00988       }
00989     }
00990     cout << "Without proton drip, density: " << newx[0]+newx[1] 
00991          << " pressure: " << at.interp("nb",newx[0]+newx[1],"pr") << endl;
00992 
00993     nd2.tol_abs=5.0e-8;
00994     nd2.tol_rel=5.0e-8;
00995   
00996     newx[3]=0.001;
00997     ret=nd2.msolve(4,newx,nucleip_f);
00998     if (ret!=0) {
00999       nucleimat_pdrip(4,newx,newy);
01000       if (fabs(newy[0])>1.0e-8 || fabs(newy[1])>1.0e-8 ||
01001           fabs(newy[2])>1.0e-8 || fabs(newy[3])>1.0e-8) {
01002         cout << endl;
01003         cout << "Problem in transition density (2)." << endl;
01004         cout << err_hnd->get_str() << endl;
01005         cout << newx[0] << " " << newy[0] << endl;
01006         cout << newx[1] << " " << newy[1] << endl;
01007         cout << newx[2] << " " << newy[2] << endl;
01008         cout << newx[3] << " " << newy[3] << endl;
01009         cout << endl;
01010       }
01011     }
01012     cout << "With proton drip, density: " << newx[0]+newx[1] 
01013          << " pressure: " << at.interp("nb",newx[0]+newx[1],"pr") << endl;
01014   
01015     nd2.tol_abs=1.0e-16;
01016     nd2.tol_rel=1.0e-16;
01017   
01018     // Output to file
01019 
01020     string fn3=((string)prefix)+"nstar.o2";
01021     hf.open(fn3);
01022     hdf_output(hf,at,"nstar");
01023     hf.close();
01024     cout << "\nGenerated nstar.o2." << endl;
01025 
01026     cout << endl;
01027 
01028     //--------------------------------------------------------------------
01029     // Integrate TOV equations
01030 
01031     cout << "--------- TOV solver, M vs. R. ---------------------\n" << endl;
01032 
01033     tov_solve atov;
01034     tov_interp_eos teos;
01035     atov.verbose=0;
01036     teos.verbose=0;
01037     atov.set_units("1/fm^4","1/fm^4","1/fm^3");
01038     teos.set_units("1/fm^4","1/fm^4","1/fm^3");
01039     teos.default_low_dens_eos();
01040     ret=teos.read_table(at,"ed","pr","nb");
01041     if (ret!=0) {
01042       O2SCL_ERR("Failed to read table.",gsl_efailed);
01043     }
01044     ret=atov.set_eos(teos);
01045     if (ret!=0) {
01046       O2SCL_ERR("Failed to set eos for tov solver.",gsl_efailed);
01047     }
01048     atov.calcgpot=true;
01049 
01050     // Get results
01051     
01052     ret=atov.mvsr();
01053     if (ret!=0) {
01054       O2SCL_ERR("Failed to compute M vs. R.",gsl_efailed);
01055     }
01056     o2_shared_ptr<table_units>::type tov_tmp=atov.get_results();
01057     
01058     // Output to file
01059 
01060     double r_max;
01061  
01062     string fn4=((string)prefix)+"mvsr.o2";
01063     hf.open(fn4);
01064     hdf_output(hf,*tov_tmp,"mvsr");
01065     hf.close();
01066     cout << "Generated mvsr.o2." << endl;
01067     cout << endl;
01068 
01069     cout << "--------- TOV solver, 1.4 Msun ---------------------\n" << endl;
01070 
01071     atov.fixed(1.4);
01072 
01073     string fn5=((string)prefix)+"m14.o2";
01074     hf.open(fn5);
01075     hdf_output(hf,*tov_tmp,"m14");
01076     hf.close();
01077     cout << "Generated m14.o2." << endl;
01078     cout << endl;
01079 
01080     t.report();
01081 
01082     return;
01083   }
01084 
01085 };
01086 
01087 int main(void) {
01088   cout.setf(ios::scientific);
01089 
01090   ex_apr_eos ac;
01091   ac.run();
01092   return 0;
01093 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Friends

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.