3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
richards/primaryvariableswitch.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_PRIMARY_VARIABLE_SWITCH_HH
26#define DUMUX_RICHARDS_PRIMARY_VARIABLE_SWITCH_HH
27
32
33namespace Dumux {
34
40: public PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch>
41{
43 friend ParentType;
44
45public:
46 using ParentType::ParentType;
47
48protected:
49
50 // perform variable switch at a degree of freedom location
51 template<class VolumeVariables, class GlobalPosition>
52 bool update_(typename VolumeVariables::PrimaryVariables& priVars,
53 const VolumeVariables& volVars,
54 std::size_t dofIdxGlobal,
55 const GlobalPosition& globalPos)
56 {
57 using Scalar = typename VolumeVariables::PrimaryVariables::value_type;
58 using Indices = typename VolumeVariables::Indices;
59 using FluidSystem = typename VolumeVariables::FluidSystem;
60
61 static const bool usePriVarSwitch = getParam<bool>("Problem.UsePrimaryVariableSwitch");
62 if (!usePriVarSwitch)
63 return false;
64
65 if (!VolumeVariables::enableWaterDiffusionInAir())
66 DUNE_THROW(Dune::InvalidStateException, "The Richards primary variable switch only works with water diffusion in air enabled!");
67
68 static constexpr int liquidCompIdx = FluidSystem::liquidPhaseIdx;
69
70 // evaluate primary variable switch
71 bool wouldSwitch = false;
72 int phasePresence = priVars.state();
73 int newPhasePresence = phasePresence;
74
75 // check if a primary var switch is necessary
76 if (phasePresence == Indices::gasPhaseOnly)
77 {
78 // if the mole fraction of water is larger than the one
79 // predicted by a liquid-vapor equilibrium
80 Scalar xnw = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx);
81 Scalar xnwPredicted = FluidSystem::H2O::vaporPressure(volVars.temperature())
82 / volVars.pressure(FluidSystem::gasPhaseIdx);
83
84 Scalar xwMax = 1.0;
85 if (xnw / xnwPredicted > xwMax)
86 wouldSwitch = true;
87 if (this->wasSwitched_[dofIdxGlobal])
88 xwMax *= 1.01;
89
90 // if the ratio of predicted mole fraction to current mole fraction is larger than
91 // 100%, wetting phase appears
92 if (xnw / xnwPredicted > xwMax)
93 {
94 // wetting phase appears
95 if (this->verbosity() > 1)
96 std::cout << "Liquid phase appears at dof " << dofIdxGlobal
97 << ", coordinates: " << globalPos << ", xnw / xnwPredicted * 100: "
98 << xnw / xnwPredicted * 100 << "%"
99 << ", at x_n^w: " << priVars[Indices::switchIdx] << std::endl;
100 newPhasePresence = Indices::bothPhases;
101 priVars[Indices::switchIdx] = 0.0;
102 }
103 }
104 else if (phasePresence == Indices::bothPhases)
105 {
106 Scalar Smin = 0.0;
107 if (this->wasSwitched_[dofIdxGlobal])
108 Smin = -0.01;
109
110 if (volVars.saturation(FluidSystem::liquidPhaseIdx) <= Smin)
111 {
112 wouldSwitch = true;
113 // wetting phase disappears
114 newPhasePresence = Indices::gasPhaseOnly;
115 priVars[Indices::switchIdx] = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx);
116
117 if (this->verbosity() > 1)
118 std::cout << "Liquid phase disappears at dof " << dofIdxGlobal
119 << ", coordinates: " << globalPos << ", sw: "
120 << volVars.saturation(FluidSystem::liquidPhaseIdx)
121 << ", x_n^w: " << priVars[Indices::switchIdx] << std::endl;
122 }
123 }
124 else if (phasePresence == Indices::liquidPhaseOnly)
125 {
126 DUNE_THROW(Dune::NotImplemented, "Water phase only phase presence!");
127 }
128
129 priVars.setState(newPhasePresence);
130 this->wasSwitched_[dofIdxGlobal] = wouldSwitch;
131 return phasePresence != newPhasePresence;
132 }
133};
134
135} // end namespace Dumux
136
137#endif
Some exceptions thrown in DuMux
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
A central place for various physical constants occuring in some equations.
Definition: adapt.hh:29
std::string phasePresence() noexcept
I/O name of phase presence.
Definition: name.hh:147
The primary variable switch controlling the phase presence state variable.
Definition: compositional/primaryvariableswitch.hh:60
std::vector< bool > wasSwitched_
Definition: compositional/primaryvariableswitch.hh:361
int verbosity() const
The verbosity level.
Definition: compositional/primaryvariableswitch.hh:294
The primary variable switch controlling the phase presence state variable.
Definition: richards/primaryvariableswitch.hh:41
bool update_(typename VolumeVariables::PrimaryVariables &priVars, const VolumeVariables &volVars, std::size_t dofIdxGlobal, const GlobalPosition &globalPos)
Definition: richards/primaryvariableswitch.hh:52
The primary variable switch base class for compositional models.