PureFluidPhase.cpp

Go to the documentation of this file.
00001 /**
00002  *   @file PureFluidPhase.cpp
00003  *   Definitions for a ThermoPhase object for a pure fluid phase consisting 
00004  *   of gas, liquid, mixed-gas-liquid
00005  *   and supercritical fluid (see \ref thermoprops 
00006  *   and class \link Cantera::PureFluidPhase PureFluidPhase\endlink).
00007  */
00008 /*
00009  *  $Id: PureFluidPhase.cpp 279 2009-12-05 19:08:43Z hkmoffa $
00010  */
00011 #include "xml.h"
00012 #include "PureFluidPhase.h"
00013 
00014 #ifdef WITH_PURE_FLUIDS
00015 
00016 #include "../../../ext/tpx/Sub.h"
00017 #include "../../../ext/tpx/utils.h"
00018 
00019 #include <cstdlib>
00020 
00021 namespace Cantera {
00022 
00023   // Base Constructor
00024   PureFluidPhase::PureFluidPhase() :
00025     ThermoPhase(), 
00026     m_sub(0),
00027     m_subflag(0), 
00028     m_mw(-1.0), 
00029     m_verbose(false)
00030   {
00031   }
00032 
00033   // CopyConstructor
00034   PureFluidPhase::PureFluidPhase(const PureFluidPhase& right) :
00035     ThermoPhase(), 
00036     m_sub(0),
00037     m_subflag(0), 
00038     m_mw(-1.0), 
00039     m_verbose(false)
00040   {
00041     *this = right;
00042   }
00043 
00044   //! Assignment operator
00045   /*!
00046    * @param right Object to be copied
00047    */
00048   PureFluidPhase& PureFluidPhase::operator=(const PureFluidPhase& right) {
00049     if (&right != this) {
00050       ThermoPhase::operator=(right);
00051       if (m_sub) {
00052         delete m_sub;
00053       }
00054       m_subflag    = right.m_subflag;
00055       m_sub        = tpx::GetSub(m_subflag);
00056       m_mw         = right.m_mw;
00057       m_verbose    = right.m_verbose;
00058     }
00059     return *this;
00060   }
00061   
00062   // Duplicator from the %ThermoPhase parent class
00063   /*
00064    * Given a pointer to a %ThermoPhase object, this function will
00065    * duplicate the %ThermoPhase object and all underlying structures.
00066    * This is basically a wrapper around the copy constructor.
00067    *
00068    * @return returns a pointer to a %ThermoPhase
00069    */
00070   ThermoPhase *PureFluidPhase::duplMyselfAsThermoPhase() const {
00071     PureFluidPhase *igp = new PureFluidPhase(*this);
00072     return (ThermoPhase *) igp;
00073   }
00074 
00075 
00076 
00077 
00078     PureFluidPhase::~PureFluidPhase() {
00079       delete m_sub; 
00080     }
00081 
00082     void PureFluidPhase::
00083     initThermo() {
00084         if (m_sub) delete m_sub;
00085         m_sub = tpx::GetSub(m_subflag);
00086         if (m_sub == 0) {
00087             throw CanteraError("PureFluidPhase::initThermo",
00088                 "could not create new substance object.");
00089         }
00090         m_mw = m_sub->MolWt();
00091         m_weight[0] = m_mw;
00092         setMolecularWeight(0,m_mw);
00093         double one = 1.0;
00094         setMoleFractions(&one);
00095         double cp0_R, h0_RT, s0_R, T0, p;
00096         T0 = 298.15;
00097         if (T0 < m_sub->Tcrit()) {
00098             m_sub->Set(tpx::TX, T0, 1.0);
00099             p = 0.01*m_sub->P();
00100         }
00101         else {
00102             p = 0.001*m_sub->Pcrit();
00103         }
00104         m_sub->Set(tpx::TP, T0, p);
00105         
00106         m_spthermo->update_one(0, T0, &cp0_R, &h0_RT, &s0_R);
00107         double s_R = s0_R - log(p/refPressure());
00108         m_sub->setStdState(h0_RT*GasConstant*298.15/m_mw,
00109             s_R*GasConstant/m_mw, T0, p);
00110         if (m_verbose) {
00111             writelog("PureFluidPhase::initThermo: initialized phase "
00112                 +id()+"\n");
00113         }
00114     }
00115 
00116     void PureFluidPhase::
00117     setParametersFromXML(const XML_Node& eosdata) {
00118         eosdata._require("model","PureFluid");
00119         m_subflag = atoi(eosdata["fluid_type"].c_str());
00120         if (m_subflag < 0) 
00121             throw CanteraError("PureFluidPhase::setParametersFromXML",
00122                 "missing or negative substance flag");
00123     }
00124 
00125     doublereal PureFluidPhase::
00126     enthalpy_mole() const {
00127         setTPXState();
00128         doublereal h = m_sub->h() * m_mw;
00129         check(h);
00130         return h;            
00131     }
00132         
00133     doublereal PureFluidPhase::
00134     intEnergy_mole() const {
00135         setTPXState();
00136         doublereal u = m_sub->u() * m_mw;
00137         check(u);
00138         return u;            
00139     }
00140 
00141     doublereal PureFluidPhase::
00142     entropy_mole() const {
00143         setTPXState();
00144         doublereal s = m_sub->s() * m_mw;
00145         check(s);
00146         return s;            
00147     }
00148 
00149     doublereal PureFluidPhase::
00150     gibbs_mole() const {
00151         setTPXState();
00152         doublereal g = m_sub->g() * m_mw;
00153         check(g);
00154         return g;            
00155     }
00156 
00157     doublereal PureFluidPhase::
00158     cp_mole() const {
00159         setTPXState();
00160         doublereal cp = m_sub->cp() * m_mw;
00161         check(cp);
00162         return cp;            
00163     }
00164 
00165     doublereal PureFluidPhase::
00166     cv_mole() const {
00167         setTPXState();
00168         doublereal cv = m_sub->cv() * m_mw;
00169         check(cv);
00170         return cv;
00171     }
00172         
00173     doublereal PureFluidPhase::
00174     pressure() const {
00175         setTPXState();
00176         doublereal p = m_sub->P();
00177         check(p);
00178         return p;
00179     }
00180         
00181     void PureFluidPhase::
00182     setPressure(doublereal p) {
00183         Set(tpx::TP, temperature(), p);
00184         setDensity(1.0/m_sub->v());
00185         check();
00186     }
00187 
00188     void PureFluidPhase::Set(int n, double x, double y) const {
00189         try { 
00190             m_sub->Set(n, x, y); 
00191         }
00192         catch(tpx::TPX_Error) {
00193             reportTPXError();
00194         }
00195     }
00196             
00197     void PureFluidPhase::setTPXState() const {
00198         Set(tpx::TV, temperature(), 1.0/density());
00199     }
00200         
00201     void PureFluidPhase::check(doublereal v) const {
00202         if (m_sub->Error() || v == tpx::Undef) {
00203             throw CanteraError("PureFluidPhase",string(tpx::errorMsg(
00204                                                            m_sub->Error())));
00205         }
00206     }
00207 
00208     void PureFluidPhase::reportTPXError() const {
00209         string msg = tpx::TPX_Error::ErrorMessage;
00210         string proc = "tpx::"+tpx::TPX_Error::ErrorProcedure;
00211         throw CanteraError(proc,msg);
00212     }
00213 
00214 
00215     doublereal PureFluidPhase::isothermalCompressibility() const {
00216         return m_sub->isothermalCompressibility();
00217     }
00218 
00219     doublereal PureFluidPhase::thermalExpansionCoeff() const {
00220         return m_sub->thermalExpansionCoeff();
00221     }
00222 
00223     tpx::Substance& PureFluidPhase::TPX_Substance() { return *m_sub; }
00224 
00225     /// critical temperature 
00226     doublereal PureFluidPhase::critTemperature() const { return m_sub->Tcrit(); }
00227         
00228     /// critical pressure
00229     doublereal PureFluidPhase::critPressure() const { return m_sub->Pcrit(); }
00230         
00231     /// critical density
00232     doublereal PureFluidPhase::critDensity() const { return 1.0/m_sub->Vcrit(); }
00233         
00234         
00235     /// saturation temperature
00236     doublereal PureFluidPhase::satTemperature(doublereal p) const { 
00237         try {
00238             doublereal ts = m_sub->Tsat(p);
00239             return ts;
00240         }
00241         catch(tpx::TPX_Error) {
00242             reportTPXError();
00243             return -1.0;
00244         }
00245     }
00246         
00247     void PureFluidPhase::setState_HP(doublereal h, doublereal p, 
00248         doublereal tol) {
00249         Set(tpx::HP, h, p);
00250         setState_TR(m_sub->Temp(), 1.0/m_sub->v());
00251         check();
00252     }
00253 
00254     void PureFluidPhase::setState_UV(doublereal u, doublereal v, 
00255         doublereal tol) {
00256         Set(tpx::UV, u, v);
00257         setState_TR(m_sub->Temp(), 1.0/m_sub->v());
00258         check();
00259     }
00260 
00261     void PureFluidPhase::setState_SV(doublereal s, doublereal v, 
00262         doublereal tol) {
00263         Set(tpx::SV, s, v);
00264         setState_TR(m_sub->Temp(), 1.0/m_sub->v());
00265         check();
00266     }
00267 
00268     void PureFluidPhase::setState_SP(doublereal s, doublereal p, 
00269         doublereal tol) {
00270         Set(tpx::SP, s, p);
00271         setState_TR(m_sub->Temp(), 1.0/m_sub->v());
00272         check();
00273     }
00274 
00275     /// saturation pressure
00276     doublereal PureFluidPhase::satPressure(doublereal t) const {
00277         doublereal vsv = m_sub->v();
00278         try {
00279             Set(tpx::TV,t,vsv);
00280             doublereal ps = m_sub->Ps();
00281             return ps;
00282         }
00283         catch(tpx::TPX_Error) {
00284             reportTPXError();
00285             return -1.0;
00286         }
00287     }
00288         
00289     doublereal PureFluidPhase::vaporFraction() const {
00290         setTPXState();
00291         doublereal x = m_sub->x();
00292         check(x);
00293         return x;
00294     }
00295         
00296     void PureFluidPhase::setState_Tsat(doublereal t, doublereal x) {
00297         setTemperature(t);
00298         setTPXState();
00299         Set(tpx::TX, t, x);
00300         setDensity(1.0/m_sub->v());
00301         check();
00302     }
00303 
00304     void PureFluidPhase::setState_Psat(doublereal p, doublereal x) {
00305         setTPXState();
00306         Set(tpx::PX, p, x);
00307         setTemperature(m_sub->Temp());
00308         setDensity(1.0/m_sub->v());
00309         check();
00310     }
00311 
00312 
00313   /**
00314    * Format a summary of the mixture state for output.
00315    */           
00316   std::string PureFluidPhase::report(bool show_thermo) const {
00317 
00318 
00319     char p[800];
00320     string s = "";
00321     try {
00322       if (name() != "") {
00323         sprintf(p, " \n  %s:\n", name().c_str());
00324         s += p;
00325       }
00326       sprintf(p, " \n       temperature    %12.6g  K\n", temperature());
00327       s += p;
00328       sprintf(p, "          pressure    %12.6g  Pa\n", pressure());
00329       s += p;
00330       sprintf(p, "           density    %12.6g  kg/m^3\n", density());
00331       s += p;
00332       sprintf(p, "  mean mol. weight    %12.6g  amu\n", meanMolecularWeight());
00333       s += p;
00334 
00335       if (eosType() == cPureFluid) {
00336         double xx = ((PureFluidPhase *) (this))->vaporFraction();
00337         sprintf(p, "    vapor fraction    %12.6g \n", 
00338                 xx); //th.vaporFraction());
00339         s += p;
00340       }
00341 
00342       doublereal phi = electricPotential();
00343       if (phi != 0.0) {
00344         sprintf(p, "         potential    %12.6g  V\n", phi);
00345         s += p;
00346       }
00347       if (show_thermo) {
00348         sprintf(p, " \n");
00349         s += p;
00350         sprintf(p, "                          1 kg            1 kmol\n");
00351         s += p;
00352         sprintf(p, "                       -----------      ------------\n");
00353         s += p;
00354         sprintf(p, "          enthalpy    %12.6g     %12.4g     J\n", 
00355                 enthalpy_mass(), enthalpy_mole());
00356         s += p;
00357         sprintf(p, "   internal energy    %12.6g     %12.4g     J\n", 
00358                 intEnergy_mass(), intEnergy_mole());
00359         s += p;
00360         sprintf(p, "           entropy    %12.6g     %12.4g     J/K\n", 
00361                 entropy_mass(), entropy_mole());
00362         s += p;
00363         sprintf(p, "    Gibbs function    %12.6g     %12.4g     J\n", 
00364                 gibbs_mass(), gibbs_mole());
00365         s += p;
00366         sprintf(p, " heat capacity c_p    %12.6g     %12.4g     J/K\n", 
00367                 cp_mass(), cp_mole());
00368         s += p;
00369         try {
00370           sprintf(p, " heat capacity c_v    %12.6g     %12.4g     J/K\n", 
00371                   cv_mass(), cv_mole());
00372           s += p;
00373         }
00374         catch(CanteraError) {
00375           sprintf(p, " heat capacity c_v    <not implemented>       \n");
00376           s += p;
00377         }
00378       }
00379 
00380       int kk = nSpecies();
00381       array_fp x(kk);
00382       array_fp y(kk);
00383       array_fp mu(kk);
00384       getMoleFractions(&x[0]);
00385       getMassFractions(&y[0]);
00386       getChemPotentials(&mu[0]);
00387       doublereal rt = GasConstant * temperature(); 
00388       int k;
00389       //if (th.nSpecies() > 1) {
00390 
00391       if (show_thermo) {
00392         sprintf(p, " \n                           X     "
00393                 "            Y          Chem. Pot. / RT    \n");
00394         s += p;
00395         sprintf(p, "                     -------------     "
00396                 "------------     ------------\n");
00397         s += p;
00398         for (k = 0; k < kk; k++) {
00399           if (x[k] > SmallNumber) {
00400             sprintf(p, "%18s   %12.6g     %12.6g     %12.6g\n", 
00401                     speciesName(k).c_str(), x[k], y[k], mu[k]/rt);
00402           }
00403           else {
00404             sprintf(p, "%18s   %12.6g     %12.6g     \n", 
00405                     speciesName(k).c_str(), x[k], y[k]);
00406           }
00407           s += p;
00408         }
00409       }
00410       else {
00411         sprintf(p, " \n                           X"
00412                 "Y\n");
00413         s += p;
00414         sprintf(p, "                     -------------"
00415                 "     ------------\n");
00416         s += p;
00417         for (k = 0; k < kk; k++) {
00418           sprintf(p, "%18s   %12.6g     %12.6g\n", 
00419                   speciesName(k).c_str(), x[k], y[k]);
00420           s += p;
00421         }
00422       }
00423     }
00424     //}
00425     catch (CanteraError) {
00426       ;
00427     }
00428     return s;
00429   }
00430 
00431  
00432 }
00433 
00434 #endif  // WITH_PURE_FLUIDS
Generated by  doxygen 1.6.3