3.1-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
26#ifndef DUMUX_CO2_VOLUME_VARIABLES_HH
27#define DUMUX_CO2_VOLUME_VARIABLES_HH
28
29#include <array>
30
31#include <dune/common/exceptions.hh>
32
37
39
40namespace Dumux {
41
47template <class Traits>
50, public EnergyVolumeVariables<Traits, TwoPTwoCCO2VolumeVariables<Traits> >
51{
54
55 using Scalar = typename Traits::PrimaryVariables::value_type;
56 using ModelTraits = typename Traits::ModelTraits;
57 static constexpr int numFluidComps = ParentType::numFluidComponents();
58
59 // component indices
60 enum
61 {
62 comp0Idx = Traits::FluidSystem::comp0Idx,
63 comp1Idx = Traits::FluidSystem::comp1Idx,
64 phase0Idx = Traits::FluidSystem::phase0Idx,
65 phase1Idx = Traits::FluidSystem::phase1Idx
66 };
67
68 // phase presence indices
69 enum
70 {
71 firstPhaseOnly = ModelTraits::Indices::firstPhaseOnly,
72 secondPhaseOnly = ModelTraits::Indices::secondPhaseOnly,
73 bothPhases = ModelTraits::Indices::bothPhases
74 };
75
76 // primary variable indices
77 enum
78 {
79 switchIdx = ModelTraits::Indices::switchIdx,
80 pressureIdx = ModelTraits::Indices::pressureIdx
81 };
82
83 // formulation
84 static constexpr auto formulation = ModelTraits::priVarFormulation();
85
86 // type used for the permeability
87 using PermeabilityType = typename Traits::PermeabilityType;
88public:
90 using FluidState = typename Traits::FluidState;
92 using FluidSystem = typename Traits::FluidSystem;
94 using SolidState = typename Traits::SolidState;
96 using SolidSystem = typename Traits::SolidSystem;
99
100
102 static constexpr bool useMoles() { return ModelTraits::useMoles(); }
104 static constexpr TwoPFormulation priVarFormulation() { return formulation; }
105
106 // check for permissive combinations
107 static_assert(ModelTraits::numFluidPhases() == 2, "NumPhases set in the model is not two!");
108 static_assert(ModelTraits::numFluidComponents() == 2, "NumComponents set in the model is not two!");
109 static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!");
110
120 template<class ElemSol, class Problem, class Element, class Scv>
121 void update(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv)
122 {
123 ParentType::update(elemSol, problem, element, scv);
124 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
125
126 // Second instance of a parameter cache. Could be avoided if
127 // diffusion coefficients also became part of the fluid state.
128 typename FluidSystem::ParameterCache paramCache;
129 paramCache.updateAll(fluidState_);
130
131 using MaterialLaw = typename Problem::SpatialParams::MaterialLaw;
132 const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol);
133
134 const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol);
135 const int nPhaseIdx = 1 - wPhaseIdx;
136
137 // relative permeabilities -> require wetting phase saturation as parameter!
138 relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx));
139 relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx));
140
141 // binary diffusion coefficients
142 diffCoeff_[phase0Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase0Idx, comp0Idx, comp1Idx);
143 diffCoeff_[phase1Idx] = FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phase1Idx, comp0Idx, comp1Idx);
144
145 // porosity & permeabilty
146 updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps);
147 EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_);
148 permeability_ = problem.spatialParams().permeability(element, scv, elemSol);
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 using MaterialLaw = typename Problem::SpatialParams::MaterialLaw;
179 const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol);
180 const int wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol);
181 fluidState.setWettingPhase(wPhaseIdx);
182
183 // set the saturations
184 if (phasePresence == secondPhaseOnly)
185 {
186 fluidState.setSaturation(phase0Idx, 0.0);
187 fluidState.setSaturation(phase1Idx, 1.0);
188 }
189 else if (phasePresence == firstPhaseOnly)
190 {
191 fluidState.setSaturation(phase0Idx, 1.0);
192 fluidState.setSaturation(phase1Idx, 0.0);
193 }
194 else if (phasePresence == bothPhases)
195 {
196 if (formulation == TwoPFormulation::p0s1)
197 {
198 fluidState.setSaturation(phase1Idx, priVars[switchIdx]);
199 fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]);
200 }
201 else
202 {
203 fluidState.setSaturation(phase0Idx, priVars[switchIdx]);
204 fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]);
205 }
206 }
207 else
208 DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence.");
209
210 // set pressures of the fluid phases
211 pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
212 if (formulation == TwoPFormulation::p0s1)
213 {
214 fluidState.setPressure(phase0Idx, priVars[pressureIdx]);
215 fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_
216 : priVars[pressureIdx] - pc_);
217 }
218 else
219 {
220 fluidState.setPressure(phase1Idx, priVars[pressureIdx]);
221 fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_
222 : priVars[pressureIdx] + pc_);
223 }
224
225 // calculate the phase compositions
226 typename FluidSystem::ParameterCache paramCache;
227 // both phases are present
228 if (phasePresence == bothPhases)
229 {
230 //Get the equilibrium mole fractions from the FluidSystem and set them in the fluidState
231 //xCO2 = equilibrium mole fraction of CO2 in the liquid phase
232 //yH2O = equilibrium mole fraction of H2O in the gas phase
233 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
234 const auto xgH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
235 const auto xwH2O = 1 - xwCO2;
236 const auto xgCO2 = 1 - xgH2O;
237 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
238 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
239 fluidState.setMoleFraction(phase1Idx, comp0Idx, xgH2O);
240 fluidState.setMoleFraction(phase1Idx, comp1Idx, xgCO2);
241 }
242
243 // only the nonwetting phase is present, i.e. nonwetting phase
244 // composition is stored explicitly.
245 else if (phasePresence == secondPhaseOnly)
246 {
247 if( useMoles() ) // mole-fraction formulation
248 {
249 // set the fluid state
250 fluidState.setMoleFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
251 fluidState.setMoleFraction(phase1Idx, comp1Idx, 1-priVars[switchIdx]);
252 // TODO give values for non-existing wetting phase
253 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
254 const auto xwH2O = 1 - xwCO2;
255 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
256 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
257 }
258 else // mass-fraction formulation
259 {
260 // setMassFraction() has only to be called 1-numComponents times
261 fluidState.setMassFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
262 // TODO give values for non-existing wetting phase
263 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
264 const auto xwH2O = 1 - xwCO2;
265 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
266 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
267 }
268 }
269
270 // only the wetting phase is present, i.e. wetting phase
271 // composition is stored explicitly.
272 else if (phasePresence == firstPhaseOnly)
273 {
274 if( useMoles() ) // mole-fraction formulation
275 {
276 // convert mass to mole fractions and set the fluid state
277 fluidState.setMoleFraction(phase0Idx, comp0Idx, 1-priVars[switchIdx]);
278 fluidState.setMoleFraction(phase0Idx, comp1Idx, priVars[switchIdx]);
279 // TODO give values for non-existing nonwetting phase
280 Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
281 Scalar xnCO2 = 1 - xnH2O;
282 fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2);
283 fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O);
284 }
285 else // mass-fraction formulation
286 {
287 // setMassFraction() has only to be called 1-numComponents times
288 fluidState.setMassFraction(phase0Idx, comp1Idx, priVars[switchIdx]);
289 // TODO give values for non-existing nonwetting phase
290 Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
291 Scalar xnCO2 = 1 - xnH2O;
292 fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2);
293 fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O);
294 }
295 }
296
297 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
298 {
299 // set the viscosity and desity here if constraintsolver is not used
300 paramCache.updateComposition(fluidState, phaseIdx);
301 const Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx);
302 fluidState.setDensity(phaseIdx, rho);
303 const Scalar rhoMolar = FluidSystem::molarDensity(fluidState, phaseIdx);
304 fluidState.setMolarDensity(phaseIdx, rhoMolar);
305 const Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
306 fluidState.setViscosity(phaseIdx,mu);
307
308 // compute and set the enthalpy
309 Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx);
310 fluidState.setEnthalpy(phaseIdx, h);
311 }
312 }
313
317 const FluidState &fluidState() const
318 { return fluidState_; }
319
323 const SolidState &solidState() const
324 { return solidState_; }
325
331 Scalar averageMolarMass(int phaseIdx) const
332 { return fluidState_.averageMolarMass(phaseIdx); }
333
340 Scalar saturation(const int phaseIdx) const
341 { return fluidState_.saturation(phaseIdx); }
342
350 Scalar massFraction(const int phaseIdx, const int compIdx) const
351 { return fluidState_.massFraction(phaseIdx, compIdx); }
352
360 Scalar moleFraction(const int phaseIdx, const int compIdx) const
361 { return fluidState_.moleFraction(phaseIdx, compIdx); }
362
369 Scalar density(const int phaseIdx) const
370 { return fluidState_.density(phaseIdx); }
371
378 Scalar viscosity(const int phaseIdx) const
379 { return fluidState_.viscosity(phaseIdx); }
380
387 Scalar molarDensity(const int phaseIdx) const
388 { return fluidState_.molarDensity(phaseIdx) ; }
389
396 Scalar pressure(const int phaseIdx) const
397 { return fluidState_.pressure(phaseIdx); }
398
406 Scalar temperature() const
407 { return fluidState_.temperature(/*phaseIdx=*/0); }
408
415 Scalar relativePermeability(const int phaseIdx) const
416 { return relativePermeability_[phaseIdx]; }
417
424 Scalar mobility(const int phaseIdx) const
425 { return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx); }
426
431 Scalar capillaryPressure() const
432 { return fluidState_.pressure(phase1Idx) - fluidState_.pressure(phase0Idx); }
433
437 Scalar porosity() const
438 { return solidState_.porosity(); }
439
443 const PermeabilityType& permeability() const
444 { return permeability_; }
445
449 Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
450 {
451 if(phaseIdx == compIdx)
452 DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient called for phaseIdx = compIdx");
453 else
454 return diffCoeff_[phaseIdx];
455 }
456
457private:
458 FluidState fluidState_;
459 SolidState solidState_;
460 Scalar pc_; // The capillary pressure
461 PermeabilityType permeability_; // Effective permeability within the control volume
462
463 // Relative permeability within the control volume
464 std::array<Scalar, ModelTraits::numFluidPhases()> relativePermeability_;
465
466 // Binary diffusion coefficients for the phases
467 std::array<Scalar, ModelTraits::numFluidPhases()> diffCoeff_;
468};
469
470} // end namespace Dumux
471
472#endif
Update the solid volume fractions (inert and reacitve) and set them in the solidstate.
Defines an enumeration for the formulations accepted by the two-phase model.
TwoPFormulation
Enumerates the formulations which the two-phase model accepts.
Definition: formulation.hh:35
@ p1s0
first phase saturation and second phase pressure as primary variables
@ p0s1
first phase pressure and second phase saturation as primary variables
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:36
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
std::string phasePresence() noexcept
I/O name of phase presence.
Definition: name.hh:147
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string molarDensity(int phaseIdx) noexcept
I/O name of molar density for multiphase systems.
Definition: name.hh:83
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
The primary variable switch for the 2p2c-CO2 model controlling the phase presence state variable.
Definition: co2/primaryvariableswitch.hh:45
Contains the quantities which are are constant within a finite volume in the CO2 model.
Definition: porousmediumflow/co2/volumevariables.hh:51
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:350
const SolidState & solidState() const
Returns the phase state for the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:323
typename Traits::FluidState FluidState
The type of the object returned by the fluidState() method.
Definition: porousmediumflow/co2/volumevariables.hh:90
Scalar saturation(const int phaseIdx) const
Returns the saturation of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:340
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:424
Scalar porosity() const
Returns the average porosity within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:437
Scalar density(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:369
Scalar viscosity(const int phaseIdx) const
Returns the dynamic viscosity of the fluid within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:378
typename Traits::FluidSystem FluidSystem
The fluid system used here.
Definition: porousmediumflow/co2/volumevariables.hh:92
Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
Returns the binary diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:449
typename Traits::SolidState SolidState
Export type of solid state.
Definition: porousmediumflow/co2/volumevariables.hh:94
typename Traits::SolidSystem SolidSystem
Export type of solid system.
Definition: porousmediumflow/co2/volumevariables.hh:96
Scalar temperature() const
Returns temperature within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:406
Scalar pressure(const int phaseIdx) const
Returns the effective pressure of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:396
static constexpr bool useMoles()
Return whether moles or masses are balanced.
Definition: porousmediumflow/co2/volumevariables.hh:102
const PermeabilityType & permeability() const
Returns the average permeability within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:443
const FluidState & fluidState() const
Returns the phase state within the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:317
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:121
Scalar molarDensity(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:387
Scalar averageMolarMass(int phaseIdx) const
Returns the average molar mass of the fluid phase.
Definition: porousmediumflow/co2/volumevariables.hh:331
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:360
static constexpr TwoPFormulation priVarFormulation()
Return the two-phase formulation used here.
Definition: porousmediumflow/co2/volumevariables.hh:104
Scalar capillaryPressure() const
Returns the effective capillary pressure within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:431
Scalar relativePermeability(const int phaseIdx) const
Returns the relative permeability of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:415
Definition: porousmediumflow/nonisothermal/volumevariables.hh:75
The isothermal base class.
Definition: porousmediumflow/volumevariables.hh:40
static constexpr int numFluidComponents()
Return number of components considered by the model.
Definition: porousmediumflow/volumevariables.hh:52
const PrimaryVariables & priVars() const
Returns the vector of primary variables.
Definition: porousmediumflow/volumevariables.hh:76
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:64
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.