WaterPropsIAPWS.h

Go to the documentation of this file.
00001 /**
00002  * @file WaterPropsIAPWS.h
00003  * Headers for a class for calculating the equation of state of water
00004  * from the IAPWS 1995 Formulation based on the steam tables thermodynamic
00005  * basis (See class \link Cantera::WaterPropsIAPWS WaterPropsIAPWS\endlink).
00006  */
00007 /*
00008  * Copywrite (2005) Sandia Corporation. Under the terms of
00009  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
00010  * U.S. Government retains certain rights in this software.
00011  */
00012 /*
00013  * $Id: WaterPropsIAPWS.h 279 2009-12-05 19:08:43Z hkmoffa $
00014  */
00015 
00016 #ifndef WATERPROPSIAPWS_H
00017 #define WATERPROPSIAPWS_H
00018 
00019 #include "WaterPropsIAPWSphi.h"
00020 #include "config.h"
00021 
00022 namespace Cantera {
00023 /**
00024  *  @name Names for the phase regions
00025  *
00026  *  These constants are defined and used in the interface
00027  *  to describe the location of where we are in (T,rho) space.
00028  *  
00029  *   WATER_UNSTABLELIQUID indicates that we are in the unstable region, inside the
00030  *   spinodal curve where dpdrho < 0.0 amonst other properties. The difference
00031  *   between WATER_UNSTABLELIQUID and WATER_UNSTABLEGAS  is that 
00032  *     for WATER_UNSTABLELIQUID  d2pdrho2 > 0   and dpdrho < 0.0
00033  *     for WATER_UNSTABLEGAS     d2pdrho2 < 0   and dpdrho < 0.0
00034  */ 
00035 //@{
00036 #define WATER_GAS       0
00037 #define WATER_LIQUID    1
00038 #define WATER_SUPERCRIT 2
00039 #define WATER_UNSTABLELIQUID  3
00040 #define WATER_UNSTABLEGAS  4
00041 //@}
00042 
00043 //! Class for calculating the equation of state of water. 
00044 /*!
00045  *
00046  *  The reference is W. Wagner, A. Prub, "The IAPWS Formulation 1995 for the Themodynamic
00047  *  Properties of Ordinary Water Substance for General and Scientific Use,"
00048  *  J. Phys. Chem. Ref. Dat, 31, 387, 2002.
00049  *
00050  * This class provides a very complicated polynomial for the specific helmholtz free
00051  * energy of water, as a function of temperature and density.
00052  *
00053  *    \f[
00054  *        \frac{M\hat{f}(\rho,T)}{R T} = \phi(\delta, \tau) =
00055  *                        \phi^o(\delta, \tau) +  \phi^r(\delta, \tau)
00056  *    \f]
00057  *
00058  *  where
00059  *
00060  *    \f[
00061  *         \delta = \rho / \rho_c \mbox{\qquad and \qquad} \tau = T_c / T 
00062  *    \f]
00063  *
00064  *  The following constants are assumed
00065  *
00066  *     \f[
00067  *         T_c = 647.096\mbox{\ K}
00068  *    \f]
00069  *    \f[
00070  *        \rho_c = 322 \mbox{\  kg\ m$^{-3}$}
00071  *     \f]
00072  *    \f[
00073  *        R/M = 0.46151805 \mbox{\ kJ\ kg$^{-1}$\ K$^{-1}$}
00074  *    \f]
00075  *
00076  *  The free energy is a unique single-valued function of the temperature and density
00077  *  over its entire range.
00078  *
00079  * Note, the base thermodynamic state for this class is the one
00080  * used in the steam tables, i.e., the liquid at the triple point
00081  * for water has the following properties:
00082  *
00083  * -  u(273.16, rho)    = 0.0
00084  * -  s(273.16, rho)    = 0.0 
00085  * -  psat(273.16)      = 611.655 Pascal
00086  * -  rho(273.16, psat) = 999.793 kg m-3
00087  *
00088  *  Therefore, to use this class within %Cantera, offsets to u() and s() must be used
00089  *  to put the water class onto the same basis as other thermodynamic quantities.
00090  *  For example, in the WaterSSTP class, these offsets are calculated in the following way.
00091  *  The thermodynamic base state for water is set to the NIST basis here
00092  *  by specifying constants EW_Offset and SW_Offset. These offsets are
00093  *  calculated on the fly so that the following properties hold:
00094  *
00095  *   - Delta_Hfo_idealGas(298.15, 1bar) = -241.826 kJ/gmol
00096  *   - So_idealGas(298.15, 1bar)        = 188.835 J/gmolK
00097  *
00098  *   The offsets are calculated by actually computing the above quantities and then
00099  *   calculating the correction factor.
00100  *
00101  *  This class provides an interface to the #WaterPropsIAPWSphi class, which actually
00102  *  calculates the \f$ \phi^o(\delta, \tau)  \f$ and the  \f$ \phi^r(\delta, \tau) \f$
00103  *  polynomials in dimensionless form.
00104  *
00105  *  All thermodynamic results from this class are returned in dimensional form. This 
00106  *  is because the gas constant (and molecular weight) used within this class is allowed to be potentially
00107  *  different than that used elsewhere in %Cantera. Therefore, everything has to be
00108  *  in dimensional units. Note, however, the thermodynamic basis is set to that used
00109  *  in the steam tables. (u = s = 0 for liquid water at the triple point).
00110  *
00111  *  This class is not a %ThermoPhase. However, it does maintain an internal state of
00112  *  the object that is dependent on temperature and density. The internal state
00113  *  is characterized by an internally storred \f$ \tau\f$ and a \f$ \delta \f$ value,
00114  *  and an iState value, which indicates whether the point is a liquid, a gas,
00115  *  or a supercritical fluid.
00116  *  Along with that the  \f$ \tau\f$ and a \f$ \delta \f$ values are polynomials of
00117  *  \f$ \tau\f$ and a \f$ \delta \f$ that are kept by the #WaterPropsIAPWSphi class.
00118  *  Therefore, whenever  \f$ \tau\f$ or \f$ \delta \f$ is changed, the function setState()
00119  *  must be called in order for the internal state to be kept up to date. 
00120  *
00121  * The class is pretty straightfoward. However, one function deserves mention.
00122  * the #density() function calculates the density that is consistent with
00123  * a particular value of the temperature and pressure. It may therefore be 
00124  * multivalued or potentially there may be no answer from this function. It therefore
00125  * takes a phase guess and a density guess as optional parameters. If no guesses are
00126  * supplied to density(), a gas phase guess is assumed. This may or may not be what
00127  * is wanted. Therefore, density() should usually at leat be supplied with a phase
00128  * guess so that it may manufacture an appropriate density guess. 
00129  * #density() manufactures the initial density guess, nondimensionalizes everything,
00130  * and then calls #WaterPropsIAPWSphi::dfind(), which does the iterative calculation
00131  * to find the density condition that matches the desired input pressure.
00132  *
00133  * The phase guess defines are located in the .h file. they are
00134  *
00135  *   - WATER_GAS
00136  *   - WATER_LIQUID
00137  *   - WATER_SUPERCRIT
00138  *
00139  * There are only three functions which actually change the value of the internal
00140  * state of this object after it's been instantiated
00141 
00142  *   - setState_TR(temperature, rho)
00143  *   - density(temperature, pressure, phase, rhoguess) 
00144  *   - psat(temperature, waterState);
00145  *
00146  * The setState_TR() is the main function that sets the temperature and rho value.
00147  * The density() function serves as a setState_TP() function, in that it sets 
00148  * internal state to a temperature and pressure. However, note that this is potentially
00149  * multivalued. Therefore, we need to supply in addition a phase guess and a rho guess
00150  * to the input temperature and pressure.
00151  * The psat() function sets the internal state to the saturated liquid or saturated gas
00152  * state, dependeing on the waterState parameter.
00153  *
00154  * Because the underlying object WaterPropsIAPWSphi is privately held, you can be 
00155  * sure that the underlying state of this object doesn't change except due to the
00156  * three function calls listed above.
00157  *
00158  * @ingroup thermoprops
00159  *
00160  */
00161 class WaterPropsIAPWS {
00162 public:
00163 
00164   //! Base constructor
00165   WaterPropsIAPWS();
00166 
00167   //! Copy constructor
00168   /*!
00169    * @param right Object to be copied
00170    */
00171   WaterPropsIAPWS(const WaterPropsIAPWS &right);
00172 
00173   //! assignment constructor
00174   /*!
00175    * @param right Object to be copied
00176    */
00177   WaterPropsIAPWS & operator=(const WaterPropsIAPWS &right);
00178 
00179   //! destructor
00180   ~WaterPropsIAPWS();
00181 
00182   //! Set the internal state of the object wrt temperature and density
00183   /*!
00184    * @param temperature   temperature (kelvin)
00185    * @param rho           density  (kg m-3)
00186    */
00187   void setState_TR(doublereal temperature, doublereal rho);
00188   
00189   //! Calculate the Helmholtz free energy in mks units of J kmol-1 K-1, 
00190   //! using the last temperature and density
00191   doublereal helmholtzFE() const;
00192   
00193   //! Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
00194   //! using the last temperature and density
00195   doublereal Gibbs() const;
00196 
00197   //!  Calculate the enthalpy in mks units of  J kmol-1 
00198   //!  using the last temperature and density
00199   doublereal enthalpy() const;
00200  
00201   //! Calculate the internal energy in mks units of J kmol-1 
00202   doublereal intEnergy() const;
00203 
00204   //! Calculate the entropy in mks units of  J kmol-1 K-1
00205   doublereal entropy() const;
00206     
00207   //! Calculate the constant volume heat capacity in mks units of J kmol-1 K-1
00208   //! at the last temperature and density
00209   doublereal cv() const;
00210 
00211   //! Calculate the constant pressure heat capacity in mks units of J kmol-1 K-1
00212   //! at the last temperature and density
00213   doublereal cp() const;
00214 
00215   //! Calculate the molar volume (kmol m-3) 
00216   //! at the last temperature and density
00217   doublereal molarVolume() const;
00218  
00219   //! Calculates the pressure (Pascals), given the current value of the
00220   //! temperature and density.
00221   /*!
00222    * The density is an independent variable in the underlying equation of state
00223    *
00224    *  @return
00225    *    returns the pressure (Pascal)
00226    */
00227   doublereal pressure() const;
00228 
00229   //! Calculates the density given the temperature and the pressure,
00230   //! and a guess at the density. Sets the internal state. 
00231   /*!
00232    *  Note, below T_c, this is a multivalued function. 
00233    *
00234    * The #density() function calculates the density that is consistent with
00235    * a particular value of the temperature and pressure. It may therefore be 
00236    * multivalued or potentially there may be no answer from this function. It therefore
00237    * takes a phase guess and a density guess as optional parameters. If no guesses are
00238    * supplied to density(), a gas phase guess is assumed. This may or may not be what
00239    * is wanted. Therefore, density() should usually at leat be supplied with a phase
00240    * guess so that it may manufacture an appropriate density guess. 
00241    * #density() manufactures the initial density guess, nondimensionalizes everything,
00242    * and then calls #WaterPropsIAPWSphi::dfind(), which does the iterative calculation
00243    * to find the density condition that matches the desired input pressure.
00244    *
00245    *  @param  temperature: Kelvin
00246    *  @param  pressure   : Pressure in Pascals (Newton/m**2)
00247    *  @param  phase      : guessed phase of water 
00248    *                     : -1: no guessed phase
00249    *  @param rhoguess    : guessed density of the water
00250    *                     : -1.0 no guessed density
00251    *  @return
00252    *     Returns the density. If an error is encountered in the calculation
00253    *     the value of -1.0 is returned.
00254    */
00255   doublereal density(doublereal temperature, doublereal pressure, 
00256                      int phase = -1, doublereal rhoguess = -1.0);
00257 
00258   //! Calculates the density given the temperature and the pressure,
00259   //! and a guess at the density, while not changing the internal state
00260   /*!
00261    *  Note, below T_c, this is a multivalued function. 
00262    *
00263    * The #density() function calculates the density that is consistent with
00264    * a particular value of the temperature and pressure. It may therefore be 
00265    * multivalued or potentially there may be no answer from this function. It therefore
00266    * takes a phase guess and a density guess as optional parameters. If no guesses are
00267 
00268    * supplied to density(), a gas phase guess is assumed. This may or may not be what
00269    * is wanted. Therefore, density() should usually at leat be supplied with a phase
00270    * guess so that it may manufacture an appropriate density guess. 
00271    * #density() manufactures the initial density guess, nondimensionalizes everything,
00272    * and then calls #WaterPropsIAPWSphi::dfind(), which does the iterative calculation
00273    * to find the density condition that matches the desired input pressure.
00274    *
00275    *  @param  pressure   : Pressure in Pascals (Newton/m**2)
00276    *  @param  phase      : guessed phase of water 
00277    *                     : -1: no guessed phase
00278    *  @param rhoguess    : guessed density of the water
00279    *                     : -1.0 no guessed density
00280    *  @return
00281    *     Returns the density. If an error is encountered in the calculation
00282    *     the value of -1.0 is returned.
00283    */
00284   doublereal density_const(doublereal pressure, int phase = -1, doublereal rhoguess = -1.0) const;
00285 
00286   //! Returns the density (kg m-3)
00287   /*!
00288    * The density is an independent variable in the underlying equation of state
00289    *
00290    * @return  Returns the density (kg m-3)
00291    */
00292   doublereal density() const;
00293 
00294   //! Returns the temperature (Kelvin)
00295   /*!
00296    * @return  Returns the internally storred temperature 
00297    */
00298   doublereal temperature() const;
00299 
00300   //! Returns the coefficient of thermal expansion.
00301   /*!
00302    *           alpha = d (ln V) / dT at constant P.
00303    *
00304    * @return
00305    *    Returns the coefficient of thermal expansion
00306    */
00307   doublereal coeffThermExp() const;
00308 
00309   //! Returns the isochoric pressure derivative wrt temperature 
00310   /*!
00311    *
00312    *     beta = M / (rho * Rgas) (d (pressure) / dT) at constant rho
00313    *
00314    *  Note for ideal gases this is equal to one.
00315    *
00316    *    beta = delta (phi0_d() + phiR_d())
00317    *            - tau delta (phi0_dt() + phiR_dt())
00318    */
00319   doublereal coeffPresExp() const;
00320 
00321   //! Returns the coefficient of isothermal compressibility for the 
00322   //! state of the object
00323   /*!
00324    *     kappa = - d (ln V) / dP at constant T.
00325    *
00326    *  units - 1/Pascal
00327    *
00328    * @return 
00329    *    returns the isothermal compressibility
00330    */
00331   doublereal isothermalCompressibility() const;
00332 
00333   //! Returns the value of dp / drho at constant T for the
00334   //! state of the object
00335   /*!
00336    *  units - Joules / kg
00337    *
00338    * @return 
00339    *    returns dpdrho
00340    */
00341   doublereal dpdrho() const;
00342    
00343   //! This function returns an estimated value for the saturation pressure. 
00344   /*!
00345    * It does this via a polynomial fit of the vapor pressure curve. 
00346    * units = (Pascals)
00347    *
00348    * @param temperature Input temperature (Kelvin)
00349    *
00350    * @return
00351    *   Returns the estimated saturation pressure
00352    */
00353   doublereal psat_est(doublereal temperature) const;
00354 
00355   //! This function returns the saturation pressure given the
00356   //! temperature as an input parameter, and sets the internal state to the saturated 
00357   //! conditions.
00358   /*!
00359    *  Note this function will return the saturation pressure, given the temperature.
00360    *  It will then set the state of the system to the saturation condition. The input
00361    *  parameter waterState is used to either specify the liquid state or the 
00362    *  gas state at the desired temperatue and saturated pressure.
00363    *
00364    *  If the input temperature, T, is above T_c, this routine will set the internal
00365    *  state to T and the pressure to P_c. Then, return P_c.
00366    *
00367    * @param temperature   input temperature (kelvin)
00368    * @param waterState    integer specifying the water state
00369    *
00370    * @return Returns the saturation pressure
00371    *                units = Pascal
00372    */
00373   doublereal psat(doublereal temperature, int waterState = WATER_LIQUID);
00374 
00375   //! Return the value of the density at the water spinodal point (on the liquid side)
00376   //! for the current temperature.
00377   /*!
00378    * @return returns the density with units of kg m-3
00379    */
00380   doublereal densSpinodalWater() const;
00381 
00382   //! Return the value of the density at the water spinodal point (on the gas side)
00383   //! for the current temperature.
00384   /*!
00385    * @return returns the density with units of kg m-3
00386    */
00387   doublereal densSpinodalSteam() const;
00388 
00389   //! Returns the Phase State flag for the current state of the object
00390   /*!
00391    * @param checkState If true, this function does a complete check to see where
00392    *        in paramters space we are
00393    *
00394    *  There are three values:
00395    *     WATER_GAS   below the critical temperature but below the critical density
00396    *     WATER_LIQUID  below the critical temperature but above the critical density
00397    *     WATER_SUPERCRIT   above the critical temperature
00398    */
00399   int phaseState(bool checkState = false) const ;
00400 
00401   //! Returns the critical temperature of water (Kelvin)
00402   /*!
00403    *  This is hard coded to the value 647.096 Kelvin
00404    */
00405   doublereal Tcrit() const { return 647.096;}
00406 
00407   //! Returns the critical pressure of water (22.064E6 Pa)
00408   /*!
00409    *  This is hard coded to the value of 22.064E6 pascals
00410    */
00411   doublereal Pcrit() const { return 22.064E6;}
00412 
00413   //! Return the critical density of water (kg m-3)
00414   /*!
00415    * This is equal to 322 kg m-3.
00416    */
00417   doublereal Rhocrit() const { return 322.;}
00418 
00419 private:
00420   //! Calculate the dimensionless temp and rho and store internally.
00421   /*!
00422    *  Private routine
00423    *
00424    * @param temperature   input temperature (kelvin)
00425    *  @param rho          density in kg m-3
00426    */
00427   void calcDim(doublereal temperature, doublereal rho);
00428 
00429   //! Utility routine in the calculation of the saturation pressure
00430   /*!
00431    *  Private routine
00432    *
00433    * @param temperature    temperature (kelvin)
00434    * @param pressure       pressure (Pascal)
00435    * @param densLiq        Output density of liquid
00436    * @param densGas        output Density of gas
00437    * @param delGRT         output delGRT
00438    */
00439   void corr(doublereal temperature, doublereal pressure, doublereal &densLiq, 
00440               doublereal &densGas, doublereal &delGRT);
00441 
00442   //! Utility routine in the calculation of the saturation pressure
00443   /*!
00444    *  Private routine
00445    *
00446    * @param temperature    temperature (kelvin)
00447    * @param pressure       pressure (Pascal)
00448    * @param densLiq        Output density of liquid
00449    * @param densGas        output Density of gas
00450    * @param pcorr          output corrected pressure
00451    */ 
00452   void corr1(doublereal temperature, doublereal pressure, doublereal &densLiq, 
00453                doublereal &densGas, doublereal &pcorr);
00454 
00455 private:
00456 
00457   //! pointer to the underlying object that does the calculations.
00458   WaterPropsIAPWSphi *m_phi;
00459     
00460   //! Dimensionless temperature
00461   /*!
00462    *   tau = T_C / T
00463    */
00464   doublereal tau;
00465 
00466   //! Dimensionless density
00467   /*!
00468    *  delta = rho / rho_c
00469    */
00470   mutable doublereal delta;
00471 
00472   //! Current state of the system
00473   mutable int iState;
00474 };
00475 
00476 }
00477 #endif
Generated by  doxygen 1.6.3