GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/material/components/h2o.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 196 202 97.0%
Functions: 20 20 100.0%
Branches: 136 296 45.9%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup Components
10 * \brief Material properties of pure water \f$H_2O\f$.
11 */
12 #ifndef DUMUX_H2O_HH
13 #define DUMUX_H2O_HH
14
15 #include <cmath>
16 #include <cassert>
17
18 #include <dumux/nonlinear/findscalarroot.hh>
19 #include <dumux/material/idealgas.hh>
20 #include <dumux/common/exceptions.hh>
21
22 #include "iapws/common.hh"
23 #include "iapws/region1.hh"
24 #include "iapws/region2.hh"
25 #include "iapws/region4.hh"
26
27 #include <dumux/material/components/base.hh>
28 #include <dumux/material/components/liquid.hh>
29 #include <dumux/material/components/gas.hh>
30
31 namespace Dumux::Components {
32
33 /*!
34 * \ingroup Components
35 * \brief Material properties of pure water \f$H_2O\f$.
36 * \tparam Scalar The type used for scalar values
37 *
38 * See:
39 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
40 * 1997 for the Thermodynamic Properties of Water and Steam",
41 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
42 */
43 template <class Scalar>
44 class H2O
45 : public Components::Base<Scalar, H2O<Scalar> >
46 , public Components::Liquid<Scalar, H2O<Scalar> >
47 , public Components::Gas<Scalar, H2O<Scalar> >
48 {
49
50 using Common = IAPWS::Common<Scalar>;
51 using Region1 = IAPWS::Region1<Scalar>;
52 using Region2 = IAPWS::Region2<Scalar>;
53 using Region4 = IAPWS::Region4<Scalar>;
54
55 // specific gas constant of water
56 static constexpr Scalar Rs = Common::Rs;
57
58 public:
59 /*!
60 * \brief A human readable name for the water.
61 */
62
12/22
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✓ Branch 30 taken 1 times.
✓ Branch 32 taken 1 times.
✓ Branch 33 taken 1 times.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
458420 static std::string name()
63
28/54
✓ Branch 2 taken 106 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 38 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 58 times.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 2 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 2 times.
✗ Branch 27 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 30 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 33 not taken.
✓ Branch 35 taken 1 times.
✗ Branch 36 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 1 times.
✗ Branch 42 not taken.
✓ Branch 44 taken 1 times.
✗ Branch 45 not taken.
✓ Branch 47 taken 1 times.
✓ Branch 48 taken 1 times.
✓ Branch 50 taken 1 times.
✗ Branch 51 not taken.
✓ Branch 53 taken 1 times.
✗ Branch 54 not taken.
✓ Branch 56 taken 1 times.
✗ Branch 57 not taken.
✓ Branch 59 taken 1 times.
✗ Branch 60 not taken.
✓ Branch 62 taken 1 times.
✗ Branch 63 not taken.
✓ Branch 65 taken 1 times.
✗ Branch 66 not taken.
✓ Branch 68 taken 1 times.
✗ Branch 69 not taken.
✓ Branch 71 taken 1 times.
✗ Branch 72 not taken.
✓ Branch 74 taken 1 times.
✗ Branch 75 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 49 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 22 not taken.
✗ Branch 31 not taken.
✓ Branch 34 taken 2 times.
458420 { return "H2O"; }
64
65 /*!
66 * \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of water.
67 */
68 static constexpr Scalar molarMass()
69 { return Common::molarMass; }
70
71 /*!
72 * \brief The acentric factor \f$\mathrm{[-]}\f$ of water.
73 */
74 static constexpr Scalar acentricFactor()
75 { return Common::acentricFactor; }
76
77 /*!
78 * \brief Returns the critical temperature \f$\mathrm{[K]}\f$ of water
79 */
80 static constexpr Scalar criticalTemperature()
81 { return Common::criticalTemperature; }
82
83 /*!
84 * \brief Returns the critical pressure \f$\mathrm{[Pa]}\f$ of water.
85 */
86 static constexpr Scalar criticalPressure()
87 { return Common::criticalPressure; }
88
89 /*!
90 * \brief Returns the molar volume \f$\mathrm{[m^3/mol]}\f$ of water at the critical point
91 */
92 static constexpr Scalar criticalMolarVolume()
93 { return Common::criticalMolarVolume; }
94
95 /*!
96 * \brief Returns the temperature \f$\mathrm{[K]}\f$ at water's triple point.
97 */
98 static constexpr Scalar tripleTemperature()
99 { return Common::tripleTemperature; }
100
101 /*!
102 * \brief Returns the pressure \f$\mathrm{[Pa]}\f$ at water's triple point.
103 */
104 static constexpr Scalar triplePressure()
105 { return Common::triplePressure; }
106
107 /*!
108 * \brief The vapor pressure in \f$\mathrm{[Pa]}\f$ of pure water
109 * at a given temperature.
110 *
111 *\param T temperature of component in \f$\mathrm{[K]}\f$
112 *
113 * See:
114 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
115 * 1997 for the Thermodynamic Properties of Water and Steam",
116 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
117 */
118 237988795 static Scalar vaporPressure(Scalar T)
119 {
120 using std::min;
121 using std::max;
122
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 237988792 times.
237988794 T = min(T, criticalTemperature());
123
2/2
✓ Branch 0 taken 1086403 times.
✓ Branch 1 taken 236902391 times.
237988794 T = max(T,tripleTemperature());
124
125 237988795 return Region4::saturationPressure(T);
126 }
127
128 /*!
129 * \brief The vapor temperature in \f$\mathrm{[K]}\f$ of pure water
130 * at a given pressure.
131 *
132 *\param pressure pressure in \f$\mathrm{[Pa]}\f$
133 *
134 * See:
135 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
136 * 1997 for the Thermodynamic Properties of Water and Steam",
137 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
138 */
139 101966 static Scalar vaporTemperature(Scalar pressure)
140 {
141 using std::min;
142 using std::max;
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 101966 times.
101966 pressure = min(pressure, criticalPressure());
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 101966 times.
101966 pressure = max(pressure, triplePressure());
145
146 101966 return Region4::vaporTemperature(pressure);
147 }
148
149 /*!
150 * \brief Specific enthalpy of water steam \f$\mathrm{[J/kg]}\f$.
151 *
152 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
153 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
154 *
155 * See:
156 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
157 * 1997 for the Thermodynamic Properties of Water and Steam",
158 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
159 */
160 6281315 static const Scalar gasEnthalpy(Scalar temperature,
161 Scalar pressure)
162 {
163
1/2
✓ Branch 2 taken 6281315 times.
✗ Branch 3 not taken.
6281315 Region2::checkValidityRange(temperature, pressure, "Enthalpy");
164
165 // regularization
166
2/2
✓ Branch 0 taken 100453 times.
✓ Branch 1 taken 6180862 times.
6281315 if (pressure < triplePressure() - 100) {
167 // We assume an ideal gas for low pressures to avoid the
168 // 0/0 for the gas enthalpy at very low pressures. The
169 // enthalpy of an ideal gas does not exhibit any
170 // dependence on pressure, so we can just return the
171 // specific enthalpy at the point of regularization, i.e.
172 // the triple pressure - 100Pa
173 100453 return enthalpyRegion2_(temperature, triplePressure() - 100);
174 }
175 6180862 Scalar pv = vaporPressure(temperature);
176
2/2
✓ Branch 0 taken 3621212 times.
✓ Branch 1 taken 2559650 times.
6180862 if (pressure > pv) {
177 // the pressure is too high, in this case we use the slope
178 // of the enthalpy at the vapor pressure to regularize
179 3621212 Scalar dh_dp =
180 3621212 Rs*temperature*
181 3621212 Region2::tau(temperature)*
182 Region2::dPi_dp(pv)*
183 3621212 Region2::ddGamma_dTaudPi(temperature, pv);
184
185 return
186 3621212 enthalpyRegion2_(temperature, pv) +
187 3621212 (pressure - pv)*dh_dp;
188 }
189
190 2559650 return enthalpyRegion2_(temperature, pressure);
191 }
192
193 /*!
194 * \brief Specific enthalpy of liquid water \f$\mathrm{[J/kg]}\f$.
195 *
196 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
197 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
198 *
199 * See:
200 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
201 * 1997 for the Thermodynamic Properties of Water and Steam",
202 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
203 */
204 4977516 static const Scalar liquidEnthalpy(Scalar temperature,
205 Scalar pressure)
206 {
207
1/2
✓ Branch 2 taken 4977516 times.
✗ Branch 3 not taken.
4977516 Region1::checkValidityRange(temperature, pressure, "Enthalpy");
208
209 // regularization
210 4977516 Scalar pv = vaporPressure(temperature);
211
2/2
✓ Branch 0 taken 83455 times.
✓ Branch 1 taken 4894061 times.
4977516 if (pressure < pv) {
212 // the pressure is too low, in this case we use the slope
213 // of the enthalpy at the vapor pressure to regularize
214 83455 Scalar dh_dp =
215 83455 Rs * temperature*
216 83455 Region1::tau(temperature)*
217 Region1::dPi_dp(pv)*
218 83455 Region1::ddGamma_dTaudPi(temperature, pv);
219
220 return
221 83455 enthalpyRegion1_(temperature, pv) +
222 83455 (pressure - pv)*dh_dp;
223 }
224
225 4894061 return enthalpyRegion1_(temperature, pressure);
226 }
227
228 /*!
229 * \brief Specific isobaric heat capacity of water steam \f$\mathrm{[J/(kg*K)}\f$.
230 *
231 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
232 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
233 *
234 * See:
235 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
236 * 1997 for the Thermodynamic Properties of Water and Steam",
237 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
238 */
239 2825615 static const Scalar gasHeatCapacity(Scalar temperature,
240 Scalar pressure)
241 {
242
1/2
✓ Branch 2 taken 2825615 times.
✗ Branch 3 not taken.
2825615 Region2::checkValidityRange(temperature, pressure, "Heat capacity");
243
244 // regularization
245
2/2
✓ Branch 0 taken 100396 times.
✓ Branch 1 taken 2725219 times.
2825615 if (pressure < triplePressure() - 100) {
246 100396 return heatCap_p_Region2_(temperature, triplePressure() - 100);
247 }
248 2725219 Scalar pv = vaporPressure(temperature);
249
2/2
✓ Branch 0 taken 370410 times.
✓ Branch 1 taken 2354809 times.
2725219 if (pressure > pv) {
250 // the pressure is too high, in this case we use the heat
251 // cap at the vapor pressure to regularize
252 370410 return heatCap_p_Region2_(temperature, pv);
253 }
254 2354809 return heatCap_p_Region2_(temperature, pressure);
255 }
256
257 /*!
258 * \brief Specific isobaric heat capacity of liquid water \f$\mathrm{[J/(kg*K)]}\f$.
259 *
260 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
261 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
262 *
263 * See:
264 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
265 * 1997 for the Thermodynamic Properties of Water and Steam",
266 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
267 */
268 2825983 static const Scalar liquidHeatCapacity(Scalar temperature,
269 Scalar pressure)
270 {
271
1/2
✓ Branch 2 taken 2825983 times.
✗ Branch 3 not taken.
2825983 Region1::checkValidityRange(temperature, pressure, "Heat capacity");
272
273 // regularization
274 2825983 Scalar pv = vaporPressure(temperature);
275
2/2
✓ Branch 0 taken 83211 times.
✓ Branch 1 taken 2742772 times.
2825983 if (pressure < pv) {
276 // the pressure is too low, in this case we use the heat cap at the vapor pressure to regularize
277 83211 return heatCap_p_Region1_(temperature, pv);
278 }
279
280 2742772 return heatCap_p_Region1_(temperature, pressure);
281 }
282
283 /*!
284 * \brief Specific internal energy of liquid water \f$\mathrm{[J/kg]}\f$.
285 *
286 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
287 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
288 *
289 * See:
290 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
291 * 1997 for the Thermodynamic Properties of Water and Steam",
292 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
293 */
294 1235383 static const Scalar liquidInternalEnergy(Scalar temperature,
295 Scalar pressure)
296 {
297
1/2
✓ Branch 2 taken 1235383 times.
✗ Branch 3 not taken.
1235383 Region1::checkValidityRange(temperature, pressure, "Internal energy");
298
299 // regularization
300 1235383 Scalar pv = vaporPressure(temperature);
301
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 1235166 times.
1235383 if (pressure < pv) {
302 // the pressure is too low, in this case we use the slope
303 // of the internal energy at the vapor pressure to
304 // regularize
305
306 /*
307 // calculate the partial derivative of the internal energy
308 // to the pressure at the vapor pressure.
309 Scalar tau = Region1::tau(temperature);
310 Scalar dGamma_dPi = Region1::dGamma_dPi(temperature, pv);
311 Scalar ddGamma_dTaudPi = Region1::ddGamma_dTaudPi(temperature, pv);
312 Scalar ddGamma_ddPi = Region1::ddGamma_ddPi(temperature, pv);
313 Scalar pi = Region1::pi(pv);
314 Scalar dPi_dp = Region1::dPi_dp(pv);
315 Scalar du_dp =
316 Rs*temperature*
317 (tau*dPi_dp*ddGamma_dTaudPi + dPi_dp*dPi_dp*dGamma_dPi + pi*dPi_dp*ddGamma_ddPi);
318 */
319
320 // use a straight line for extrapolation. use forward
321 // differences to calculate the partial derivative to the
322 // pressure at the vapor pressure
323 static const Scalar eps = 1e-7;
324 217 Scalar uv = internalEnergyRegion1_(temperature, pv);
325 217 Scalar uvPEps = internalEnergyRegion1_(temperature, pv + eps);
326 217 Scalar du_dp = (uvPEps - uv)/eps;
327 217 return uv + du_dp*(pressure - pv);
328 }
329
330 1235166 return internalEnergyRegion1_(temperature, pressure);
331 }
332
333 /*!
334 * \brief Specific internal energy of steam and water vapor \f$\mathrm{[J/kg]}\f$.
335 *
336 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
337 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
338 *
339 * See:
340 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
341 * 1997 for the Thermodynamic Properties of Water and Steam",
342 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
343 */
344 205023 static Scalar gasInternalEnergy(Scalar temperature, Scalar pressure)
345 {
346
1/2
✓ Branch 2 taken 205023 times.
✗ Branch 3 not taken.
205023 Region2::checkValidityRange(temperature, pressure, "Internal energy");
347
348 // regularization
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 205023 times.
205023 if (pressure < triplePressure() - 100) {
350 // We assume an ideal gas for low pressures to avoid the
351 // 0/0 for the internal energy of gas at very low
352 // pressures. The enthalpy of an ideal gas does not
353 // exhibit any dependence on pressure, so we can just
354 // return the specific enthalpy at the point of
355 // regularization, i.e. the triple pressure - 100Pa, and
356 // subtract the work required to change the volume for an
357 // ideal gas.
358 return
359 enthalpyRegion2_(temperature, triplePressure() - 100)
360 -
361 Rs*temperature; // = p*v for an ideal gas!
362 }
363 205023 Scalar pv = vaporPressure(temperature);
364
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 204834 times.
205023 if (pressure > pv) {
365 // the pressure is too high, in this case we use the slope
366 // of the internal energy at the vapor pressure to
367 // regularize
368
369 /*
370 // calculate the partial derivative of the internal energy
371 // to the pressure at the vapor pressure.
372 Scalar tau = Region2::tau(temperature);
373 Scalar dGamma_dPi = Region2::dGamma_dPi(temperature, pv);
374 Scalar ddGamma_dTaudPi = Region2::ddGamma_dTaudPi(temperature, pv);
375 Scalar ddGamma_ddPi = Region2::ddGamma_ddPi(temperature, pv);
376 Scalar pi = Region2::pi(pv);
377 Scalar dPi_dp = Region2::dPi_dp(pv);
378 Scalar du_dp =
379 Rs*temperature*
380 (tau*dPi_dp*ddGamma_dTaudPi + dPi_dp*dPi_dp*dGamma_dPi + pi*dPi_dp*ddGamma_ddPi);
381
382 // use a straight line for extrapolation
383 Scalar uv = internalEnergyRegion2_(temperature, pv);
384 return uv + du_dp*(pressure - pv);
385 */
386
387 // use a straight line for extrapolation. use backward
388 // differences to calculate the partial derivative to the
389 // pressure at the vapor pressure
390 static const Scalar eps = 1e-7;
391 189 Scalar uv = internalEnergyRegion2_(temperature, pv);
392 189 Scalar uvMEps = internalEnergyRegion2_(temperature, pv - eps);
393 189 Scalar du_dp = (uv - uvMEps)/eps;
394 189 return uv + du_dp*(pressure - pv);
395 }
396
397 204834 return internalEnergyRegion2_(temperature, pressure);
398 }
399
400 /*!
401 * \brief Specific isochoric heat capacity of liquid water \f$\mathrm{[J/(m^3*K)]}\f$.
402 *
403 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
404 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
405 *
406 * See:
407 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
408 * 1997 for the Thermodynamic Properties of Water and Steam",
409 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
410 */
411 static const Scalar liquidHeatCapacityConstVolume(Scalar temperature,
412 Scalar pressure)
413 {
414 Region1::checkValidityRange(temperature, pressure, "Heat capacity for a constant volume");
415
416 // regularization
417 Scalar pv = vaporPressure(temperature);
418 if (pressure < pv) {
419 // the pressure is too low, in this case we use the heat cap at the vapor pressure to regularize
420
421 return heatCap_v_Region1_(temperature, pv);
422 }
423
424 return heatCap_v_Region1_(temperature, pressure);
425 }
426
427 /*!
428 * \brief Specific isochoric heat capacity of steam and water vapor \f$\mathrm{[J/(kg*K)}\f$.
429 *
430 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
431 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
432 *
433 * See:
434 *
435 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
436 * 1997 for the Thermodynamic Properties of Water and Steam",
437 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
438 */
439 static Scalar gasHeatCapacityConstVolume(Scalar temperature, Scalar pressure)
440 {
441 Region2::checkValidityRange(temperature, pressure, "Heat capacity for a constant volume");
442
443 // regularization
444 if (pressure < triplePressure() - 100) {
445 return
446 heatCap_v_Region2_(temperature, triplePressure() - 100);
447 }
448 Scalar pv = vaporPressure(temperature);
449 if (pressure > pv) {
450 return heatCap_v_Region2_(temperature, pv);
451 }
452
453 return heatCap_v_Region2_(temperature, pressure);
454 }
455
456 /*!
457 * \brief Returns true if the gas phase is assumed to be compressible
458 */
459 static constexpr bool gasIsCompressible()
460 { return true; }
461
462 /*!
463 * \brief Returns true if the liquid phase is assumed to be compressible
464 */
465 static constexpr bool liquidIsCompressible()
466 { return true; }
467
468 /*!
469 * \brief The density of steam in \f$\mathrm{[kg/m^3]}\f$ at a given pressure and temperature.
470 *
471 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
472 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
473 *
474 * See:
475 *
476 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
477 * 1997 for the Thermodynamic Properties of Water and Steam",
478 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
479 */
480 49808950 static Scalar gasDensity(Scalar temperature, Scalar pressure)
481 {
482
1/2
✓ Branch 2 taken 49808950 times.
✗ Branch 3 not taken.
49808950 Region2::checkValidityRange(temperature, pressure, "Density");
483
484 // regularization
485
2/2
✓ Branch 0 taken 7934053 times.
✓ Branch 1 taken 41874897 times.
49808950 if (pressure < triplePressure() - 100) {
486 // We assume an ideal gas for low pressures to avoid the
487 // 0/0 for the internal energy and enthalpy.
488 7934053 Scalar rho0IAPWS = 1.0/volumeRegion2_(temperature,
489 triplePressure() - 100);
490 7934053 Scalar rho0Id = IdealGas<Scalar>::density(molarMass(),
491 temperature,
492 triplePressure() - 100);
493 return
494 7934053 rho0IAPWS/rho0Id *
495 7934053 IdealGas<Scalar>::density(molarMass(),
496 temperature,
497 7934053 pressure);
498 }
499 41874897 Scalar pv = vaporPressure(temperature);
500
2/2
✓ Branch 0 taken 6212878 times.
✓ Branch 1 taken 35662019 times.
41874897 if (pressure > pv) {
501 // the pressure is too high, in this case we use the slope
502 // of the density energy at the vapor pressure to
503 // regularize
504
505 // calculate the partial derivative of the specific volume
506 // to the pressure at the vapor pressure.
507 6212878 const Scalar eps = pv*1e-8;
508 6212878 Scalar v0 = volumeRegion2_(temperature, pv);
509 12425756 Scalar v1 = volumeRegion2_(temperature, pv + eps);
510 6212878 Scalar dv_dp = (v1 - v0)/eps;
511 /*
512 Scalar pi = Region2::pi(pv);
513 Scalar dp_dPi = Region2::dp_dPi(pv);
514 Scalar dGamma_dPi = Region2::dGamma_dPi(temperature, pv);
515 Scalar ddGamma_ddPi = Region2::ddGamma_ddPi(temperature, pv);
516
517 Scalar RT = Rs*temperature;
518 Scalar dv_dp =
519 RT/(dp_dPi*pv)
520 *
521 (dGamma_dPi + pi*ddGamma_ddPi - v0*dp_dPi/RT);
522 */
523
524 // calculate the partial derivative of the density to the
525 // pressure at vapor pressure
526 6212878 Scalar drho_dp = - 1/(v0*v0)*dv_dp;
527
528 // use a straight line for extrapolation
529 6212878 return 1.0/v0 + (pressure - pv)*drho_dp;
530 }
531
532 35662019 return 1.0/volumeRegion2_(temperature, pressure);
533 }
534
535 /*!
536 * \brief The molar density of steam in \f$\mathrm{[mol/m^3]}\f$ at a given pressure and temperature.
537 *
538 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
539 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
540 *
541 */
542 2511380 static Scalar gasMolarDensity(Scalar temperature, Scalar pressure)
543 2511380 { return gasDensity(temperature, pressure)/molarMass(); }
544
545 /*!
546 * \brief Returns true if the gas phase is assumed to be ideal
547 */
548 static constexpr bool gasIsIdeal()
549 { return false; }
550
551 /*!
552 * \brief The pressure of steam in \f$\mathrm{[Pa]}\f$ at a given density and temperature.
553 *
554 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
555 * \param density of component in \f$\mathrm{[kg/m^3]}\f$
556 *
557 * See:
558 *
559 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
560 * 1997 for the Thermodynamic Properties of Water and Steam",
561 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
562 */
563 3030232 static Scalar gasPressure(Scalar temperature, Scalar density)
564 {
565 // We use the newton method for this. For the initial value we
566 // assume steam to be an ideal gas
567 3030232 Scalar pressure = IdealGas<Scalar>::pressure(temperature, density/molarMass());
568 3030232 Scalar eps = pressure*1e-7;
569
570 3030232 Scalar deltaP = pressure*2;
571 using std::abs;
572
4/4
✓ Branch 0 taken 12063956 times.
✓ Branch 1 taken 221030 times.
✓ Branch 2 taken 9254754 times.
✓ Branch 3 taken 2809202 times.
12284986 for (int i = 0; i < 5 && abs(pressure*1e-9) < abs(deltaP); ++i)
573 {
574 9254754 const Scalar f = gasDensity(temperature, pressure) - density;
575
576 Scalar df_dp;
577 9254754 df_dp = gasDensity(temperature, pressure + eps);
578 9254754 df_dp -= gasDensity(temperature, pressure - eps);
579 9254754 df_dp /= 2*eps;
580
581 9254754 deltaP = - f/df_dp;
582
583 9254754 pressure += deltaP;
584 }
585
586 3030232 return pressure;
587 }
588
589 /*!
590 * \brief The density of pure water in \f$\mathrm{[kg/m^3]}\f$ at a given pressure and temperature.
591 *
592 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
593 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
594 *
595 * See:
596 *
597 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
598 * 1997 for the Thermodynamic Properties of Water and Steam",
599 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
600 */
601 147370031 static Scalar liquidDensity(Scalar temperature, Scalar pressure)
602 {
603
2/2
✓ Branch 2 taken 147370025 times.
✓ Branch 3 taken 6 times.
147370031 Region1::checkValidityRange(temperature, pressure, "Density");
604
605 // regularization
606 147370025 Scalar pv = vaporPressure(temperature);
607
2/2
✓ Branch 0 taken 7878504 times.
✓ Branch 1 taken 139491521 times.
147370025 if (pressure < pv) {
608 // the pressure is too low, in this case we use the slope
609 // of the density at the vapor pressure to regularize
610
611 // calculate the partial derivative of the specific volume
612 // to the pressure at the vapor pressure.
613 7878504 const Scalar eps = pv*1e-8;
614 7878504 Scalar v0 = volumeRegion1_(temperature, pv);
615 15757008 Scalar v1 = volumeRegion1_(temperature, pv + eps);
616 7878504 Scalar dv_dp = (v1 - v0)/eps;
617
618 /*
619 Scalar v0 = volumeRegion1_(temperature, pv);
620 Scalar pi = Region1::pi(pv);
621 Scalar dp_dPi = Region1::dp_dPi(pv);
622 Scalar dGamma_dPi = Region1::dGamma_dPi(temperature, pv);
623 Scalar ddGamma_ddPi = Region1::ddGamma_ddPi(temperature, pv);
624
625 Scalar RT = Rs*temperature;
626 Scalar dv_dp =
627 RT/(dp_dPi*pv)
628 *
629 (dGamma_dPi + pi*ddGamma_ddPi - v0*dp_dPi/RT);
630 */
631
632 // calculate the partial derivative of the density to the
633 // pressure at vapor pressure
634 7878504 Scalar drho_dp = - 1/(v0*v0)*dv_dp;
635
636 // use a straight line for extrapolation
637 7878504 return 1.0/v0 + (pressure - pv)*drho_dp;
638 }
639
640 139491521 return 1/volumeRegion1_(temperature, pressure);
641 }
642
643 /*!
644 * \brief The molar density of water in \f$\mathrm{[mol/m^3]}\f$ at a given pressure and temperature.
645 *
646 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
647 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
648 *
649 */
650 14 static Scalar liquidMolarDensity(Scalar temperature, Scalar pressure)
651 14 { return liquidDensity(temperature, pressure)/molarMass(); }
652
653 /*!
654 * \brief The pressure of liquid water in \f$\mathrm{[Pa]}\f$ at a given density and
655 * temperature.
656 *
657 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
658 * \param density density of component in \f$\mathrm{[kg/m^3]}\f$
659 *
660 * See:
661 *
662 * IAPWS: "Revised Release on the IAPWS Industrial Formulation
663 * 1997 for the Thermodynamic Properties of Water and Steam",
664 * http://www.iapws.org/relguide/IF97-Rev.pdf \cite IAPWS1997
665 */
666 4060592 static Scalar liquidPressure(Scalar temperature, Scalar density)
667 {
668 // We use Brent's method for this, with a pressure range including the surroundings of the
669 // vapor pressure line
670 4060592 Scalar minPressure = vaporPressure(temperature)/1.11;
671 4060592 Scalar maxPressure = 100e6;
672 4060592 const auto residualFunction = [&] (const Scalar pressure) {
673
3/4
✗ Branch 2 not taken.
✓ Branch 3 taken 4060592 times.
✓ Branch 5 taken 112089136 times.
✓ Branch 6 taken 7856436 times.
124006164 return liquidDensity(temperature, pressure) - density;
674 };
675 try
676 {
677
1/2
✓ Branch 1 taken 4060592 times.
✗ Branch 2 not taken.
4060592 return findScalarRootBrent(minPressure, maxPressure, residualFunction);
678 }
679 catch (const NumericalProblem& e)
680 {
681 DUNE_THROW(NumericalProblem,
682 "searched for pressure(T=" << temperature << ",rho=" << density
683 <<") in [" << minPressure << ", " << maxPressure << "]: "
684 << e.what());
685 }
686 }
687
688 /*!
689 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of steam.
690 *
691 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
692 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
693 *
694 * We assume pure water vapor here. For water in a mixture of other gaseous
695 * components, consider the free function h2oGasViscosityInMixture.
696 *
697 * We use the IAPWS Formulation, see:
698 * IAPWS: "Release on the IAPWS Formulation 2008 for the Viscosity
699 * of Ordinary Water Substance", http://www.iapws.org/relguide/visc.pdf \cite cooper2008
700 * This method is only valid if pressure is below or at the vapor
701 * pressure of water.
702 */
703 3030440 static Scalar gasViscosity(Scalar temperature, Scalar pressure)
704 {
705
1/2
✓ Branch 2 taken 3030440 times.
✗ Branch 3 not taken.
3030440 Region2::checkValidityRange(temperature, pressure, "Viscosity");
706
707 3030440 Scalar rho = gasDensity(temperature, pressure);
708 3030440 return Common::viscosity(temperature, rho);
709 }
710
711
712 /*!
713 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of pure water.
714 *
715 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
716 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
717 *
718 * See:
719 * IAPWS: "Release on the IAPWS Formulation 2008 for the Viscosity
720 * of Ordinary Water Substance", http://www.iapws.org/relguide/visc.pdf \cite cooper2008
721 */
722 5008805 static Scalar liquidViscosity(Scalar temperature, Scalar pressure)
723 {
724
1/2
✓ Branch 2 taken 5008805 times.
✗ Branch 3 not taken.
5008805 Region1::checkValidityRange(temperature, pressure, "Viscosity");
725
726 5008805 Scalar rho = liquidDensity(temperature, pressure);
727 5008805 return Common::viscosity(temperature, rho);
728 }
729
730 /*!
731 * \brief Thermal conductivity \f$\mathrm{[[W/(m*K)]}\f$ of water (IAPWS) .
732 *
733 * Implementation taken from:
734 * freesteam - IAPWS-IF97 steam tables library
735 * copyright (C) 2004-2009 John Pye
736 *
737 * See:
738 * IAPWS: "Release on the IAPWS Formulation 2011 for the Thermal Conductivity
739 * of Ordinary Water Substance", http://www.iapws.org/relguide/ThCond.pdf
740 * \cite IAPWS_ThCond
741 *
742 * \param temperature absolute temperature in \f$\mathrm{[K]}\f$
743 * \param pressure of the phase in \f$\mathrm{[Pa]}\f$
744 */
745 3718777 static Scalar liquidThermalConductivity( Scalar temperature, Scalar pressure)
746 {
747 // Thermal conductivity of water is empirically fit.
748 // Evaluating that fitting-function outside the area of validity does not make sense.
749
5/6
✓ Branch 0 taken 3718777 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3718760 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 1658000 times.
✓ Branch 5 taken 2060760 times.
3718777 if ( !( (pressure <= 400e6 && (273.15 <= temperature) && (temperature <= 398.15))
750
5/6
✓ Branch 0 taken 1658017 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1658000 times.
✓ Branch 3 taken 17 times.
✓ Branch 4 taken 744800 times.
✓ Branch 5 taken 913200 times.
1658017 || (pressure <= 200e6 && (398.15 < temperature) && (temperature <= 523.15))
751
4/6
✓ Branch 0 taken 744817 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 744800 times.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 744800 times.
744817 || (pressure <= 150e6 && (523.15 < temperature) && (temperature <= 673.15))
752
2/6
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
17 || (pressure <= 100e6 && (673.15 < temperature) && (temperature <= 1073.15)) ))
753 {
754
15/30
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 17 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 17 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 17 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 17 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 17 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 17 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 17 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 17 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 17 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 17 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 17 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 17 times.
✗ Branch 41 not taken.
✓ Branch 44 taken 17 times.
✗ Branch 45 not taken.
68 DUNE_THROW(NumericalProblem,
755 "Evaluating the IAPWS fit function for thermal conductivity outside range of applicability."
756 "(T=" << temperature << ", p=" << pressure << ")");
757 }
758
759 3718760 Scalar rho = liquidDensity(temperature, pressure);
760 3718760 return Common::thermalConductivityIAPWS(temperature, rho);
761 }
762
763 /*!
764 * \brief Thermal conductivity \f$\mathrm{[[W/(m*K)]}\f$ of steam (IAPWS) .
765 *
766 * Implementation taken from:
767 * freesteam - IAPWS-IF97 steam tables library
768 * copyright (C) 2004-2009 John Pye
769 *
770 * See:
771 * IAPWS: "Release on the IAPWS Formulation 2011 for the Thermal Conductivity
772 * of Ordinary Water Substance", http://www.iapws.org/relguide/ThCond.pdf
773 * \cite IAPWS_ThCond
774 *
775 * \param temperature absolute temperature in \f$\mathrm{[K]}\f$
776 * \param pressure of the phase in \f$\mathrm{[Pa]}\f$
777 */
778 3069808 static Scalar gasThermalConductivity(const Scalar temperature, const Scalar pressure)
779 {
780 // Thermal conductivity of water is empirically fit.
781 // Evaluating that fitting-function outside the area of validity does not make sense.
782
4/6
✓ Branch 0 taken 3069808 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3069808 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1658000 times.
✓ Branch 5 taken 1411808 times.
3069808 if ( !( (pressure <= 400e6 && (273.15 <= temperature) && (temperature <= 398.15))
783
4/6
✓ Branch 0 taken 1658000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1658000 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 744800 times.
✓ Branch 5 taken 913200 times.
1658000 || (pressure <= 200e6 && (398.15 < temperature) && (temperature <= 523.15))
784
3/6
✓ Branch 0 taken 744800 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 744800 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 744800 times.
744800 || (pressure <= 150e6 && (523.15 < temperature) && (temperature <= 673.15))
785 || (pressure <= 100e6 && (673.15 < temperature) && (temperature <= 1073.15)) ))
786 {
787 DUNE_THROW(NumericalProblem,
788 "Evaluating the IAPWS fit function for thermal conductivity outside range of applicability."
789 "(T=" << temperature << ", p=" << pressure << ")");
790 }
791
792 3069808 Scalar rho = gasDensity(temperature, pressure);
793 3069808 return Common::thermalConductivityIAPWS(temperature, rho);
794 }
795
796 private:
797 // the unregularized specific enthalpy for liquid water
798 4894061 static constexpr Scalar enthalpyRegion1_(Scalar temperature, Scalar pressure)
799 {
800 return
801 9955032 Region1::tau(temperature) *
802 4977516 Region1::dGamma_dTau(temperature, pressure) *
803 4977516 Rs*temperature;
804 }
805
806 // the unregularized specific isobaric heat capacity
807 2825983 static constexpr Scalar heatCap_p_Region1_(Scalar temperature, Scalar pressure)
808 {
809 return
810 5651966 - Region1::tau(temperature) * Region1::tau(temperature) *
811 2825983 Region1::ddGamma_ddTau(temperature, pressure) *
812 2825983 Rs;
813 }
814
815 // the unregularized specific isochoric heat capacity
816 static Scalar heatCap_v_Region1_(Scalar temperature, Scalar pressure)
817 {
818 Scalar tau = Region1::tau(temperature);
819 Scalar num = Region1::dGamma_dPi(temperature, pressure) - tau * Region1::ddGamma_dTaudPi(temperature, pressure);
820 Scalar diff = num * num / Region1::ddGamma_ddPi(temperature, pressure);
821
822 return
823 - tau * tau *
824 Region1::ddGamma_ddTau(temperature, pressure) * Rs +
825 diff;
826 }
827
828 // the unregularized specific internal energy for liquid water
829 1235600 static constexpr Scalar internalEnergyRegion1_(Scalar temperature, Scalar pressure)
830 {
831 return
832 1235600 Rs * temperature *
833 1235600 ( Region1::tau(temperature)*Region1::dGamma_dTau(temperature, pressure) -
834 1235600 Region1::pi(pressure)*Region1::dGamma_dPi(temperature, pressure));
835 }
836
837 // the unregularized specific volume for liquid water
838 147370025 static constexpr Scalar volumeRegion1_(Scalar temperature, Scalar pressure)
839 {
840 return
841 302618554 Region1::pi(pressure)*
842 147370025 Region1::dGamma_dPi(temperature, pressure) *
843 147370025 Rs * temperature / pressure;
844 }
845
846 // the unregularized specific enthalpy for steam
847 2660103 static constexpr Scalar enthalpyRegion2_(Scalar temperature, Scalar pressure)
848 {
849 return
850 12562630 Region2::tau(temperature) *
851 6281315 Region2::dGamma_dTau(temperature, pressure) *
852 6281315 Rs*temperature;
853 }
854
855 // the unregularized specific internal energy for steam
856 205212 static constexpr Scalar internalEnergyRegion2_(Scalar temperature, Scalar pressure)
857 {
858 return
859 205212 Rs * temperature *
860 205212 ( Region2::tau(temperature)*Region2::dGamma_dTau(temperature, pressure) -
861 205212 Region2::pi(pressure)*Region2::dGamma_dPi(temperature, pressure));
862 }
863
864 // the unregularized specific isobaric heat capacity
865 2825615 static constexpr Scalar heatCap_p_Region2_(Scalar temperature, Scalar pressure)
866 {
867 return
868 5651230 - Region2::tau(temperature) * Region2::tau(temperature) *
869 2825615 Region2::ddGamma_ddTau(temperature, pressure) *
870 2825615 Rs;
871 }
872
873 // the unregularized specific isochoric heat capacity
874 static Scalar heatCap_v_Region2_(Scalar temperature, Scalar pressure)
875 {
876 Scalar tau = Region2::tau(temperature);
877 Scalar pi = Region2::pi(pressure);
878 Scalar num = 1 + pi * Region2::dGamma_dPi(temperature, pressure) + tau * pi * Region2::ddGamma_dTaudPi(temperature, pressure);
879 Scalar diff = num * num / (1 - pi * pi * Region2::ddGamma_ddPi(temperature, pressure));
880 return
881 - tau * tau *
882 Region2::ddGamma_ddTau(temperature, pressure) * Rs
883 - diff;
884 }
885
886 // the unregularized specific volume for steam
887 41874897 static constexpr Scalar volumeRegion2_(Scalar temperature, Scalar pressure)
888 {
889 return
890 105830778 Region2::pi(pressure)*
891 49808950 Region2::dGamma_dPi(temperature, pressure) *
892 49808950 Rs * temperature / pressure;
893 }
894 };
895
896 template <class Scalar>
897 struct IsAqueous<H2O<Scalar>> : public std::true_type {};
898
899 } // end namespace Dumux::Components
900
901 namespace Dumux::FluidSystems::Detail {
902
903 // viscosity according to Reid, R.C.
904 template <class Scalar>
905 63459392 Scalar viscosityReid_(Scalar temperature)
906 {
907 63459392 constexpr Scalar tc = 647.3;
908 using std::max;
909
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 63459138 times.
63459392 const Scalar tr = max(temperature/tc, 1e-8);
910
911 63459392 const Scalar fp0 = 1.0 + 0.221*(0.96 + 0.1*(tr - 0.7));
912 63459392 constexpr Scalar xi = 3.334e-3;
913 using std::pow;
914 using std::exp;
915 63459392 const Scalar eta_xi = (0.807*pow(tr, 0.618) - 0.357*exp((-0.449)*tr)
916 63459392 + 0.34*exp((-4.058)*tr) + 0.018)*fp0;
917
918 63459392 return 1.0e-7*eta_xi/xi;
919 }
920
921 // viscosity according to Nagel, T. et al.
922 template <class Scalar>
923 25428 Scalar viscosityNagel_(Scalar temperature)
924 {
925 25428 constexpr Scalar a1 = -4.4189440e-6;
926 25428 constexpr Scalar a2 = 4.6876380e-8;
927 25428 constexpr Scalar a3 = -5.3894310e-12;
928 25428 constexpr Scalar a4 = 3.2028560e-16;
929 25428 constexpr Scalar a5 = 4.9191790e-22;
930
931 25428 return a1 + a2*temperature + a3*temperature*temperature
932 25428 + a4*temperature*temperature*temperature
933 25428 + a5*temperature*temperature*temperature*temperature;
934 }
935
936 } // end Dumux::FluidSystems::Detail
937
938 namespace Dumux::FluidSystems {
939
940 /*!
941 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of steam in a gas mixture.
942 *
943 * \param temperature temperature in \f$\mathrm{[K]}\f$
944 * \param pressure pressure
945 *
946 * We assume here that water is in mixture with other gaseous components.
947 * For pure water, use the gasViscosity function of Components::H2O.
948 *
949 * We apply two different laws depending on the gas temperature.
950 *
951 * For temperatures below 480 K see:
952 * "Reid, R.C., Prausnitz, J.M., Poling, B.E.: The Properties of
953 * Gases and Liquids (1987)"
954 * Lucas corresponding states method
955 * https://www.osti.gov/scitech/biblio/6504847 \cite reid1987
956 *
957 * For temperatures above 500 K see:
958 * Nagel, T. et al.: THC-Processes (2018)
959 * https://doi.org/10.1007/978-3-319-68225-9_12
960 *
961 * In the range 480 - 500 K, we interpolate between the two laws.
962 */
963 template <class Scalar>
964 63484715 Scalar h2oGasViscosityInMixture(Scalar temperature, Scalar pressure)
965 {
966
2/2
✓ Branch 0 taken 63459287 times.
✓ Branch 1 taken 25428 times.
63484715 if (temperature < 480.0)
967 63459287 return Detail::viscosityReid_(temperature);
968
969
2/2
✓ Branch 0 taken 25323 times.
✓ Branch 1 taken 105 times.
25428 else if (temperature > 500.0)
970 25323 return Detail::viscosityNagel_(temperature);
971
972 else // interpolate
973 {
974 105 const Scalar op = (500.0 - temperature)/20.0;
975
976 105 return op*Detail::viscosityReid_(temperature)
977 105 + (1.0 - op)*Detail::viscosityNagel_(temperature);
978 }
979 }
980
981 } // end namespace Dumux::FluidSystems
982
983 #endif
984