GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/material/components/air.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 28 30 93.3%
Functions: 2 3 66.7%
Branches: 22 44 50.0%

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-FileCopyrightInfo: 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 A simple class for the air fluid properties
11 */
12 #ifndef DUMUX_AIR_HH
13 #define DUMUX_AIR_HH
14
15 #include <dune/common/math.hh>
16
17 #include <dumux/common/exceptions.hh>
18 #include <dumux/material/components/base.hh>
19 #include <dumux/material/components/gas.hh>
20 #include <dumux/material/idealgas.hh>
21
22 namespace Dumux {
23 namespace Components {
24
25 /*!
26 * \ingroup Components
27 * \brief A class for the air fluid properties
28 *
29 * \tparam Scalar The type used for scalar values
30 */
31 template <class Scalar>
32 class Air
33 : public Components::Base<Scalar, Air<Scalar> >
34 , public Components::Gas<Scalar, Air<Scalar> >
35 {
36 using IdealGas = Dumux::IdealGas<Scalar>;
37
38 public:
39 /*!
40 * \brief A human readable name for Air.
41 */
42 static std::string name()
43
22/44
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 1 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 1 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 1 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 1 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
548294 { return "Air"; }
44
45 /*!
46 * \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of Air.
47 *
48 * Taken from constrelair.hh.
49 */
50 static constexpr Scalar molarMass()
51 { return 0.02896; /* [kg/mol] */ }
52
53 /*!
54 * \brief Returns the critical temperature \f$\mathrm{[K]}\f$ of Air.
55 */
56 static Scalar criticalTemperature()
57 { return 132.6312; /* [K] */ }
58
59 /*!
60 * \brief Returns the critical pressure \f$\mathrm{[Pa]}\f$ of Air.
61 */
62 static Scalar criticalPressure()
63 { return 37.86e5; /* [Pa] */ }
64
65 /*!
66 * \brief The density \f$\mathrm{[kg/m^3]}\f$ of Air at a given pressure and temperature.
67 *
68 * Ideal gas is assumed.
69 *
70 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
71 * \param pressure pressure of phase in \f$\mathrm{[Pa]}\f$
72 */
73 static Scalar gasDensity(Scalar temperature, Scalar pressure)
74 {
75 // Assume an ideal gas
76 117927190 return IdealGas::density(molarMass(), temperature, pressure);
77 }
78
79 /*!
80 * \brief The molar density of air in \f$\mathrm{[mol/m^3]}\f$,
81 * depending on pressure and temperature.
82 * \param temperature The temperature of the gas
83 * \param pressure The pressure of the gas
84 */
85 static Scalar gasMolarDensity(Scalar temperature, Scalar pressure)
86 92888636 { return IdealGas::molarDensity(temperature, pressure); }
87
88 /*!
89 * \brief Returns true, the gas phase is assumed to be compressible
90 */
91 static constexpr bool gasIsCompressible()
92 { return true; }
93
94 /*!
95 * \brief Returns true, the gas phase is assumed to be ideal
96 */
97 static constexpr bool gasIsIdeal()
98 { return true; }
99
100 /*!
101 * \brief Returns true if the gas phase viscosity is constant
102 */
103 static constexpr bool gasViscosityIsConstant()
104 { return false; }
105
106 /*!
107 * \brief The pressure \f$\mathrm{[Pa]}\f$ of gaseous Air at a given density and temperature.
108 *
109 * Ideal gas is assumed.
110 *
111 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
112 * \param density density of component in \f$\mathrm{[kg/m^3]}\f$
113 */
114 static Scalar gasPressure(Scalar temperature, Scalar density)
115 {
116 // Assume an ideal gas
117 40818 return IdealGas::pressure(temperature, density/molarMass());
118 }
119
120 /*!
121 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of Air at a given pressure and temperature.
122 *
123 * Critical specific volume calculated by \f$V_c = (R*T_c)/p_c\f$.
124 *
125 * Reid et al. (1987, pp 396-397, 667) \cite reid1987 <BR>
126 * Poling et al. (2001, pp 9.7-9.8) \cite poling2001 <BR>
127 *
128 * Accentric factor taken from: <BR>
129 * Adebiyi (2003) \cite adebiyi2003
130 *
131 * air is a non-polar substance,
132 * thus dipole moment mu is zero, as well the dimensionless dipole moment mu_r
133 * therefore not considered below
134 * the same holds for the correction value kappa for highly polar substances
135 *
136 * This calculation was introduced into Dumux in 2012 although the method here
137 * is designed for general polar substances. Air, however, is (a) non-polar,
138 * and (b) there are more precise methods available
139 *
140 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
141 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
142 */
143 static Scalar oldGasViscosity(Scalar temperature, Scalar pressure)
144 {
145 const Scalar Tc = criticalTemperature();
146 const Scalar Vc = 84.525138; // critical specific volume [cm^3/mol]
147 const Scalar omega = 0.078; // accentric factor
148 const Scalar M = molarMass() * 1e3; // molar mas [g/mol]
149
150 const Scalar Fc = 1.0 - 0.2756*omega;
151 const Scalar Tstar = 1.2593*temperature/Tc;
152
153 using std::exp;
154 using std::pow;
155 const Scalar Omega_v = 1.16145*pow(Tstar, -0.14874)
156 + 0.52487*exp(-0.77320*Tstar)
157 + 2.16178*exp(-2.43787*Tstar);
158
159 using std::cbrt;
160 using std::sqrt;
161 const Scalar mu = 40.785 * Fc * sqrt(M * temperature)/(cbrt(Vc * Vc) * Omega_v);
162
163 // conversion from micro poise to Pa s
164 return mu/1.0e6/10.0;
165 }
166
167 /*!
168 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of Air at a given pressure and temperature.
169 *
170 * Simple method, already implemented in MUFTE-UG, but pretty accurate.
171 *
172 * The pressure correction is even simpler and developed and tested by
173 * Holger Class in 2016 against the results of the Lemmon and Jacobsen (2004)
174 * approach \cite Lemmon2004a
175 * It shows very reasonable results throughout realistic pressure and
176 * temperature ranges up to several hundred Kelvin and up to 500 bar
177 *
178 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
179 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
180 */
181 109238845 static Scalar gasViscosity(Scalar temperature, Scalar pressure)
182 {
183 // above 1200 K, the function becomes inaccurate
184 // since this should realistically never happen, we can live with it
185 109238845 const Scalar tempCelsius = temperature - 273.15;
186 109238845 const Scalar pressureCorrectionFactor = 9.7115e-9*tempCelsius*tempCelsius - 5.5e-6*tempCelsius + 0.0010809;
187
188 using std::sqrt;
189 218477690 const Scalar mu = 1.496e-6 * sqrt(temperature * temperature * temperature) / (temperature + 120.0)
190 109238845 * (1.0 + (pressure/1.0e5 - 1.0)*pressureCorrectionFactor);
191 109238845 return mu;
192 }
193
194 /*!
195 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of Air at a given pressure and temperature.
196 *
197 * Simple method, already implemented in MUFTE-UG, but pretty accurate
198 * at atmospheric pressures.
199 * Gas viscosity is not very dependent on pressure. Thus, for
200 * low pressures one might switch the pressure correction off
201 *
202 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
203 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
204 */
205 static Scalar simpleGasViscosity(Scalar temperature, Scalar pressure)
206 {
207 // above 1200 K, the function becomes inaccurate
208 // since this should realistically never happen, we can live with it
209 using std::sqrt;
210 return 1.496e-6 * sqrt(temperature * temperature * temperature) / (temperature + 120.0);
211 }
212
213 /*!
214 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of Air at a given pressure and temperature.
215 *
216 * This is a very exact approach by Lemmon and Jacobsen (2004) \cite Lemmon2004a
217 * All the values and parameters used below are explained in their paper
218 * Since they use ''eta'' for dyn. viscosity, we do it as well for easier
219 * comparison with the paper
220 *
221 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
222 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
223 */
224 static Scalar exactGasViscosity(Scalar temperature, Scalar pressure)
225 {
226 const Scalar epsk = 103.3; // [K]
227
228 using std::log;
229 using std::exp;
230 using std::sqrt;
231 const Scalar logTstar = log(temperature/epsk);
232 const Scalar Omega = exp(0.431
233 - 0.4623*logTstar
234 + 0.08406*logTstar*logTstar
235 + 0.005341*logTstar*logTstar*logTstar
236 - 0.00331*logTstar*logTstar*logTstar*logTstar);
237
238 const Scalar sigma = 0.36; // [nm]
239 const Scalar eta0 = 0.0266958*sqrt(1000.0*molarMass()*temperature)/(sigma*sigma*Omega);
240
241 using std::pow;
242 using Dune::power;
243 const Scalar tau = criticalTemperature()/temperature;
244 const Scalar rhoc = 10.4477; // [mol/m^3]
245 const Scalar delta = 0.001*pressure/(temperature*8.3144598)/rhoc;
246 const Scalar etaR = 10.72 * pow(tau, 0.2) * delta
247 + 1.122 * pow(tau, 0.05) * power(delta, 4)
248 + 0.002019 * pow(tau, 2.4) * power(delta, 9)
249 - 8.876 * pow(tau, 0.6) * delta * exp(-delta)
250 - 0.02916 * pow(tau, 3.6) * power(delta, 8) * exp(-delta);
251
252 return (eta0 + etaR)*1e-6;
253 }
254
255 /*!
256 * \brief Specific enthalpy of Air \f$\mathrm{[J/kg]}\f$
257 * with 273.15 \f$ K \f$ as basis.
258 *
259 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
260 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
261 *
262 * Kays et al. (2005, 431ff) \cite kays2005 <BR>
263 */
264 static Scalar gasEnthalpy(Scalar temperature, Scalar pressure)
265 {
266 53256248 return gasHeatCapacity(temperature, pressure) * (temperature-273.15);
267 }
268
269 /*!
270 * \brief Specific internal energy of Air \f$\mathrm{[J/kg]}\f$.
271 *
272 * Definition of enthalpy: \f$h= u + pv = u + p / \rho\f$.
273 * Rearranging for internal energy yields: \f$u = h - pv\f$.
274 * Exploiting the Ideal Gas assumption
275 * (\f$pv = R_{\textnormal{specific}} T\f$) gives: \f$u = h - R / M T \f$.
276 *
277 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
278 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
279 */
280 static const Scalar gasInternalEnergy(Scalar temperature,
281 Scalar pressure)
282 {
283 return gasEnthalpy(temperature, pressure)
284 - IdealGas::R * temperature // = pressure * molar volume for an ideal gas
285 / molarMass(); // conversion from [J/(mol K)] to [J/(kg K)]
286 }
287
288 /*!
289 * \brief Specific isobaric heat capacity \f$\mathrm{[J/(kg*K)]}\f$ of pure
290 * air.
291 *
292 * This methods uses the formula for "zero-pressure" heat capacity that
293 * is only dependent on temperature, because the pressure dependence is rather small.
294 * This one should be accurate for a pressure of 1 atm.
295 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
296 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
297 *
298 * Values taken from Hollis (1996) \cite hollis1996 <BR>
299 * "Tables of Thermal Properties of Gases"
300 */
301 120373420 static const Scalar gasHeatCapacity(Scalar temperature,
302 Scalar pressure)
303 {
304 // scale temperature with reference temp of 100K
305 120373420 Scalar phi = temperature/100;
306
307 using std::pow;
308 using Dune::power;
309 120373420 Scalar c_p = 0.661738E+01
310 120373420 -0.105885E+01 * phi
311 120373420 +0.201650E+00 * power(phi,2)
312 120373420 -0.196930E-01 * power(phi,3)
313 120373420 +0.106460E-02 * power(phi,4)
314 120373420 -0.303284E-04 * power(phi,5)
315 120373420 +0.355861E-06 * power(phi,6);
316 120373420 c_p += -0.549169E+01 * power(phi,-1)
317 120373420 +0.585171E+01 * power(phi,-2)
318 120373420 -0.372865E+01 * power(phi,-3)
319 120373420 +0.133981E+01 * power(phi,-4)
320 120373420 -0.233758E+00 * power(phi,-5)
321 120373420 +0.125718E-01 * power(phi,-6);
322 120373420 c_p *= IdealGas::R / molarMass(); // in J/(mol*K) / (kg/mol)
323
324 120373420 return c_p;
325 }
326
327 /*!
328 * \brief Thermal conductivity \f$\mathrm{[[W/(m*K)]}\f$ of air.
329 *
330 * Isobaric Properties for Nitrogen in: NIST Standard \cite NIST <BR>
331 * evaluated at p=.1 MPa, T=20°C <BR>
332 * Nitrogen: 0.025398 <BR>
333 * Oxygen: 0.026105 <BR>
334 * lambda_air is approximately 0.78*lambda_N2+0.22*lambda_O2
335 *
336 * \param temperature absolute temperature in \f$\mathrm{[K]}\f$
337 * \param pressure of the phase in \f$\mathrm{[Pa]}\f$
338 */
339 static Scalar gasThermalConductivity(Scalar temperature, Scalar pressure)
340 {
341 return 0.0255535;
342 }
343 };
344
345 } // end namespace Components
346 } // end namespace Dumux
347
348 #endif
349