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 | * \copybrief Dumux::FluidSystems::ThreePImmiscible | ||
11 | */ | ||
12 | #ifndef DUMUX_3P_IMMISCIBLE_FLUID_SYSTEM_HH | ||
13 | #define DUMUX_3P_IMMISCIBLE_FLUID_SYSTEM_HH | ||
14 | |||
15 | #include <cassert> | ||
16 | #include <limits> | ||
17 | #include <iostream> | ||
18 | |||
19 | #include <dune/common/exceptions.hh> | ||
20 | |||
21 | #include <dumux/material/fluidsystems/1pliquid.hh> | ||
22 | #include <dumux/material/fluidsystems/1pgas.hh> | ||
23 | #include <dumux/material/fluidstates/immiscible.hh> | ||
24 | #include <dumux/material/components/base.hh> | ||
25 | #include <dumux/io/name.hh> | ||
26 | |||
27 | namespace Dumux::FluidSystems { | ||
28 | |||
29 | /*! | ||
30 | * \ingroup FluidSystems | ||
31 | * \brief A fluid system for three-phase models assuming immiscibility and | ||
32 | * thermodynamic equilibrium | ||
33 | * | ||
34 | * The fluid phases are completely specified by means of their | ||
35 | * constituting components. | ||
36 | * The wetting and the nonwetting phase can be defined individually | ||
37 | * via FluidSystem::OnePLiquid<Scalar, Component>. The gas phase can be defined via | ||
38 | * FluidSystems::OnePGas<Scalar, Component> | ||
39 | * These phases consist of one pure component. | ||
40 | * | ||
41 | * \tparam Scalar the scalar type | ||
42 | * \tparam WettingFluid the wetting phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component>) | ||
43 | * \tparam NonwettingFluid the wetting phase fluid system (use FluidSystem::OnePLiquid<Scalar, Component>) | ||
44 | * \tparam Gas the gas phase fluid system (use FluidSystem::OnePGas<Scalar, Component>) | ||
45 | */ | ||
46 | template <class Scalar, class WettingFluid, class NonwettingFluid, class Gas> | ||
47 | class ThreePImmiscible | ||
48 | : public Base<Scalar, ThreePImmiscible<Scalar, WettingFluid, NonwettingFluid, Gas> > | ||
49 | { | ||
50 | static_assert((WettingFluid::numPhases == 1), "WettingFluid has more than one phase"); | ||
51 | static_assert((NonwettingFluid::numPhases == 1), "NonwettingFluid has more than one phase"); | ||
52 | static_assert((Gas::numPhases == 1), "Gas has more than one phase"); | ||
53 | static_assert((WettingFluid::numComponents == 1), "WettingFluid has more than one component"); | ||
54 | static_assert((NonwettingFluid::numComponents == 1), "NonwettingFluid has more than one component"); | ||
55 | static_assert((Gas::numComponents == 1), "Gas has more than one component"); | ||
56 | |||
57 | using ThisType = ThreePImmiscible<Scalar, WettingFluid, NonwettingFluid, Gas>; | ||
58 | |||
59 | public: | ||
60 | /**************************************** | ||
61 | * Fluid phase related static parameters | ||
62 | ****************************************/ | ||
63 | |||
64 | //! Number of phases in the fluid system | ||
65 | static constexpr int numPhases = 3; | ||
66 | |||
67 | //! Index of the wetting phase | ||
68 | static constexpr int wPhaseIdx = 0; | ||
69 | //! Index of the nonwetting phase | ||
70 | static constexpr int nPhaseIdx = 1; | ||
71 | //! Index of the gas phase | ||
72 | static constexpr int gPhaseIdx = 2; | ||
73 | |||
74 | /*! | ||
75 | * \brief Return the human readable name of a fluid phase | ||
76 | * \param phaseIdx The index of the fluid phase to consider | ||
77 | */ | ||
78 | 21 | static std::string phaseName(int phaseIdx) | |
79 | { | ||
80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
|
21 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
81 |
3/3✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
|
21 | switch (phaseIdx) |
82 | { | ||
83 | 7 | case wPhaseIdx: return Components::IsAqueous<typename WettingFluid::Component>::value | |
84 | ? IOName::aqueousPhase() : IOName::naplPhase(); | ||
85 | 7 | case nPhaseIdx: return Components::IsAqueous<typename NonwettingFluid::Component>::value | |
86 | ? IOName::aqueousPhase() : IOName::naplPhase(); | ||
87 | 7 | case gPhaseIdx: return IOName::gaseousPhase(); | |
88 | } | ||
89 | DUNE_THROW(Dune::InvalidStateException, "Invalid phase index " << phaseIdx); | ||
90 | } | ||
91 | |||
92 | /*! | ||
93 | * \brief Returns whether the fluids are miscible | ||
94 | */ | ||
95 | static constexpr bool isMiscible() | ||
96 | { return false; } | ||
97 | |||
98 | /*! | ||
99 | * \brief Return whether a phase is gaseous | ||
100 | * \param phaseIdx The index of the fluid phase to consider | ||
101 | */ | ||
102 | static constexpr bool isGas(int phaseIdx) | ||
103 | { | ||
104 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
105 | |||
106 | switch (phaseIdx) | ||
107 | { | ||
108 | case wPhaseIdx: return WettingFluid::isGas(); break; | ||
109 | case nPhaseIdx: return NonwettingFluid::isGas(); break; | ||
110 | case gPhaseIdx: return Gas::isGas(); break; | ||
111 | default: return false; // TODO: constexpr-compatible throw | ||
112 | } | ||
113 | } | ||
114 | |||
115 | /*! | ||
116 | * \brief Returns true if and only if a fluid phase is assumed to | ||
117 | * be an ideal mixture. | ||
118 | * \param phaseIdx The index of the fluid phase to consider | ||
119 | * | ||
120 | * We define an ideal mixture as a fluid phase where the fugacity | ||
121 | * coefficients of all components times the pressure of the phase | ||
122 | * are independent on the fluid composition. This assumption is true | ||
123 | * if immiscibility is assumed. If you are unsure what | ||
124 | * this function should return, it is safe to return false. The | ||
125 | * only damage done will be (slightly) increased computation times | ||
126 | * in some cases. | ||
127 | */ | ||
128 | static constexpr bool isIdealMixture(int phaseIdx) | ||
129 | { return true; } | ||
130 | |||
131 | /*! | ||
132 | * \brief Returns true if and only if a fluid phase is assumed to | ||
133 | * be compressible. | ||
134 | * | ||
135 | * Compressible means. that the partial derivative of the density | ||
136 | * to the fluid pressure is always larger than zero. | ||
137 | * | ||
138 | * \param phaseIdx The index of the fluid phase to consider | ||
139 | */ | ||
140 | static constexpr bool isCompressible(int phaseIdx) | ||
141 | { | ||
142 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
143 | |||
144 | // let the fluids decide | ||
145 | switch(phaseIdx) | ||
146 | { | ||
147 | case wPhaseIdx: return WettingFluid::isCompressible(); break; | ||
148 | case nPhaseIdx: return NonwettingFluid::isCompressible(); break; | ||
149 | case gPhaseIdx: return Gas::isCompressible(); break; | ||
150 | default: return false; // TODO: constexpr-compatible throw | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /*! | ||
155 | * \brief Returns true if and only if a fluid phase is assumed to | ||
156 | * be an ideal gas. | ||
157 | * | ||
158 | * \param phaseIdx The index of the fluid phase to consider | ||
159 | */ | ||
160 | static constexpr bool isIdealGas(int phaseIdx) | ||
161 | { | ||
162 | assert(0 <= phaseIdx && phaseIdx < numPhases); | ||
163 | |||
164 | // let the fluids decide | ||
165 | switch(phaseIdx) | ||
166 | { | ||
167 | case wPhaseIdx: return WettingFluid::isIdealGas(); break; | ||
168 | case nPhaseIdx: return NonwettingFluid::isIdealGas(); break; | ||
169 | case gPhaseIdx: return Gas::isIdealGas(); break; | ||
170 | default: return false; // TODO: constexpr-compatible throw | ||
171 | } | ||
172 | } | ||
173 | |||
174 | /**************************************** | ||
175 | * Component related static parameters | ||
176 | ****************************************/ | ||
177 | |||
178 | //! Number of components in the fluid system | ||
179 | static constexpr int numComponents = 3;//WettingFluid::numComponents + NonwettingFluid::numComponents + Gas::numComponents; // TODO: 3?? | ||
180 | |||
181 | //! Index of the wetting phase's component | ||
182 | static constexpr int wCompIdx = 0; | ||
183 | //! Index of the nonwetting phase's component | ||
184 | static constexpr int nCompIdx = 1; | ||
185 | //! Index of the gas phase's component | ||
186 | static constexpr int gCompIdx = 2; // TODO: correct?? | ||
187 | |||
188 | /*! | ||
189 | * \brief Return the human readable name of a component | ||
190 | * | ||
191 | * \param compIdx index of the component | ||
192 | */ | ||
193 | 3 | static std::string componentName(int compIdx) | |
194 | { | ||
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= compIdx && compIdx < numComponents); |
196 | |||
197 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
3 | switch(compIdx) |
198 | { | ||
199 | 1 | case wCompIdx: return WettingFluid::name(); break; | |
200 | 1 | case nCompIdx: return NonwettingFluid::name(); break; | |
201 | 1 | case gCompIdx: return Gas::name(); break; | |
202 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index"); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | /*! | ||
207 | * \brief Return the molar mass of a component in \f$\mathrm{[kg/mol]}\f$. | ||
208 | * \param compIdx index of the component | ||
209 | */ | ||
210 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | static Scalar molarMass(int compIdx) |
211 | { | ||
212 | assert(0 <= compIdx && compIdx < numComponents); | ||
213 | |||
214 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 18 times.
|
27 | switch(compIdx) |
215 | { | ||
216 | case wCompIdx: return WettingFluid::molarMass(); break; | ||
217 | case nCompIdx: return NonwettingFluid::molarMass(); break; | ||
218 | 9 | case gCompIdx: return Gas::molarMass(); break; | |
219 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index"); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /*! | ||
224 | * \brief Critical temperature of a component \f$\mathrm{[K]}\f$. | ||
225 | * \param compIdx index of the component | ||
226 | */ | ||
227 | static Scalar criticalTemperature(int compIdx) | ||
228 | { | ||
229 | assert(0 <= compIdx && compIdx < numComponents); | ||
230 | |||
231 | switch(compIdx) | ||
232 | { | ||
233 | case wCompIdx: return WettingFluid::criticalTemperature(); break; | ||
234 | case nCompIdx: return NonwettingFluid::criticalTemperature(); break; | ||
235 | case gCompIdx: return Gas::criticalTemperature(); break; | ||
236 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index"); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /*! | ||
241 | * \brief Critical pressure of a component \f$\mathrm{[Pa]}\f$. | ||
242 | * \param compIdx index of the component | ||
243 | */ | ||
244 | static Scalar criticalPressure(int compIdx) | ||
245 | { | ||
246 | assert(0 <= compIdx && compIdx < numComponents); | ||
247 | |||
248 | switch(compIdx) | ||
249 | { | ||
250 | case wCompIdx: return WettingFluid::criticalPressure(); break; | ||
251 | case nCompIdx: return NonwettingFluid::criticalPressure(); break; | ||
252 | case gCompIdx: return Gas::criticalPressure(); break; | ||
253 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index"); | ||
254 | } | ||
255 | } | ||
256 | |||
257 | /*! | ||
258 | * \brief The acentric factor of a component \f$\mathrm{[-]}\f$. | ||
259 | * \param compIdx index of the component | ||
260 | */ | ||
261 | static Scalar acentricFactor(int compIdx) | ||
262 | { | ||
263 | assert(0 <= compIdx && compIdx < numComponents); | ||
264 | |||
265 | switch(compIdx) | ||
266 | { | ||
267 | case wCompIdx: return WettingFluid::Component::acentricFactor(); break; | ||
268 | case nCompIdx: return NonwettingFluid::Component::acentricFactor(); break; | ||
269 | case gCompIdx: return Gas::Component::acentricFactor(); break; | ||
270 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid component index"); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | /**************************************** | ||
275 | * thermodynamic relations | ||
276 | ****************************************/ | ||
277 | |||
278 | /*! | ||
279 | * \brief Initialize the fluid system's static parameters | ||
280 | */ | ||
281 | static constexpr void init() | ||
282 | { | ||
283 | // two gaseous phases at once do not make sense physically! | ||
284 | // (But two liquids are fine) | ||
285 | static_assert(!WettingFluid::isGas() && !NonwettingFluid::isGas() && Gas::isGas(), "There can only be one gaseous phase!"); | ||
286 | } | ||
287 | |||
288 | /*! | ||
289 | * \brief Initialize the fluid system's static parameters using | ||
290 | * problem specific temperature and pressure ranges | ||
291 | * | ||
292 | * \param tempMin The minimum temperature used for tabulation of water \f$\mathrm{[K]}\f$ | ||
293 | * \param tempMax The maximum temperature used for tabulation of water \f$\mathrm{[K]}\f$ | ||
294 | * \param nTemp The number of ticks on the temperature axis of the table of water | ||
295 | * \param pressMin The minimum pressure used for tabulation of water \f$\mathrm{[Pa]}\f$ | ||
296 | * \param pressMax The maximum pressure used for tabulation of water \f$\mathrm{[Pa]}\f$ | ||
297 | * \param nPress The number of ticks on the pressure axis of the table of water | ||
298 | */ | ||
299 | 2 | static void init(Scalar tempMin, Scalar tempMax, unsigned nTemp, | |
300 | Scalar pressMin, Scalar pressMax, unsigned nPress) | ||
301 | { | ||
302 | // two gaseous phases at once do not make sense physically! | ||
303 | static_assert(!WettingFluid::isGas() && !NonwettingFluid::isGas() && Gas::isGas(), "There can only be one gaseous phase!"); | ||
304 | |||
305 | if (WettingFluid::Component::isTabulated) | ||
306 | { | ||
307 | 2 | std::cout << "Initializing tables for the wetting fluid properties (" | |
308 | 2 | << nTemp*nPress | |
309 | 2 | << " entries).\n"; | |
310 | |||
311 | 2 | WettingFluid::Component::init(tempMin, tempMax, nTemp, | |
312 | pressMin, pressMax, nPress); | ||
313 | |||
314 | } | ||
315 | |||
316 | if (NonwettingFluid::Component::isTabulated) | ||
317 | { | ||
318 | std::cout << "Initializing tables for the nonwetting fluid properties (" | ||
319 | << nTemp*nPress | ||
320 | << " entries).\n"; | ||
321 | |||
322 | NonwettingFluid::Component::init(tempMin, tempMax, nTemp, | ||
323 | pressMin, pressMax, nPress); | ||
324 | |||
325 | } | ||
326 | |||
327 | if (Gas::Component::isTabulated) | ||
328 | { | ||
329 | std::cout << "Initializing tables for the gas fluid properties (" | ||
330 | << nTemp*nPress | ||
331 | << " entries).\n"; | ||
332 | |||
333 | Gas::Component::init(tempMin, tempMax, nTemp, | ||
334 | pressMin, pressMax, nPress); | ||
335 | |||
336 | } | ||
337 | 2 | } | |
338 | |||
339 | using Base<Scalar, ThisType>::density; | ||
340 | //! \copydoc Base<Scalar,ThisType>::density(const FluidState&,int) | ||
341 | template <class FluidState> | ||
342 | 758703 | static Scalar density(const FluidState &fluidState, | |
343 | int phaseIdx) | ||
344 | { | ||
345 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 758703 times.
|
758703 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
346 | |||
347 |
3/3✓ Branch 0 taken 252900 times.
✓ Branch 1 taken 252900 times.
✓ Branch 2 taken 252900 times.
|
758703 | Scalar temperature = fluidState.temperature(phaseIdx); |
348 | 758703 | Scalar pressure = fluidState.pressure(phaseIdx); | |
349 | |||
350 |
3/3✓ Branch 0 taken 252901 times.
✓ Branch 1 taken 252901 times.
✓ Branch 2 taken 252901 times.
|
758703 | switch(phaseIdx) |
351 | { | ||
352 | 252901 | case wPhaseIdx: return WettingFluid::density(temperature, pressure); break; | |
353 | 252901 | case nPhaseIdx: return NonwettingFluid::density(temperature, pressure); break; | |
354 | 252901 | case gPhaseIdx: return Gas::density(temperature, pressure); break; | |
355 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | using Base<Scalar, ThisType>::molarDensity; | ||
360 | /*! | ||
361 | * \brief The molar density \f$\rho_{mol,\alpha}\f$ | ||
362 | * of a fluid phase \f$\alpha\f$ in \f$\mathrm{[mol/m^3]}\f$ | ||
363 | * | ||
364 | * The molar density is defined by the | ||
365 | * mass density \f$\rho_\alpha\f$ and the component molar mass \f$M_\alpha\f$: | ||
366 | * | ||
367 | * \f[\rho_{mol,\alpha} = \frac{\rho_\alpha}{M_\alpha} \;.\f] | ||
368 | */ | ||
369 | template <class FluidState> | ||
370 | 3 | static Scalar molarDensity(const FluidState &fluidState, | |
371 | int phaseIdx) | ||
372 | { | ||
373 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
374 | |||
375 | 3 | Scalar temperature = fluidState.temperature(phaseIdx); | |
376 | 3 | Scalar pressure = fluidState.pressure(phaseIdx); | |
377 | |||
378 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
3 | switch(phaseIdx) |
379 | { | ||
380 | 1 | case wPhaseIdx: return WettingFluid::molarDensity(temperature, pressure); | |
381 | 1 | case nPhaseIdx: return NonwettingFluid::molarDensity(temperature, pressure); | |
382 | 1 | case gPhaseIdx: return Gas::molarDensity(temperature, pressure); | |
383 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | using Base<Scalar, ThisType>::viscosity; | ||
388 | /*! | ||
389 | * \brief Return the viscosity of a phase \f$\mathrm{[Pa*s]}\f$. | ||
390 | * \param fluidState The fluid state of the two-phase model | ||
391 | * \param phaseIdx Index of the fluid phase | ||
392 | */ | ||
393 | template <class FluidState> | ||
394 | 758703 | static Scalar viscosity(const FluidState &fluidState, | |
395 | int phaseIdx) | ||
396 | { | ||
397 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 758703 times.
|
758703 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
398 | |||
399 |
3/3✓ Branch 0 taken 252900 times.
✓ Branch 1 taken 252900 times.
✓ Branch 2 taken 252900 times.
|
758703 | Scalar temperature = fluidState.temperature(phaseIdx); |
400 | 758703 | Scalar pressure = fluidState.pressure(phaseIdx); | |
401 | |||
402 |
3/3✓ Branch 0 taken 252901 times.
✓ Branch 1 taken 252901 times.
✓ Branch 2 taken 252901 times.
|
758703 | switch(phaseIdx) |
403 | { | ||
404 | 252901 | case wPhaseIdx: return WettingFluid::viscosity(temperature, pressure); break; | |
405 | 252901 | case nPhaseIdx: return NonwettingFluid::viscosity(temperature, pressure); break; | |
406 | 252901 | case gPhaseIdx: return Gas::viscosity(temperature, pressure); break; | |
407 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
408 | } | ||
409 | } | ||
410 | |||
411 | using Base<Scalar, ThisType>::fugacityCoefficient; | ||
412 | /*! | ||
413 | * \brief Calculate the fugacity coefficient \f$\mathrm{[-]}\f$ of an individual | ||
414 | * component in a fluid phase | ||
415 | * | ||
416 | * The fugacity coefficient \f$\mathrm{\phi^\kappa_\alpha}\f$ is connected to the | ||
417 | * fugacity \f$\mathrm{f^\kappa_\alpha}\f$ and the component's mole | ||
418 | * fraction \f$\mathrm{x^\kappa_\alpha}\f$ by means of the relation | ||
419 | * | ||
420 | * \f[ | ||
421 | f^\kappa_\alpha = \phi^\kappa_\alpha\;x^\kappa_\alpha\;p_\alpha | ||
422 | * \f] | ||
423 | * | ||
424 | * \param fluidState The fluid state of the two-phase model | ||
425 | * \param phaseIdx Index of the fluid phase | ||
426 | * \param compIdx index of the component | ||
427 | */ | ||
428 | template <class FluidState> | ||
429 | 9 | static Scalar fugacityCoefficient(const FluidState &fluidState, | |
430 | int phaseIdx, | ||
431 | int compIdx) | ||
432 | { | ||
433 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
434 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
|
9 | assert(0 <= compIdx && compIdx < numComponents); |
435 | |||
436 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
|
9 | if (phaseIdx == compIdx) |
437 | // We could calculate the real fugacity coefficient of | ||
438 | // the component in the fluid. Probably that's not worth | ||
439 | // the effort, since the fugacity coefficient of the other | ||
440 | // component is infinite anyway... | ||
441 | 3 | return 1.0; | |
442 | return std::numeric_limits<Scalar>::infinity(); | ||
443 | } | ||
444 | |||
445 | using Base<Scalar, ThisType>::diffusionCoefficient; | ||
446 | /*! | ||
447 | * \brief Calculate the binary molecular diffusion coefficient for | ||
448 | * a component in a fluid phase \f$\mathrm{[mol^2 * s / (kg*m^3)]}\f$ | ||
449 | * \param fluidState The fluid state of the two-phase model | ||
450 | * \param phaseIdx Index of the fluid phase | ||
451 | * \param compIdx index of the component | ||
452 | * | ||
453 | * Molecular diffusion of a component \f$\mathrm{\kappa}\f$ is caused by a | ||
454 | * gradient of the chemical potential and follows the law | ||
455 | * | ||
456 | * \f[ J = - D \nabla \mu_\kappa \f] | ||
457 | * | ||
458 | * where \f$\mathrm{\mu_\kappa]}\f$ is the component's chemical potential, | ||
459 | * \f$\mathrm{D}\f$ is the diffusion coefficient and \f$\mathrm{J}\f$ is the | ||
460 | * diffusive flux. \f$\mathrm{\mu_\kappa}\f$ is connected to the component's | ||
461 | * fugacity \f$\mathrm{f_\kappa}\f$ by the relation | ||
462 | * | ||
463 | * \f[ \mu_\kappa = R T_\alpha \mathrm{ln} \frac{f_\kappa}{p_\alpha} \f] | ||
464 | * | ||
465 | * where \f$\mathrm{p_\alpha}\f$ and \f$\mathrm{T_\alpha}\f$ are the fluid phase' | ||
466 | * pressure and temperature. | ||
467 | */ | ||
468 | template <class FluidState> | ||
469 | 9 | static Scalar diffusionCoefficient(const FluidState &fluidState, | |
470 | int phaseIdx, | ||
471 | int compIdx) | ||
472 | { | ||
473 |
10/20✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 9 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 9 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 9 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 9 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 9 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 9 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 9 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 9 times.
✗ Branch 29 not taken.
|
36 | DUNE_THROW(Dune::InvalidStateException, |
474 | "Diffusion coefficients of components are meaningless if" | ||
475 | " immiscibility is assumed"); | ||
476 | } | ||
477 | |||
478 | using Base<Scalar, ThisType>::binaryDiffusionCoefficient; | ||
479 | /*! | ||
480 | * \brief Given a phase's composition, temperature and pressure, | ||
481 | * return the binary diffusion coefficient \f$\mathrm{[m^2/s]}\f$ for components | ||
482 | * \f$\mathrm{i}\f$ and \f$\mathrm{j}\f$ in this phase. | ||
483 | * \param fluidState The fluid state of the two-phase model | ||
484 | * \param phaseIdx Index of the fluid phase | ||
485 | * \param compIIdx index of the component i | ||
486 | * \param compJIdx index of the component j | ||
487 | */ | ||
488 | template <class FluidState> | ||
489 | 27 | static Scalar binaryDiffusionCoefficient(const FluidState &fluidState, | |
490 | int phaseIdx, | ||
491 | int compIIdx, | ||
492 | int compJIdx) | ||
493 | |||
494 | { | ||
495 |
10/20✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 27 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 27 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 27 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 27 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 27 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 27 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 27 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 27 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 27 times.
✗ Branch 29 not taken.
|
108 | DUNE_THROW(Dune::InvalidStateException, |
496 | "Binary diffusion coefficients of components are meaningless if" | ||
497 | " immiscibility is assumed"); | ||
498 | } | ||
499 | |||
500 | using Base<Scalar, ThisType>::enthalpy; | ||
501 | /*! | ||
502 | * \brief Return the specific enthalpy of a fluid phase \f$\mathrm{[J/kg]}\f$. | ||
503 | * \param fluidState The fluid state of the two-phase model | ||
504 | * \param phaseIdx Index of the fluid phase | ||
505 | */ | ||
506 | template <class FluidState> | ||
507 | 3 | static Scalar enthalpy(const FluidState &fluidState, | |
508 | int phaseIdx) | ||
509 | { | ||
510 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
511 | |||
512 | 3 | Scalar temperature = fluidState.temperature(phaseIdx); | |
513 | 3 | Scalar pressure = fluidState.pressure(phaseIdx); | |
514 | |||
515 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
3 | switch(phaseIdx) |
516 | { | ||
517 | 1 | case wPhaseIdx: return WettingFluid::enthalpy(temperature, pressure); break; | |
518 | 1 | case nPhaseIdx: return NonwettingFluid::enthalpy(temperature, pressure); break; | |
519 | 1 | case gPhaseIdx: return Gas::enthalpy(temperature, pressure); break; | |
520 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
521 | } | ||
522 | } | ||
523 | |||
524 | using Base<Scalar, ThisType>::thermalConductivity; | ||
525 | /*! | ||
526 | * \brief Thermal conductivity of a fluid phase \f$\mathrm{[W/(m K)]}\f$. | ||
527 | * \param fluidState The fluid state of the two-phase model | ||
528 | * \param phaseIdx Index of the fluid phase | ||
529 | */ | ||
530 | template <class FluidState> | ||
531 | 3 | static Scalar thermalConductivity(const FluidState &fluidState, | |
532 | int phaseIdx) | ||
533 | { | ||
534 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
535 | |||
536 | 3 | Scalar temperature = fluidState.temperature(phaseIdx); | |
537 | 3 | Scalar pressure = fluidState.pressure(phaseIdx); | |
538 | |||
539 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
3 | switch(phaseIdx) |
540 | { | ||
541 | 1 | case wPhaseIdx: return WettingFluid::thermalConductivity(temperature, pressure); break; | |
542 | 1 | case nPhaseIdx: return NonwettingFluid::thermalConductivity(temperature, pressure); break; | |
543 | 1 | case gPhaseIdx: return Gas::thermalConductivity(temperature, pressure); break; | |
544 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | using Base<Scalar, ThisType>::heatCapacity; | ||
549 | /*! | ||
550 | * @copybrief Base::thermalConductivity | ||
551 | * | ||
552 | * Additional comments: | ||
553 | * | ||
554 | * Specific isobaric heat capacity of a fluid phase. | ||
555 | * \f$\mathrm{[J/(kg*K)]}\f$. | ||
556 | * | ||
557 | * \param fluidState The fluid state of the two-phase model | ||
558 | * \param phaseIdx for which phase to give back the heat capacity | ||
559 | */ | ||
560 | template <class FluidState> | ||
561 | 3 | static Scalar heatCapacity(const FluidState &fluidState, | |
562 | int phaseIdx) | ||
563 | { | ||
564 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | assert(0 <= phaseIdx && phaseIdx < numPhases); |
565 | |||
566 | 3 | Scalar temperature = fluidState.temperature(phaseIdx); | |
567 | 3 | Scalar pressure = fluidState.pressure(phaseIdx); | |
568 | |||
569 |
3/3✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
|
3 | switch(phaseIdx) |
570 | { | ||
571 | 1 | case wPhaseIdx: return WettingFluid::heatCapacity(temperature, pressure); break; | |
572 | 1 | case nPhaseIdx: return NonwettingFluid::heatCapacity(temperature, pressure); break; | |
573 | 1 | case gPhaseIdx: return Gas::heatCapacity(temperature, pressure); break; | |
574 | default: DUNE_THROW(Dune::InvalidStateException, "Invalid phase index"); | ||
575 | } | ||
576 | } | ||
577 | }; | ||
578 | |||
579 | } // end namespace Dumux::FluidSystems | ||
580 | |||
581 | #endif | ||
582 |