version 3.10-dev
porousmediumflow/co2/volumevariables.hh
Go to the documentation of this file.
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//
14#ifndef DUMUX_CO2_VOLUME_VARIABLES_HH
15#define DUMUX_CO2_VOLUME_VARIABLES_HH
16
17#include <array>
18
19#include <dune/common/exceptions.hh>
20
25
27
28namespace Dumux {
29
35template <class Traits>
38, public EnergyVolumeVariables<Traits, TwoPTwoCCO2VolumeVariables<Traits> >
39{
42
43 using Scalar = typename Traits::PrimaryVariables::value_type;
44 using ModelTraits = typename Traits::ModelTraits;
45 static constexpr int numFluidComps = ParentType::numFluidComponents();
46
47 // component indices
48 enum
49 {
50 comp0Idx = Traits::FluidSystem::comp0Idx,
51 comp1Idx = Traits::FluidSystem::comp1Idx,
52 phase0Idx = Traits::FluidSystem::phase0Idx,
53 phase1Idx = Traits::FluidSystem::phase1Idx
54 };
55
56 // phase presence indices
57 enum
58 {
59 firstPhaseOnly = ModelTraits::Indices::firstPhaseOnly,
60 secondPhaseOnly = ModelTraits::Indices::secondPhaseOnly,
61 bothPhases = ModelTraits::Indices::bothPhases
62 };
63
64 // primary variable indices
65 enum
66 {
67 switchIdx = ModelTraits::Indices::switchIdx,
68 pressureIdx = ModelTraits::Indices::pressureIdx
69 };
70
71 // formulation
72 static constexpr auto formulation = ModelTraits::priVarFormulation();
73
74 // type used for the permeability
75 using PermeabilityType = typename Traits::PermeabilityType;
76
77 // type used for the diffusion coefficients
78 using EffDiffModel = typename Traits::EffectiveDiffusivityModel;
79 using DiffusionCoefficients = typename Traits::DiffusionType::DiffusionCoefficientsContainer;
80
81public:
83 using FluidState = typename Traits::FluidState;
85 using FluidSystem = typename Traits::FluidSystem;
87 using Indices = typename ModelTraits::Indices;
89 using SolidState = typename Traits::SolidState;
91 using SolidSystem = typename Traits::SolidSystem;
94
95
97 static constexpr bool useMoles() { return ModelTraits::useMoles(); }
99 static constexpr TwoPFormulation priVarFormulation() { return formulation; }
100
101 // check for permissive combinations
102 static_assert(ModelTraits::numFluidPhases() == 2, "NumPhases set in the model is not two!");
103 static_assert(ModelTraits::numFluidComponents() == 2, "NumComponents set in the model is not two!");
104 static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!");
105
115 template<class ElemSol, class Problem, class Element, class Scv>
116 void update(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv)
117 {
118 ParentType::update(elemSol, problem, element, scv);
119 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
120
121 // Second instance of a parameter cache. Could be avoided if
122 // diffusion coefficients also became part of the fluid state.
123 typename FluidSystem::ParameterCache paramCache;
124 paramCache.updateAll(fluidState_);
125
126 const auto& spatialParams = problem.spatialParams();
127 const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol);
128
129 const int wPhaseIdx = fluidState_.wettingPhase();
130 const int nPhaseIdx = 1 - wPhaseIdx;
131
132 // relative permeabilities -> require wetting phase saturation as parameter!
133 relativePermeability_[wPhaseIdx] = fluidMatrixInteraction.krw(saturation(wPhaseIdx));
134 relativePermeability_[nPhaseIdx] = fluidMatrixInteraction.krn(saturation(wPhaseIdx));
135
136 // porosity & permeabilty
137 updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps);
138 EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_);
139 permeability_ = spatialParams.permeability(element, scv, elemSol);
140
141 auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx)
142 {
143 return EffDiffModel::effectiveDiffusionCoefficient(*this, phaseIdx, compIIdx, compJIdx);
144 };
145
146 effectiveDiffCoeff_.update(getEffectiveDiffusionCoefficient);
147
148 EnergyVolVars::updateEffectiveThermalConductivity();
149 }
150
165 template<class ElemSol, class Problem, class Element, class Scv>
166 void completeFluidState(const ElemSol& elemSol,
167 const Problem& problem,
168 const Element& element,
169 const Scv& scv,
172 {
173 EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState);
174
175 const auto& priVars = elemSol[scv.localDofIndex()];
176 const auto phasePresence = priVars.state();
177
178 const auto& spatialParams = problem.spatialParams();
179 const auto wPhaseIdx = spatialParams.template wettingPhase<FluidSystem>(element, scv, elemSol);
180 fluidState.setWettingPhase(wPhaseIdx);
181
182 const auto fluidMatrixInteraction = spatialParams.fluidMatrixInteraction(element, scv, elemSol);
183
184 // set the saturations
185 if (phasePresence == secondPhaseOnly)
186 {
187 fluidState.setSaturation(phase0Idx, 0.0);
188 fluidState.setSaturation(phase1Idx, 1.0);
189 }
190 else if (phasePresence == firstPhaseOnly)
191 {
192 fluidState.setSaturation(phase0Idx, 1.0);
193 fluidState.setSaturation(phase1Idx, 0.0);
194 }
195 else if (phasePresence == bothPhases)
196 {
197 if (formulation == TwoPFormulation::p0s1)
198 {
199 fluidState.setSaturation(phase1Idx, priVars[switchIdx]);
200 fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]);
201 }
202 else
203 {
204 fluidState.setSaturation(phase0Idx, priVars[switchIdx]);
205 fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]);
206 }
207 }
208 else
209 DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence.");
210
211 // set pressures of the fluid phases
212 pc_ = fluidMatrixInteraction.pc(fluidState.saturation(wPhaseIdx));
213 if (formulation == TwoPFormulation::p0s1)
214 {
215 fluidState.setPressure(phase0Idx, priVars[pressureIdx]);
216 fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_
217 : priVars[pressureIdx] - pc_);
218 }
219 else
220 {
221 fluidState.setPressure(phase1Idx, priVars[pressureIdx]);
222 fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_
223 : priVars[pressureIdx] + pc_);
224 }
225
226 // calculate the phase compositions
227 typename FluidSystem::ParameterCache paramCache;
228 // both phases are present
229 if (phasePresence == bothPhases)
230 {
231 //Get the equilibrium mole fractions from the FluidSystem and set them in the fluidState
232 //xCO2 = equilibrium mole fraction of CO2 in the liquid phase
233 //yH2O = equilibrium mole fraction of H2O in the gas phase
234 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
235 const auto xgH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
236 const auto xwH2O = 1 - xwCO2;
237 const auto xgCO2 = 1 - xgH2O;
238 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
239 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
240 fluidState.setMoleFraction(phase1Idx, comp0Idx, xgH2O);
241 fluidState.setMoleFraction(phase1Idx, comp1Idx, xgCO2);
242 }
243
244 // only the nonwetting phase is present, i.e. nonwetting phase
245 // composition is stored explicitly.
246 else if (phasePresence == secondPhaseOnly)
247 {
248 if( useMoles() ) // mole-fraction formulation
249 {
250 // set the fluid state
251 fluidState.setMoleFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
252 fluidState.setMoleFraction(phase1Idx, comp1Idx, 1-priVars[switchIdx]);
253 // TODO give values for non-existing wetting phase
254 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
255 const auto xwH2O = 1 - xwCO2;
256 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
257 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
258 }
259 else // mass-fraction formulation
260 {
261 // setMassFraction() has only to be called 1-numComponents times
262 fluidState.setMassFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
263 // TODO give values for non-existing wetting phase
264 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
265 const auto xwH2O = 1 - xwCO2;
266 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
267 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
268 }
269 }
270
271 // only the wetting phase is present, i.e. wetting phase
272 // composition is stored explicitly.
273 else if (phasePresence == firstPhaseOnly)
274 {
275 if( useMoles() ) // mole-fraction formulation
276 {
277 // convert mass to mole fractions and set the fluid state
278 fluidState.setMoleFraction(phase0Idx, comp0Idx, 1-priVars[switchIdx]);
279 fluidState.setMoleFraction(phase0Idx, comp1Idx, priVars[switchIdx]);
280 // TODO give values for non-existing nonwetting phase
281 Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
282 Scalar xnCO2 = 1 - xnH2O;
283 fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2);
284 fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O);
285 }
286 else // mass-fraction formulation
287 {
288 // setMassFraction() has only to be called 1-numComponents times
289 fluidState.setMassFraction(phase0Idx, comp1Idx, priVars[switchIdx]);
290 // TODO give values for non-existing nonwetting phase
291 Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
292 Scalar xnCO2 = 1 - xnH2O;
293 fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2);
294 fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O);
295 }
296 }
297
298 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
299 {
300 // set the viscosity and desity here if constraintsolver is not used
301 paramCache.updateComposition(fluidState, phaseIdx);
302 const Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx);
303 fluidState.setDensity(phaseIdx, rho);
304 const Scalar rhoMolar = FluidSystem::molarDensity(fluidState, phaseIdx);
305 fluidState.setMolarDensity(phaseIdx, rhoMolar);
306 const Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
307 fluidState.setViscosity(phaseIdx,mu);
308
309 // compute and set the enthalpy
310 Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx);
311 fluidState.setEnthalpy(phaseIdx, h);
312 }
313 }
314
318 const FluidState &fluidState() const
319 { return fluidState_; }
320
324 const SolidState &solidState() const
325 { return solidState_; }
326
332 Scalar averageMolarMass(int phaseIdx) const
333 { return fluidState_.averageMolarMass(phaseIdx); }
334
341 Scalar saturation(const int phaseIdx) const
342 { return fluidState_.saturation(phaseIdx); }
343
351 Scalar massFraction(const int phaseIdx, const int compIdx) const
352 { return fluidState_.massFraction(phaseIdx, compIdx); }
353
361 Scalar moleFraction(const int phaseIdx, const int compIdx) const
362 { return fluidState_.moleFraction(phaseIdx, compIdx); }
363
370 Scalar density(const int phaseIdx) const
371 { return fluidState_.density(phaseIdx); }
372
379 Scalar viscosity(const int phaseIdx) const
380 { return fluidState_.viscosity(phaseIdx); }
381
388 Scalar molarDensity(const int phaseIdx) const
389 { return fluidState_.molarDensity(phaseIdx) ; }
390
397 Scalar pressure(const int phaseIdx) const
398 { return fluidState_.pressure(phaseIdx); }
399
407 Scalar temperature() const
408 { return fluidState_.temperature(/*phaseIdx=*/0); }
409
416 Scalar relativePermeability(const int phaseIdx) const
417 { return relativePermeability_[phaseIdx]; }
418
425 Scalar mobility(const int phaseIdx) const
426 { return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx); }
427
432 Scalar capillaryPressure() const
433 { return fluidState_.pressure(phase1Idx) - fluidState_.pressure(phase0Idx); }
434
438 Scalar porosity() const
439 { return solidState_.porosity(); }
440
444 const PermeabilityType& permeability() const
445 { return permeability_; }
446
450 Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
451 {
452 typename FluidSystem::ParameterCache paramCache;
453 paramCache.updatePhase(fluidState_, phaseIdx);
454 return FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, compIIdx, compJIdx);
455 }
456
460 Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
461 { return effectiveDiffCoeff_(phaseIdx, compIIdx, compJIdx); }
462
463
467 int wettingPhase() const
468 { return fluidState_.wettingPhase(); }
469
470private:
471 FluidState fluidState_;
472 SolidState solidState_;
473 Scalar pc_; // The capillary pressure
474 PermeabilityType permeability_; // Effective permeability within the control volume
475
476 // Relative permeability within the control volume
477 std::array<Scalar, ModelTraits::numFluidPhases()> relativePermeability_;
478
479 // Effective diffusion coefficients for the phases
480 DiffusionCoefficients effectiveDiffCoeff_;
481};
482
483} // end namespace Dumux
484
485#endif
Definition: porousmediumflow/nonisothermal/volumevariables.hh:63
The isothermal base class.
Definition: porousmediumflow/volumevariables.hh:28
static constexpr int numFluidComponents()
Return number of components considered by the model.
Definition: porousmediumflow/volumevariables.hh:40
const PrimaryVariables & priVars() const
Returns the vector of primary variables.
Definition: porousmediumflow/volumevariables.hh:64
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Updates all quantities for a given control volume.
Definition: porousmediumflow/volumevariables.hh:52
The primary variable switch for the 2p2c-CO2 model controlling the phase presence state variable.
Definition: co2/primaryvariableswitch.hh:33
Contains the quantities which are are constant within a finite volume in the CO2 model.
Definition: porousmediumflow/co2/volumevariables.hh:39
Scalar massFraction(const int phaseIdx, const int compIdx) const
Returns the mass fraction of a given component in a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:351
const SolidState & solidState() const
Returns the phase state for the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:324
typename Traits::FluidState FluidState
The type of the object returned by the fluidState() method.
Definition: porousmediumflow/co2/volumevariables.hh:83
Scalar saturation(const int phaseIdx) const
Returns the saturation of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:341
void completeFluidState(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, FluidState &fluidState, SolidState &solidState)
Completes the fluid state.
Definition: porousmediumflow/co2/volumevariables.hh:166
Scalar mobility(const int phaseIdx) const
Returns the effective mobility of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:425
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the effective diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:460
Scalar porosity() const
Returns the average porosity within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:438
typename ModelTraits::Indices Indices
Export the indices.
Definition: porousmediumflow/co2/volumevariables.hh:87
Scalar density(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:370
Scalar viscosity(const int phaseIdx) const
Returns the dynamic viscosity of the fluid within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:379
typename Traits::FluidSystem FluidSystem
The fluid system used here.
Definition: porousmediumflow/co2/volumevariables.hh:85
int wettingPhase() const
Returns the wetting phase index.
Definition: porousmediumflow/co2/volumevariables.hh:467
typename Traits::SolidState SolidState
Export type of solid state.
Definition: porousmediumflow/co2/volumevariables.hh:89
typename Traits::SolidSystem SolidSystem
Export type of solid system.
Definition: porousmediumflow/co2/volumevariables.hh:91
Scalar temperature() const
Returns temperature within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:407
Scalar pressure(const int phaseIdx) const
Returns the effective pressure of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:397
static constexpr bool useMoles()
Return whether moles or masses are balanced.
Definition: porousmediumflow/co2/volumevariables.hh:97
const PermeabilityType & permeability() const
Returns the average permeability within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:444
const FluidState & fluidState() const
Returns the phase state within the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:318
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Updates all quantities for a given control volume.
Definition: porousmediumflow/co2/volumevariables.hh:116
Scalar molarDensity(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:388
Scalar averageMolarMass(int phaseIdx) const
Returns the average molar mass of the fluid phase.
Definition: porousmediumflow/co2/volumevariables.hh:332
Scalar moleFraction(const int phaseIdx, const int compIdx) const
Returns the mole fraction of a given component in a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:361
static constexpr TwoPFormulation priVarFormulation()
Return the two-phase formulation used here.
Definition: porousmediumflow/co2/volumevariables.hh:99
Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the binary diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:450
Scalar capillaryPressure() const
Returns the effective capillary pressure within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:432
Scalar relativePermeability(const int phaseIdx) const
Returns the relative permeability of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:416
Defines an enumeration for the formulations accepted by the two-phase model.
void updateSolidVolumeFractions(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, SolidState &solidState, const int solidVolFracOffset)
update the solid volume fractions (inert and reacitve) and set them in the solidstate
Definition: updatesolidvolumefractions.hh:24
TwoPFormulation
Enumerates the formulations which the two-phase model accepts.
Definition: formulation.hh:23
@ p1s0
first phase saturation and second phase pressure as primary variables
@ p0s1
first phase pressure and second phase saturation as primary variables
std::string phasePresence() noexcept
I/O name of phase presence.
Definition: name.hh:135
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:62
std::string molarDensity(int phaseIdx) noexcept
I/O name of molar density for multiphase systems.
Definition: name.hh:71
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:53
Definition: adapt.hh:17
Base class for the model specific class which provides access to all volume averaged quantities.
Base class for the model specific class which provides access to all volume averaged quantities.
The primary variable switch for the extended Richards model.
Update the solid volume fractions (inert and reacitve) and set them in the solidstate.