GCC Code Coverage Report


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