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 ThreePThreeCModel | ||
10 | * \brief Contains the quantities which are constant within a | ||
11 | * finite volume in the three-phase three-component model. | ||
12 | */ | ||
13 | #ifndef DUMUX_3P3C_VOLUME_VARIABLES_HH | ||
14 | #define DUMUX_3P3C_VOLUME_VARIABLES_HH | ||
15 | |||
16 | #include <dumux/material/constants.hh> | ||
17 | #include <dumux/material/fluidstates/compositional.hh> | ||
18 | #include <dumux/material/constraintsolvers/computefromreferencephase.hh> | ||
19 | #include <dumux/material/constraintsolvers/misciblemultiphasecomposition.hh> | ||
20 | |||
21 | #include <dumux/porousmediumflow/volumevariables.hh> | ||
22 | #include <dumux/porousmediumflow/nonisothermal/volumevariables.hh> | ||
23 | #include <dumux/material/solidstates/updatesolidvolumefractions.hh> | ||
24 | #include <dumux/common/optionalscalar.hh> | ||
25 | |||
26 | #include "primaryvariableswitch.hh" | ||
27 | |||
28 | namespace Dumux { | ||
29 | |||
30 | namespace Detail { | ||
31 | // helper struct and function detecting if the fluid matrix interaction features a adsorptionModel() function | ||
32 | template <class FluidMatrixInteraction> | ||
33 | using AdsorptionModelDetector = decltype(std::declval<FluidMatrixInteraction>().adsorptionModel()); | ||
34 | |||
35 | template<class FluidMatrixInteraction> | ||
36 | static constexpr bool hasAdsorptionModel() | ||
37 | { return Dune::Std::is_detected<AdsorptionModelDetector, FluidMatrixInteraction>::value; } | ||
38 | |||
39 | } | ||
40 | |||
41 | /*! | ||
42 | * \ingroup ThreePThreeCModel | ||
43 | * \brief Contains the quantities which are are constant within a | ||
44 | * finite volume in the three-phase three-component model. | ||
45 | */ | ||
46 | template <class Traits> | ||
47 | 2048886 | class ThreePThreeCVolumeVariables | |
48 | : public PorousMediumFlowVolumeVariables<Traits> | ||
49 | , public EnergyVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits> > | ||
50 | { | ||
51 | using ParentType = PorousMediumFlowVolumeVariables<Traits>; | ||
52 | using EnergyVolVars = EnergyVolumeVariables<Traits, ThreePThreeCVolumeVariables<Traits> >; | ||
53 | |||
54 | using Scalar = typename Traits::PrimaryVariables::value_type; | ||
55 | using PermeabilityType = typename Traits::PermeabilityType; | ||
56 | |||
57 | using FS = typename Traits::FluidSystem; | ||
58 | using MiscibleMultiPhaseComposition = Dumux::MiscibleMultiPhaseComposition<Scalar, FS>; | ||
59 | using ComputeFromReferencePhase = Dumux::ComputeFromReferencePhase<Scalar, FS>; | ||
60 | |||
61 | using ModelTraits = typename Traits::ModelTraits; | ||
62 | using Idx = typename ModelTraits::Indices; | ||
63 | static constexpr int numFluidComps = ParentType::numFluidComponents(); | ||
64 | enum { | ||
65 | wCompIdx = FS::wCompIdx, | ||
66 | gCompIdx = FS::gCompIdx, | ||
67 | nCompIdx = FS::nCompIdx, | ||
68 | |||
69 | wPhaseIdx = FS::wPhaseIdx, | ||
70 | gPhaseIdx = FS::gPhaseIdx, | ||
71 | nPhaseIdx = FS::nPhaseIdx, | ||
72 | |||
73 | switch1Idx = Idx::switch1Idx, | ||
74 | switch2Idx = Idx::switch2Idx, | ||
75 | pressureIdx = Idx::pressureIdx | ||
76 | }; | ||
77 | |||
78 | // present phases | ||
79 | enum { | ||
80 | threePhases = Idx::threePhases, | ||
81 | wPhaseOnly = Idx::wPhaseOnly, | ||
82 | gnPhaseOnly = Idx::gnPhaseOnly, | ||
83 | wnPhaseOnly = Idx::wnPhaseOnly, | ||
84 | gPhaseOnly = Idx::gPhaseOnly, | ||
85 | wgPhaseOnly = Idx::wgPhaseOnly | ||
86 | }; | ||
87 | |||
88 | using EffDiffModel = typename Traits::EffectiveDiffusivityModel; | ||
89 | using DiffusionCoefficients = typename Traits::DiffusionType::DiffusionCoefficientsContainer; | ||
90 | |||
91 | public: | ||
92 | //! export fluid state type | ||
93 | using FluidState = typename Traits::FluidState; | ||
94 | //! export fluid system type | ||
95 | using FluidSystem = typename Traits::FluidSystem; | ||
96 | //! export the indices | ||
97 | using Indices = typename ModelTraits::Indices; | ||
98 | //! export type of solid state | ||
99 | using SolidState = typename Traits::SolidState; | ||
100 | //! export type of solid system | ||
101 | using SolidSystem = typename Traits::SolidSystem; | ||
102 | //! export the primary variable switch | ||
103 | using PrimaryVariableSwitch = ThreePThreeCPrimaryVariableSwitch; | ||
104 | |||
105 | /*! | ||
106 | * \brief Update all quantities for a given control volume | ||
107 | * | ||
108 | * \param elemSol A vector containing all primary variables connected to the element | ||
109 | * \param problem The object specifying the problem which ought to | ||
110 | * be simulated | ||
111 | * \param element An element which contains part of the control volume | ||
112 | * \param scv The sub control volume | ||
113 | */ | ||
114 | template<class ElemSol, class Problem, class Element, class Scv> | ||
115 | 4678725 | void update(const ElemSol &elemSol, | |
116 | const Problem &problem, | ||
117 | const Element &element, | ||
118 | const Scv& scv) | ||
119 | { | ||
120 | 4678725 | ParentType::update(elemSol, problem, element, scv); | |
121 | 4678725 | const auto& priVars = elemSol[scv.localDofIndex()]; | |
122 | 4678725 | const auto phasePresence = priVars.state(); | |
123 | |||
124 | 4475850 | constexpr bool useConstraintSolver = ModelTraits::useConstraintSolver(); | |
125 | |||
126 | 4678725 | EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_); | |
127 | |||
128 | /* first the saturations */ | ||
129 |
2/2✓ Branch 0 taken 3496302 times.
✓ Branch 1 taken 1182423 times.
|
4678725 | if (phasePresence == threePhases) |
130 | { | ||
131 | 3496302 | sw_ = priVars[switch1Idx]; | |
132 | 3496302 | sn_ = priVars[switch2Idx]; | |
133 | 3496302 | sg_ = 1. - sw_ - sn_; | |
134 | } | ||
135 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == wPhaseOnly) |
136 | { | ||
137 | ✗ | sw_ = 1.; | |
138 | ✗ | sn_ = 0.; | |
139 | ✗ | sg_ = 0.; | |
140 | } | ||
141 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == gnPhaseOnly) |
142 | { | ||
143 | ✗ | sw_ = 0.; | |
144 | ✗ | sn_ = priVars[switch2Idx]; | |
145 | ✗ | sg_ = 1. - sn_; | |
146 | } | ||
147 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == wnPhaseOnly) |
148 | { | ||
149 | ✗ | sn_ = priVars[switch2Idx]; | |
150 | ✗ | sw_ = 1. - sn_; | |
151 | ✗ | sg_ = 0.; | |
152 | } | ||
153 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == gPhaseOnly) |
154 | { | ||
155 | ✗ | sw_ = 0.; | |
156 | ✗ | sn_ = 0.; | |
157 | ✗ | sg_ = 1.; | |
158 | } | ||
159 |
1/2✓ Branch 0 taken 1182423 times.
✗ Branch 1 not taken.
|
1182423 | else if (phasePresence == wgPhaseOnly) |
160 | { | ||
161 | 1182423 | sw_ = priVars[switch1Idx]; | |
162 | 1182423 | sn_ = 0.; | |
163 | 1182423 | sg_ = 1. - sw_; | |
164 | } | ||
165 | else | ||
166 | ✗ | DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); | |
167 | |||
168 |
2/2✓ Branch 0 taken 1207452 times.
✓ Branch 1 taken 3268398 times.
|
4678725 | fluidState_.setSaturation(wPhaseIdx, sw_); |
169 |
2/2✓ Branch 0 taken 1207452 times.
✓ Branch 1 taken 3268398 times.
|
4678725 | fluidState_.setSaturation(gPhaseIdx, sg_); |
170 |
2/2✓ Branch 0 taken 1207452 times.
✓ Branch 1 taken 3268398 times.
|
4678725 | fluidState_.setSaturation(nPhaseIdx, sn_); |
171 | |||
172 | /* now the pressures */ | ||
173 |
2/2✓ Branch 0 taken 1207452 times.
✓ Branch 1 taken 3268398 times.
|
4678725 | pg_ = priVars[pressureIdx]; |
174 | |||
175 | // calculate capillary pressures | ||
176 | |||
177 |
4/4✓ Branch 0 taken 1207452 times.
✓ Branch 1 taken 3268398 times.
✓ Branch 2 taken 1207452 times.
✓ Branch 3 taken 3268398 times.
|
9357450 | const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol); |
178 | 4678725 | Scalar pcgw = fluidMatrixInteraction.pcgw(sw_, sn_); | |
179 | 4678725 | Scalar pcnw = fluidMatrixInteraction.pcnw(sw_, sn_); | |
180 | 4678725 | Scalar pcgn = fluidMatrixInteraction.pcgn(sw_, sn_); | |
181 | |||
182 |
2/2✓ Branch 0 taken 3646834 times.
✓ Branch 1 taken 1031891 times.
|
4678725 | const Scalar pcAlpha = fluidMatrixInteraction.pcAlpha(sw_, sn_); |
183 | 4678725 | const Scalar pcNW1 = 0.0; // TODO: this should be possible to assign in the problem file | |
184 | |||
185 | 4678725 | pn_ = pg_- pcAlpha * pcgn - (1.-pcAlpha)*(pcgw - pcNW1); | |
186 | 4678725 | pw_ = pn_ - pcAlpha * pcnw - (1.-pcAlpha)*pcNW1; | |
187 | |||
188 | 4678725 | fluidState_.setPressure(wPhaseIdx, pw_); | |
189 | 4678725 | fluidState_.setPressure(gPhaseIdx, pg_); | |
190 | 4678725 | fluidState_.setPressure(nPhaseIdx, pn_); | |
191 | |||
192 | // calculate and set all fugacity coefficients. this is | ||
193 | // possible because we require all phases to be an ideal | ||
194 | // mixture, i.e. fugacity coefficients are not supposed to | ||
195 | // depend on composition! | ||
196 | typename FluidSystem::ParameterCache paramCache; | ||
197 | // assert(FluidSystem::isIdealGas(gPhaseIdx)); | ||
198 |
2/2✓ Branch 0 taken 14036175 times.
✓ Branch 1 taken 4678725 times.
|
18714900 | for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++ phaseIdx) { |
199 | assert(FluidSystem::isIdealMixture(phaseIdx)); | ||
200 | |||
201 |
2/2✓ Branch 0 taken 42108525 times.
✓ Branch 1 taken 14036175 times.
|
56144700 | for (int compIdx = 0; compIdx < ModelTraits::numFluidComponents(); ++ compIdx) { |
202 | 42108525 | Scalar phi = FluidSystem::fugacityCoefficient(fluidState_, paramCache, phaseIdx, compIdx); | |
203 | 84217050 | fluidState_.setFugacityCoefficient(phaseIdx, compIdx, phi); | |
204 | } | ||
205 | } | ||
206 | |||
207 | // now comes the tricky part: calculate phase composition | ||
208 |
2/2✓ Branch 0 taken 3496302 times.
✓ Branch 1 taken 1182423 times.
|
4678725 | if (phasePresence == threePhases) { |
209 | // all phases are present, phase compositions are a | ||
210 | // result of the the gas <-> liquid equilibrium. This is | ||
211 | // the job of the "MiscibleMultiPhaseComposition" | ||
212 | // constraint solver ... | ||
213 | if (useConstraintSolver) { | ||
214 | MiscibleMultiPhaseComposition::solve(fluidState_, | ||
215 | paramCache); | ||
216 | } | ||
217 | // ... or calculated explicitly this way ... | ||
218 | // please note that we experienced some problems with un-regularized | ||
219 | // partial pressures due to their calculation from fugacity coefficients - | ||
220 | // that's why they are regularized below "within physically meaningful bounds" | ||
221 | else { | ||
222 | 3496302 | Scalar partPressH2O = FluidSystem::fugacityCoefficient(fluidState_, | |
223 | wPhaseIdx, | ||
224 | 3496302 | wCompIdx) * pw_; | |
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3496302 times.
|
3496302 | if (partPressH2O > pg_) partPressH2O = pg_; |
226 | 3496302 | Scalar partPressNAPL = FluidSystem::fugacityCoefficient(fluidState_, | |
227 | nPhaseIdx, | ||
228 | 3496302 | nCompIdx) * pn_; | |
229 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3496302 times.
|
3496302 | if (partPressNAPL > pg_) partPressNAPL = pg_; |
230 | 3496302 | Scalar partPressAir = pg_ - partPressH2O - partPressNAPL; | |
231 | |||
232 | 3496302 | Scalar xgn = partPressNAPL/pg_; | |
233 | 3496302 | Scalar xgw = partPressH2O/pg_; | |
234 | 3496302 | Scalar xgg = partPressAir/pg_; | |
235 | |||
236 | // actually, it's nothing else than Henry coefficient | ||
237 | 3496302 | Scalar xwn = partPressNAPL | |
238 | 3496302 | / (FluidSystem::fugacityCoefficient(fluidState_, | |
239 | wPhaseIdx,nCompIdx) | ||
240 | 3496302 | * pw_); | |
241 | 3496302 | Scalar xwg = partPressAir | |
242 | 3496302 | / (FluidSystem::fugacityCoefficient(fluidState_, | |
243 | wPhaseIdx,gCompIdx) | ||
244 | 3496302 | * pw_); | |
245 | 3496302 | Scalar xww = 1.-xwg-xwn; | |
246 | |||
247 | 3496302 | Scalar xnn = 1.-2.e-10; | |
248 | 3496302 | Scalar xna = 1.e-10; | |
249 | 3496302 | Scalar xnw = 1.e-10; | |
250 | |||
251 | 3496302 | fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); | |
252 | 3496302 | fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); | |
253 | 3496302 | fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); | |
254 | 3496302 | fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); | |
255 | 3496302 | fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); | |
256 | 3496302 | fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); | |
257 | 3496302 | fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); | |
258 | 3496302 | fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); | |
259 | 3496302 | fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); | |
260 | |||
261 | 3496302 | Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); | |
262 | 3496302 | Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); | |
263 | 3496302 | Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); | |
264 | 3496302 | Scalar rhoWMolar = FluidSystem::molarDensity(fluidState_, wPhaseIdx); | |
265 | 3496302 | Scalar rhoGMolar = FluidSystem::molarDensity(fluidState_, gPhaseIdx); | |
266 | 3496302 | Scalar rhoNMolar = FluidSystem::molarDensity(fluidState_, nPhaseIdx); | |
267 | |||
268 | 3496302 | fluidState_.setDensity(wPhaseIdx, rhoW); | |
269 | 3496302 | fluidState_.setDensity(gPhaseIdx, rhoG); | |
270 | 3496302 | fluidState_.setDensity(nPhaseIdx, rhoN); | |
271 | 3496302 | fluidState_.setMolarDensity(wPhaseIdx, rhoWMolar); | |
272 | 3496302 | fluidState_.setMolarDensity(gPhaseIdx, rhoGMolar); | |
273 | 3496302 | fluidState_.setMolarDensity(nPhaseIdx, rhoNMolar); | |
274 | } | ||
275 | } | ||
276 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == wPhaseOnly) { |
277 | // only the water phase is present, water phase composition is | ||
278 | // stored explicitly. | ||
279 | |||
280 | // extract mole fractions in the water phase | ||
281 | ✗ | Scalar xwg = priVars[switch1Idx]; | |
282 | ✗ | Scalar xwn = priVars[switch2Idx]; | |
283 | ✗ | Scalar xww = 1 - xwg - xwn; | |
284 | |||
285 | // write water mole fractions in the fluid state | ||
286 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); | |
287 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); | |
288 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); | |
289 | |||
290 | // calculate the composition of the remaining phases (as | ||
291 | // well as the densities of all phases). this is the job | ||
292 | // of the "ComputeFromReferencePhase" constraint solver ... | ||
293 | if (useConstraintSolver) | ||
294 | { | ||
295 | ComputeFromReferencePhase::solve(fluidState_, | ||
296 | paramCache, | ||
297 | wPhaseIdx); | ||
298 | } | ||
299 | // ... or calculated explicitly this way ... | ||
300 | else { | ||
301 | // note that the gas phase is actually not existing! | ||
302 | // thus, this is used as phase switch criterion | ||
303 | ✗ | Scalar xgg = xwg * FluidSystem::fugacityCoefficient(fluidState_, | |
304 | wPhaseIdx,gCompIdx) | ||
305 | ✗ | * pw_ / pg_; | |
306 | ✗ | Scalar xgn = xwn * FluidSystem::fugacityCoefficient(fluidState_, | |
307 | wPhaseIdx,nCompIdx) | ||
308 | ✗ | * pw_ / pg_; | |
309 | ✗ | Scalar xgw = FluidSystem::fugacityCoefficient(fluidState_, | |
310 | wPhaseIdx,wCompIdx) | ||
311 | ✗ | * pw_ / pg_; | |
312 | |||
313 | |||
314 | // note that the gas phase is actually not existing! | ||
315 | // thus, this is used as phase switch criterion | ||
316 | ✗ | Scalar xnn = xwn * FluidSystem::fugacityCoefficient(fluidState_, | |
317 | wPhaseIdx,nCompIdx) | ||
318 | ✗ | * pw_; | |
319 | ✗ | Scalar xna = 1.e-10; | |
320 | ✗ | Scalar xnw = 1.e-10; | |
321 | |||
322 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); | |
323 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); | |
324 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); | |
325 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); | |
326 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); | |
327 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); | |
328 | |||
329 | ✗ | Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); | |
330 | ✗ | Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); | |
331 | ✗ | Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); | |
332 | ✗ | Scalar rhoWMolar = FluidSystem::molarDensity(fluidState_, wPhaseIdx); | |
333 | ✗ | Scalar rhoGMolar = FluidSystem::molarDensity(fluidState_, gPhaseIdx); | |
334 | ✗ | Scalar rhoNMolar = FluidSystem::molarDensity(fluidState_, nPhaseIdx); | |
335 | |||
336 | ✗ | fluidState_.setDensity(wPhaseIdx, rhoW); | |
337 | ✗ | fluidState_.setDensity(gPhaseIdx, rhoG); | |
338 | ✗ | fluidState_.setDensity(nPhaseIdx, rhoN); | |
339 | ✗ | fluidState_.setMolarDensity(wPhaseIdx, rhoWMolar); | |
340 | ✗ | fluidState_.setMolarDensity(gPhaseIdx, rhoGMolar); | |
341 | ✗ | fluidState_.setMolarDensity(nPhaseIdx, rhoNMolar); | |
342 | } | ||
343 | } | ||
344 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == gnPhaseOnly) { |
345 | // only gas and NAPL phases are present | ||
346 | // we have all (partly hypothetical) phase pressures | ||
347 | // and temperature and the mole fraction of water in | ||
348 | // the gas phase | ||
349 | |||
350 | // we have all (partly hypothetical) phase pressures | ||
351 | // and temperature and the mole fraction of water in | ||
352 | // the gas phase | ||
353 | ✗ | Scalar partPressNAPL = fluidState_.fugacityCoefficient(nPhaseIdx, nCompIdx)*pn_; | |
354 | ✗ | if (partPressNAPL > pg_) partPressNAPL = pg_; | |
355 | |||
356 | ✗ | Scalar xgw = priVars[switch1Idx]; | |
357 | ✗ | Scalar xgn = partPressNAPL/pg_; | |
358 | ✗ | Scalar xgg = 1.-xgw-xgn; | |
359 | |||
360 | // write mole fractions in the fluid state | ||
361 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); | |
362 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); | |
363 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); | |
364 | |||
365 | // calculate the composition of the remaining phases (as | ||
366 | // well as the densities of all phases). this is the job | ||
367 | // of the "ComputeFromReferencePhase" constraint solver | ||
368 | ✗ | ComputeFromReferencePhase::solve(fluidState_, | |
369 | paramCache, | ||
370 | gPhaseIdx); | ||
371 | } | ||
372 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == wnPhaseOnly) { |
373 | // only water and NAPL phases are present | ||
374 | ✗ | Scalar partPressNAPL = fluidState_.fugacityCoefficient(nPhaseIdx,nCompIdx)*pn_; | |
375 | ✗ | if (partPressNAPL > pg_) partPressNAPL = pg_; | |
376 | ✗ | Scalar henryC = fluidState_.fugacityCoefficient(wPhaseIdx,nCompIdx)*pw_; | |
377 | |||
378 | ✗ | Scalar xwg = priVars[switch1Idx]; | |
379 | ✗ | Scalar xwn = partPressNAPL/henryC; | |
380 | ✗ | Scalar xww = 1.-xwg-xwn; | |
381 | |||
382 | // write mole fractions in the fluid state | ||
383 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); | |
384 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); | |
385 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); | |
386 | |||
387 | // calculate the composition of the remaining phases (as | ||
388 | // well as the densities of all phases). this is the job | ||
389 | // of the "ComputeFromReferencePhase" constraint solver | ||
390 | ✗ | ComputeFromReferencePhase::solve(fluidState_, | |
391 | paramCache, | ||
392 | wPhaseIdx); | ||
393 | } | ||
394 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | else if (phasePresence == gPhaseOnly) { |
395 | // only the gas phase is present, gas phase composition is | ||
396 | // stored explicitly here below. | ||
397 | |||
398 | ✗ | const Scalar xgw = priVars[switch1Idx]; | |
399 | ✗ | const Scalar xgn = priVars[switch2Idx]; | |
400 | ✗ | Scalar xgg = 1 - xgw - xgn; | |
401 | |||
402 | // write mole fractions in the fluid state | ||
403 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); | |
404 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); | |
405 | ✗ | fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); | |
406 | |||
407 | // calculate the composition of the remaining phases (as | ||
408 | // well as the densities of all phases). this is the job | ||
409 | // of the "ComputeFromReferencePhase" constraint solver ... | ||
410 | if (useConstraintSolver) | ||
411 | { | ||
412 | ComputeFromReferencePhase::solve(fluidState_, | ||
413 | paramCache, | ||
414 | gPhaseIdx); | ||
415 | } | ||
416 | // ... or calculated explicitly this way ... | ||
417 | else { | ||
418 | |||
419 | // note that the water phase is actually not existing! | ||
420 | // thus, this is used as phase switch criterion | ||
421 | ✗ | Scalar xww = xgw * pg_ | |
422 | ✗ | / (FluidSystem::fugacityCoefficient(fluidState_, | |
423 | wPhaseIdx,wCompIdx) | ||
424 | ✗ | * pw_); | |
425 | ✗ | Scalar xwn = 1.e-10; | |
426 | ✗ | Scalar xwg = 1.e-10; | |
427 | |||
428 | // note that the NAPL phase is actually not existing! | ||
429 | // thus, this is used as phase switch criterion | ||
430 | ✗ | Scalar xnn = xgn * pg_ | |
431 | ✗ | / (FluidSystem::fugacityCoefficient(fluidState_, | |
432 | nPhaseIdx,nCompIdx) | ||
433 | ✗ | * pn_); | |
434 | ✗ | Scalar xna = 1.e-10; | |
435 | ✗ | Scalar xnw = 1.e-10; | |
436 | |||
437 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); | |
438 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); | |
439 | ✗ | fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); | |
440 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); | |
441 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); | |
442 | ✗ | fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); | |
443 | |||
444 | ✗ | Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); | |
445 | ✗ | Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); | |
446 | ✗ | Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); | |
447 | ✗ | Scalar rhoWMolar = FluidSystem::molarDensity(fluidState_, wPhaseIdx); | |
448 | ✗ | Scalar rhoGMolar = FluidSystem::molarDensity(fluidState_, gPhaseIdx); | |
449 | ✗ | Scalar rhoNMolar = FluidSystem::molarDensity(fluidState_, nPhaseIdx); | |
450 | |||
451 | ✗ | fluidState_.setDensity(wPhaseIdx, rhoW); | |
452 | ✗ | fluidState_.setDensity(gPhaseIdx, rhoG); | |
453 | ✗ | fluidState_.setDensity(nPhaseIdx, rhoN); | |
454 | ✗ | fluidState_.setMolarDensity(wPhaseIdx, rhoWMolar); | |
455 | ✗ | fluidState_.setMolarDensity(gPhaseIdx, rhoGMolar); | |
456 | ✗ | fluidState_.setMolarDensity(nPhaseIdx, rhoNMolar); | |
457 | } | ||
458 | } | ||
459 |
1/2✓ Branch 0 taken 1182423 times.
✗ Branch 1 not taken.
|
1182423 | else if (phasePresence == wgPhaseOnly) { |
460 | // only water and gas phases are present | ||
461 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | Scalar xgn = priVars[switch2Idx]; |
462 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | Scalar partPressH2O = fluidState_.fugacityCoefficient(wPhaseIdx, wCompIdx)*pw_; |
463 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1182423 times.
|
1182423 | if (partPressH2O > pg_) partPressH2O = pg_; |
464 | |||
465 | 1182423 | Scalar xgw = partPressH2O/pg_; | |
466 | 1182423 | Scalar xgg = 1.-xgn-xgw; | |
467 | |||
468 | // write mole fractions in the fluid state | ||
469 | 1182423 | fluidState_.setMoleFraction(gPhaseIdx, wCompIdx, xgw); | |
470 | 1182423 | fluidState_.setMoleFraction(gPhaseIdx, gCompIdx, xgg); | |
471 | 1182423 | fluidState_.setMoleFraction(gPhaseIdx, nCompIdx, xgn); | |
472 | |||
473 | // calculate the composition of the remaining phases (as | ||
474 | // well as the densities of all phases). this is the job | ||
475 | // of the "ComputeFromReferencePhase" constraint solver ... | ||
476 | if (useConstraintSolver) | ||
477 | { | ||
478 | ComputeFromReferencePhase::solve(fluidState_, | ||
479 | paramCache, | ||
480 | gPhaseIdx); | ||
481 | } | ||
482 | // ... or calculated explicitly this way ... | ||
483 | else { | ||
484 | // actually, it's nothing else than Henry coefficient | ||
485 | 2364846 | Scalar xwn = xgn * pg_ | |
486 | 1182423 | / (FluidSystem::fugacityCoefficient(fluidState_, | |
487 | wPhaseIdx,nCompIdx) | ||
488 | 1182423 | * pw_); | |
489 | 2364846 | Scalar xwg = xgg * pg_ | |
490 | 1182423 | / (FluidSystem::fugacityCoefficient(fluidState_, | |
491 | wPhaseIdx,gCompIdx) | ||
492 | 1182423 | * pw_); | |
493 | 1182423 | Scalar xww = 1.-xwg-xwn; | |
494 | |||
495 | // note that the NAPL phase is actually not existing! | ||
496 | // thus, this is used as phase switch criterion | ||
497 | 2364846 | Scalar xnn = xgn * pg_ | |
498 | 1182423 | / (FluidSystem::fugacityCoefficient(fluidState_, | |
499 | nPhaseIdx,nCompIdx) | ||
500 | 1182423 | * pn_); | |
501 | 1182423 | Scalar xna = 1.e-10; | |
502 | 1182423 | Scalar xnw = 1.e-10; | |
503 | |||
504 | 1182423 | fluidState_.setMoleFraction(wPhaseIdx, wCompIdx, xww); | |
505 | 1182423 | fluidState_.setMoleFraction(wPhaseIdx, gCompIdx, xwg); | |
506 | 1182423 | fluidState_.setMoleFraction(wPhaseIdx, nCompIdx, xwn); | |
507 | 1182423 | fluidState_.setMoleFraction(nPhaseIdx, wCompIdx, xnw); | |
508 | 1182423 | fluidState_.setMoleFraction(nPhaseIdx, gCompIdx, xna); | |
509 | 1182423 | fluidState_.setMoleFraction(nPhaseIdx, nCompIdx, xnn); | |
510 | |||
511 | 1182423 | Scalar rhoW = FluidSystem::density(fluidState_, wPhaseIdx); | |
512 | 1182423 | Scalar rhoG = FluidSystem::density(fluidState_, gPhaseIdx); | |
513 | 1182423 | Scalar rhoN = FluidSystem::density(fluidState_, nPhaseIdx); | |
514 | 1182423 | Scalar rhoWMolar = FluidSystem::molarDensity(fluidState_, wPhaseIdx); | |
515 | 1182423 | Scalar rhoGMolar = FluidSystem::molarDensity(fluidState_, gPhaseIdx); | |
516 | 1182423 | Scalar rhoNMolar = FluidSystem::molarDensity(fluidState_, nPhaseIdx); | |
517 | |||
518 | 1182423 | fluidState_.setDensity(wPhaseIdx, rhoW); | |
519 | 1182423 | fluidState_.setDensity(gPhaseIdx, rhoG); | |
520 | 1182423 | fluidState_.setDensity(nPhaseIdx, rhoN); | |
521 | 1182423 | fluidState_.setMolarDensity(wPhaseIdx, rhoWMolar); | |
522 | 1182423 | fluidState_.setMolarDensity(gPhaseIdx, rhoGMolar); | |
523 | 1182423 | fluidState_.setMolarDensity(nPhaseIdx, rhoNMolar); | |
524 | } | ||
525 | } | ||
526 | else | ||
527 | ✗ | DUNE_THROW(Dune::InvalidStateException, "phasePresence: " << phasePresence << " is invalid."); | |
528 | |||
529 |
2/2✓ Branch 0 taken 14036175 times.
✓ Branch 1 taken 4678725 times.
|
18714900 | for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx) |
530 | { | ||
531 | // mobilities | ||
532 | const Scalar mu = | ||
533 | 14036175 | FluidSystem::viscosity(fluidState_, | |
534 | paramCache, | ||
535 | phaseIdx); | ||
536 | 14036175 | fluidState_.setViscosity(phaseIdx,mu); | |
537 | |||
538 | 42108525 | const Scalar kr = fluidMatrixInteraction.kr(phaseIdx, | |
539 | fluidState_.saturation(wPhaseIdx), | ||
540 | fluidState_.saturation(nPhaseIdx)); | ||
541 | 14036175 | mobility_[phaseIdx] = kr / mu; | |
542 | } | ||
543 | |||
544 | // material dependent parameters for NAPL adsorption (only if law is provided) | ||
545 | if constexpr (Detail::hasAdsorptionModel<std::decay_t<decltype(fluidMatrixInteraction)>>()) | ||
546 | 1179193 | bulkDensTimesAdsorpCoeff_ = fluidMatrixInteraction.adsorptionModel().bulkDensTimesAdsorpCoeff(); | |
547 | |||
548 | /* compute the diffusion coefficient | ||
549 | * \note This is the part of the diffusion coefficient determined by the fluid state, e.g. | ||
550 | * important if they are tabularized. In the diffusive flux computation (e.g. Fick's law) | ||
551 | * this gets converted into an efficient coefficient depending on saturation and porosity. | ||
552 | * We can then add a normalized tensorial component | ||
553 | * e.g. obtained from DTI from the spatial params (currently not implemented) | ||
554 | */ | ||
555 | |||
556 | 4678725 | auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx) | |
557 | { | ||
558 | 28072350 | return EffDiffModel::effectiveDiffusionCoefficient(*this, phaseIdx, compIIdx, compJIdx); | |
559 | }; | ||
560 | |||
561 | // porosity & permeabilty | ||
562 | 4678725 | updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps); | |
563 | |||
564 | 4678725 | effectiveDiffCoeff_.update(getEffectiveDiffusionCoefficient); | |
565 | |||
566 | 4678725 | EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_); | |
567 |
4/4✓ Branch 0 taken 3010933 times.
✓ Branch 1 taken 1667792 times.
✓ Branch 2 taken 3010933 times.
✓ Branch 3 taken 1667792 times.
|
9357450 | permeability_ = problem.spatialParams().permeability(element, scv, elemSol); |
568 | 4678725 | EnergyVolVars::updateEffectiveThermalConductivity(); | |
569 | |||
570 | // compute and set the enthalpy | ||
571 |
2/2✓ Branch 0 taken 14036175 times.
✓ Branch 1 taken 4678725 times.
|
18714900 | for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx) |
572 | { | ||
573 | 14036175 | Scalar h = EnergyVolVars::enthalpy(fluidState_, paramCache, phaseIdx); | |
574 | 28072350 | fluidState_.setEnthalpy(phaseIdx, h); | |
575 | } | ||
576 | 4678725 | } | |
577 | |||
578 | /*! | ||
579 | * \brief Returns the phase state for the control volume. | ||
580 | */ | ||
581 | const FluidState &fluidState() const | ||
582 | 148603092 | { return fluidState_; } | |
583 | |||
584 | /*! | ||
585 | * \brief Returns the phase state for the control volume. | ||
586 | */ | ||
587 | const SolidState &solidState() const | ||
588 | 4475850 | { return solidState_; } | |
589 | |||
590 | /*! | ||
591 | * \brief Returns the average molar mass \f$\mathrm{[kg/mol]}\f$ of the fluid phase. | ||
592 | * | ||
593 | * \param phaseIdx The phase index | ||
594 | */ | ||
595 | Scalar averageMolarMass(int phaseIdx) const | ||
596 | { return fluidState_.averageMolarMass(phaseIdx); } | ||
597 | |||
598 | /*! | ||
599 | * \brief Returns the effective saturation of a given phase within | ||
600 | * the control volume. | ||
601 | * | ||
602 | * \param phaseIdx The phase index | ||
603 | */ | ||
604 | Scalar saturation(const int phaseIdx) const | ||
605 |
21/48✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 268 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 268 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 156144 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 156412 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 268 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 156144 times.
✓ Branch 16 taken 14 times.
✓ Branch 17 taken 156398 times.
✓ Branch 18 taken 14 times.
✓ Branch 19 taken 254 times.
✓ Branch 20 taken 9 times.
✓ Branch 21 taken 156135 times.
✓ Branch 22 taken 9 times.
✓ Branch 23 taken 156135 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✓ Branch 35 taken 8127 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 8127 times.
✗ Branch 38 not taken.
✓ Branch 39 taken 34791 times.
✗ Branch 40 not taken.
✓ Branch 41 taken 42918 times.
✗ Branch 42 not taken.
✓ Branch 43 taken 8127 times.
✗ Branch 44 not taken.
✓ Branch 45 taken 34791 times.
✗ Branch 46 not taken.
✓ Branch 47 taken 34791 times.
|
552063494 | { return fluidState_.saturation(phaseIdx); } |
606 | |||
607 | /*! | ||
608 | * \brief Returns the mass fraction of a given component in a | ||
609 | * given phase within the control volume in \f$[-]\f$. | ||
610 | * | ||
611 | * \param phaseIdx The phase index | ||
612 | * \param compIdx The component index | ||
613 | */ | ||
614 | Scalar massFraction(const int phaseIdx, const int compIdx) const | ||
615 | 187190940 | { return fluidState_.massFraction(phaseIdx, compIdx); } | |
616 | |||
617 | /*! | ||
618 | * \brief Returns the mole fraction of a given component in a | ||
619 | * given phase within the control volume in \f$[-]\f$. | ||
620 | * | ||
621 | * \param phaseIdx The phase index | ||
622 | * \param compIdx The component index | ||
623 | */ | ||
624 | Scalar moleFraction(const int phaseIdx, const int compIdx) const | ||
625 |
4/44✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✓ Branch 40 taken 39 times.
✓ Branch 41 taken 42879 times.
✓ Branch 42 taken 39 times.
✓ Branch 43 taken 42879 times.
|
885414262 | { return fluidState_.moleFraction(phaseIdx, compIdx); } |
626 | |||
627 | /*! | ||
628 | * \brief Returns the mass density of a given phase within the | ||
629 | * control volume. | ||
630 | * | ||
631 | * \param phaseIdx The phase index | ||
632 | */ | ||
633 | Scalar density(const int phaseIdx) const | ||
634 | 798739326 | { return fluidState_.density(phaseIdx); } | |
635 | |||
636 | /*! | ||
637 | * \brief Returns the molar density of a given phase within the | ||
638 | * control volume. | ||
639 | * | ||
640 | * \param phaseIdx The phase index | ||
641 | */ | ||
642 | Scalar molarDensity(const int phaseIdx) const | ||
643 | 885328380 | { return fluidState_.molarDensity(phaseIdx); } | |
644 | |||
645 | /*! | ||
646 | * \brief Returns the effective pressure of a given phase within | ||
647 | * the control volume. | ||
648 | * | ||
649 | * \param phaseIdx The phase index | ||
650 | */ | ||
651 | Scalar pressure(const int phaseIdx) const | ||
652 | 294984660 | { return fluidState_.pressure(phaseIdx); } | |
653 | |||
654 | /*! | ||
655 | * \brief Returns temperature inside the sub-control volume. | ||
656 | * | ||
657 | * Note that we assume thermodynamic equilibrium, i.e. the | ||
658 | * temperatures of the rock matrix and of all fluid phases are | ||
659 | * identical. | ||
660 | */ | ||
661 | Scalar temperature() const | ||
662 |
2/4✓ Branch 0 taken 2195127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2195127 times.
✗ Branch 3 not taken.
|
94443228 | { return fluidState_.temperature(/*phaseIdx=*/0); } |
663 | |||
664 | /*! | ||
665 | * \brief Returns the effective mobility of a given phase within | ||
666 | * the control volume. | ||
667 | * | ||
668 | * \param phaseIdx The phase index | ||
669 | */ | ||
670 | Scalar mobility(const int phaseIdx) const | ||
671 | 319953672 | { return mobility_[phaseIdx]; } | |
672 | |||
673 | /*! | ||
674 | * \brief Returns the effective capillary pressure within the control volume. | ||
675 | */ | ||
676 | Scalar capillaryPressure() const | ||
677 | { return fluidState_.capillaryPressure(); } | ||
678 | |||
679 | /*! | ||
680 | * \brief Returns the average porosity within the control volume. | ||
681 | */ | ||
682 | Scalar porosity() const | ||
683 |
0/6✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
542627220 | { return solidState_.porosity(); } |
684 | |||
685 | /*! | ||
686 | * \brief Returns the adsorption information. | ||
687 | */ | ||
688 | Scalar bulkDensTimesAdsorpCoeff() const | ||
689 | { | ||
690 | if (bulkDensTimesAdsorpCoeff_) | ||
691 | return bulkDensTimesAdsorpCoeff_.value(); | ||
692 | else | ||
693 | DUNE_THROW(Dune::NotImplemented, "Your spatialParams do not provide an adsorption model"); | ||
694 | } | ||
695 | |||
696 | /*! | ||
697 | * \brief Returns the average permeability within the control volume in \f$[m^2]\f$. | ||
698 | */ | ||
699 | const PermeabilityType& permeability() const | ||
700 | ✗ | { return permeability_; } | |
701 | |||
702 | /* | ||
703 | * \brief Returns the binary diffusion coefficients for a phase in \f$[m^2/s]\f$. | ||
704 | */ | ||
705 | ✗ | Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const | |
706 | { | ||
707 | typename FluidSystem::ParameterCache paramCache; | ||
708 | ✗ | paramCache.updatePhase(fluidState_, phaseIdx); | |
709 | ✗ | return FluidSystem::diffusionCoefficient(fluidState_, paramCache, phaseIdx, compJIdx); | |
710 | } | ||
711 | |||
712 | /*! | ||
713 | * \brief Returns the effective diffusion coefficients for a phase in \f$[m^2/s]\f$. | ||
714 | */ | ||
715 | Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const | ||
716 | 76038808 | { return effectiveDiffCoeff_(phaseIdx, compIIdx, compJIdx); } | |
717 | |||
718 | protected: | ||
719 | FluidState fluidState_; | ||
720 | SolidState solidState_; | ||
721 | |||
722 | |||
723 | private: | ||
724 | Scalar sw_, sg_, sn_, pg_, pw_, pn_; | ||
725 | |||
726 | Scalar moleFrac_[ModelTraits::numFluidPhases()][ModelTraits::numFluidComponents()]; | ||
727 | Scalar massFrac_[ModelTraits::numFluidPhases()][ModelTraits::numFluidComponents()]; | ||
728 | |||
729 | PermeabilityType permeability_; //!< Effective permeability within the control volume | ||
730 | Scalar mobility_[ModelTraits::numFluidPhases()]; //!< Effective mobility within the control volume | ||
731 | OptionalScalar<Scalar> bulkDensTimesAdsorpCoeff_; //!< the basis for calculating adsorbed NAPL | ||
732 | |||
733 | DiffusionCoefficients effectiveDiffCoeff_; | ||
734 | }; | ||
735 | |||
736 | } // end namespace Dumux | ||
737 | |||
738 | #endif | ||
739 |