3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
co2/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_2P2C_CO2_PRIMARY_VARIABLE_SWITCH_HH
26#define DUMUX_2P2C_CO2_PRIMARY_VARIABLE_SWITCH_HH
27
28#include <iostream>
29
32
33namespace Dumux
34{
44: public PrimaryVariableSwitch< TwoPTwoCCO2PrimaryVariableSwitch >
45{
47 friend ParentType;
48
49public:
50 using ParentType::ParentType;
51
52protected:
53 // perform variable switch at a degree of freedom location
54 template<class VolumeVariables, class IndexType, class GlobalPosition>
55 bool update_(typename VolumeVariables::PrimaryVariables& priVars,
56 const VolumeVariables& volVars,
57 IndexType dofIdxGlobal,
58 const GlobalPosition& globalPos)
59 {
60 using Scalar = typename VolumeVariables::PrimaryVariables::value_type;
61
62 using FluidSystem = typename VolumeVariables::FluidSystem;
63 static constexpr int phase0Idx = FluidSystem::phase0Idx;
64 static constexpr int phase1Idx = FluidSystem::phase1Idx;
65 static constexpr int comp0Idx = FluidSystem::comp0Idx;
66 static constexpr int comp1Idx = FluidSystem::comp1Idx;
67
68 static constexpr bool useMoles = VolumeVariables::useMoles();
69 static constexpr auto formulation = VolumeVariables::priVarFormulation();
70 static_assert( (formulation == TwoPFormulation::p0s1 || formulation == TwoPFormulation::p1s0),
71 "Chosen TwoPFormulation not supported!");
72
73 using Indices = typename VolumeVariables::Indices;
74 static constexpr int switchIdx = Indices::switchIdx;
75
76 // evaluate primary variable switch
77 bool wouldSwitch = false;
78 int phasePresence = priVars.state();
79 int newPhasePresence = phasePresence;
80
81 // the param cache to evaluate the equilibrium mole fraction
82 typename FluidSystem::ParameterCache paramCache;
83
84 // check if a primary var switch is necessary
85 if (phasePresence == Indices::secondPhaseOnly)
86 {
87 // calculate wetting component mole fraction in the second phase
88 Scalar xnw = volVars.moleFraction(phase1Idx, comp0Idx);
89 Scalar xnwMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, phase1Idx);
90
91 // if it is larger than the equilibirum mole fraction switch
92 if(xnw > xnwMax)
93 wouldSwitch = true;
94
95 if (this->wasSwitched_[dofIdxGlobal])
96 xnwMax *= 1.02;
97
98 // if it is larger than the equilibirum mole fraction switch: first phase appears
99 if (xnw > xnwMax)
100 {
101 // wetting phase appears
102 if (this->verbosity() > 1)
103 std::cout << "First phase (" << FluidSystem::phaseName(phase0Idx) << ") appears at dof " << dofIdxGlobal
104 << ", coordinates: " << globalPos
105 << ", x^" << FluidSystem::componentName(comp0Idx) << "_" << FluidSystem::phaseName(phase1Idx) << " > x_equilibrium: "
106 << xnw << " > " << xnwMax << std::endl;
107 newPhasePresence = Indices::bothPhases;
108 if (formulation == TwoPFormulation::p1s0)
109 priVars[switchIdx] = 0.0;
110 else
111 priVars[switchIdx] = 1.0;
112 }
113 }
114 else if (phasePresence == Indices::firstPhaseOnly)
115 {
116 // calculate second component mole fraction in the wetting phase
117 Scalar xwn = volVars.moleFraction(phase0Idx, comp1Idx);
118 Scalar xwnMax = FluidSystem::equilibriumMoleFraction(volVars.fluidState(), paramCache, phase0Idx);
119
120 // if it is larger than the equilibirum mole fraction switch
121 if(xwn > xwnMax)
122 wouldSwitch = true;
123
124 if (this->wasSwitched_[dofIdxGlobal])
125 xwnMax *= 1.02;
126
127 // if it is larger than the equilibirum mole fraction switch second phase appears
128 if(xwn > xwnMax)
129 {
130 // Second phase appears
131 if (this->verbosity() > 1)
132 std::cout << "Second phase (" << FluidSystem::phaseName(phase1Idx) << ") appears at dof " << dofIdxGlobal
133 << ", coordinates: " << globalPos
134 << ", x^" << FluidSystem::componentName(comp1Idx) << "_" << FluidSystem::phaseName(phase0Idx) << " > x_equilibrium: "
135 << xwn << " > " << xwnMax << std::endl;
136 newPhasePresence = Indices::bothPhases;
137 if (formulation == TwoPFormulation::p1s0)
138 priVars[switchIdx] = 0.999;
139 else
140 priVars[switchIdx] = 0.001;
141 }
142 }
143 // TODO: this is the same as for the 2p2c model maybe factor out
144 else if (phasePresence == Indices::bothPhases)
145 {
146 Scalar Smin = 0.0;
147 if (this->wasSwitched_[dofIdxGlobal])
148 Smin = -0.01;
149
150 if (volVars.saturation(phase1Idx) <= Smin)
151 {
152 wouldSwitch = true;
153 // nonwetting phase disappears
154 if (this->verbosity() > 1)
155 std::cout << "Second phase (" << FluidSystem::phaseName(phase1Idx) << ") disappears at dof " << dofIdxGlobal
156 << ", coordinates: " << globalPos
157 << ", S_" << FluidSystem::phaseName(phase1Idx) << ": " << volVars.saturation(phase1Idx)
158 << std::endl;
159 newPhasePresence = Indices::firstPhaseOnly;
160
161 if(useMoles) // mole-fraction formulation
162 priVars[switchIdx] = volVars.moleFraction(phase0Idx, comp1Idx);
163 else // mass-fraction formulation
164 priVars[switchIdx] = volVars.massFraction(phase0Idx, comp1Idx);
165 }
166 else if (volVars.saturation(phase0Idx) <= Smin)
167 {
168 wouldSwitch = true;
169 // wetting phase disappears
170 if (this->verbosity() > 1)
171 std::cout << "First phase (" << FluidSystem::phaseName(phase0Idx) << ") disappears at dof " << dofIdxGlobal
172 << ", coordinates: " << globalPos
173 << ", S_" << FluidSystem::phaseName(phase0Idx) << ": " << volVars.saturation(phase0Idx)
174 << std::endl;
175 newPhasePresence = Indices::secondPhaseOnly;
176
177 if(useMoles) // mole-fraction formulation
178 priVars[switchIdx] = volVars.moleFraction(phase1Idx, comp0Idx);
179 else // mass-fraction formulation
180 priVars[switchIdx] = volVars.massFraction(phase1Idx, comp0Idx);
181 }
182 }
183
184 priVars.setState(newPhasePresence);
185 this->wasSwitched_[dofIdxGlobal] = wouldSwitch;
186 return phasePresence != newPhasePresence;
187 }
188};
189
190} // end namespace Dumux
191
192#endif
Defines an enumeration for the formulations accepted by the two-phase model.
@ p1s0
first phase saturation and second phase pressure as primary variables
@ p0s1
first phase pressure and second phase saturation as primary variables
Definition: adapt.hh:29
std::string phasePresence() noexcept
I/O name of phase presence.
Definition: name.hh:147
The primary variable switch for the 2p2c-CO2 model controlling the phase presence state variable.
Definition: co2/primaryvariableswitch.hh:45
bool update_(typename VolumeVariables::PrimaryVariables &priVars, const VolumeVariables &volVars, IndexType dofIdxGlobal, const GlobalPosition &globalPos)
Definition: co2/primaryvariableswitch.hh:55
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 base class for compositional models.