3.2-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;
88
89 // type used for the diffusion coefficients
90 using EffDiffModel = typename Traits::EffectiveDiffusivityModel;
91 using DiffusionCoefficients = typename Traits::DiffusionType::DiffusionCoefficientsContainer;
92
93public:
95 using FluidState = typename Traits::FluidState;
97 using FluidSystem = typename Traits::FluidSystem;
99 using SolidState = typename Traits::SolidState;
101 using SolidSystem = typename Traits::SolidSystem;
104
105
107 static constexpr bool useMoles() { return ModelTraits::useMoles(); }
109 static constexpr TwoPFormulation priVarFormulation() { return formulation; }
110
111 // check for permissive combinations
112 static_assert(ModelTraits::numFluidPhases() == 2, "NumPhases set in the model is not two!");
113 static_assert(ModelTraits::numFluidComponents() == 2, "NumComponents set in the model is not two!");
114 static_assert((formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0), "Chosen TwoPFormulation not supported!");
115
125 template<class ElemSol, class Problem, class Element, class Scv>
126 void update(const ElemSol& elemSol, const Problem& problem, const Element& element, const Scv& scv)
127 {
128 ParentType::update(elemSol, problem, element, scv);
129 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
130
131 // Second instance of a parameter cache. Could be avoided if
132 // diffusion coefficients also became part of the fluid state.
133 typename FluidSystem::ParameterCache paramCache;
134 paramCache.updateAll(fluidState_);
135
136 using MaterialLaw = typename Problem::SpatialParams::MaterialLaw;
137 const auto& matParams = problem.spatialParams().materialLawParams(element, scv, elemSol);
138
139 const int wPhaseIdx = fluidState_.wettingPhase();
140 const int nPhaseIdx = 1 - wPhaseIdx;
141
142 // relative permeabilities -> require wetting phase saturation as parameter!
143 relativePermeability_[wPhaseIdx] = MaterialLaw::krw(matParams, saturation(wPhaseIdx));
144 relativePermeability_[nPhaseIdx] = MaterialLaw::krn(matParams, saturation(wPhaseIdx));
145
146 // porosity & permeabilty
147 updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps);
148 EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_);
149 permeability_ = problem.spatialParams().permeability(element, scv, elemSol);
150
151 auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx)
152 {
153 return EffDiffModel::effectiveDiffusionCoefficient(*this, phaseIdx, compIIdx, compJIdx);
154 };
155
156 effectiveDiffCoeff_.update(getEffectiveDiffusionCoefficient);
157
158 EnergyVolVars::updateEffectiveThermalConductivity();
159 }
160
175 template<class ElemSol, class Problem, class Element, class Scv>
176 void completeFluidState(const ElemSol& elemSol,
177 const Problem& problem,
178 const Element& element,
179 const Scv& scv,
182 {
183 EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState);
184
185 const auto& priVars = elemSol[scv.localDofIndex()];
186 const auto phasePresence = priVars.state();
187
188 using MaterialLaw = typename Problem::SpatialParams::MaterialLaw;
189 const auto& materialParams = problem.spatialParams().materialLawParams(element, scv, elemSol);
190 const auto wPhaseIdx = problem.spatialParams().template wettingPhase<FluidSystem>(element, scv, elemSol);
191 fluidState.setWettingPhase(wPhaseIdx);
192
193 // set the saturations
194 if (phasePresence == secondPhaseOnly)
195 {
196 fluidState.setSaturation(phase0Idx, 0.0);
197 fluidState.setSaturation(phase1Idx, 1.0);
198 }
199 else if (phasePresence == firstPhaseOnly)
200 {
201 fluidState.setSaturation(phase0Idx, 1.0);
202 fluidState.setSaturation(phase1Idx, 0.0);
203 }
204 else if (phasePresence == bothPhases)
205 {
206 if (formulation == TwoPFormulation::p0s1)
207 {
208 fluidState.setSaturation(phase1Idx, priVars[switchIdx]);
209 fluidState.setSaturation(phase0Idx, 1 - priVars[switchIdx]);
210 }
211 else
212 {
213 fluidState.setSaturation(phase0Idx, priVars[switchIdx]);
214 fluidState.setSaturation(phase1Idx, 1 - priVars[switchIdx]);
215 }
216 }
217 else
218 DUNE_THROW(Dune::InvalidStateException, "Invalid phase presence.");
219
220 // set pressures of the fluid phases
221 pc_ = MaterialLaw::pc(materialParams, fluidState.saturation(wPhaseIdx));
222 if (formulation == TwoPFormulation::p0s1)
223 {
224 fluidState.setPressure(phase0Idx, priVars[pressureIdx]);
225 fluidState.setPressure(phase1Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] + pc_
226 : priVars[pressureIdx] - pc_);
227 }
228 else
229 {
230 fluidState.setPressure(phase1Idx, priVars[pressureIdx]);
231 fluidState.setPressure(phase0Idx, (wPhaseIdx == phase0Idx) ? priVars[pressureIdx] - pc_
232 : priVars[pressureIdx] + pc_);
233 }
234
235 // calculate the phase compositions
236 typename FluidSystem::ParameterCache paramCache;
237 // both phases are present
238 if (phasePresence == bothPhases)
239 {
240 //Get the equilibrium mole fractions from the FluidSystem and set them in the fluidState
241 //xCO2 = equilibrium mole fraction of CO2 in the liquid phase
242 //yH2O = equilibrium mole fraction of H2O in the gas phase
243 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
244 const auto xgH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
245 const auto xwH2O = 1 - xwCO2;
246 const auto xgCO2 = 1 - xgH2O;
247 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
248 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
249 fluidState.setMoleFraction(phase1Idx, comp0Idx, xgH2O);
250 fluidState.setMoleFraction(phase1Idx, comp1Idx, xgCO2);
251 }
252
253 // only the nonwetting phase is present, i.e. nonwetting phase
254 // composition is stored explicitly.
255 else if (phasePresence == secondPhaseOnly)
256 {
257 if( useMoles() ) // mole-fraction formulation
258 {
259 // set the fluid state
260 fluidState.setMoleFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
261 fluidState.setMoleFraction(phase1Idx, comp1Idx, 1-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 else // mass-fraction formulation
269 {
270 // setMassFraction() has only to be called 1-numComponents times
271 fluidState.setMassFraction(phase1Idx, comp0Idx, priVars[switchIdx]);
272 // TODO give values for non-existing wetting phase
273 const auto xwCO2 = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase0Idx);
274 const auto xwH2O = 1 - xwCO2;
275 fluidState.setMoleFraction(phase0Idx, comp1Idx, xwCO2);
276 fluidState.setMoleFraction(phase0Idx, comp0Idx, xwH2O);
277 }
278 }
279
280 // only the wetting phase is present, i.e. wetting phase
281 // composition is stored explicitly.
282 else if (phasePresence == firstPhaseOnly)
283 {
284 if( useMoles() ) // mole-fraction formulation
285 {
286 // convert mass to mole fractions and set the fluid state
287 fluidState.setMoleFraction(phase0Idx, comp0Idx, 1-priVars[switchIdx]);
288 fluidState.setMoleFraction(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 else // mass-fraction formulation
296 {
297 // setMassFraction() has only to be called 1-numComponents times
298 fluidState.setMassFraction(phase0Idx, comp1Idx, priVars[switchIdx]);
299 // TODO give values for non-existing nonwetting phase
300 Scalar xnH2O = FluidSystem::equilibriumMoleFraction(fluidState, paramCache, phase1Idx);
301 Scalar xnCO2 = 1 - xnH2O;
302 fluidState.setMoleFraction(phase1Idx, comp1Idx, xnCO2);
303 fluidState.setMoleFraction(phase1Idx, comp0Idx, xnH2O);
304 }
305 }
306
307 for (int phaseIdx = 0; phaseIdx < ModelTraits::numFluidPhases(); ++phaseIdx)
308 {
309 // set the viscosity and desity here if constraintsolver is not used
310 paramCache.updateComposition(fluidState, phaseIdx);
311 const Scalar rho = FluidSystem::density(fluidState, paramCache, phaseIdx);
312 fluidState.setDensity(phaseIdx, rho);
313 const Scalar rhoMolar = FluidSystem::molarDensity(fluidState, phaseIdx);
314 fluidState.setMolarDensity(phaseIdx, rhoMolar);
315 const Scalar mu = FluidSystem::viscosity(fluidState, paramCache, phaseIdx);
316 fluidState.setViscosity(phaseIdx,mu);
317
318 // compute and set the enthalpy
319 Scalar h = EnergyVolVars::enthalpy(fluidState, paramCache, phaseIdx);
320 fluidState.setEnthalpy(phaseIdx, h);
321 }
322 }
323
327 const FluidState &fluidState() const
328 { return fluidState_; }
329
333 const SolidState &solidState() const
334 { return solidState_; }
335
341 Scalar averageMolarMass(int phaseIdx) const
342 { return fluidState_.averageMolarMass(phaseIdx); }
343
350 Scalar saturation(const int phaseIdx) const
351 { return fluidState_.saturation(phaseIdx); }
352
360 Scalar massFraction(const int phaseIdx, const int compIdx) const
361 { return fluidState_.massFraction(phaseIdx, compIdx); }
362
370 Scalar moleFraction(const int phaseIdx, const int compIdx) const
371 { return fluidState_.moleFraction(phaseIdx, compIdx); }
372
379 Scalar density(const int phaseIdx) const
380 { return fluidState_.density(phaseIdx); }
381
388 Scalar viscosity(const int phaseIdx) const
389 { return fluidState_.viscosity(phaseIdx); }
390
397 Scalar molarDensity(const int phaseIdx) const
398 { return fluidState_.molarDensity(phaseIdx) ; }
399
406 Scalar pressure(const int phaseIdx) const
407 { return fluidState_.pressure(phaseIdx); }
408
416 Scalar temperature() const
417 { return fluidState_.temperature(/*phaseIdx=*/0); }
418
425 Scalar relativePermeability(const int phaseIdx) const
426 { return relativePermeability_[phaseIdx]; }
427
434 Scalar mobility(const int phaseIdx) const
435 { return relativePermeability_[phaseIdx]/fluidState_.viscosity(phaseIdx); }
436
441 Scalar capillaryPressure() const
442 { return fluidState_.pressure(phase1Idx) - fluidState_.pressure(phase0Idx); }
443
447 Scalar porosity() const
448 { return solidState_.porosity(); }
449
453 const PermeabilityType& permeability() const
454 { return permeability_; }
455
459 [[deprecated("Will be removed after release 3.2. Use diffusionCoefficient(phaseIdx, compIIdx, compJIdx)!")]]
460 Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
461 {
462 if (phaseIdx == compIdx)
463 DUNE_THROW(Dune::InvalidStateException, "Diffusion coefficient called for phaseIdx = compIdx");
464 else
465 return diffusionCoefficient(phaseIdx, FluidSystem::getMainComponent(phaseIdx), compIdx);
466 }
467
471 Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
472 {
473 typename FluidSystem::ParameterCache paramCache;
474 paramCache.updatePhase(fluidState_, phaseIdx);
475 return FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, compIIdx, compJIdx);
476 }
477
481 Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
482 { return effectiveDiffCoeff_(phaseIdx, compIIdx, compJIdx); }
483
484
488 int wettingPhase() const
489 { return fluidState_.wettingPhase(); }
490
491private:
492 FluidState fluidState_;
493 SolidState solidState_;
494 Scalar pc_; // The capillary pressure
495 PermeabilityType permeability_; // Effective permeability within the control volume
496
497 // Relative permeability within the control volume
498 std::array<Scalar, ModelTraits::numFluidPhases()> relativePermeability_;
499
500 // Effective diffusion coefficients for the phases
501 DiffusionCoefficients effectiveDiffCoeff_;
502};
503
504} // end namespace Dumux
505
506#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
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:360
const SolidState & solidState() const
Returns the phase state for the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:333
typename Traits::FluidState FluidState
The type of the object returned by the fluidState() method.
Definition: porousmediumflow/co2/volumevariables.hh:95
Scalar saturation(const int phaseIdx) const
Returns the saturation of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:350
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:176
Scalar mobility(const int phaseIdx) const
Returns the effective mobility of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:434
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the effective diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:481
Scalar porosity() const
Returns the average porosity within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:447
Scalar density(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:379
Scalar viscosity(const int phaseIdx) const
Returns the dynamic viscosity of the fluid within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:388
typename Traits::FluidSystem FluidSystem
The fluid system used here.
Definition: porousmediumflow/co2/volumevariables.hh:97
Scalar diffusionCoefficient(int phaseIdx, int compIdx) const
Returns the binary diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:460
int wettingPhase() const
Returns the wetting phase index.
Definition: porousmediumflow/co2/volumevariables.hh:488
typename Traits::SolidState SolidState
Export type of solid state.
Definition: porousmediumflow/co2/volumevariables.hh:99
typename Traits::SolidSystem SolidSystem
Export type of solid system.
Definition: porousmediumflow/co2/volumevariables.hh:101
Scalar temperature() const
Returns temperature within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:416
Scalar pressure(const int phaseIdx) const
Returns the effective pressure of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:406
static constexpr bool useMoles()
Return whether moles or masses are balanced.
Definition: porousmediumflow/co2/volumevariables.hh:107
const PermeabilityType & permeability() const
Returns the average permeability within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:453
const FluidState & fluidState() const
Returns the phase state within the control volume.
Definition: porousmediumflow/co2/volumevariables.hh:327
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:126
Scalar molarDensity(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:397
Scalar averageMolarMass(int phaseIdx) const
Returns the average molar mass of the fluid phase.
Definition: porousmediumflow/co2/volumevariables.hh:341
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:370
static constexpr TwoPFormulation priVarFormulation()
Return the two-phase formulation used here.
Definition: porousmediumflow/co2/volumevariables.hh:109
Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the binary diffusion coefficients for a phase in .
Definition: porousmediumflow/co2/volumevariables.hh:471
Scalar capillaryPressure() const
Returns the effective capillary pressure within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:441
Scalar relativePermeability(const int phaseIdx) const
Returns the relative permeability of a given phase within the control volume in .
Definition: porousmediumflow/co2/volumevariables.hh:425
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.