Cantera  2.5.1
WaterPropsIAPWS.h
Go to the documentation of this file.
1 /**
2  * @file WaterPropsIAPWS.h
3  * Headers for a class for calculating the equation of state of water
4  * from the IAPWS 1995 Formulation based on the steam tables thermodynamic
5  * basis (See class \link Cantera::WaterPropsIAPWS WaterPropsIAPWS\endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
11 #ifndef WATERPROPSIAPWS_H
12 #define WATERPROPSIAPWS_H
13 
14 #include "WaterPropsIAPWSphi.h"
15 
16 namespace Cantera
17 {
18 /**
19  * @name Names for the phase regions
20  *
21  * These constants are defined and used in the interface to describe the
22  * location of where we are in (T,rho) space.
23  *
24  * WATER_UNSTABLELIQUID indicates that we are in the unstable region, inside the
25  * spinodal curve where dpdrho < 0.0 amongst other properties. The difference
26  * between WATER_UNSTABLELIQUID and WATER_UNSTABLEGAS is that
27  * for WATER_UNSTABLELIQUID d2pdrho2 > 0 and dpdrho < 0.0
28  * for WATER_UNSTABLEGAS d2pdrho2 < 0 and dpdrho < 0.0
29  */
30 //@{
31 #define WATER_GAS 0
32 #define WATER_LIQUID 1
33 #define WATER_SUPERCRIT 2
34 #define WATER_UNSTABLELIQUID 3
35 #define WATER_UNSTABLEGAS 4
36 //@}
37 
38 //! Class for calculating the equation of state of water.
39 /*!
40  * This is a helper class for WaterSSTP and PDSS_Water and does not constitute
41  * a complete implementation of a thermo phase by itself (see \ref thermoprops
42  * and classes \link Cantera::WaterSSTP WaterSSTP\endlink and
43  * \link Cantera::PDSS_Water PDSS_Water\endlink).
44  *
45  * The reference is W. Wagner, A. Pruss, "The IAPWS Formulation 1995 for the
46  * Thermodynamic Properties of Ordinary Water Substance for General and
47  * Scientific Use," J. Phys. Chem. Ref. Dat, 31, 387, 2002.
48  *
49  * This class provides a very complicated polynomial for the specific
50  * Helmholtz free energy of water, as a function of temperature and density.
51  *
52  * \f[
53  * \frac{M\hat{f}(\rho,T)}{R T} = \phi(\delta, \tau) =
54  * \phi^o(\delta, \tau) + \phi^r(\delta, \tau)
55  * \f]
56  *
57  * where
58  *
59  * \f[
60  * \delta = \rho / \rho_c \quad \mathrm{and} \quad \tau = T_c / T
61  * \f]
62  *
63  * The following constants are assumed
64  *
65  * \f[
66  * T_c = 647.096\mathrm{\;K}
67  * \f]
68  * \f[
69  * \rho_c = 322 \mathrm{\;kg\,m^{-3}}
70  * \f]
71  * \f[
72  * R/M = 0.46151805 \mathrm{\;kJ\,kg^{-1}\,K^{-1}}
73  * \f]
74  *
75  * The free energy is a unique single-valued function of the temperature and
76  * density over its entire range.
77  *
78  * Note, the base thermodynamic state for this class is the one used in the
79  * steam tables, i.e., the liquid at the triple point for water has the
80  * following properties:
81  *
82  * - u(273.16, rho) = 0.0
83  * - s(273.16, rho) = 0.0
84  * - psat(273.16) = 611.655 Pascal
85  * - rho(273.16, psat) = 999.793 kg m-3
86  *
87  * Therefore, to use this class within %Cantera, offsets to u() and s() must
88  * be used to put the water class onto the same basis as other thermodynamic
89  * quantities. For example, in the WaterSSTP class, these offsets are
90  * calculated in the following way. The thermodynamic base state for water is
91  * set to the NIST basis here by specifying constants EW_Offset and SW_Offset.
92  * These offsets are calculated on the fly so that the following properties
93  * hold:
94  *
95  * - Delta_Hfo_idealGas(298.15, 1bar) = -241.826 kJ/gmol
96  * - So_idealGas(298.15, 1bar) = 188.835 J/gmolK
97  *
98  * The offsets are calculated by actually computing the above quantities and
99  * then calculating the correction factor.
100  *
101  * This class provides an interface to the WaterPropsIAPWSphi class, which
102  * actually calculates the \f$ \phi^o(\delta, \tau) \f$ and the
103  * \f$ \phi^r(\delta, \tau) \f$ polynomials in dimensionless form.
104  *
105  * All thermodynamic results from this class are returned in dimensional form.
106  * This is because the gas constant (and molecular weight) used within this
107  * class is allowed to be potentially different than that used elsewhere in
108  * %Cantera. Therefore, everything has to be in dimensional units. Note,
109  * however, the thermodynamic basis is set to that used in the steam tables.
110  * (u = s = 0 for liquid water at the triple point).
111  *
112  * This class is not a ThermoPhase. However, it does maintain an internal
113  * state of the object that is dependent on temperature and density. The
114  * internal state is characterized by an internally stored \f$ \tau\f$ and a
115  * \f$ \delta \f$ value, and an iState value, which indicates whether the
116  * point is a liquid, a gas, or a supercritical fluid. Along with that the
117  * \f$ \tau\f$ and a \f$ \delta \f$ values are polynomials of \f$ \tau\f$ and
118  * a \f$ \delta \f$ that are kept by the WaterPropsIAPWSphi class. Therefore,
119  * whenever \f$ \tau\f$ or \f$ \delta \f$ is changed, the function setState()
120  * must be called in order for the internal state to be kept up to date.
121  *
122  * The class is pretty straightforward. However, one function deserves
123  * mention. The density() function calculates the density that is consistent
124  * with a particular value of the temperature and pressure. It may therefore
125  * be multivalued or potentially there may be no answer from this function. It
126  * therefore takes a phase guess and a density guess as optional parameters.
127  * If no guesses are supplied to density(), a gas phase guess is assumed. This
128  * may or may not be what is wanted. Therefore, density() should usually at
129  * least be supplied with a phase guess so that it may manufacture an
130  * appropriate density guess. density() manufactures the initial density
131  * guess, nondimensionalizes everything, and then calls
132  * WaterPropsIAPWSphi::dfind(), which does the iterative calculation to find
133  * the density condition that matches the desired input pressure.
134  *
135  * The phase guess defines are located in the .h file. they are
136  *
137  * - WATER_GAS
138  * - WATER_LIQUID
139  * - WATER_SUPERCRIT
140  *
141  * There are only three functions which actually change the value of the
142  * internal state of this object after it's been instantiated
143  *
144  * - setState_TR(temperature, rho)
145  * - density(temperature, pressure, phase, rhoguess)
146  * - psat(temperature, waterState);
147  *
148  * The setState_TR() is the main function that sets the temperature and rho
149  * value. The density() function serves as a setState_TP() function, in that
150  * it sets internal state to a temperature and pressure. However, note that
151  * this is potentially multivalued. Therefore, we need to supply in addition a
152  * phase guess and a rho guess to the input temperature and pressure. The
153  * psat() function sets the internal state to the saturated liquid or
154  * saturated gas state, depending on the waterState parameter.
155  *
156  * Because the underlying object WaterPropsIAPWSphi is privately held, you can
157  * be sure that the underlying state of this object doesn't change except due
158  * to the three function calls listed above.
159  *
160  * @ingroup thermoprops
161  */
163 {
164 public:
165  //! Base constructor
166  WaterPropsIAPWS();
167 
168  WaterPropsIAPWS(const WaterPropsIAPWS& right) = delete;
169  WaterPropsIAPWS& operator=(const WaterPropsIAPWS& right) = delete;
170 
171  //! Set the internal state of the object wrt temperature and density
172  /*!
173  * @param temperature temperature (kelvin)
174  * @param rho density (kg m-3)
175  */
176  void setState_TR(doublereal temperature, doublereal rho);
177 
178  //! Calculate the Helmholtz free energy in mks units of J kmol-1 K-1,
179  //! using the last temperature and density
180  doublereal helmholtzFE() const;
181 
182  //! Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
183  //! using the last temperature and density
184  doublereal Gibbs() const;
185 
186  //! Calculate the enthalpy in mks units of J kmol-1
187  //! using the last temperature and density
188  doublereal enthalpy() const;
189 
190  //! Calculate the internal energy in mks units of J kmol-1
191  doublereal intEnergy() const;
192 
193  //! Calculate the entropy in mks units of J kmol-1 K-1
194  doublereal entropy() const;
195 
196  //! Calculate the constant volume heat capacity in mks units of J kmol-1 K-1
197  //! at the last temperature and density
198  doublereal cv() const;
199 
200  //! Calculate the constant pressure heat capacity in mks units of J kmol-1 K-1
201  //! at the last temperature and density
202  doublereal cp() const;
203 
204  //! Calculate the molar volume (kmol m-3) at the last temperature and
205  //! density
206  doublereal molarVolume() const;
207 
208  //! Calculates the pressure (Pascals), given the current value of the
209  //! temperature and density.
210  /*!
211  * The density is an independent variable in the underlying equation of state
212  *
213  * @returns the pressure (Pascal)
214  */
215  doublereal pressure() const;
216 
217  //! Calculates the density given the temperature and the pressure,
218  //! and a guess at the density. Sets the internal state.
219  /*!
220  * Note, below T_c, this is a multivalued function.
221  *
222  * The density() function calculates the density that is consistent with
223  * a particular value of the temperature and pressure. It may therefore be
224  * multivalued or potentially there may be no answer from this function.
225  * It therefore takes a phase guess and a density guess as optional
226  * parameters. If no guesses are supplied to density(), a gas phase guess
227  * is assumed. This may or may not be what is wanted. Therefore, density()
228  * should usually at least be supplied with a phase guess so that it may
229  * manufacture an appropriate density guess. density() manufactures the
230  * initial density guess, nondimensionalizes everything, and then calls
231  * WaterPropsIAPWSphi::dfind(), which does the iterative calculation to
232  * find the density condition that matches the desired input pressure.
233  *
234  * @param temperature Kelvin
235  * @param pressure Pressure in Pascals (Newton/m**2)
236  * @param phase guessed phase of water; -1: no guessed phase
237  * @param rhoguess guessed density of the water; -1.0 no guessed density
238  * @returns the density. If an error is encountered in the calculation the
239  * value of -1.0 is returned.
240  */
241  doublereal density(doublereal temperature, doublereal pressure,
242  int phase = -1, doublereal rhoguess = -1.0);
243 
244  //! Calculates the density given the temperature and the pressure,
245  //! and a guess at the density, while not changing the internal state
246  /*!
247  * Note, below T_c, this is a multivalued function.
248  *
249  * The density() function calculates the density that is consistent with a
250  * particular value of the temperature and pressure. It may therefore be
251  * multivalued or potentially there may be no answer from this function.
252  * It therefore takes a phase guess and a density guess as optional
253  * parameters. If no guesses are supplied to density(), a gas phase guess
254  * is assumed. This may or may not be what is wanted. Therefore, density()
255  * should usually at least be supplied with a phase guess so that it may
256  * manufacture an appropriate density guess. density() manufactures the
257  * initial density guess, nondimensionalizes everything, and then calls
258  * WaterPropsIAPWSphi::dfind(), which does the iterative calculation to
259  * find the density condition that matches the desired input pressure.
260  *
261  * @param pressure Pressure in Pascals (Newton/m**2)
262  * @param phase guessed phase of water; -1: no guessed phase
263  * @param rhoguess guessed density of the water; -1.0: no guessed density
264  * @returns the density. If an error is encountered in the calculation the
265  * value of -1.0 is returned.
266  */
267  doublereal density_const(doublereal pressure, int phase = -1, doublereal rhoguess = -1.0) const;
268 
269  //! Returns the density (kg m-3)
270  /*!
271  * The density is an independent variable in the underlying equation of state
272  *
273  * @returns the density (kg m-3)
274  */
275  doublereal density() const;
276 
277  //! Returns the temperature (Kelvin)
278  /*!
279  * @return s the internally stored temperature
280  */
281  doublereal temperature() const;
282 
283  //! Returns the coefficient of thermal expansion.
284  /*!
285  * alpha = d (ln V) / dT at constant P.
286  *
287  * @returns the coefficient of thermal expansion
288  */
289  doublereal coeffThermExp() const;
290 
291  //! Returns the isochoric pressure derivative wrt temperature
292  /*!
293  * beta = M / (rho * Rgas) (d (pressure) / dT) at constant rho
294  *
295  * Note for ideal gases this is equal to one.
296  *
297  * beta = delta (phi0_d() + phiR_d()) - tau delta (phi0_dt() + phiR_dt())
298  */
299  doublereal coeffPresExp() const;
300 
301  //! Returns the coefficient of isothermal compressibility for the state of
302  //! the object
303  /*!
304  * kappa = - d (ln V) / dP at constant T.
305  *
306  * units - 1/Pascal
307  *
308  * @returns the isothermal compressibility
309  */
310  doublereal isothermalCompressibility() const;
311 
312  //! Returns the value of dp / drho at constant T for the state of the object
313  /*!
314  * units - Joules / kg
315  *
316  * @returns dpdrho
317  */
318  doublereal dpdrho() const;
319 
320  //! This function returns an estimated value for the saturation pressure.
321  /*!
322  * It does this via a polynomial fit of the vapor pressure curve.
323  * units = (Pascals)
324  *
325  * @param temperature Input temperature (Kelvin)
326  *
327  * @returns the estimated saturation pressure
328  */
329  doublereal psat_est(doublereal temperature) const;
330 
331  //! This function returns the saturation pressure given the temperature as
332  //! an input parameter, and sets the internal state to the saturated
333  //! conditions.
334  /*!
335  * Note this function will return the saturation pressure, given the
336  * temperature. It will then set the state of the system to the saturation
337  * condition. The input parameter waterState is used to either specify the
338  * liquid state or the gas state at the desired temperature and saturated
339  * pressure.
340  *
341  * If the input temperature, T, is above T_c, this routine will set the
342  * internal state to T and the pressure to P_c. Then, return P_c.
343  *
344  * @param temperature input temperature (kelvin)
345  * @param waterState integer specifying the water state
346  * @returns the saturation pressure. units = Pascal
347  */
348  doublereal psat(doublereal temperature, int waterState = WATER_LIQUID);
349 
350  //! Return the value of the density at the water spinodal point (on the
351  //! liquid side) for the current temperature.
352  /*!
353  * @returns the density with units of kg m-3
354  */
355  doublereal densSpinodalWater() const;
356 
357  //! Return the value of the density at the water spinodal point (on the gas
358  //! side) for the current temperature.
359  /*!
360  * @returns the density with units of kg m-3
361  */
362  doublereal densSpinodalSteam() const;
363 
364  //! Returns the Phase State flag for the current state of the object
365  /*!
366  * @param checkState If true, this function does a complete check to see
367  * where in parameters space we are
368  *
369  * There are three values:
370  * - WATER_GAS below the critical temperature but below the critical density
371  * - WATER_LIQUID below the critical temperature but above the critical density
372  * - WATER_SUPERCRIT above the critical temperature
373  */
374  int phaseState(bool checkState = false) const;
375 
376  //! Returns the critical temperature of water (Kelvin)
377  /*!
378  * This is hard coded to the value 647.096 Kelvin
379  */
380  doublereal Tcrit() const {
381  return 647.096;
382  }
383 
384  //! Returns the critical pressure of water (22.064E6 Pa)
385  /*!
386  * This is hard coded to the value of 22.064E6 pascals
387  */
388  doublereal Pcrit() const {
389  return 22.064E6;
390  }
391 
392  //! Return the critical density of water (kg m-3)
393  /*!
394  * This is equal to 322 kg m-3.
395  */
396  doublereal Rhocrit() const {
397  return 322.;
398  }
399 
400 private:
401  //! Calculate the dimensionless temp and rho and store internally.
402  /*!
403  * @param temperature input temperature (kelvin)
404  * @param rho density in kg m-3
405  */
406  void calcDim(doublereal temperature, doublereal rho);
407 
408  //! Utility routine in the calculation of the saturation pressure
409  /*!
410  * Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
411  *
412  * @param temperature temperature (kelvin)
413  * @param pressure pressure (Pascal)
414  * @param densLiq Output density of liquid
415  * @param densGas output Density of gas
416  * @param delGRT output delGRT
417  */
418  void corr(doublereal temperature, doublereal pressure, doublereal& densLiq,
419  doublereal& densGas, doublereal& delGRT);
420 
421  //! Utility routine in the calculation of the saturation pressure
422  /*!
423  * @param temperature temperature (kelvin)
424  * @param pressure pressure (Pascal)
425  * @param densLiq Output density of liquid
426  * @param densGas output Density of gas
427  * @param pcorr output corrected pressure
428  */
429  void corr1(doublereal temperature, doublereal pressure, doublereal& densLiq,
430  doublereal& densGas, doublereal& pcorr);
431 
432  //! pointer to the underlying object that does the calculations.
434 
435  //! Dimensionless temperature, tau = T_C / T
436  doublereal tau;
437 
438  //! Dimensionless density, delta = rho / rho_c
439  mutable doublereal delta;
440 
441  //! Current state of the system
442  mutable int iState;
443 };
444 
445 }
446 #endif
Header for Lowest level of the classes which support a real water model (see class WaterPropsIAPWS an...
Class for calculating the equation of state of water.
void corr(doublereal temperature, doublereal pressure, doublereal &densLiq, doublereal &densGas, doublereal &delGRT)
Utility routine in the calculation of the saturation pressure.
void corr1(doublereal temperature, doublereal pressure, doublereal &densLiq, doublereal &densGas, doublereal &pcorr)
Utility routine in the calculation of the saturation pressure.
void calcDim(doublereal temperature, doublereal rho)
Calculate the dimensionless temp and rho and store internally.
doublereal coeffThermExp() const
Returns the coefficient of thermal expansion.
doublereal densSpinodalWater() const
Return the value of the density at the water spinodal point (on the liquid side) for the current temp...
doublereal cp() const
Calculate the constant pressure heat capacity in mks units of J kmol-1 K-1 at the last temperature an...
doublereal tau
Dimensionless temperature, tau = T_C / T.
doublereal pressure() const
Calculates the pressure (Pascals), given the current value of the temperature and density.
doublereal enthalpy() const
Calculate the enthalpy in mks units of J kmol-1 using the last temperature and density.
doublereal density_const(doublereal pressure, int phase=-1, doublereal rhoguess=-1.0) const
Calculates the density given the temperature and the pressure, and a guess at the density,...
doublereal coeffPresExp() const
Returns the isochoric pressure derivative wrt temperature.
doublereal Tcrit() const
Returns the critical temperature of water (Kelvin)
WaterPropsIAPWS()
Base constructor.
doublereal densSpinodalSteam() const
Return the value of the density at the water spinodal point (on the gas side) for the current tempera...
doublereal cv() const
Calculate the constant volume heat capacity in mks units of J kmol-1 K-1 at the last temperature and ...
doublereal molarVolume() const
Calculate the molar volume (kmol m-3) at the last temperature and density.
doublereal entropy() const
Calculate the entropy in mks units of J kmol-1 K-1.
doublereal intEnergy() const
Calculate the internal energy in mks units of J kmol-1.
doublereal Rhocrit() const
Return the critical density of water (kg m-3)
doublereal density() const
Returns the density (kg m-3)
doublereal Gibbs() const
Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
int iState
Current state of the system.
doublereal temperature() const
Returns the temperature (Kelvin)
doublereal helmholtzFE() const
Calculate the Helmholtz free energy in mks units of J kmol-1 K-1, using the last temperature and dens...
doublereal psat_est(doublereal temperature) const
This function returns an estimated value for the saturation pressure.
doublereal delta
Dimensionless density, delta = rho / rho_c.
doublereal psat(doublereal temperature, int waterState=WATER_LIQUID)
This function returns the saturation pressure given the temperature as an input parameter,...
void setState_TR(doublereal temperature, doublereal rho)
Set the internal state of the object wrt temperature and density.
WaterPropsIAPWSphi m_phi
pointer to the underlying object that does the calculations.
doublereal dpdrho() const
Returns the value of dp / drho at constant T for the state of the object.
int phaseState(bool checkState=false) const
Returns the Phase State flag for the current state of the object.
doublereal isothermalCompressibility() const
Returns the coefficient of isothermal compressibility for the state of the object.
doublereal Pcrit() const
Returns the critical pressure of water (22.064E6 Pa)
Low level class for the real description of water.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264