GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/material/fluidsystems/h2oheavyoil.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 106 111 95.5%
Functions: 19 19 100.0%
Branches: 85 231 36.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 FluidSystems
10 * \brief @copybrief Dumux::FluidSystems::H2OHeavyOil
11 */
12 #ifndef DUMUX_H2O_HEAVYOIL_FLUID_SYSTEM_HH
13 #define DUMUX_H2O_HEAVYOIL_FLUID_SYSTEM_HH
14
15 #include <dumux/material/idealgas.hh>
16 #include <dumux/material/components/h2o.hh>
17 #include <dumux/material/components/tabulatedcomponent.hh>
18 #include <dumux/material/components/heavyoil.hh>
19
20 #include <dumux/material/binarycoefficients/h2o_heavyoil.hh>
21
22 #include <dumux/material/fluidsystems/base.hh>
23
24 #include <dumux/io/name.hh>
25
26 namespace Dumux::FluidSystems {
27
28 /*!
29 * \ingroup FluidSystems
30 * \brief A compositional fluid system with water and heavy oil
31 * components in both the liquid and the gas phase.
32 */
33 template <class Scalar,
34 class H2OType = Dumux::Components::TabulatedComponent<Dumux::Components::H2O<Scalar> > >
35 class H2OHeavyOil
36 : public Base<Scalar, H2OHeavyOil<Scalar, H2OType> >
37 {
38 using ThisType = H2OHeavyOil<Scalar, H2OType>;
39
40 public:
41 using HeavyOil = Dumux::Components::HeavyOil<Scalar>;
42 using H2O = H2OType;
43
44
45 static const int numPhases = 3;
46 static const int numComponents = 2;
47
48 static const int wPhaseIdx = 0; // index of the water phase
49 static const int nPhaseIdx = 1; // index of the NAPL phase
50 static const int gPhaseIdx = 2; // index of the gas phase
51
52 static const int H2OIdx = 0;
53 static const int NAPLIdx = 1;
54
55 // export component indices to indicate the main component
56 // of the corresponding phase at atmospheric pressure 1 bar
57 // and room temperature 20°C:
58 static const int wCompIdx = H2OIdx;
59 static const int nCompIdx = NAPLIdx;
60
61 /*!
62 * \brief Initialize the fluid system's static parameters generically
63 *
64 * If a tabulated H2O component is used, we do our best to create
65 * tables that always work.
66 */
67 2 static void init()
68 {
69
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 init(/*tempMin=*/273.15,
70 /*tempMax=*/623.15,
71 /*numTemp=*/100,
72 /*pMin=*/0.0,
73 /*pMax=*/20e6,
74 /*numP=*/200);
75 1 }
76
77 /*!
78 * \brief Initialize the fluid system's static parameters using
79 * problem specific temperature and pressure ranges
80 *
81 * \param tempMin The minimum temperature used for tabulation of water [K]
82 * \param tempMax The maximum temperature used for tabulation of water [K]
83 * \param nTemp The number of ticks on the temperature axis of the table of water
84 * \param pressMin The minimum pressure used for tabulation of water [Pa]
85 * \param pressMax The maximum pressure used for tabulation of water [Pa]
86 * \param nPress The number of ticks on the pressure axis of the table of water
87 */
88 2 static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp,
89 Scalar pressMin, Scalar pressMax, unsigned nPress)
90 {
91 if (H2O::isTabulated)
92 {
93
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 H2O::init(tempMin, tempMax, nTemp,
94 pressMin, pressMax, nPress);
95 }
96 }
97
98 /*!
99 * \brief Get the main component of a given phase
100 * \param phaseIdx The index of the fluid phase to consider
101 */
102 95846400 static constexpr int getMainComponent(int phaseIdx)
103 {
104 // For the gas phase, choosing a main component appears to be
105 // rather arbitrary. Motivated by the fact that the thermal conductivity
106 // of the gas phase is set to the thermal conductivity of pure water,
107 // water is chosen for now.
108
6/6
✓ Branch 0 taken 15974400 times.
✓ Branch 1 taken 7987200 times.
✓ Branch 2 taken 31948800 times.
✓ Branch 3 taken 15974400 times.
✓ Branch 4 taken 15974400 times.
✓ Branch 5 taken 7987200 times.
95846400 if (phaseIdx == nPhaseIdx)
109 return nCompIdx;
110 else
111 63897600 return wCompIdx;
112 }
113
114 /*!
115 * \brief Returns whether the fluids are miscible
116 */
117 static constexpr bool isMiscible()
118 { return true; }
119
120 /*!
121 * \brief Return whether a phase is gaseous
122 *
123 * \param phaseIdx The index of the fluid phase to consider
124 */
125 2 static constexpr bool isGas(int phaseIdx)
126 {
127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(0 <= phaseIdx && phaseIdx < numPhases);
128 return phaseIdx == gPhaseIdx;
129 }
130
131 /*!
132 * \brief Returns true if and only if a fluid phase is assumed to
133 * be an ideal gas.
134 *
135 * \param phaseIdx The index of the fluid phase to consider
136 */
137 static bool isIdealGas(int phaseIdx)
138 { return phaseIdx == gPhaseIdx && H2O::gasIsIdeal() && HeavyOil::gasIsIdeal(); }
139
140 /*!
141 * \brief Returns true if and only if a fluid phase is assumed to
142 * be an ideal mixture.
143 *
144 * We define an ideal mixture as a fluid phase where the fugacity
145 * coefficients of all components times the pressure of the phase
146 * are independent on the fluid composition. This assumption is true
147 * if Henry's law and Raoult's law apply. If you are unsure what
148 * this function should return, it is safe to return false. The
149 * only damage done will be (slightly) increased computation times
150 * in some cases.
151 *
152 * \param phaseIdx The index of the fluid phase to consider
153 */
154 static bool isIdealMixture(int phaseIdx)
155 {
156 assert(0 <= phaseIdx && phaseIdx < numPhases);
157 // we assume Henry's and Raoult's laws for the water phase and
158 // and no interaction between gas molecules of different
159 // components, so all phases are ideal mixtures!
160 return true;
161 }
162
163 /*!
164 * \brief Returns true if and only if a fluid phase is assumed to
165 * be compressible.
166 *
167 * Compressible means that the partial derivative of the density
168 * to the fluid pressure is always larger than zero.
169 *
170 * \param phaseIdx The index of the fluid phase to consider
171 */
172 static constexpr bool isCompressible(int phaseIdx)
173 {
174 assert(0 <= phaseIdx && phaseIdx < numPhases);
175 // gases are always compressible
176 if (phaseIdx == gPhaseIdx)
177 return true;
178 else if (phaseIdx == wPhaseIdx)
179 // the water component decides for the water phase...
180 return H2O::liquidIsCompressible();
181
182 // the NAPL component decides for the napl phase...
183 return HeavyOil::liquidIsCompressible();
184 }
185
186 /*!
187 * \brief Return the human readable name of a phase (used in indices)
188 */
189 24 static std::string phaseName(int phaseIdx)
190 {
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(0 <= phaseIdx && phaseIdx < numPhases);
192
3/3
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
24 switch (phaseIdx)
193 {
194 8 case wPhaseIdx: return IOName::aqueousPhase();
195 8 case nPhaseIdx: return IOName::naplPhase();
196 8 case gPhaseIdx: return IOName::gaseousPhase();
197 }
198 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
199 }
200
201 /*!
202 * \brief Return the human readable name of a component (used in indices)
203 */
204 8 static std::string componentName(int compIdx)
205 {
206
2/3
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
8 switch (compIdx) {
207 4 case H2OIdx: return H2O::name();
208 4 case NAPLIdx: return HeavyOil::name();
209 };
210 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx);
211 }
212
213 /*!
214 * \brief Return the molar mass of a component in [kg/mol].
215 */
216 7987216 static Scalar molarMass(int compIdx)
217 {
218
2/3
✓ Branch 0 taken 90882242 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 58933442 times.
149815684 switch (compIdx) {
219 case H2OIdx: return H2O::molarMass();
220 90882242 case NAPLIdx: return HeavyOil::molarMass();
221 };
222 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << compIdx);
223 }
224
225 using Base<Scalar, ThisType>::density;
226 //! \copydoc Base<Scalar,ThisType>::density(const FluidState&,int)
227 template <class FluidState>
228 11564843 static Scalar density(const FluidState &fluidState, int phaseIdx)
229 {
230
2/2
✓ Branch 0 taken 3854949 times.
✓ Branch 1 taken 7709894 times.
11564843 if (phaseIdx == wPhaseIdx) {
231 // See: doctoral thesis of Steffen Ochs 2007
232 // Steam injection into saturated porous media : process analysis including experimental and numerical investigations
233 // http://elib.uni-stuttgart.de/bitstream/11682/271/1/Diss_Ochs_OPUS.pdf
234
235 // This assumes each gas molecule displaces exactly one
236 // molecule in the liquid.
237
238 3854949 return H2O::liquidMolarDensity(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx))
239 3854947 * (H2O::molarMass()*fluidState.moleFraction(wPhaseIdx, H2OIdx)
240 3854947 + HeavyOil::molarMass()*fluidState.moleFraction(wPhaseIdx, NAPLIdx));
241 }
242
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 3854947 times.
7709894 else if (phaseIdx == nPhaseIdx) {
243 // assume pure NAPL for the NAPL phase
244 3854947 Scalar pressure = HeavyOil::liquidIsCompressible()?fluidState.pressure(phaseIdx):1e100;
245 3854947 return HeavyOil::liquidDensity(fluidState.temperature(phaseIdx), pressure);
246 }
247
248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3854947 times.
3854947 assert (phaseIdx == gPhaseIdx);
249 3854947 Scalar pH2O =
250 3854947 fluidState.moleFraction(gPhaseIdx, H2OIdx) *
251 3854947 fluidState.pressure(gPhaseIdx);
252 3854947 Scalar pNAPL =
253 3854947 fluidState.moleFraction(gPhaseIdx, NAPLIdx) *
254 3854947 fluidState.pressure(gPhaseIdx);
255 3854947 return H2O::gasDensity(fluidState.temperature(phaseIdx), pH2O)
256 3854947 + HeavyOil::gasDensity(fluidState.temperature(phaseIdx), pNAPL);
257 }
258
259 using Base<Scalar, ThisType>::molarDensity;
260 //! \copydoc Base<Scalar,ThisType>::molarDensity(const FluidState&,int)
261 template <class FluidState>
262
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 3854946 times.
11564841 static Scalar molarDensity(const FluidState &fluidState, int phaseIdx)
263 {
264
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 3854946 times.
11564841 Scalar temperature = fluidState.temperature(phaseIdx);
265 3854949 Scalar pressure = fluidState.pressure(phaseIdx);
266
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 3854948 times.
7709895 if (phaseIdx == nPhaseIdx)
267 {
268 3854947 return HeavyOil::liquidMolarDensity(temperature, pressure);
269 }
270
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3854947 times.
3854948 else if (phaseIdx == wPhaseIdx)
271 { // This assumes each gas molecule displaces exactly one
272 // molecule in the liquid.
273 3854947 return H2O::liquidMolarDensity(temperature, pressure);
274 }
275 else
276 {
277 3854947 return H2O::gasMolarDensity(temperature, fluidState.partialPressure(gPhaseIdx, H2OIdx))
278 3854947 + HeavyOil::gasMolarDensity(temperature, fluidState.partialPressure(gPhaseIdx, NAPLIdx));
279 }
280 }
281
282 using Base<Scalar, ThisType>::viscosity;
283 //! \copydoc Base<Scalar,ThisType>::viscosity(const FluidState&,int)
284 template <class FluidState>
285 11564841 static Scalar viscosity(const FluidState &fluidState,
286 int phaseIdx)
287 {
288
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 7709894 times.
11564841 if (phaseIdx == wPhaseIdx) {
289 // assume pure water viscosity
290 3854947 return H2O::liquidViscosity(fluidState.temperature(phaseIdx),
291 fluidState.pressure(phaseIdx));
292 }
293
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 3854947 times.
7709894 else if (phaseIdx == nPhaseIdx) {
294 // assume pure NAPL viscosity
295 3854947 return HeavyOil::liquidViscosity(fluidState.temperature(phaseIdx),
296 3854947 fluidState.pressure(phaseIdx));
297 }
298
299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3854947 times.
3854947 assert (phaseIdx == gPhaseIdx);
300
301 /* Wilke method. See:
302 *
303 * See: R. Reid, et al.: The Properties of Gases and Liquids,
304 * 4th edition, McGraw-Hill, 1987, 407-410
305 * 5th edition, McGraw-Hill, 20001, p. 9.21/22
306 *
307 * in this case, we use a simplified version in order to avoid
308 * computationally costly evaluation of sqrt and pow functions and
309 * divisions
310 * -- compare e.g. with Promo Class p. 32/33
311 */
312 3854948 const Scalar mu[numComponents] = {
313 3854947 h2oGasViscosityInMixture(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx)),
314 3854947 HeavyOil::gasViscosity(fluidState.temperature(phaseIdx), HeavyOil::vaporPressure(fluidState.temperature(phaseIdx)))
315 };
316
317 3854947 return mu[H2OIdx]*fluidState.moleFraction(gPhaseIdx, H2OIdx)
318 3854947 + mu[NAPLIdx]*fluidState.moleFraction(gPhaseIdx, NAPLIdx);
319 }
320
321 using Base<Scalar, ThisType>::binaryDiffusionCoefficient;
322 /*!
323 * \brief Given a phase's composition, temperature and pressure,
324 * return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ for components
325 * \f$\mathrm{i}\f$ and \f$\mathrm{j}\f$ in this phase.
326 *
327 * Be aware that in this case there are only two components in three phases.
328 * Therefore, we assume the diffusion to simply be the binary diffusion coefficients.
329 * This was previously implemented in diffusionCoefficient(), but is now moved.
330 *
331 * \param fluidState The fluid state
332 * \param phaseIdx Index of the fluid phase
333 * \param compIIdx Index of the component i
334 * \param compJIdx Index of the component j
335 */
336 template <class FluidState>
337
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 3854946 times.
7709904 static Scalar binaryDiffusionCoefficient(const FluidState &fluidState,
338 int phaseIdx,
339 int compIIdx,
340 int compJIdx)
341
342 {
343
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 3854946 times.
7709904 const Scalar T = fluidState.temperature(phaseIdx);
344 7709904 const Scalar p = fluidState.pressure(phaseIdx);
345
346 // liquid phase
347
2/2
✓ Branch 0 taken 3854954 times.
✓ Branch 1 taken 3854950 times.
7709904 if (phaseIdx == wPhaseIdx)
348 return BinaryCoeff::H2O_HeavyOil::liquidDiffCoeff(T, p);
349
350 // gas phase
351
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 3854950 times.
3854954 else if (phaseIdx == gPhaseIdx)
352 return BinaryCoeff::H2O_HeavyOil::gasDiffCoeff(T, p);
353 else
354
11/22
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 4 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 4 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 4 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 4 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 4 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
16 DUNE_THROW(Dune::InvalidStateException,
355 "Non-existent binary diffusion coefficient for phase index "
356 << phaseIdx);
357 }
358
359 using Base<Scalar, ThisType>::diffusionCoefficient;
360 /*!
361 * \brief Calculate the molecular diffusion coefficient for
362 * a component in a fluid phase \f$\mathrm{[mol^2 * s / (kg*m^3)]}\f$
363 * \param fluidState The fluid state
364 * \param phaseIdx Index of the fluid phase
365 * \todo This signature does not match the base fluid system's signature,
366 * which takes an additional component index.
367 */
368 template <class FluidState>
369 7709892 static Scalar diffusionCoefficient(const FluidState &fluidState, int phaseIdx)
370 {
371 // liquid phase
372
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 3854946 times.
7709892 if (phaseIdx == wPhaseIdx)
373 3854946 return binaryDiffusionCoefficient(fluidState, phaseIdx, H2OIdx, NAPLIdx);
374 // gas phase
375
1/2
✓ Branch 0 taken 3854946 times.
✗ Branch 1 not taken.
3854946 else if (phaseIdx == gPhaseIdx)
376 3854946 return binaryDiffusionCoefficient(fluidState, phaseIdx, NAPLIdx, H2OIdx);
377 else
378 DUNE_THROW(Dune::InvalidStateException,
379 "Non-existent diffusion coefficient for phase index "<< phaseIdx);
380 }
381
382 /*!
383 * \brief Henry coefficients \f$[N/m^2]\f$ of a component in a phase.
384 * \param fluidState An arbitrary fluid state
385 * \param phaseIdx The index of the phase to consider
386 * \param compIdx The index of the component to consider
387 */
388 template <class FluidState>
389 static Scalar henryCoefficient(const FluidState &fluidState,
390 int phaseIdx,
391 int compIdx)
392 {
393 assert(0 <= phaseIdx && phaseIdx < numPhases);
394 assert(0 <= compIdx && compIdx < numComponents);
395
396 const Scalar T = fluidState.temperature(phaseIdx);
397
398 if (compIdx == NAPLIdx && phaseIdx == wPhaseIdx)
399 return Dumux::BinaryCoeff::H2O_HeavyOil::henryOilInWater(T);
400
401 else if (phaseIdx == nPhaseIdx && compIdx == H2OIdx)
402 return Dumux::BinaryCoeff::H2O_HeavyOil::henryWaterInOil(T);
403
404 else
405 DUNE_THROW(Dune::InvalidStateException, "non-existent henry coefficient for phase index " << phaseIdx
406 << " and component index " << compIdx);
407 }
408
409 /*!
410 * \brief Partial pressures in the gas phase, taken from saturation vapor pressures.
411 * \param fluidState An arbitrary fluid state
412 * \param phaseIdx The index of the phase to consider
413 * \param compIdx The index of the component to consider
414 */
415 template <class FluidState>
416 3856420 static Scalar partialPressureGas(const FluidState &fluidState, int phaseIdx,
417 int compIdx)
418 {
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3856050 times.
3856050 assert(0 <= compIdx && compIdx < numComponents);
420
421 7712470 const Scalar T = fluidState.temperature(phaseIdx);
422
1/2
✓ Branch 0 taken 3856050 times.
✗ Branch 1 not taken.
3856050 if (compIdx == NAPLIdx)
423 3856050 return HeavyOil::vaporPressure(T);
424 else if (compIdx == H2OIdx)
425 3856420 return H2O::vaporPressure(T);
426 else
427 DUNE_THROW(Dune::InvalidStateException, "non-existent component index " << compIdx);
428 }
429
430 /*!
431 * \brief Inverse vapor pressures, taken from inverse saturation vapor pressures
432 * \param fluidState An arbitrary fluid state
433 * \param phaseIdx The index of the phase to consider
434 * \param compIdx The index of the component to consider
435 */
436 template <class FluidState>
437 380 static Scalar inverseVaporPressureCurve(const FluidState &fluidState,
438 int phaseIdx,
439 int compIdx)
440 {
441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 370 times.
370 assert(0 <= compIdx && compIdx < numComponents);
442
443 380 const Scalar pressure = fluidState.pressure(phaseIdx);
444
1/2
✓ Branch 0 taken 370 times.
✗ Branch 1 not taken.
370 if (compIdx == NAPLIdx)
445 370 return HeavyOil::vaporTemperature(pressure);
446 else if (compIdx == H2OIdx)
447 380 return H2O::vaporTemperature(pressure);
448 else
449 DUNE_THROW(Dune::InvalidStateException, "non-existent component index " << compIdx);
450 }
451
452 using Base<Scalar, ThisType>::enthalpy;
453 /*!
454 * \brief Given all mole fractions in a phase, return the specific
455 * phase enthalpy\f$\mathrm{[J/kg]}\f$.
456 * \param fluidState An arbitrary fluid state
457 * \param phaseIdx The index of the phase to consider
458 * \todo This system neglects the contribution of gas-molecules in the liquid phase.
459 * This contribution is probably not big.
460 * Somebody would have to find out the enthalpy of solution for this system. ...
461 */
462 template <class FluidState>
463 11564841 static Scalar enthalpy(const FluidState &fluidState,
464 int phaseIdx)
465 {
466
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 7709894 times.
11564841 if (phaseIdx == wPhaseIdx) {
467 3854947 return H2O::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
468 }
469
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 3854947 times.
7709894 else if (phaseIdx == nPhaseIdx) {
470 3854947 return HeavyOil::liquidEnthalpy(fluidState.temperature(phaseIdx), fluidState.pressure(phaseIdx));
471 }
472
1/2
✓ Branch 0 taken 3854947 times.
✗ Branch 1 not taken.
3854947 else if (phaseIdx == gPhaseIdx) { // gas phase enthalpy depends strongly on composition
473 3854947 Scalar hgc = HeavyOil::gasEnthalpy(fluidState.temperature(phaseIdx),
474 fluidState.pressure(phaseIdx));
475 3854947 Scalar hgw = H2O::gasEnthalpy(fluidState.temperature(phaseIdx),
476 fluidState.pressure(phaseIdx));
477
478 3854947 Scalar result = 0;
479 3854947 result += hgw * fluidState.massFraction(gPhaseIdx, H2OIdx);
480 3854947 result += hgc * fluidState.massFraction(gPhaseIdx, NAPLIdx);
481
482 3854947 return result;
483 }
484 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
485 }
486
487 /*!
488 * \brief Returns the specific enthalpy \f$\mathrm{[J/kg]}\f$ of a component in a specific phase
489 * \param fluidState The fluid state
490 * \param phaseIdx The index of the phase
491 * \param componentIdx The index of the component
492 */
493 template <class FluidState>
494 static Scalar componentEnthalpy(const FluidState& fluidState, int phaseIdx, int componentIdx)
495 {
496 const Scalar T = fluidState.temperature(phaseIdx);
497 const Scalar p = fluidState.pressure(phaseIdx);
498
499 if (phaseIdx == wPhaseIdx)
500 {
501 if (componentIdx == H2OIdx)
502 return H2O::liquidEnthalpy(T, p);
503 else if (componentIdx == NAPLIdx)
504 DUNE_THROW(Dune::NotImplemented, "The component enthalpy for NAPL in water is not implemented.");
505 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << componentIdx);
506 }
507 else if (phaseIdx == nPhaseIdx)
508 {
509 if (componentIdx == H2OIdx)
510 DUNE_THROW(Dune::NotImplemented, "The component enthalpy for water in NAPL is not implemented.");
511 else if (componentIdx == NAPLIdx)
512 return HeavyOil::liquidEnthalpy(T, p);
513 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << componentIdx);
514 }
515 else if (phaseIdx == gPhaseIdx)
516 {
517 if (componentIdx == H2OIdx)
518 return H2O::gasEnthalpy(T, p);
519 else if (componentIdx == NAPLIdx)
520 return HeavyOil::gasEnthalpy(T, p);
521 DUNE_THROW(Dune::InvalidStateException, "Invalid component index " << componentIdx);
522 }
523 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
524 }
525
526 using Base<Scalar, ThisType>::heatCapacity;
527 //! \copydoc Base<Scalar,ThisType>::heatCapacity(const FluidState&,int)
528 template <class FluidState>
529 3 static Scalar heatCapacity(const FluidState &fluidState,
530 int phaseIdx)
531 {
532
10/20
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 3 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 3 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 3 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 3 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 3 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 3 times.
✗ Branch 29 not taken.
12 DUNE_THROW(Dune::NotImplemented, "FluidSystems::H2ONAPL::heatCapacity()");
533 }
534
535 using Base<Scalar, ThisType>::thermalConductivity;
536 /*!
537 * \brief Thermal conductivity of a fluid phase \f$\mathrm{[W/(m K)]}\f$.
538 *
539 * Use the conductivity of water (wPhase and gPhase) and oil (nPhase) as a first approximation.
540 *
541 * \param fluidState An arbitrary fluid state
542 * \param phaseIdx The index of the fluid phase to consider
543 */
544 template <class FluidState>
545
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 7709892 times.
11564841 static Scalar thermalConductivity(const FluidState &fluidState,
546 int phaseIdx)
547 {
548
2/2
✓ Branch 0 taken 3854946 times.
✓ Branch 1 taken 7709892 times.
11564841 const Scalar temperature = fluidState.temperature(phaseIdx) ;
549 11564841 const Scalar pressure = fluidState.pressure(phaseIdx);
550
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 7709894 times.
11564841 if (phaseIdx == wPhaseIdx)
551 {
552 3854947 return H2O::liquidThermalConductivity(temperature, pressure);
553 }
554
2/2
✓ Branch 0 taken 3854947 times.
✓ Branch 1 taken 3854947 times.
7709894 else if (phaseIdx == nPhaseIdx)
555 {
556 return HeavyOil::liquidThermalConductivity(temperature, pressure);
557 }
558
1/2
✓ Branch 0 taken 3854947 times.
✗ Branch 1 not taken.
3854947 else if (phaseIdx == gPhaseIdx)
559 {
560 3854947 return H2O::gasThermalConductivity(temperature, pressure);
561 }
562 DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx);
563 }
564
565 };
566
567 } // end namespace Dumux::FluidSystems
568
569 #endif
570