eos_multi_poly.C

00001 /*
00002  *  Methods of class Eos_multi_poly
00003  *
00004  *    (see file eos_multi_poly.h for documentation).
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2009 Keisuke Taniguchi
00010  *   Copyright (c) 2004 Keisuke Taniguchi
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License version 2
00016  *   as published by the Free Software Foundation.
00017  *
00018  *   LORENE is distributed in the hope that it will be useful,
00019  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *   GNU General Public License for more details.
00022  *
00023  *   You should have received a copy of the GNU General Public License
00024  *   along with LORENE; if not, write to the Free Software
00025  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00026  *
00027  */
00028 
00029 char eos_multi_poly_C[] = "$Header: /cvsroot/Lorene/C++/Source/Eos/eos_multi_poly.C,v 1.6 2009/06/23 14:34:04 k_taniguchi Exp $" ;
00030 
00031 /*
00032  * $Id: eos_multi_poly.C,v 1.6 2009/06/23 14:34:04 k_taniguchi Exp $
00033  * $Log: eos_multi_poly.C,v $
00034  * Revision 1.6  2009/06/23 14:34:04  k_taniguchi
00035  * Completely revised.
00036  *
00037  * Revision 1.5  2004/06/23 15:42:08  e_gourgoulhon
00038  * Replaced all "abs" by "fabs".
00039  *
00040  * Revision 1.4  2004/05/13 07:38:57  k_taniguchi
00041  * Change the procedure for searching the baryon density from enthalpy.
00042  *
00043  * Revision 1.3  2004/05/09 10:43:52  k_taniguchi
00044  * Change the searching method of the baryon density again.
00045  *
00046  * Revision 1.2  2004/05/07 11:55:59  k_taniguchi
00047  * Change the searching procedure of the baryon density.
00048  *
00049  * Revision 1.1  2004/05/07 08:10:58  k_taniguchi
00050  * Initial revision
00051  *
00052  *
00053  *
00054  * $Header: /cvsroot/Lorene/C++/Source/Eos/eos_multi_poly.C,v 1.6 2009/06/23 14:34:04 k_taniguchi Exp $
00055  *
00056  */
00057 
00058 // C headers
00059 #include <stdlib.h>
00060 #include <string.h>
00061 #include <math.h>
00062 
00063 // Lorene headers
00064 #include "headcpp.h"
00065 #include "eos_multi_poly.h"
00066 #include "eos.h"
00067 #include "utilitaires.h"
00068 #include "unites.h"
00069 
00070 double logp(double, double, double, double, double, double) ;
00071 double dlpsdlh(double, double, double, double, double, double) ;
00072 double dlpsdlnb(double, double, double, double, double) ;
00073 
00074 //*********************************************************************
00075 
00076                //--------------------------------------//
00077                //              Constructors            //
00078                //--------------------------------------//
00079 
00080 // Standard constructor
00081 Eos_multi_poly::Eos_multi_poly(int npoly, double* gamma_i, double kappa0_i,
00082                    double logP1_i, double* logRho_i,
00083                    double* decInc_i)
00084     : Eos("Multi-polytropic EOS"),
00085       npeos(npoly), kappa0(kappa0_i), logP1(logP1_i), m0(double(1)) {
00086 
00087     assert(npeos > 1) ;
00088 
00089     gamma = new double [npeos] ;
00090 
00091     for (int l=0; l<npeos; l++) {
00092         gamma[l] = gamma_i[l] ;
00093     }
00094 
00095     logRho = new double [npeos-1] ;
00096 
00097     for (int l=0; l<npeos-1; l++) {
00098         logRho[l] = logRho_i[l] ;
00099     }
00100 
00101     decInc = new double [npeos-1] ;
00102 
00103     for (int l=0; l<npeos-1; l++) {
00104         decInc[l] = decInc_i[l] ;
00105     }
00106 
00107     set_auxiliary() ;
00108 
00109 }
00110 
00111 
00112 // Copy constructor
00113 Eos_multi_poly::Eos_multi_poly(const Eos_multi_poly& eosmp)
00114     : Eos(eosmp),
00115       npeos(eosmp.npeos), kappa0(eosmp.kappa0), logP1(eosmp.logP1),
00116       m0(eosmp.m0) {
00117 
00118     gamma = new double [npeos] ;
00119 
00120     for (int l=0; l<npeos; l++) {
00121         gamma[l] = eosmp.gamma[l] ;
00122     }
00123 
00124     logRho = new double [npeos-1] ;
00125 
00126     for (int l=0; l<npeos-1; l++) {
00127         logRho[l] = eosmp.logRho[l] ;
00128     }
00129 
00130     kappa = new double [npeos] ;
00131 
00132     for (int l=0; l<npeos; l++) {
00133         kappa[l] = eosmp.kappa[l] ;
00134     }
00135 
00136     nbCrit = new double [npeos-1] ;
00137 
00138     for (int l=0; l<npeos-1; l++) {
00139         nbCrit[l] = eosmp.nbCrit[l] ;
00140     }
00141 
00142     entCrit = new double [npeos-1] ;
00143 
00144     for (int l=0; l<npeos-1; l++) {
00145         entCrit[l] = eosmp.entCrit[l] ;
00146     }
00147 
00148     decInc = new double [npeos-1] ;
00149 
00150     for (int l=0; l<npeos-1; l++) {
00151         decInc[l] = eosmp.decInc[l] ;
00152     }
00153 
00154     mu0 = new double [npeos] ;
00155 
00156     for (int l=0; l<npeos; l++) {
00157         mu0[l] = eosmp.mu0[l] ;
00158     }
00159 
00160 }
00161 
00162 //  Constructor from a binary file
00163 Eos_multi_poly::Eos_multi_poly(FILE* fich) : Eos(fich) {
00164 
00165     fread_be(&npeos, sizeof(int), 1, fich) ;
00166 
00167     gamma = new double [npeos] ;
00168 
00169     for (int l=0; l<npeos; l++) {
00170         fread_be(&gamma[l], sizeof(double), 1, fich) ;
00171     }
00172 
00173     fread_be(&kappa0, sizeof(int), 1, fich) ;
00174     fread_be(&logP1, sizeof(int), 1, fich) ;
00175 
00176     logRho = new double [npeos-1] ;
00177 
00178     for (int l=0; l<npeos-1; l++) {
00179         fread_be(&logRho[l], sizeof(double), 1, fich) ;
00180     }
00181 
00182     decInc = new double [npeos-1] ;
00183 
00184     for (int l=0; l<npeos-1; l++) {
00185         fread_be(&decInc[l], sizeof(double), 1, fich) ;
00186     }
00187 
00188     m0 = double(1) ;
00189 
00190     set_auxiliary() ;
00191 
00192 }
00193 
00194 //  Constructor from a formatted file
00195 Eos_multi_poly::Eos_multi_poly(ifstream& fich) : Eos(fich) {
00196 
00197     char blabla[80] ;
00198 
00199     fich >> npeos ; fich.getline(blabla, 80) ;
00200 
00201     gamma = new double [npeos] ;
00202 
00203     for (int l=0; l<npeos; l++) {
00204         fich >> gamma[l] ; fich.getline(blabla, 80) ;
00205     }
00206 
00207     fich >> kappa0 ; fich.getline(blabla, 80) ;
00208     fich >> logP1 ; fich.getline(blabla, 80) ;
00209 
00210     logRho = new double [npeos-1] ;
00211 
00212     for (int l=0; l<npeos-1; l++) {
00213         fich >> logRho[l] ; fich.getline(blabla, 80) ;
00214     }
00215 
00216     decInc = new double [npeos-1] ;
00217 
00218     for (int l=0; l<npeos-1; l++) {
00219         fich >> decInc[l] ; fich.getline(blabla, 80) ;
00220     }
00221 
00222     m0 = double(1) ;
00223 
00224     set_auxiliary() ;
00225 
00226 }
00227 
00228 // Destructor
00229 Eos_multi_poly::~Eos_multi_poly() {
00230 
00231     delete [] gamma ;
00232     delete [] logRho ;
00233     delete [] kappa ;
00234     delete [] nbCrit ;
00235     delete [] entCrit ;
00236     delete [] decInc ;
00237     delete [] mu0 ;
00238 
00239 }
00240 
00241             //--------------//
00242             //  Assignment  //
00243             //--------------//
00244 
00245 void Eos_multi_poly::operator=(const Eos_multi_poly& ) {
00246 
00247     cout << "Eos_multi_poly::operator=  : not implemented yet !" << endl ;
00248     abort() ;
00249 
00250 }
00251 
00252 
00253              //-----------------------//
00254              //     Miscellaneous     //
00255              //-----------------------//
00256 
00257 void Eos_multi_poly::set_auxiliary() {
00258 
00259     using namespace Unites ;
00260 
00261     double* kappa_cgs = new double [npeos] ;
00262 
00263     kappa_cgs[0] = kappa0 ;
00264 
00265     kappa_cgs[1] = pow(10., logP1-logRho[0]*gamma[1]) ;
00266 
00267     if (npeos > 2) {
00268 
00269         kappa_cgs[2] = kappa_cgs[1]
00270       * pow(10., logRho[0]*(gamma[1]-gamma[2])) ;
00271 
00272     if (npeos > 3) {
00273 
00274         for (int l=3; l<npeos; l++) {
00275 
00276             kappa_cgs[l] = kappa_cgs[l-1]
00277           * pow(10., logRho[l-2]*(gamma[l-1]-gamma[l])) ;
00278 
00279         }
00280 
00281     }
00282 
00283     }
00284 
00285     kappa = new double [npeos] ;
00286 
00287     double rhonuc_cgs = rhonuc_si * 1.e-3 ;
00288 
00289     for (int l=0; l<npeos; l++) {
00290         kappa[l] = kappa_cgs[l] * pow( rhonuc_cgs, gamma[l] - double(1) ) ;
00291     // Conversion from cgs units to Lorene units
00292     }
00293 
00294     delete [] kappa_cgs ;
00295 
00296     mu0 = new double [npeos] ;
00297     mu0[0] = double(1) ;  // We define
00298 
00299     entCrit = new double [npeos-1] ;
00300 
00301     nbCrit = new double [npeos-1] ;
00302 
00303     for (int l=0; l<npeos-1; l++) {
00304 
00305         nbCrit[l] =
00306       pow(kappa[l]/kappa[l+1], double(1)/(gamma[l+1]-gamma[l])) ;
00307 
00308     mu0[l+1] = mu0[l]
00309       + ( kappa[l] * pow(nbCrit[l], gamma[l]-double(1))
00310           / (gamma[l]-double(1))
00311           - kappa[l+1] * pow(nbCrit[l], gamma[l+1]-double(1))
00312           / (gamma[l+1]-double(1)) ) ;
00313 
00314     entCrit[l] = log ( mu0[l] / m0
00315                + kappa[l] * gamma[l]
00316                * pow(nbCrit[l], gamma[l]-double(1))
00317                / (gamma[l]-double(1)) / m0 ) ;
00318 
00319     }
00320 
00321 }
00322 
00323 
00324                //------------------------------//
00325                //     Comparison operators     //
00326                //------------------------------//
00327 
00328 bool Eos_multi_poly::operator==(const Eos& eos_i) const {
00329     
00330     bool resu = true ; 
00331     
00332     if ( eos_i.identify() != identify() ) {
00333     cout << "The second EOS is not of type Eos_multi_poly !" << endl ; 
00334     resu = false ; 
00335     }
00336     else{
00337     
00338     const Eos_multi_poly& eos
00339       = dynamic_cast<const Eos_multi_poly&>(eos_i) ; 
00340 
00341     if (eos.get_npeos() != npeos) {
00342         cout << "The two Eos_multi_poly have "
00343          << "different number of polytropes : "
00344          << npeos << " <-> " << eos.get_npeos() << endl ; 
00345         resu = false ; 
00346     }
00347 
00348     for (int l=0; l<npeos; l++) {
00349         if (eos.get_gamma(l) != gamma[l]) {
00350             cout << "The two Eos_multi_poly have different gamma "
00351              << gamma[l] << " <-> " 
00352              << eos.get_gamma(l) << endl ;
00353         resu = false ;
00354         }
00355     }
00356 
00357     for (int l=0; l<npeos; l++) {
00358         if (eos.get_kappa(l) != kappa[l]) {
00359             cout << "The two Eos_multi_poly have different kappa "
00360              << kappa[l] << " <-> " 
00361              << eos.get_kappa(l) << endl ;
00362         resu = false ;
00363         }
00364     }
00365 
00366     }
00367     
00368     return resu ; 
00369     
00370 }
00371 
00372 bool Eos_multi_poly::operator!=(const Eos& eos_i) const {
00373  
00374     return !(operator==(eos_i)) ; 
00375        
00376 }
00377 
00378                      //--------------------------//
00379                      //         Outputs          //
00380                      //--------------------------//
00381 
00382 void Eos_multi_poly::sauve(FILE* fich) const {
00383 
00384     Eos::sauve(fich) ;
00385 
00386     fwrite_be(&npeos, sizeof(int), 1, fich) ;
00387 
00388     for (int l=0; l<npeos; l++) {
00389         fwrite_be(&gamma[l], sizeof(double), 1, fich) ;
00390     }
00391 
00392     fwrite_be(&kappa0, sizeof(int), 1, fich) ;
00393     fwrite_be(&logP1, sizeof(int), 1, fich) ;
00394 
00395     for (int l=0; l<npeos-1; l++) {
00396         fwrite_be(&logRho[l], sizeof(double), 1, fich) ;
00397     }
00398 
00399     for (int l=0; l<npeos-1; l++) {
00400         fwrite_be(&decInc[l], sizeof(double), 1, fich) ;
00401     }
00402 
00403 }
00404 
00405 
00406 ostream& Eos_multi_poly::operator>>(ostream & ost) const {
00407 
00408     using namespace Unites ;
00409 
00410     ost << "EOS of class Eos_multi_poly "
00411     << "(multiple polytropic equation of state) : " << endl ;
00412 
00413     ost << "  Number of polytropes : "
00414     << npeos << endl << endl ;
00415 
00416     double rhonuc_cgs = rhonuc_si * 1.e-3 ;
00417 
00418     ost.precision(16) ;
00419     for (int l=0; l<npeos; l++) {
00420         ost << "  EOS in region " << l << " : " << endl ;
00421     ost << "  ---------------" << endl ;
00422     ost << "    gamma  : " << gamma[l] << endl ;
00423     ost << "    kappa  : " << kappa[l]
00424         << " [Lorene units: rho_nuc c^2 / n_nuc^gamma]" << endl ;
00425 
00426     double kappa_cgs = kappa[l]
00427       * pow( rhonuc_cgs, double(1) - gamma[l] ) ;
00428 
00429     ost << "           : " << kappa_cgs
00430         << " [(g/cm^3)^{1-gamma}]" << endl ;
00431     }
00432 
00433     ost << endl ;
00434     ost << "  Exponent of the pressure at the fiducial density rho_1"
00435     << endl ;
00436     ost << "  ------------------------------------------------------"
00437     << endl ;
00438     ost << "    log P1 : " << logP1 << endl ;
00439 
00440     ost << endl ;
00441     ost << "  Exponent of fiducial densities" << endl ;
00442     ost << "  ------------------------------" << endl ;
00443     for (int l=0; l<npeos-1; l++) {
00444       ost << "    log rho[" << l << "] : " << logRho[l] << endl ;
00445     }
00446 
00447     ost << endl ;
00448     for (int l=0; l<npeos-1; l++) {
00449         ost << "  Critical density and enthalpy between domains "
00450         << l << " and " << l+1 << " : " << endl ;
00451     ost << "  -----------------------------------------------------"
00452         << endl ;
00453     ost << "    num. dens. : " << nbCrit[l] << " [Lorene units: n_nuc]"
00454         << endl ;
00455     ost << "    density :    " << nbCrit[l] * rhonuc_cgs << " [g/cm^3]"
00456         << endl ;
00457 
00458     ost << "    ln(ent) :    " << entCrit[l] << endl ;
00459     }
00460 
00461     ost << endl ;
00462     for (int l=0; l<npeos; l++) {
00463         ost << "  Relat. chem. pot. in region " << l << " : " << endl ;
00464     ost << "  -----------------------------" << endl ;
00465     ost << "    mu : " << mu0[l] << " [m_B c^2]" << endl ;
00466     }
00467 
00468     return ost ;
00469 
00470 }
00471 
00472 
00473                //------------------------------------------//
00474                //          Computational routines          //
00475            //------------------------------------------//
00476 
00477 // Baryon rest-mass density from enthalpy
00478 //----------------------------------------
00479 
00480 double Eos_multi_poly::nbar_ent_p(double ent, const Param* ) const {
00481 
00482     int i = 0 ; // "i" corresponds to the number of domain
00483                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00484                 // The buffer zone is included in the next zone.
00485     for (int l=0; l<npeos-1; l++) {
00486         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00487         i++ ;
00488     }
00489     }
00490 
00491     double mgam1skapgam = 1. ;  // Initialization
00492     if (i == 0) {
00493 
00494         if ( ent > double(0) ) {
00495 
00496         mgam1skapgam = m0*(gamma[0]-double(1))/kappa[0]/gamma[0] ;
00497 
00498         return pow( mgam1skapgam*(exp(ent)-double(1)),
00499             double(1)/(gamma[0]-double(1)) ) ; // mu0[0]/m0=1
00500 
00501     }
00502     else {
00503         return double(0) ;
00504     }
00505 
00506     }
00507     else {
00508 
00509         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
00510         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
00511 
00512         if ( ent < entLarge ) {
00513 
00514         double log10H = log10( ent ) ;
00515         double log10HSmall = log10( entSmall ) ;
00516         double log10HLarge = log10( entLarge ) ;
00517         double dH = log10HLarge - log10HSmall ;
00518         double uu = (log10H - log10HSmall) / dH ;
00519 
00520         double mgam1skapgamSmall = m0*(gamma[i-1]-double(1))
00521           /kappa[i-1]/gamma[i-1] ;
00522         double mgam1skapgamLarge = m0*(gamma[i]-double(1))
00523           /kappa[i]/gamma[i] ;
00524 
00525         double nnSmall = pow( mgam1skapgamSmall
00526                   *(exp(entSmall)-mu0[i-1]/m0),
00527                   double(1)/(gamma[i-1]-double(1)) ) ;
00528         double nnLarge = pow( mgam1skapgamLarge
00529                   *(exp(entLarge)-mu0[i]/m0),
00530                   double(1)/(gamma[i]-double(1)) ) ;
00531 
00532         double ppSmall = kappa[i-1] * pow( nnSmall, gamma[i-1] ) ;
00533         double ppLarge = kappa[i] * pow( nnLarge, gamma[i] ) ;
00534 
00535         double eeSmall = mu0[i-1] * nnSmall
00536           + ppSmall / (gamma[i-1] - double(1)) ;
00537         double eeLarge = mu0[i] * nnLarge
00538           + ppLarge / (gamma[i] - double(1)) ;
00539 
00540         double log10PSmall = log10( ppSmall ) ;
00541         double log10PLarge = log10( ppLarge ) ;
00542 
00543         double dlpsdlhSmall = entSmall
00544           * (double(1) + eeSmall / ppSmall) ;
00545         double dlpsdlhLarge = entLarge
00546           * (double(1) + eeLarge / ppLarge) ;
00547 
00548         double log10PInterpolate = logp(log10PSmall, log10PLarge,
00549                         dlpsdlhSmall, dlpsdlhLarge,
00550                         dH, uu) ;
00551 
00552         double dlpsdlhInterpolate = dlpsdlh(log10PSmall, log10PLarge,
00553                         dlpsdlhSmall, dlpsdlhLarge,
00554                         dH, uu) ;
00555 
00556         double pp = pow(double(10), log10PInterpolate) ;
00557 
00558         return pp / ent * dlpsdlhInterpolate * exp(-ent) / m0 ;
00559         // Is m0 necessary?
00560 
00561     }
00562     else {
00563 
00564         mgam1skapgam = m0*(gamma[i]-double(1))/kappa[i]/gamma[i] ;
00565 
00566         return pow( mgam1skapgam*(exp(ent)-mu0[i]/m0),
00567             double(1)/(gamma[i]-double(1)) ) ;
00568 
00569     }
00570 
00571     }
00572 
00573 }
00574 
00575 // Energy density from enthalpy
00576 //------------------------------
00577 
00578 double Eos_multi_poly::ener_ent_p(double ent, const Param* ) const {
00579 
00580     int i = 0 ; // "i" corresponds to the number of domain
00581                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00582                 // The buffer zone is included in the next zone.
00583     for (int l=0; l<npeos-1; l++) {
00584         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00585         i++ ;
00586     }
00587     }
00588 
00589     double mgam1skapgam = 1. ;  // Initialization
00590     double nn = 0. ;  // Initialization
00591     double pp = 0. ;  // Initialization
00592 
00593     if (i == 0) {
00594 
00595         if ( ent > double(0) ) {
00596 
00597         mgam1skapgam = m0*(gamma[0]-double(1))/kappa[0]/gamma[0] ;
00598 
00599         nn = pow( mgam1skapgam*(exp(ent)-double(1)),
00600               double(1)/(gamma[0]-double(1)) ) ; // mu0[0]/m0=1
00601 
00602         pp = kappa[0] * pow( nn, gamma[0] ) ;
00603 
00604         return mu0[0] * nn + pp / (gamma[0] - double(1)) ;
00605 
00606     }
00607     else {
00608         return double(0) ;
00609     }
00610 
00611     }
00612     else {
00613 
00614         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
00615         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
00616 
00617         if ( ent < entLarge ) {
00618 
00619         double log10H = log10( ent ) ;
00620         double log10HSmall = log10( entSmall ) ;
00621         double log10HLarge = log10( entLarge ) ;
00622         double dH = log10HLarge - log10HSmall ;
00623         double uu = (log10H - log10HSmall) / dH ;
00624 
00625         double mgam1skapgamSmall = m0*(gamma[i-1]-double(1))
00626           /kappa[i-1]/gamma[i-1] ;
00627         double mgam1skapgamLarge = m0*(gamma[i]-double(1))
00628           /kappa[i]/gamma[i] ;
00629 
00630         double nnSmall = pow( mgam1skapgamSmall
00631                   *(exp(entSmall)-mu0[i-1]/m0),
00632                   double(1)/(gamma[i-1]-double(1)) ) ;
00633         double nnLarge = pow( mgam1skapgamLarge
00634                   *(exp(entLarge)-mu0[i]/m0),
00635                   double(1)/(gamma[i]-double(1)) ) ;
00636 
00637         double ppSmall = kappa[i-1] * pow( nnSmall, gamma[i-1] ) ;
00638         double ppLarge = kappa[i] * pow( nnLarge, gamma[i] ) ;
00639 
00640         double eeSmall = mu0[i-1] * nnSmall
00641           + ppSmall / (gamma[i-1] - double(1)) ;
00642         double eeLarge = mu0[i] * nnLarge
00643           + ppLarge / (gamma[i] - double(1)) ;
00644 
00645         double log10PSmall = log10( ppSmall ) ;
00646         double log10PLarge = log10( ppLarge ) ;
00647 
00648         double dlpsdlhSmall = entSmall
00649           * (double(1) + eeSmall / ppSmall) ;
00650         double dlpsdlhLarge = entLarge
00651           * (double(1) + eeLarge / ppLarge) ;
00652 
00653         double log10PInterpolate = logp(log10PSmall, log10PLarge,
00654                         dlpsdlhSmall, dlpsdlhLarge,
00655                         dH, uu) ;
00656 
00657         double dlpsdlhInterpolate = dlpsdlh(log10PSmall, log10PLarge,
00658                         dlpsdlhSmall, dlpsdlhLarge,
00659                         dH, uu) ;
00660 
00661         pp = pow(double(10), log10PInterpolate) ;
00662 
00663         return pp / ent * dlpsdlhInterpolate - pp ;
00664 
00665     }
00666     else {
00667 
00668         mgam1skapgam = m0*(gamma[i]-double(1))/kappa[i]/gamma[i] ;
00669 
00670         nn = pow( mgam1skapgam*(exp(ent)-mu0[i]/m0),
00671               double(1)/(gamma[i]-double(1)) ) ;
00672 
00673         pp = kappa[i] * pow( nn, gamma[i] ) ;
00674 
00675         return mu0[i] * nn + pp / (gamma[i] - double(1)) ;
00676 
00677     }
00678 
00679     }
00680 
00681 }
00682 
00683 
00684 // Pressure from enthalpy
00685 //------------------------
00686 
00687 double Eos_multi_poly::press_ent_p(double ent, const Param* ) const {
00688 
00689     int i = 0 ; // "i" corresponds to the number of domain
00690                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00691                 // The buffer zone is included in the next zone.
00692     for (int l=0; l<npeos-1; l++) {
00693         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00694         i++ ;
00695     }
00696     }
00697 
00698     double mgam1skapgam = 1. ;  // Initialization
00699     double nn = 0. ;  // Initialization
00700 
00701     if (i == 0) {
00702 
00703         if ( ent > double(0) ) {
00704 
00705         mgam1skapgam = m0*(gamma[0]-double(1))/kappa[0]/gamma[0] ;
00706 
00707         nn = pow( mgam1skapgam*(exp(ent)-double(1)),
00708               double(1)/(gamma[0]-double(1)) ) ; // mu0[0]/m0=1
00709 
00710         return kappa[0] * pow( nn, gamma[0] ) ;
00711 
00712     }
00713     else {
00714         return double(0) ;
00715     }
00716 
00717     }
00718     else {
00719 
00720         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
00721         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
00722 
00723         if ( ent < entLarge ) {
00724 
00725         double log10H = log10( ent ) ;
00726         double log10HSmall = log10( entSmall ) ;
00727         double log10HLarge = log10( entLarge ) ;
00728         double dH = log10HLarge - log10HSmall ;
00729         double uu = (log10H - log10HSmall) / dH ;
00730 
00731         double mgam1skapgamSmall = m0*(gamma[i-1]-double(1))
00732           /kappa[i-1]/gamma[i-1] ;
00733         double mgam1skapgamLarge = m0*(gamma[i]-double(1))
00734           /kappa[i]/gamma[i] ;
00735 
00736         double nnSmall = pow( mgam1skapgamSmall
00737                   *(exp(entSmall)-mu0[i-1]/m0),
00738                   double(1)/(gamma[i-1]-double(1)) ) ;
00739         double nnLarge = pow( mgam1skapgamLarge
00740                   *(exp(entLarge)-mu0[i]/m0),
00741                   double(1)/(gamma[i]-double(1)) ) ;
00742 
00743         double ppSmall = kappa[i-1] * pow( nnSmall, gamma[i-1] ) ;
00744         double ppLarge = kappa[i] * pow( nnLarge, gamma[i] ) ;
00745 
00746         double eeSmall = mu0[i-1] * nnSmall
00747           + ppSmall / (gamma[i-1] - double(1)) ;
00748         double eeLarge = mu0[i] * nnLarge
00749           + ppLarge / (gamma[i] - double(1)) ;
00750 
00751         double log10PSmall = log10( ppSmall ) ;
00752         double log10PLarge = log10( ppLarge ) ;
00753 
00754         double dlpsdlhSmall = entSmall
00755           * (double(1) + eeSmall / ppSmall) ;
00756         double dlpsdlhLarge = entLarge
00757           * (double(1) + eeLarge / ppLarge) ;
00758 
00759         double log10PInterpolate = logp(log10PSmall, log10PLarge,
00760                         dlpsdlhSmall, dlpsdlhLarge,
00761                         dH, uu) ;
00762 
00763         return pow(double(10), log10PInterpolate) ;
00764 
00765     }
00766     else {
00767 
00768         mgam1skapgam = m0*(gamma[i]-double(1))/kappa[i]/gamma[i] ;
00769 
00770         nn = pow( mgam1skapgam*(exp(ent)-mu0[i]/m0),
00771               double(1)/(gamma[i]-double(1)) ) ;
00772 
00773         return kappa[i] * pow( nn, gamma[i] ) ;
00774 
00775     }
00776 
00777     }
00778 
00779 }
00780 
00781 
00782 // dln(n)/dln(H) from enthalpy
00783 //----------------------------
00784 
00785 double Eos_multi_poly::der_nbar_ent_p(double ent, const Param* ) const {
00786 
00787     int i = 0 ; // "i" corresponds to the number of domain
00788                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00789                 // The buffer zone is included in the next zone.
00790     for (int l=0; l<npeos-1; l++) {
00791         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00792         i++ ;
00793     }
00794     }
00795 
00796     if (i == 0) {
00797 
00798         if ( ent > double(0) ) {
00799 
00800         if ( ent < 1.e-13 ) {
00801 
00802             return ( double(1) + ent/double(2) + ent*ent/double(12) )
00803           / (gamma[0] - double(1)) ;
00804 
00805         }
00806         else {
00807 
00808             return ent / (double(1) - exp(-ent))
00809           / (gamma[0] - double(1)) ; // mu0[0]/m0=1
00810 
00811         }
00812 
00813     }
00814     else {
00815 
00816       return double(1) / (gamma[0] - double(1)) ;
00817 
00818     }
00819 
00820     }
00821     else {
00822 
00823         if ( ent < entCrit[i-1]*(double(1)+decInc[i-1]) ) {
00824 
00825         double zeta = der_press_ent_p(ent) / der_press_nbar_p(ent) ;
00826 
00827         return zeta ;
00828 
00829     }
00830     else {
00831 
00832         return ent / (double(1) - (mu0[i]/m0) * exp(-ent))
00833           / (gamma[i] - double(1)) ;
00834 
00835     }
00836 
00837     }
00838 }
00839 
00840 
00841 // dln(e)/dln(H) from enthalpy
00842 //----------------------------
00843 
00844 double Eos_multi_poly::der_ener_ent_p(double ent, const Param* ) const {
00845 
00846     int i = 0 ; // "i" corresponds to the number of domain
00847                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00848                 // The buffer zone is included in the next zone.
00849     for (int l=0; l<npeos-1; l++) {
00850         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00851         i++ ;
00852     }
00853     }
00854 
00855     double mgam1skapgam = 1. ;  // Initialization
00856     double nn = 0. ;  // Initialization
00857     double pp = 0. ;  // Initialization
00858     double ee = 0. ;  // Initialization
00859 
00860     if (i == 0) {
00861 
00862         if ( ent > double(0) ) {
00863 
00864         mgam1skapgam = m0*(gamma[0]-double(1))/kappa[0]/gamma[0] ;
00865 
00866         nn = pow( mgam1skapgam*(exp(ent)-double(1)),
00867               double(1)/(gamma[0]-double(1)) ) ; // mu0[0]/m0=1
00868 
00869         pp = kappa[0] * pow( nn, gamma[0] ) ;
00870 
00871         ee = mu0[0] * nn + pp / (gamma[0] - double(1)) ;
00872 
00873         if ( ent < 1.e-13 ) {
00874 
00875             return ( double(1) + ent/double(2) + ent*ent/double(12) )
00876           / (gamma[0] - double(1)) * (double(1) + pp / ee) ;
00877 
00878         }
00879         else {
00880 
00881             return ent / (double(1) - exp(-ent))
00882           / (gamma[0] - double(1)) * (double(1) + pp / ee) ;
00883         // mu0[0]/m0=1
00884 
00885         }
00886 
00887     }
00888     else {
00889 
00890       return double(1) / (gamma[0] - double(1)) ;
00891 
00892     }
00893 
00894     }
00895     else {
00896 
00897         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
00898         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
00899 
00900         if ( ent < entLarge ) {
00901 
00902         double log10H = log10( ent ) ;
00903         double log10HSmall = log10( entSmall ) ;
00904         double log10HLarge = log10( entLarge ) ;
00905         double dH = log10HLarge - log10HSmall ;
00906         double uu = (log10H - log10HSmall) / dH ;
00907 
00908         double mgam1skapgamSmall = m0*(gamma[i-1]-double(1))
00909           /kappa[i-1]/gamma[i-1] ;
00910         double mgam1skapgamLarge = m0*(gamma[i]-double(1))
00911           /kappa[i]/gamma[i] ;
00912 
00913         double nnSmall = pow( mgam1skapgamSmall
00914                   *(exp(entSmall)-mu0[i-1]/m0),
00915                   double(1)/(gamma[i-1]-double(1)) ) ;
00916         double nnLarge = pow( mgam1skapgamLarge
00917                   *(exp(entLarge)-mu0[i]/m0),
00918                   double(1)/(gamma[i]-double(1)) ) ;
00919 
00920         double ppSmall = kappa[i-1] * pow( nnSmall, gamma[i-1] ) ;
00921         double ppLarge = kappa[i] * pow( nnLarge, gamma[i] ) ;
00922 
00923         double eeSmall = mu0[i-1] * nnSmall
00924           + ppSmall / (gamma[i-1] - double(1)) ;
00925         double eeLarge = mu0[i] * nnLarge
00926           + ppLarge / (gamma[i] - double(1)) ;
00927 
00928         double log10PSmall = log10( ppSmall ) ;
00929         double log10PLarge = log10( ppLarge ) ;
00930 
00931         double dlpsdlhSmall = entSmall
00932           * (double(1) + eeSmall / ppSmall) ;
00933         double dlpsdlhLarge = entLarge
00934           * (double(1) + eeLarge / ppLarge) ;
00935 
00936         double log10PInterpolate = logp(log10PSmall, log10PLarge,
00937                         dlpsdlhSmall, dlpsdlhLarge,
00938                         dH, uu) ;
00939 
00940         double dlpsdlhInterpolate = dlpsdlh(log10PSmall, log10PLarge,
00941                         dlpsdlhSmall, dlpsdlhLarge,
00942                         dH, uu) ;
00943 
00944         pp = pow(double(10), log10PInterpolate) ;
00945 
00946         ee = pp / ent * dlpsdlhInterpolate - pp ;
00947 
00948         double zeta = (double(1) + pp / ee) * der_press_ent_p(ent)
00949           / der_press_nbar_p(ent) ;
00950 
00951         return zeta ;
00952 
00953     }
00954     else {
00955 
00956         mgam1skapgam = m0*(gamma[i]-double(1))/kappa[i]/gamma[i] ;
00957 
00958         nn = pow( mgam1skapgam*(exp(ent)-mu0[i]/m0),
00959               double(1)/(gamma[i]-double(1)) ) ;
00960 
00961         pp = kappa[i] * pow( nn, gamma[i] ) ;
00962 
00963         ee = mu0[i] * nn + pp / (gamma[i] - double(1)) ;
00964 
00965         return ent / (double(1) - (mu0[i]/m0) * exp(-ent))
00966           / (gamma[i] - double(1)) * (double(1) + pp / ee) ;
00967 
00968     }
00969 
00970     }
00971 }
00972 
00973 
00974 // dln(p)/dln(H) from enthalpy
00975 //----------------------------
00976 
00977 double Eos_multi_poly::der_press_ent_p(double ent, const Param* ) const {
00978 
00979     int i = 0 ; // "i" corresponds to the number of domain
00980                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
00981                 // The buffer zone is included in the next zone.
00982     for (int l=0; l<npeos-1; l++) {
00983         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
00984         i++ ;
00985     }
00986     }
00987 
00988     if (i == 0) {
00989 
00990         if ( ent > double(0) ) {
00991 
00992         if ( ent < 1.e-13 ) {
00993 
00994             return gamma[0]
00995           * ( double(1) + ent/double(2) + ent*ent/double(12) )
00996           / (gamma[0] - double(1)) ;
00997 
00998         }
00999         else {
01000 
01001             return gamma[0] * ent / (double(1) - exp(-ent))
01002           / (gamma[0] - double(1)) ; // mu0[0]/m0=1
01003 
01004         }
01005 
01006     }
01007     else {
01008 
01009       return gamma[0] / (gamma[0] - double(1)) ;
01010 
01011     }
01012 
01013     }
01014     else {
01015 
01016         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
01017         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
01018 
01019         if ( ent < entLarge ) {
01020 
01021         double log10H = log10( ent ) ;
01022         double log10HSmall = log10( entSmall ) ;
01023         double log10HLarge = log10( entLarge ) ;
01024         double dH = log10HLarge - log10HSmall ;
01025         double uu = (log10H - log10HSmall) / dH ;
01026 
01027         double mgam1skapgamSmall = m0*(gamma[i-1]-double(1))
01028           /kappa[i-1]/gamma[i-1] ;
01029         double mgam1skapgamLarge = m0*(gamma[i]-double(1))
01030           /kappa[i]/gamma[i] ;
01031 
01032         double nnSmall = pow( mgam1skapgamSmall
01033                   *(exp(entSmall)-mu0[i-1]/m0),
01034                   double(1)/(gamma[i-1]-double(1)) ) ;
01035         double nnLarge = pow( mgam1skapgamLarge
01036                   *(exp(entLarge)-mu0[i]/m0),
01037                   double(1)/(gamma[i]-double(1)) ) ;
01038 
01039         double ppSmall = kappa[i-1] * pow( nnSmall, gamma[i-1] ) ;
01040         double ppLarge = kappa[i] * pow( nnLarge, gamma[i] ) ;
01041 
01042         double eeSmall = mu0[i-1] * nnSmall
01043           + ppSmall / (gamma[i-1] - double(1)) ;
01044         double eeLarge = mu0[i] * nnLarge
01045           + ppLarge / (gamma[i] - double(1)) ;
01046 
01047         double log10PSmall = log10( ppSmall ) ;
01048         double log10PLarge = log10( ppLarge ) ;
01049 
01050         double dlpsdlhSmall = entSmall
01051           * (double(1) + eeSmall / ppSmall) ;
01052         double dlpsdlhLarge = entLarge
01053           * (double(1) + eeLarge / ppLarge) ;
01054 
01055         double dlpsdlhInterpolate = dlpsdlh(log10PSmall, log10PLarge,
01056                         dlpsdlhSmall, dlpsdlhLarge,
01057                         dH, uu) ;
01058         return dlpsdlhInterpolate ;
01059 
01060     }
01061     else {
01062 
01063         return gamma[i] * ent / (double(1) - (mu0[i]/m0) * exp(-ent))
01064           / (gamma[i] - double(1)) ;
01065 
01066     }
01067 
01068     }
01069 }
01070 
01071 
01072 // dln(p)/dln(n) from enthalpy
01073 //----------------------------
01074 
01075 double Eos_multi_poly::der_press_nbar_p(double ent, const Param* ) const {
01076 
01077     int i = 0 ; // "i" corresponds to the number of domain
01078                 // i=0: gamma[0], kappa[0], i=1: gamma[1], kappa[1], .....
01079                 // The buffer zone is included in the next zone.
01080     for (int l=0; l<npeos-1; l++) {
01081         if ( ent > entCrit[l]*(double(1)-decInc[l]) ) {
01082         i++ ;
01083     }
01084     }
01085 
01086     if (i == 0) {
01087 
01088         return gamma[0] ;
01089 
01090     }
01091     else {
01092 
01093         double entSmall = entCrit[i-1]*(double(1)-decInc[i-1]) ;
01094         double entLarge = entCrit[i-1]*(double(1)+decInc[i-1]) ;
01095 
01096         if ( ent < entLarge ) {
01097 
01098         double log10H = log10( ent ) ;
01099         double log10HSmall = log10( entSmall ) ;
01100         double log10HLarge = log10( entLarge ) ;
01101 
01102         double dlpsdlnbInterpolate = dlpsdlnb(log10HSmall, log10HLarge,
01103                           gamma[i-1], gamma[i],
01104                           log10H) ;
01105 
01106         return dlpsdlnbInterpolate ;
01107 
01108     }
01109     else {
01110 
01111         return gamma[i] ;
01112 
01113     }
01114 
01115     }
01116 }
01117 
01118 
01119 //***************************************************//
01120 //     Functions which appear in the computation     //
01121 //***************************************************//
01122 
01123 double logp(double log10PressSmall, double log10PressLarge,
01124         double dlpsdlhSmall, double dlpsdlhLarge,
01125         double dx, double u) {
01126 
01127     double resu = log10PressSmall * (double(2) * u * u * u
01128                      - double(3) * u * u + double(1))
01129       + log10PressLarge * (double(3) * u * u - double(2) * u * u * u)
01130       + dlpsdlhSmall * dx * (u * u * u - double(2) * u * u + u)
01131       - dlpsdlhLarge * dx * (u * u - u * u * u) ;
01132 
01133     return resu ;
01134 
01135 }
01136 
01137 double dlpsdlh(double log10PressSmall, double log10PressLarge,
01138            double dlpsdlhSmall, double dlpsdlhLarge,
01139            double dx, double u) {
01140 
01141     double resu = double(6) * (log10PressSmall - log10PressLarge)
01142       * (u * u - u) / dx
01143       + dlpsdlhSmall * (double(3) * u * u - double(4) * u + double(1))
01144       + dlpsdlhLarge * (double(3) * u * u - double(2) * u) ;
01145 
01146     return resu ;
01147 
01148 }
01149 
01150 double dlpsdlnb(double log10HSmall, double log10HLarge,
01151         double dlpsdlnbSmall, double dlpsdlnbLarge,
01152         double log10H) {
01153 
01154     double resu = log10H * (dlpsdlnbSmall - dlpsdlnbLarge)
01155       / (log10HSmall - log10HLarge)
01156       + (log10HSmall * dlpsdlnbLarge - log10HLarge * dlpsdlnbSmall)
01157       / (log10HSmall - log10HLarge) ;
01158 
01159     return resu ;
01160 
01161 }

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