3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
porousmediumflow/richards/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 *****************************************************************************/
25#ifndef DUMUX_RICHARDS_VOLUME_VARIABLES_HH
26#define DUMUX_RICHARDS_VOLUME_VARIABLES_HH
27
28#include <cassert>
29
30#include <dune/common/exceptions.hh>
31
34
39
41
42namespace Dumux {
43
44namespace Detail {
47{
49};
50
52{};
53} // end namespace Detail
54
62template <class Traits>
65, public EnergyVolumeVariables<Traits, RichardsVolumeVariables<Traits> >
66, public std::conditional_t<Traits::ModelTraits::enableMolecularDiffusion(),
67 Detail::VolVarsWithPVSwitch, Detail::VolVarsWithOutPVSwitch>
68{
71 using Scalar = typename Traits::PrimaryVariables::value_type;
72 using PermeabilityType = typename Traits::PermeabilityType;
73 using ModelTraits = typename Traits::ModelTraits;
74
75 static constexpr int numFluidComps = ParentType::numFluidComponents();
76 static constexpr int numPhases = ParentType::numFluidPhases();
77
78 using EffDiffModel = typename Traits::EffectiveDiffusivityModel;
79
80 // checks if the fluid system uses the Richards model index convention
81 static constexpr auto fsCheck = ModelTraits::checkFluidSystem(typename Traits::FluidSystem{});
82
83public:
85 using FluidSystem = typename Traits::FluidSystem;
87 using FluidState = typename Traits::FluidState;
90 using SolidState = typename Traits::SolidState;
92 using SolidSystem = typename Traits::SolidSystem;
93 using Indices = typename Traits::ModelTraits::Indices;
95 static constexpr bool enableWaterDiffusionInAir() { return Dumux::Deprecated::ExtendedRichardsHelper<ModelTraits::enableMolecularDiffusion()>::isExtendedRichards(); }
96
98 static constexpr auto liquidPhaseIdx = Traits::FluidSystem::phase0Idx;
99 static constexpr auto gasPhaseIdx = Traits::FluidSystem::phase1Idx;
100
110 template<class ElemSol, class Problem, class Element, class Scv>
111 void update(const ElemSol &elemSol,
112 const Problem &problem,
113 const Element &element,
114 const Scv& scv)
115 {
116 ParentType::update(elemSol, problem, element, scv);
117
118 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
119
120 // precompute the minimum capillary pressure (entry pressure)
121 // needed to make sure we don't compute unphysical capillary pressures and thus saturations
122 minPc_ = fluidMatrixInteraction.endPointPc();
123
124 //update porosity before calculating the effective properties depending on it
125 updateSolidVolumeFractions(elemSol, problem, element, scv, solidState_, numFluidComps);
126
127 if constexpr (enableWaterDiffusionInAir())
128 {
129 const auto& priVars = elemSol[scv.localDofIndex()];
130 const auto phasePresence = priVars.state();
131
132 typename FluidSystem::ParameterCache paramCache;
133 auto getEffectiveDiffusionCoefficient = [&](int phaseIdx, int compIIdx, int compJIdx)
134 {
135 return EffDiffModel::effectiveDiffusionCoefficient(*this, phaseIdx, compIIdx, compJIdx);
136 };
137
138 if (phasePresence == Indices::gasPhaseOnly)
139 {
142 moleFraction_[gasPhaseIdx] = priVars[Indices::switchIdx];
143
144 const auto averageMolarMassGasPhase = (moleFraction_[gasPhaseIdx]*FluidSystem::molarMass(liquidPhaseIdx)) +
145 ((1-moleFraction_[gasPhaseIdx])*FluidSystem::molarMass(gasPhaseIdx));
146
147 //X_w = x_w* M_w/ M_avg
148 massFraction_[gasPhaseIdx] = priVars[Indices::switchIdx]*FluidSystem::molarMass(liquidPhaseIdx)/averageMolarMassGasPhase;
149
150 fluidState_.setSaturation(liquidPhaseIdx, 0.0);
151 fluidState_.setSaturation(gasPhaseIdx, 1.0);
152
153 EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState_, solidState_);
154
155 // get pc for sw = 0.0
156 const Scalar pc = fluidMatrixInteraction.pc(0.0);
157
158 // set the wetting pressure
159 fluidState_.setPressure(liquidPhaseIdx, problem.nonwettingReferencePressure() - pc);
160 fluidState_.setPressure(gasPhaseIdx, problem.nonwettingReferencePressure());
161
162 // set molar densities
163 if constexpr (enableWaterDiffusionInAir())
164 {
165 molarDensity_[liquidPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(liquidPhaseIdx))/FluidSystem::H2O::molarMass();
166 molarDensity_[gasPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonwettingReferencePressure());
167 }
168
169 // density and viscosity
170 paramCache.updateAll(fluidState_);
174
175 // compute and set the enthalpy
176 fluidState_.setEnthalpy(liquidPhaseIdx, EnergyVolVars::enthalpy(fluidState_, paramCache, liquidPhaseIdx));
177 fluidState_.setEnthalpy(gasPhaseIdx, EnergyVolVars::enthalpy(fluidState_, paramCache, gasPhaseIdx));
178
179 //binary diffusion coefficients
180 paramCache.updateAll(fluidState_);
181 effectiveDiffCoeff_ = getEffectiveDiffusionCoefficient(gasPhaseIdx,
182 FluidSystem::comp1Idx,
183 FluidSystem::comp0Idx);
184 }
185 else if (phasePresence == Indices::bothPhases)
186 {
187 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
188
189 // if we want to account for diffusion in the air phase
190 // use Raoult to compute the water mole fraction in air
191 if constexpr (enableWaterDiffusionInAir())
192 {
193 molarDensity_[liquidPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(liquidPhaseIdx))/FluidSystem::H2O::molarMass();
194 molarDensity_[gasPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonwettingReferencePressure());
196
197 moleFraction_[gasPhaseIdx] = FluidSystem::H2O::vaporPressure(temperature()) / problem.nonwettingReferencePressure();
198
199 const auto averageMolarMassGasPhase = (moleFraction_[gasPhaseIdx]*FluidSystem::molarMass(liquidPhaseIdx)) +
200 ((1-moleFraction_[gasPhaseIdx])*FluidSystem::molarMass(gasPhaseIdx));
201
202 //X_w = x_w* M_w/ M_avg
203 massFraction_[gasPhaseIdx] = moleFraction_[gasPhaseIdx]*FluidSystem::molarMass(liquidPhaseIdx)/averageMolarMassGasPhase;
204
205 // binary diffusion coefficients
206 paramCache.updateAll(fluidState_);
207 effectiveDiffCoeff_ = getEffectiveDiffusionCoefficient(gasPhaseIdx,
208 FluidSystem::comp1Idx,
209 FluidSystem::comp0Idx);
210 }
211 }
212 else if (phasePresence == Indices::liquidPhaseOnly)
213 {
214 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
215
216 if constexpr (enableWaterDiffusionInAir())
217 {
218 molarDensity_[liquidPhaseIdx] = FluidSystem::H2O::liquidDensity(temperature(), pressure(liquidPhaseIdx))/FluidSystem::H2O::molarMass();
219 molarDensity_[gasPhaseIdx] = IdealGas<Scalar>::molarDensity(temperature(), problem.nonwettingReferencePressure());
224
225 // binary diffusion coefficients (none required for liquid phase only)
227 }
228 }
229 }
230 else
231 {
232 completeFluidState(elemSol, problem, element, scv, fluidState_, solidState_);
233 }
234
236 // specify the other parameters
238 relativePermeabilityWetting_ = fluidMatrixInteraction.krw(fluidState_.saturation(liquidPhaseIdx));
239 EnergyVolVars::updateSolidEnergyParams(elemSol, problem, element, scv, solidState_);
240 permeability_ = problem.spatialParams().permeability(element, scv, elemSol);
241 EnergyVolVars::updateEffectiveThermalConductivity();
242 }
243
258 template<class ElemSol, class Problem, class Element, class Scv>
259 void completeFluidState(const ElemSol& elemSol,
260 const Problem& problem,
261 const Element& element,
262 const Scv& scv,
265 {
266 EnergyVolVars::updateTemperature(elemSol, problem, element, scv, fluidState, solidState);
267
268 const auto fluidMatrixInteraction = problem.spatialParams().fluidMatrixInteraction(element, scv, elemSol);
269
270 const auto& priVars = elemSol[scv.localDofIndex()];
271
272 // set the wetting pressure
273 using std::max;
274 fluidState.setPressure(liquidPhaseIdx, priVars[Indices::pressureIdx]);
275 fluidState.setPressure(gasPhaseIdx, max(problem.nonwettingReferencePressure(), fluidState.pressure(liquidPhaseIdx) + minPc_));
276
277 // compute the capillary pressure to compute the saturation
278 // make sure that we the capillary pressure is not smaller than the minimum pc
279 // this would possibly return unphysical values from regularized material laws
280 using std::max;
281 const Scalar pc = max(minPc_, problem.nonwettingReferencePressure() - fluidState.pressure(liquidPhaseIdx));
282 const Scalar sw = fluidMatrixInteraction.sw(pc);
283 fluidState.setSaturation(liquidPhaseIdx, sw);
284 fluidState.setSaturation(gasPhaseIdx, 1.0-sw);
285
286 // density and viscosity
287 typename FluidSystem::ParameterCache paramCache;
288 paramCache.updateAll(fluidState);
289 fluidState.setDensity(liquidPhaseIdx,
291 fluidState.setDensity(gasPhaseIdx,
293
294 fluidState.setViscosity(liquidPhaseIdx,
296
297 // compute and set the enthalpy
298 fluidState.setEnthalpy(liquidPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, liquidPhaseIdx));
299 fluidState.setEnthalpy(gasPhaseIdx, EnergyVolVars::enthalpy(fluidState, paramCache, gasPhaseIdx));
300 }
301
306 const FluidState &fluidState() const
307 { return fluidState_; }
308
312 const SolidState &solidState() const
313 { return solidState_; }
314
318 Scalar temperature() const
319 { return fluidState_.temperature(); }
320
327 Scalar porosity() const
328 { return solidState_.porosity(); }
329
333 const PermeabilityType& permeability() const
334 { return permeability_; }
335
346 Scalar saturation(const int phaseIdx = liquidPhaseIdx) const
347 { return fluidState_.saturation(phaseIdx); }
348
355 Scalar density(const int phaseIdx = liquidPhaseIdx) const
356 { return fluidState_.density(phaseIdx); }
357
369 Scalar pressure(const int phaseIdx = liquidPhaseIdx) const
370 { return fluidState_.pressure(phaseIdx); }
371
383 Scalar mobility(const int phaseIdx = liquidPhaseIdx) const
384 { return relativePermeability(phaseIdx)/fluidState_.viscosity(phaseIdx); }
385
393 Scalar viscosity(const int phaseIdx = liquidPhaseIdx) const
394 { return phaseIdx == liquidPhaseIdx ? fluidState_.viscosity(liquidPhaseIdx) : 0.0; }
395
402 Scalar relativePermeability(const int phaseIdx = liquidPhaseIdx) const
403 { return phaseIdx == liquidPhaseIdx ? relativePermeabilityWetting_ : 1.0; }
404
416 Scalar capillaryPressure() const
417 {
418 using std::max;
420 }
421
436 Scalar pressureHead(const int phaseIdx = liquidPhaseIdx) const
437 { return 100.0 *(pressure(phaseIdx) - pressure(gasPhaseIdx))/density(phaseIdx)/9.81; }
438
449 Scalar waterContent(const int phaseIdx = liquidPhaseIdx) const
450 { return saturation(phaseIdx) * solidState_.porosity(); }
451
459 Scalar moleFraction(const int phaseIdx, const int compIdx) const
460 {
461 static_assert(enableWaterDiffusionInAir());
462 if (compIdx != FluidSystem::comp0Idx)
463 DUNE_THROW(Dune::InvalidStateException, "There is only one component for Richards!");
464 return moleFraction_[phaseIdx];
465 }
466
474 Scalar massFraction(const int phaseIdx, const int compIdx) const
475 {
476 static_assert(enableWaterDiffusionInAir());
477 if (compIdx != FluidSystem::comp0Idx)
478 DUNE_THROW(Dune::InvalidStateException, "There is only one component for Richards!");
479 return massFraction_[phaseIdx];
480 }
481
488 Scalar molarDensity(const int phaseIdx) const
489 {
490 static_assert(enableWaterDiffusionInAir());
491 return molarDensity_[phaseIdx];
492 }
493
497 Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
498 {
500 assert(phaseIdx == gasPhaseIdx);
501 assert(compIIdx != compJIdx);
502 typename FluidSystem::ParameterCache paramCache;
503 paramCache.updatePhase(fluidState_, phaseIdx);
504 return FluidSystem::binaryDiffusionCoefficient(fluidState_, paramCache, phaseIdx, compIIdx, compJIdx);
505 }
506
510 Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
511 {
513 assert(phaseIdx == gasPhaseIdx);
514 assert(compIIdx != compJIdx);
515 return effectiveDiffCoeff_;
516 }
517
518protected:
522 PermeabilityType permeability_;
523 Scalar minPc_;
524 Scalar moleFraction_[numPhases];
525 Scalar massFraction_[numPhases];
526 Scalar molarDensity_[numPhases];
527
528 // Effective diffusion coefficients for the phases
530
531private:
533 template<class PriVars>
534 auto getState_(const PriVars& priVars)
535 {
536 if constexpr (Detail::priVarsHaveState<PriVars>())
537 return priVars.state();
538 else
539 return Indices::bothPhases;
540 }
541
542};
543} // end namespace Dumux
544
545#endif
Type traits to be used with matrix types.
Helpers for deprecation.
Update the solid volume fractions (inert and reacitve) and set them in the solidstate.
Relations valid for an ideal gas.
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
Adaption of the non-isothermal two-phase two-component flow model to problems with CO2.
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 density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
static constexpr Scalar molarDensity(Scalar temperature, Scalar pressure)
The molar density of the gas , depending on pressure and temperature.
Definition: idealgas.hh:70
Definition: porousmediumflow/nonisothermal/volumevariables.hh:75
Helper structs to conditionally use a primary variable switch or not.
Definition: porousmediumflow/richards/volumevariables.hh:47
Definition: porousmediumflow/richards/volumevariables.hh:52
Volume averaged quantities required by the Richards model.
Definition: porousmediumflow/richards/volumevariables.hh:68
Scalar saturation(const int phaseIdx=liquidPhaseIdx) const
Returns the average absolute saturation [] of a given fluid phase within the finite volume.
Definition: porousmediumflow/richards/volumevariables.hh:346
FluidState fluidState_
the fluid state
Definition: porousmediumflow/richards/volumevariables.hh:519
Scalar relativePermeabilityWetting_
the relative permeability of the wetting phase
Definition: porousmediumflow/richards/volumevariables.hh:521
const PermeabilityType & permeability() const
Returns the permeability within the control volume in .
Definition: porousmediumflow/richards/volumevariables.hh:333
Scalar diffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the binary diffusion coefficients for a phase in .
Definition: porousmediumflow/richards/volumevariables.hh:497
Scalar waterContent(const int phaseIdx=liquidPhaseIdx) const
Returns the water content of a fluid phase within the finite volume.
Definition: porousmediumflow/richards/volumevariables.hh:449
Scalar porosity() const
Returns the average porosity [] within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:327
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/richards/volumevariables.hh:459
SolidState solidState_
Definition: porousmediumflow/richards/volumevariables.hh:520
const FluidState & fluidState() const
Returns the fluid configuration at the given primary variables.
Definition: porousmediumflow/richards/volumevariables.hh:306
Scalar viscosity(const int phaseIdx=liquidPhaseIdx) const
Returns the dynamic viscosity of a given phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:393
static constexpr auto liquidPhaseIdx
Export phase indices.
Definition: porousmediumflow/richards/volumevariables.hh:98
static constexpr auto gasPhaseIdx
Definition: porousmediumflow/richards/volumevariables.hh:99
Scalar pressureHead(const int phaseIdx=liquidPhaseIdx) const
Returns the pressureHead of a given phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:436
static constexpr bool enableWaterDiffusionInAir()
If water diffusion in air is enabled.
Definition: porousmediumflow/richards/volumevariables.hh:95
void update(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv)
Updates all quantities for a given control volume.
Definition: porousmediumflow/richards/volumevariables.hh:111
Scalar capillaryPressure() const
Returns the effective capillary pressure within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:416
PermeabilityType permeability_
the intrinsic permeability
Definition: porousmediumflow/richards/volumevariables.hh:522
Scalar density(const int phaseIdx=liquidPhaseIdx) const
Returns the average mass density of a given fluid phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:355
typename Traits::SolidSystem SolidSystem
Export type of solid system.
Definition: porousmediumflow/richards/volumevariables.hh:92
Scalar massFraction_[numPhases]
The water mass fractions in water and air.
Definition: porousmediumflow/richards/volumevariables.hh:525
Scalar effectiveDiffusionCoefficient(int phaseIdx, int compIIdx, int compJIdx) const
Returns the effective diffusion coefficients for a phase in .
Definition: porousmediumflow/richards/volumevariables.hh:510
Scalar molarDensity_[numPhases]
The molar density of water and air.
Definition: porousmediumflow/richards/volumevariables.hh:526
typename Traits::ModelTraits::Indices Indices
Definition: porousmediumflow/richards/volumevariables.hh:93
Scalar relativePermeability(const int phaseIdx=liquidPhaseIdx) const
Returns relative permeability [-] of a given phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:402
Scalar moleFraction_[numPhases]
The water mole fractions in water and air.
Definition: porousmediumflow/richards/volumevariables.hh:524
const SolidState & solidState() const
Returns the phase state for the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:312
typename Traits::SolidState SolidState
Definition: porousmediumflow/richards/volumevariables.hh:90
Scalar effectiveDiffCoeff_
Definition: porousmediumflow/richards/volumevariables.hh:529
void completeFluidState(const ElemSol &elemSol, const Problem &problem, const Element &element, const Scv &scv, FluidState &fluidState, SolidState &solidState)
Fills the fluid state according to the primary variables.
Definition: porousmediumflow/richards/volumevariables.hh:259
Scalar molarDensity(const int phaseIdx) const
Returns the mass density of a given phase within the control volume in .
Definition: porousmediumflow/richards/volumevariables.hh:488
Scalar massFraction(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/richards/volumevariables.hh:474
Scalar mobility(const int phaseIdx=liquidPhaseIdx) const
Returns the effective mobility of a given phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:383
Scalar pressure(const int phaseIdx=liquidPhaseIdx) const
Returns the effective pressure of a given phase within the control volume.
Definition: porousmediumflow/richards/volumevariables.hh:369
typename Traits::FluidSystem FluidSystem
Export type of the fluid system.
Definition: porousmediumflow/richards/volumevariables.hh:85
typename Traits::FluidState FluidState
Export type of the fluid state.
Definition: porousmediumflow/richards/volumevariables.hh:87
Scalar temperature() const
Returns the temperature.
Definition: porousmediumflow/richards/volumevariables.hh:318
Scalar minPc_
the minimum capillary pressure (entry pressure)
Definition: porousmediumflow/richards/volumevariables.hh:523
The primary variable switch controlling the phase presence state variable.
Definition: richardsextended/primaryvariableswitch.hh:41
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
static constexpr int numFluidPhases()
Return number of phases considered by the model.
Definition: porousmediumflow/volumevariables.hh:50
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.