eos_fitting.C

00001 /*
00002  *  Method of class Eos_fitting
00003  *
00004  *    (see file eos_fitting.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2004 Keisuke Taniguchi
00010  *
00011  *   This file is part of LORENE.
00012  *
00013  *   LORENE is free software; you can redistribute it and/or modify
00014  *   it under the terms of the GNU General Public License version 2
00015  *   as published by the Free Software Foundation.
00016  *
00017  *   LORENE is distributed in the hope that it will be useful,
00018  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  *   GNU General Public License for more details.
00021  *
00022  *   You should have received a copy of the GNU General Public License
00023  *   along with LORENE; if not, write to the Free Software
00024  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  */
00027 
00028 char eos_fitting_C[] = "$Header: /cvsroot/Lorene/C++/Source/Eos/eos_fitting.C,v 1.3 2005/05/23 14:14:00 k_taniguchi Exp $" ;
00029 
00030 /*
00031  * $Id: eos_fitting.C,v 1.3 2005/05/23 14:14:00 k_taniguchi Exp $
00032  * $Log: eos_fitting.C,v $
00033  * Revision 1.3  2005/05/23 14:14:00  k_taniguchi
00034  * Minor modification.
00035  *
00036  * Revision 1.2  2005/05/22 20:53:06  k_taniguchi
00037  * Modify the method to calculate baryon number density from enthalpy.
00038  *
00039  * Revision 1.1  2004/09/26 18:53:53  k_taniguchi
00040  * Initial revision
00041  *
00042  *
00043  * $Header: /cvsroot/Lorene/C++/Source/Eos/eos_fitting.C,v 1.3 2005/05/23 14:14:00 k_taniguchi Exp $
00044  *
00045  */
00046 
00047 // C headers
00048 #include <stdlib.h>
00049 #include <string.h>
00050 #include <math.h>
00051 
00052 // Lorene headers
00053 #include "headcpp.h"
00054 #include "eos_fitting.h"
00055 #include "eos.h"
00056 #include "utilitaires.h"
00057 #include "unites.h"
00058 
00059 double fc(double) ;
00060 double gc(double) ;
00061 double hc(double) ;
00062 
00063 //************************************************************************
00064 
00065                     //--------------------------------//
00066                     //          Constructors          //
00067                     //--------------------------------//
00068 
00069 // Standard constructor
00070 // --------------------
00071 Eos_fitting::Eos_fitting(const char* name_i, const char* data,
00072              const char* path) : Eos(name_i) {
00073 
00074     strcpy(dataname, path) ;
00075     strcat(dataname, "/") ;
00076     strcat(dataname, data) ;
00077 
00078     read_coef() ;
00079 
00080 }
00081 
00082 // Constructor from a binary file
00083 // ------------------------------
00084 Eos_fitting::Eos_fitting(FILE* fich) : Eos(fich) {
00085 
00086     fread(dataname, sizeof(char), 160, fich) ;
00087 
00088     read_coef() ;
00089 
00090 }
00091 
00092 // Constructor from a formatted file
00093 // ---------------------------------
00094 Eos_fitting::Eos_fitting(ifstream& fich, const char* data) : Eos(fich) {
00095 
00096     char path[160] ;
00097 
00098     fich.getline(path, 160) ;
00099 
00100     strcpy(dataname, path) ;
00101     strcat(dataname, "/") ;
00102     strcat(dataname, data) ;
00103 
00104     read_coef() ;
00105 
00106 }
00107 
00108 // Destructor
00109 Eos_fitting::~Eos_fitting() {
00110 
00111     delete [] pp ;
00112 
00113 }
00114 
00115 
00116                      //---------------------------------------//
00117                      //              Outputs                  //
00118                      //---------------------------------------//
00119 
00120 void Eos_fitting::sauve(FILE* fich) const {
00121 
00122     Eos::sauve(fich) ;
00123 
00124     fwrite(dataname, sizeof(char), 160, fich) ;
00125 
00126 }
00127           //-----------------------//
00128           //    Miscellaneous      //
00129           //-----------------------//
00130 
00131 void Eos_fitting::read_coef() {
00132 
00133     char blabla[120] ;
00134 
00135     ifstream fich(dataname) ;
00136 
00137     for (int i=0; i<3; i++) {      // Jump over the file header
00138         fich.getline(blabla, 120) ;
00139     }
00140 
00141     int nb_coef ;
00142     fich >> nb_coef ; fich.getline(blabla, 120) ;  // Number of coefficients
00143 
00144     for (int i=0; i<3; i++) {      // Jump over the table header
00145         fich.getline(blabla, 120) ;
00146     }
00147 
00148     pp = new double[nb_coef] ;
00149 
00150     for (int i=0; i<nb_coef; i++) {
00151         fich >> pp[i] ; fich.getline(blabla, 120) ;
00152     }
00153 
00154     fich.close() ;
00155 
00156 }
00157 
00158 
00159             //------------------------------//
00160             //    Computational routines    //
00161             //------------------------------//
00162 
00163 // Baryon density from enthalpy
00164 //------------------------------
00165 
00166 double Eos_fitting::nbar_ent_p(double ent, const Param* ) const {
00167 
00168   using namespace Unites ;
00169 
00170     if ( ent > double(0) ) {
00171 
00172         double aa = 0. ;
00173     double xx = 0.01 ;
00174     int m ;
00175     double yy ;
00176     double ent_value ;
00177     double rhob ;      
00178     double nb ;        
00179     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00180       / rhonuc_si ;
00181 
00182     while (xx > 1.e-15) {
00183 
00184         ent_value = 1. ;   // Initialization
00185         xx = 0.1 * xx ;
00186         m = 0 ;
00187 
00188         while (ent_value > 1.e-15) {
00189 
00190             m++ ;
00191         yy = aa + m * xx ;
00192 
00193         double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00194         double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00195         double ccc = pp[0]*pp[1]*pow(yy,pp[1])
00196           +pp[2]*pp[3]*pow(yy,pp[3]) ;
00197         double ddd = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-1.) ;
00198         double eee = -pp[7]*yy+pp[9] ;
00199         double fff = -pp[8]*yy+pp[10] ;
00200         double ggg = pp[4]*pp[5]*pp[6]*pow(yy,pp[5]) ;
00201 
00202         ent_value = exp(ent) - 1.0
00203           -( aaa*bbb - 1. ) * fc(eee)
00204           -pp[11]*pow(yy,pp[12])*fc(-eee)*fc(fff)
00205           -pp[13]*pow(yy,pp[14])*fc(-fff)
00206           -( ccc*bbb + aaa*ddd*ggg )*fc(eee)
00207           -yy*( aaa*bbb - 1. )*pp[7]*gc(eee)
00208           -pp[11]*pp[12]*pow(yy,pp[12])*fc(-eee)*fc(fff)
00209           +pp[11]*pow(yy,pp[12]+1.)*(pp[7]*gc(-eee)*fc(fff)
00210                          -pp[8]*fc(-eee)*gc(fff))
00211           -pp[13]*pow(yy,pp[14])*(pp[14]*fc(-fff)
00212                       -pp[8]*yy*gc(-fff)) ;
00213 
00214         }
00215         aa += (m - 1) * xx ;
00216     }
00217     rhob = aa ;
00218 
00219     // The transformation from rhob to nb
00220     nb = rhob * trans_dens ;
00221 
00222     return nb ;
00223     }
00224     else {
00225         return 0 ;
00226     }
00227 
00228 }
00229 
00230 // Energy density from enthalpy
00231 //------------------------------
00232 
00233 double Eos_fitting::ener_ent_p(double ent, const Param* ) const {
00234 
00235   using namespace Unites ;
00236 
00237     if ( ent > double(0) ) {
00238 
00239         // Number density in the unit of [n_nuc]
00240         double nb = nbar_ent_p(ent) ;
00241 
00242     // The transformation from nb to yy
00243     // --------------------------------
00244 
00245     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00246       / rhonuc_si ; 
00247 
00248     // Baryon density in the unit of c=G=Msol=1
00249     double yy = nb / trans_dens ;
00250 
00251     double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00252     double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00253     double eee = -pp[7]*yy+pp[9] ;
00254     double fff = -pp[8]*yy+pp[10] ;
00255 
00256     double epsil = ( aaa*bbb - 1. ) * fc(eee)
00257       +pp[11]*pow(yy,pp[12])*fc(-eee)*fc(fff)
00258       +pp[13]*pow(yy,pp[14])*fc(-fff) ;
00259 
00260     // The transformation from epsil to ee
00261     // -----------------------------------
00262 
00263     // Energy density in the unit of [rho_nuc * c^2]
00264     double ee = nb * (1. + epsil) ;
00265 
00266     return ee ;
00267     }
00268     else {
00269         return 0 ;
00270     }
00271 
00272 }
00273 
00274 // Pressure from enthalpy
00275 //------------------------
00276 
00277 double Eos_fitting::press_ent_p(double ent, const Param* ) const {
00278 
00279   using namespace Unites ;
00280 
00281     if ( ent > double(0) ) {
00282 
00283         // Number density in the unit of [n_nuc]
00284         double nb = nbar_ent_p(ent) ;
00285 
00286     // The transformation from nb to yy
00287     // --------------------------------
00288 
00289     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00290       / rhonuc_si ; 
00291 
00292     // Baryon density in the unit of c=G=Msol=1
00293     double yy = nb / trans_dens ;
00294 
00295     double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00296     double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00297     double ccc = pp[0]*pp[1]*pow(yy,pp[1])+pp[2]*pp[3]*pow(yy,pp[3]) ;
00298     double ddd = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-1.) ;
00299     double eee = -pp[7]*yy+pp[9] ;
00300     double fff = -pp[8]*yy+pp[10] ;
00301     double ggg = pp[4]*pp[5]*pp[6]*pow(yy,pp[5]) ;
00302 
00303     double ppp = yy*( ccc*bbb + aaa*ddd*ggg )*fc(eee)
00304       +yy*yy*( aaa*bbb - 1. )*pp[7]*gc(eee)
00305       +pp[11]*pp[12]*pow(yy,pp[12]+1.)*fc(-eee)*fc(fff)
00306       -pp[11]*pow(yy,pp[12]+2.)*(pp[7]*gc(-eee)*fc(fff)
00307                      -pp[8]*fc(-eee)*gc(fff))
00308       +pp[13]*pow(yy,pp[14]+1.)*(pp[14]*fc(-fff)-pp[8]*yy*gc(-fff)) ;
00309 
00310     // The transformation from ppp to pres
00311     // -----------------------------------
00312 
00313     // Pressure in the unit of [rho_nuc * c^2]
00314     double pres = ppp * trans_dens ;
00315 
00316     return pres ;
00317     }
00318     else {
00319         return 0 ;
00320     }
00321 
00322 }
00323 
00324 // dln(n)/dln(H) from enthalpy
00325 //----------------------------
00326 
00327 double Eos_fitting::der_nbar_ent_p(double ent, const Param* ) const {
00328 
00329   using namespace Unites ;
00330 
00331     if ( ent > double(0) ) {
00332 
00333         // Number density in the unit of [n_nuc]
00334         double nb = nbar_ent_p(ent) ;
00335 
00336     // The transformation from nb to yy
00337     // --------------------------------
00338 
00339     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00340       / rhonuc_si ; 
00341 
00342     // Baryon density in the unit of c=G=Msol=1
00343     double yy = nb / trans_dens ;
00344 
00345     double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00346     double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00347     double ccc = pp[0]*pp[1]*pow(yy,pp[1]) + pp[2]*pp[3]*pow(yy,pp[3]) ;
00348     double ddd = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-1.) ;
00349     double eee = -pp[7]*yy+pp[9] ;
00350     double fff = -pp[8]*yy+pp[10] ;
00351     double ggg = pp[4]*pp[5]*pp[6]*pow(yy,pp[5]) ;
00352     double jjj = pp[0]*pp[1]*pp[1]*pow(yy,pp[1])
00353       +pp[2]*pp[3]*pp[3]*pow(yy,pp[3]) ;
00354 
00355         double dlnsdlh = exp(ent) * ent /
00356       ( ( ccc*bbb + aaa*ddd*ggg )*( fc(eee) + 2.*yy*pp[7]*gc(eee) )
00357         +yy*pp[7]*( aaa*bbb - 1. )*( 2.*gc(eee) - yy*pp[7]*hc(eee) )
00358         +pp[11]*pp[12]*(pp[12]+1.)*pow(yy,pp[12])*fc(-eee)*fc(fff)
00359         +2.*pp[11]*(pp[12]+1.)*pow(yy,pp[12]+1.)
00360           *( -pp[7]*gc(-eee)*fc(fff) + pp[8]*fc(-eee)*gc(fff) )
00361         -pp[11]*pow(yy,pp[12]+2.)*( pp[7]*pp[7]*hc(-eee)*fc(fff)
00362                     +2.*pp[7]*pp[8]*gc(-eee)*gc(fff)
00363                     +pp[8]*pp[8]*fc(-eee)*hc(fff) )
00364         +pp[13]*pp[14]*(pp[14]+1.)*pow(yy,pp[14])*fc(-fff)
00365         -2.*pp[8]*pp[13]*(pp[14]+1.)*pow(yy,pp[14]+1.)*gc(-fff)
00366         -pp[8]*pp[8]*pp[13]*pow(yy,pp[14]+2.)*hc(-fff)
00367         +( jjj*bbb + 2.*ccc*ddd*ggg
00368            + aaa*pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-2.)
00369            *ggg*(ggg+pp[5]) )*fc(eee)
00370         ) ;
00371 
00372     return dlnsdlh ;
00373 
00374     }
00375     else {
00376 
00377         return double(1) / pp[12] ;  // To ensure continuity at ent=0
00378 
00379     }
00380 
00381 }
00382 
00383 // dln(e)/dln(H) from enthalpy
00384 //----------------------------
00385 
00386 double Eos_fitting::der_ener_ent_p(double ent, const Param* ) const {
00387 
00388   using namespace Unites ;
00389 
00390     if ( ent > double(0) ) {
00391 
00392          // Number density in the unit of [n_nuc]
00393         double nb = nbar_ent_p(ent) ;
00394 
00395     // The transformation from nb to yy
00396     // --------------------------------
00397 
00398     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00399       / rhonuc_si ; 
00400 
00401     // Baryon density in the unit of c=G=Msol=1
00402     double yy = nb / trans_dens ;
00403 
00404     double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00405     double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00406     double ccc = pp[0]*pp[1]*pow(yy,pp[1]) + pp[2]*pp[3]*pow(yy,pp[3]) ;
00407     double ddd = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-1.) ;
00408     double eee = -pp[7]*yy+pp[9] ;
00409     double fff = -pp[8]*yy+pp[10] ;
00410     double ggg = pp[4]*pp[5]*pp[6]*pow(yy,pp[5]) ;
00411 
00412     double dlnsdlh = der_nbar_ent_p(ent) ;
00413 
00414     double dlesdlh = dlnsdlh
00415       * (1. + ( ( ccc*bbb + aaa*ddd*ggg )*fc(eee)
00416             +yy*pp[7]*( aaa*bbb - 1. )*gc(eee)
00417             +pp[11]*pp[12]*pow(yy,pp[12])*fc(-eee)*fc(fff)
00418             +pp[11]*pow(yy,pp[12]+1.)*( -pp[7]*gc(-eee)*fc(fff)
00419                         +pp[8]*fc(-eee)*gc(fff) )
00420             +pp[13]*pp[14]*pow(yy,pp[14])*fc(-fff)
00421             -pp[8]*pp[13]*pow(yy,pp[14]+1.)*gc(-fff) )
00422          / ( 1. + ( aaa*bbb - 1. )*fc(eee)
00423          + pp[11]*pow(yy,pp[12])*fc(-eee)*fc(fff)
00424          + pp[13]*pow(yy,pp[14])*fc(-fff) ) ) ;
00425 
00426     return dlesdlh ;
00427 
00428     }
00429     else {
00430 
00431         return double(1) / pp[12] ;  // To ensure continuity at ent=0
00432 
00433     }
00434 
00435 }
00436 
00437 // dln(p)/dln(H) from enthalpy
00438 //----------------------------
00439 
00440 double Eos_fitting::der_press_ent_p(double ent, const Param* ) const {
00441 
00442   using namespace Unites ;
00443 
00444     if ( ent > double(0) ) {
00445 
00446          // Number density in the unit of [n_nuc]
00447         double nb = nbar_ent_p(ent) ;
00448 
00449     // The transformation from nb to yy
00450     // --------------------------------
00451 
00452     double trans_dens = msol_si / pow(g_si*msol_si/c_si/c_si,3.)
00453       / rhonuc_si ; 
00454 
00455     // Baryon density in the unit of c=G=Msol=1
00456     double yy = nb / trans_dens ;
00457 
00458     double aaa = 1.+pp[0]*pow(yy,pp[1])+pp[2]*pow(yy,pp[3]) ;
00459     double bbb = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]) ;
00460     double ccc = pp[0]*pp[1]*pow(yy,pp[1]) + pp[2]*pp[3]*pow(yy,pp[3]) ;
00461     double ddd = pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-1.) ;
00462     double eee = -pp[7]*yy+pp[9] ;
00463     double fff = -pp[8]*yy+pp[10] ;
00464     double ggg = pp[4]*pp[5]*pp[6]*pow(yy,pp[5]) ;
00465     double jjj = pp[0]*pp[1]*pp[1]*pow(yy,pp[1])
00466       +pp[2]*pp[3]*pp[3]*pow(yy,pp[3]) ;
00467 
00468     double dlnsdlh = der_nbar_ent_p(ent) ;
00469 
00470     double dlpsdlh = dlnsdlh
00471       * ( ( ccc*bbb + aaa*ddd*ggg )*fc(eee)
00472           +( jjj*bbb + 2.*ccc*ddd*ggg
00473          + aaa*pow(1.+pp[4]*pow(yy,pp[5]),pp[6]-2.)*ggg*(ggg+pp[5])
00474          )*fc(eee)
00475           +2.*yy*pp[7]*( ccc*bbb + aaa*ddd*ggg )*gc(eee)
00476           +yy*pp[7]*( aaa*bbb - 1. )*(2.*gc(eee) - yy*pp[7]*hc(eee))
00477           +pp[11]*pp[12]*(pp[12]+1.)*pow(yy,pp[12])*fc(-eee)*fc(fff)
00478           +2.*pp[11]*(pp[12]+1.)*pow(yy,pp[12]+1.)
00479             *( -pp[7]*gc(-eee)*fc(fff) + pp[8]*fc(-eee)*gc(fff) )
00480           -pp[11]*pow(yy,pp[12]+2.)*( pp[7]*pp[7]*hc(-eee)*fc(fff)
00481                       +2.*pp[7]*pp[8]*gc(-eee)*gc(fff)
00482                       +pp[8]*pp[8]*fc(-eee)*hc(fff) )
00483           +pp[13]*(pp[14]+1.)*pow(yy,pp[14])*( pp[14]*fc(-fff)
00484                            -2.*pp[8]*yy*gc(-fff) )
00485           -pp[8]*pp[8]*pp[13]*pow(yy,pp[14]+2.)*hc(-fff) )
00486       / ( ( ccc*bbb + aaa*ddd*ggg )*fc(eee)
00487           +yy*pp[7]*( aaa*bbb - 1. )*gc(eee)
00488           +pp[11]*pow(yy,pp[12])*( pp[12]*fc(-eee)*fc(fff)
00489                        -yy*pp[7]*gc(-eee)*fc(fff)
00490                        +yy*pp[8]*fc(-eee)*gc(fff) )
00491           +pp[13]*pow(yy,pp[14])*( pp[14]*fc(-fff)
00492                        -yy*pp[8]*gc(-fff) ) ) ;
00493 
00494     return dlpsdlh ;
00495 
00496     }
00497     else {
00498 
00499         return (pp[12] + 1.) / pp[12] ;  // To ensure continuity at ent=0
00500 
00501     }
00502 
00503 }
00504 
00505 //********************************************************
00506 //     Functions which appear in the fitting formula
00507 //********************************************************
00508 
00509 double fc(double xx) {
00510 
00511     double resu = double(1) / (double(1) + exp(xx)) ;
00512 
00513     return resu ;
00514 
00515 }
00516 
00517 double gc(double xx) {
00518 
00519     double resu ;
00520 
00521     if (xx > 0.) {
00522         resu = exp(-xx) / pow(exp(-xx)+double(1),double(2)) ;
00523     }
00524     else {
00525         resu = exp(xx) / pow(double(1)+exp(xx),double(2)) ;
00526     }
00527 
00528     return resu ;
00529 
00530 }
00531 
00532  double hc(double xx) {
00533 
00534      double resu ;
00535 
00536      if (xx > 0.) {
00537          resu = exp(-xx) * (exp(-xx)-double(1)) /
00538          pow(exp(-xx)+double(1),double(3)) ;
00539      }
00540      else {
00541          resu = exp(xx) * (double(1)-exp(xx)) / 
00542          pow(double(1)+exp(xx),double(3)) ;
00543      }
00544 
00545      return resu ;
00546 
00547  }

Generated on Tue Feb 7 01:35:16 2012 for LORENE by  doxygen 1.4.6