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