3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
Loading...
Searching...
No Matches
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 *****************************************************************************/
24
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 {
50
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_);
171 fluidState_.setDensity(liquidPhaseIdx, FluidSystem::density(fluidState_, paramCache, liquidPhaseIdx));
172 fluidState_.setDensity(gasPhaseIdx, FluidSystem::density(fluidState_, paramCache, gasPhaseIdx));
173 fluidState_.setViscosity(liquidPhaseIdx, FluidSystem::viscosity(fluidState_, paramCache, liquidPhaseIdx));
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,
290 FluidSystem::density(fluidState, paramCache, liquidPhaseIdx));
291 fluidState.setDensity(gasPhaseIdx,
292 FluidSystem::density(fluidState, paramCache, gasPhaseIdx));
293
294 fluidState.setViscosity(liquidPhaseIdx,
295 FluidSystem::viscosity(fluidState, paramCache, 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.
EnergyVolumeVariablesImplementation< IsothermalTraits, Impl, IsothermalTraits::ModelTraits::enableEnergyBalance()> EnergyVolumeVariables
Base class for the model specific class which provides access to all volume averaged quantities.
Definition porousmediumflow/nonisothermal/volumevariables.hh:85
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
Distance implementation details.
Definition cvfelocalresidual.hh:37
constexpr bool priVarsHaveState()
Definition state.hh:44
static constexpr Scalar molarDensity(Scalar temperature, Scalar pressure)
The molar density of the gas , depending on pressure and temperature.
Definition idealgas.hh:70
Helper structs to conditionally use a primary variable switch or not.
Definition porousmediumflow/richards/volumevariables.hh:47
ExtendedRichardsPrimaryVariableSwitch PrimaryVariableSwitch
Definition porousmediumflow/richards/volumevariables.hh:48
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_
Definition porousmediumflow/richards/volumevariables.hh:519
Scalar relativePermeabilityWetting_
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
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
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_
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 NITraits< BaseTraits, ETCM >::SolidSystem SolidSystem
Definition porousmediumflow/richards/volumevariables.hh:92
Scalar massFraction_[numPhases]
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]
Definition porousmediumflow/richards/volumevariables.hh:526
typename NITraits< BaseTraits, ETCM >::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]
Definition porousmediumflow/richards/volumevariables.hh:524
const SolidState & solidState() const
Definition porousmediumflow/richards/volumevariables.hh:312
typename NITraits< BaseTraits, ETCM >::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 NITraits< BaseTraits, ETCM >::FluidSystem FluidSystem
Definition porousmediumflow/richards/volumevariables.hh:85
typename NITraits< BaseTraits, ETCM >::FluidState FluidState
Definition porousmediumflow/richards/volumevariables.hh:87
Scalar temperature() const
Returns the temperature.
Definition porousmediumflow/richards/volumevariables.hh:318
Scalar minPc_
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
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.