Cantera  3.1.0a1
Loading...
Searching...
No Matches
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
16namespace 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{
163public:
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
390private:
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