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 |