GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/material/components/xylene.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 81 81 100.0%
Functions: 7 7 100.0%
Branches: 49 82 59.8%

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 Properties of xylene.
11 */
12 #ifndef DUMUX_XYLENE_HH
13 #define DUMUX_XYLENE_HH
14
15 #include <cmath>
16 #include <dumux/material/idealgas.hh>
17 #include <dumux/material/constants.hh>
18
19 #include <dumux/material/components/base.hh>
20 #include <dumux/material/components/liquid.hh>
21 #include <dumux/material/components/gas.hh>
22
23 namespace Dumux::Components {
24
25 /*!
26 * \ingroup Components
27 * \brief Properties of xylene.
28 *
29 * \tparam Scalar The type used for scalar values
30 */
31 template <class Scalar>
32 class Xylene
33 : public Components::Base<Scalar, Xylene<Scalar> >
34 , public Components::Liquid<Scalar, Xylene<Scalar> >
35 , public Components::Gas<Scalar, Xylene<Scalar> >
36 {
37 using Consts = Constants<Scalar>;
38 using IdealGas = Dumux::IdealGas<Scalar>;
39
40 public:
41 /*!
42 * \brief A human readable name for the xylene
43 */
44
8/16
✓ 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.
✓ 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.
16 static std::string name()
45
17/33
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ 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.
✓ 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 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 3 not taken.
16 { return "xylene"; }
46
47 /*!
48 * \brief The molar mass in \f$\mathrm{[kg/mol]}\f$ of xylene
49 */
50 constexpr static Scalar molarMass()
51 { return 0.106; }
52
53 /*!
54 * \brief Returns the critical temperature \f$\mathrm{[K]}\f$ of xylene
55 */
56 constexpr static Scalar criticalTemperature()
57 { return 617.1; }
58
59 /*!
60 * \brief Returns the critical pressure \f$\mathrm{[Pa]}\f$ of xylene
61 */
62 constexpr static Scalar criticalPressure()
63 { return 35.4e5; }
64
65 /*!
66 * \brief Returns the temperature \f$\mathrm{[K]}\f$ at xylene's boiling point (1 atm).
67 */
68 constexpr static Scalar boilingTemperature()
69 { return 412.3; }
70
71 /*!
72 * \brief Returns the temperature \f$\mathrm{[K]}\f$ at xylene's triple point.
73 */
74 static Scalar tripleTemperature()
75 {
76 DUNE_THROW(Dune::NotImplemented, "tripleTemperature for xylene");
77 }
78
79 /*!
80 * \brief Returns the pressure \f$\mathrm{[Pa]}\f$ at xylene's triple point.
81 */
82 static Scalar triplePressure()
83 {
84 DUNE_THROW(Dune::NotImplemented, "triplePressure for xylene");
85 }
86
87 /*!
88 * \brief The saturation vapor pressure in \f$\mathrm{[Pa]}\f$ of pure xylene
89 * at a given temperature according to Antoine after Betz 1997 -> Gmehling et al 1980 \cite gmehling1980 <BR>
90 *
91 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
92 */
93 16483292 static Scalar vaporPressure(Scalar temperature)
94 {
95 16483292 const Scalar A = 7.00909;
96 16483292 const Scalar B = 1462.266;
97 16483292 const Scalar C = 215.110;
98
99 16483292 Scalar T = temperature - 273.15;
100
101 using std::pow;
102 16483292 Scalar psat = 1.334*pow(10.0, (A - (B/(T + C)))); // in [mbar]
103
3/3
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6593315 times.
✓ Branch 2 taken 6593314 times.
16483292 psat *= 100.0; // in [Pa] (0.001*1.E5)
104
105 return psat;
106 }
107
108 /*!
109 * \brief Specific heat cap of liquid xylene \f$\mathrm{[J/kg]}\f$.
110 *
111 * source : Reid et al. (fourth edition): Missenard group contrib. method (chap 5-7, Table 5-11, s. example 5-8) \cite reid1987 <BR>
112 *
113 * \param temp temperature of component in \f$\mathrm{[K]}\f$
114 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
115 */
116 13187182 static Scalar liquidHeatCapacity(Scalar temp, Scalar pressure)
117 {
118 Scalar CH3,C6H5,H;
119 // after Reid et al. : Missenard group contrib. method (s. example 5-8) \cite reid1987 <BR>
120 // Xylene: C9H12 : 3* CH3 ; 1* C6H5 (phenyl-ring) ; -2* H (this was too much!)
121 // linear interpolation between table values [J/(mol K)]
122
123
2/2
✓ Branch 0 taken 13113087 times.
✓ Branch 1 taken 74095 times.
13187182 if(temp < 298.0){ // take care: extrapolation for Temp<273
124 13113087 H = 13.4 + 1.2*(temp - 273.0)/25.0; // 13.4 + 1.2 = 14.6 = H(T=298K) i.e. interpolation of table values 273<T<298
125 13113087 CH3 = 40.0 + 1.6*(temp - 273.0)/25.0; // 40 + 1.6 = 41.6 = CH3(T=298K)
126 13113087 C6H5 = 113.0 + 4.2*(temp - 273.0)/25.0; // 113 + 4.2 = 117.2 = C6H5(T=298K)
127 }
128
2/2
✓ Branch 0 taken 19754 times.
✓ Branch 1 taken 54341 times.
74095 else if(temp < 323.0){
129 19754 H = 14.6 + 0.9*(temp - 298.0)/25.0; // i.e. interpolation of table values 298<T<323
130 19754 CH3 = 41.6 + 1.9*(temp - 298.0)/25.0;
131 19754 C6H5 = 117.2 + 6.2*(temp - 298.0)/25.0;
132 }
133
2/2
✓ Branch 0 taken 43207 times.
✓ Branch 1 taken 11134 times.
54341 else if(temp < 348.0){
134 43207 H = 15.5 + 1.2*(temp - 323.0)/25.0; // i.e. interpolation of table values 323<T<348
135 43207 CH3 = 43.5 + 2.3*(temp - 323.0)/25.0;
136 43207 C6H5 = 123.4 + 6.3*(temp - 323.0)/25.0;
137 }
138 else {
139 11134 H = 16.7 + 2.1*(temp - 348.0)/25.0; // i.e. interpolation of table values 348<T<373
140 11134 CH3 = 45.8 + 2.5*(temp - 348.0)/25.0; // take care: extrapolation for Temp>373
141 11134 C6H5 = 129.7 + 6.3*(temp - 348.0)/25.0; // most likely leads to underestimation
142 }
143
144 13187182 return (C6H5 + 2*CH3 - H)/molarMass();// J/(mol K) -> J/(kg K)
145 }
146
147
148 /*!
149 * \brief Specific enthalpy of liquid xylene \f$\mathrm{[J/kg]}\f$.
150 *
151 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
152 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
153 */
154 6593536 static Scalar liquidEnthalpy(const Scalar temperature,
155 const Scalar pressure)
156 {
157 // Gauss quadrature rule:
158 // Interval: [0K; temperature (K)]
159 // Gauss-Legendre-Integration with variable transformation:
160 // \int_a^b f(T) dT \approx (b-a)/2 \sum_i=1^n \alpha_i f( (b-a)/2 x_i + (a+b)/2 )
161 // with: n=2, legendre -> x_i = +/- \sqrt(1/3), \apha_i=1
162 // here: a=273.15K, b=actual temperature in Kelvin
163 // \leadsto h(T) = \int_273.15^T c_p(T) dT
164 // \approx 0.5 (T-273.15) * (cp( 0.5(temperature-273.15)sqrt(1/3) ) + cp(0.5(temperature-273.15)(-1)sqrt(1/3))
165
166 // Enthalpy may have arbitrary reference state, but the empirical/fitted heatCapacity function needs Kelvin as input and is
167 // fit over a certain temperature range. This suggests choosing an interval of integration being in the actual fit range.
168 // I.e. choosing T=273.15K as reference point for liquid enthalpy.
169 using std::sqrt;
170 6593536 const Scalar sqrt1over3 = sqrt(1./3.);
171 // evaluation points according to Gauss-Legendre integration
172 6593536 const Scalar TEval1 = 0.5*(temperature-273.15)* sqrt1over3 + 0.5*(273.15+temperature);
173 // evaluation points according to Gauss-Legendre integration
174 6593536 const Scalar TEval2 = 0.5*(temperature-273.15)* (-1)* sqrt1over3 + 0.5*(273.15+temperature);
175
176 6593536 const Scalar h_n = 0.5 * (temperature-273.15) * ( liquidHeatCapacity(TEval1, pressure) + liquidHeatCapacity(TEval2, pressure) );
177
178 6593536 return h_n;
179 }
180
181 /*!
182 * \brief Latent heat of vaporization for xylene \f$\mathrm{[J/kg]}\f$.
183 *
184 * source : Reid et al. (fourth edition): Chen method (chap. 7-11, Delta H_v = Delta H_v (T) according to chap. 7-12) \cite reid1987
185 *
186 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
187 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
188 */
189 3296768 static Scalar heatVap(Scalar temperature,
190 const Scalar pressure)
191 {
192 using std::min;
193 using std::max;
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temperature = min(temperature, criticalTemperature()); // regularization
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temperature = max(temperature, 0.0); // regularization
196
197 3296768 constexpr Scalar T_crit = criticalTemperature();
198 3296768 constexpr Scalar Tr1 = boilingTemperature()/criticalTemperature();
199 3296768 constexpr Scalar p_crit = criticalPressure();
200
201 // Chen method, eq. 7-11.4 (at boiling)
202 using std::log;
203 3296768 const Scalar DH_v_boil = Consts::R * T_crit * Tr1
204 * (3.978 * Tr1 - 3.958 + 1.555*log(p_crit * 1e-5 /*Pa->bar*/ ) )
205 / (1.07 - Tr1); /* [J/mol] */
206
207 /* Variation with temp according to Watson relation eq 7-12.1*/
208 using std::pow;
209 3296768 const Scalar Tr2 = temperature/criticalTemperature();
210 3296768 const Scalar n = 0.375;
211 3296768 const Scalar DH_vap = DH_v_boil * pow(((1.0 - Tr2)/(1.0 - Tr1)), n);
212
213 3296768 return (DH_vap/molarMass()); // we need [J/kg]
214 }
215
216 /*!
217 * \brief Specific enthalpy of xylene vapor \f$\mathrm{[J/kg]}\f$.
218 *
219 * This relation is true on the vapor pressure curve, i.e. as long
220 * as there is a liquid phase present.
221 *
222 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
223 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
224 */
225 3296768 static Scalar gasEnthalpy(Scalar temperature, Scalar pressure)
226 {
227 3296768 return liquidEnthalpy(temperature, pressure) + heatVap(temperature, pressure);
228 }
229
230 /*!
231 * \brief The density \f$\mathrm{[kg/m^3]}\f$ of xylene gas at a given pressure and temperature.
232 *
233 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
234 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
235 */
236
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3296771 static Scalar gasDensity(Scalar temperature, Scalar pressure)
237 {
238
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3296771 return IdealGas::density(molarMass(),
239 temperature,
240 pressure);
241 }
242
243 /*!
244 * \brief The molar gas density \f$\mathrm{[mol/m^3]}\f$ of xylene gas at a given pressure and temperature.
245 *
246 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
247 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
248 */
249 3296658 static Scalar gasMolarDensity(Scalar temperature, Scalar pressure)
250 3296658 { return IdealGas::molarDensity(temperature, pressure); }
251
252 /*!
253 * \brief The molar liquid density of pure xylene at a given pressure and temperature
254 * \f$\mathrm{[mol/m^3]}\f$.
255 *
256 * source : Reid et al. (fourth edition): Modified Racket technique (chap. 3-11, eq. 3-11.9) \cite reid1987 <BR>
257 *
258 * \param temp temperature of component in \f$\mathrm{[K]}\f$
259 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
260 */
261 6593432 static Scalar liquidMolarDensity(Scalar temp, Scalar pressure)
262 {
263 // saturated molar volume according to Lide, CRC Handbook of
264 // Thermophysical and Thermochemical Data, CRC Press, 1994
265 // valid for 245 < Temp < 600
266 using std::min;
267 using std::max;
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6593432 times.
6593432 temp = min(temp, 500.0); // regularization
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6593432 times.
6593432 temp = max(temp, 250.0); // regularization
270
271 using std::pow;
272 6593432 const Scalar A1 = 0.25919; // from table
273 6593432 const Scalar A2 = 0.0014569; // from table
274 6593432 const Scalar expo = 1.0 + pow((1.0 - temp/criticalTemperature()), (2.0/7.0));
275 6593432 const Scalar V = A2*pow(A1, expo); // liquid molar volume [m^3/mol]
276
277 6593432 return 1.0/V; // molar density [mol/m^3]
278 }
279
280 /*!
281 * \brief The density of pure xylene at a given pressure and temperature \f$\mathrm{[kg/m^3]}\f$.
282 *
283 * \param temperature temperature of component in \f$\mathrm{[K]}\f$
284 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
285 */
286 3296774 static Scalar liquidDensity(Scalar temperature, Scalar pressure)
287 {
288
2/2
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
3296774 return liquidMolarDensity(temperature, pressure)*molarMass();
289 }
290
291 /*!
292 * \brief Returns true if the gas phase is assumed to be compressible
293 */
294 static constexpr bool gasIsCompressible()
295 { return true; }
296
297 /*!
298 * \brief Returns true if the gas phase is assumed to be ideal
299 */
300 static constexpr bool gasIsIdeal()
301 { return true; }
302
303 /*!
304 * \brief Returns true if the liquid phase is assumed to be compressible
305 */
306 static constexpr bool liquidIsCompressible()
307 { return false; }
308
309 /*!
310 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of xylene vapor
311 *
312 * \param temp temperature of component in \f$\mathrm{[K]}\f$
313 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
314 */
315 3296768 static Scalar gasViscosity(Scalar temp, Scalar pressure)
316 {
317 using std::min;
318 using std::max;
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temp = min(temp, 500.0); // regularization
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temp = max(temp, 250.0); // regularization
321
322 using std::pow;
323 using std::exp;
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 const Scalar Tr = max(temp/criticalTemperature(), 1e-10);
325 3296768 const Scalar Fp0 = 1.0;
326 3296768 const Scalar xi = 0.004623;
327 3296768 const Scalar eta_xi = Fp0*(0.807*pow(Tr, 0.618)
328 3296768 - 0.357*exp(-0.449*Tr)
329 3296768 + 0.34*exp(-4.058*Tr)
330 + 0.018);
331 3296768 Scalar r = eta_xi/xi; // [1e-6 P]
332 3296768 r /= 1.0e7; // [Pa s]
333
334 3296768 return r;
335 }
336
337 /*!
338 * \brief The dynamic viscosity \f$\mathrm{[Pa*s]}\f$ of pure xylene.
339 *
340 * \param temp temperature of component in \f$\mathrm{[K]}\f$
341 * \param pressure pressure of component in \f$\mathrm{[Pa]}\f$
342 */
343 3296768 static Scalar liquidViscosity(Scalar temp, Scalar pressure)
344 {
345 using std::min;
346 using std::max;
347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temp = min(temp, 500.0); // regularization
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3296768 times.
3296768 temp = max(temp, 250.0); // regularization
349
350 3296768 const Scalar A = -3.82;
351 3296768 const Scalar B = 1027.0;
352 3296768 const Scalar C = -6.38e-4;
353 3296768 const Scalar D = 4.52e-7;
354
355 using std::exp;
356 3296768 Scalar r = exp(A + B/temp + C*temp + D*temp*temp); // in [cP]
357 3296768 r *= 1.0e-3; // in [Pa s]
358
359 3296768 return r; // [Pa s]
360 }
361
362 /*!
363 * \brief Thermal conductivity \f$\mathrm{[[W/(m*K)]}\f$ of xylene
364 *
365 * Thermal Conductivity of p-Xylene taken from the Dortmund Data Bank, see:
366 * http://www.ddbst.de/en/EED/PCP/TCN_C176.php
367 *
368 * \param temperature absolute temperature in \f$\mathrm{[K]}\f$
369 * \param pressure of the phase in \f$\mathrm{[Pa]}\f$
370 */
371 static Scalar liquidThermalConductivity( Scalar temperature, Scalar pressure)
372 {
373 return 0.13;
374 }
375 };
376
377 } // end namespace Dumux::Components
378
379 #endif
380