Cantera  3.2.0
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 * @deprecated To be removed after %Cantera 3.1.
257 */
258 double density_const(double pressure, int phase = -1, double rhoguess = -1.0) const;
259
260 //! Returns the density (kg m-3)
261 /*!
262 * The density is an independent variable in the underlying equation of state
263 *
264 * @returns the density (kg m-3)
265 */
266 double density() const;
267
268 //! Returns the temperature (Kelvin)
269 /*!
270 * @return s the internally stored temperature
271 */
272 double temperature() const;
273
274 //! Returns the coefficient of thermal expansion.
275 /*!
276 * alpha = d (ln V) / dT at constant P.
277 *
278 * @returns the coefficient of thermal expansion
279 */
280 double coeffThermExp() const;
281
282 //! Returns the isochoric pressure derivative wrt temperature
283 /*!
284 * beta = M / (rho * Rgas) (d (pressure) / dT) at constant rho
285 *
286 * Note for ideal gases this is equal to one.
287 *
288 * beta = delta (phi0_d() + phiR_d()) - tau delta (phi0_dt() + phiR_dt())
289 */
290 double coeffPresExp() const;
291
292 //! Returns the coefficient of isothermal compressibility for the state of
293 //! the object
294 /*!
295 * kappa = - d (ln V) / dP at constant T.
296 *
297 * units - 1/Pascal
298 *
299 * @returns the isothermal compressibility
300 */
301 double isothermalCompressibility() const;
302
303 //! Returns the value of dp / drho at constant T for the state of the object
304 /*!
305 * units - Joules / kg
306 *
307 * @returns dpdrho
308 */
309 double dpdrho() const;
310
311 //! This function returns an estimated value for the saturation pressure.
312 /*!
313 * It does this via a polynomial fit of the vapor pressure curve.
314 * units = (Pascals)
315 *
316 * @param temperature Input temperature (Kelvin)
317 *
318 * @returns the estimated saturation pressure
319 */
320 double psat_est(double temperature) const;
321
322 //! This function returns the saturation pressure given the temperature as
323 //! an input parameter, and sets the internal state to the saturated
324 //! conditions.
325 /*!
326 * Note this function will return the saturation pressure, given the
327 * temperature. It will then set the state of the system to the saturation
328 * condition. The input parameter waterState is used to either specify the
329 * liquid state or the gas state at the desired temperature and saturated
330 * pressure.
331 *
332 * If the input temperature, T, is above T_c, this routine will set the
333 * internal state to T and the pressure to P_c. Then, return P_c.
334 *
335 * @param temperature input temperature (kelvin)
336 * @param waterState integer specifying the water state
337 * @returns the saturation pressure. units = Pascal
338 */
339 double psat(double temperature, int waterState = WATER_LIQUID);
340
341 //! Return the value of the density at the water spinodal point (on the
342 //! liquid side) for the current temperature.
343 /*!
344 * @returns the density with units of kg m-3
345 * @deprecated To be removed after %Cantera 3.1.
346 */
347 double densSpinodalWater() const;
348
349 //! Return the value of the density at the water spinodal point (on the gas
350 //! side) for the current temperature.
351 /*!
352 * @returns the density with units of kg m-3
353 * @deprecated To be removed after %Cantera 3.1.
354 */
355 double densSpinodalSteam() const;
356
357 //! Returns the Phase State flag for the current state of the object
358 /*!
359 * @param checkState If true, this function does a complete check to see
360 * where in parameters space we are
361 *
362 * There are three values:
363 * - WATER_GAS below the critical temperature but below the critical density
364 * - WATER_LIQUID below the critical temperature but above the critical density
365 * - WATER_SUPERCRIT above the critical temperature
366 */
367 int phaseState(bool checkState = false) const;
368
369 //! Returns the critical temperature of water (Kelvin)
370 /*!
371 * This is hard coded to the value 647.096 Kelvin
372 */
373 double Tcrit() const {
374 return 647.096;
375 }
376
377 //! Returns the critical pressure of water (22.064E6 Pa)
378 /*!
379 * This is hard coded to the value of 22.064E6 pascals
380 */
381 double Pcrit() const {
382 return 22.064E6;
383 }
384
385 //! Return the critical density of water (kg m-3)
386 /*!
387 * This is equal to 322 kg m-3.
388 */
389 double Rhocrit() const {
390 return 322.;
391 }
392
393private:
394 //! Calculate the dimensionless temp and rho and store internally.
395 /*!
396 * @param temperature input temperature (kelvin)
397 * @param rho density in kg m-3
398 */
399 void calcDim(double temperature, double rho);
400
401 //! Utility routine in the calculation of the saturation pressure
402 /*!
403 * Calculate the Gibbs free energy in mks units of J kmol-1 K-1.
404 *
405 * @param temperature temperature (kelvin)
406 * @param pressure pressure (Pascal)
407 * @param densLiq Output density of liquid
408 * @param densGas output Density of gas
409 * @param delGRT output delGRT
410 */
411 void corr(double temperature, double pressure, double& densLiq,
412 double& densGas, double& delGRT);
413
414 //! pointer to the underlying object that does the calculations.
416
417 //! Dimensionless temperature, tau = T_C / T
418 double tau = -1.0;
419
420 //! Dimensionless density, delta = rho / rho_c
421 mutable double delta = -1.0;
422
423 //! Current state of the system
424 mutable int iState = -30000;
425};
426
427}
428#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.
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:595