version 3.11-dev
Loading...
Searching...
No Matches
richardsextended/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// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12
13#ifndef DUMUX_RICHARDSEXTENDED_PRIMARY_VARIABLE_SWITCH_HH
14#define DUMUX_RICHARDSEXTENDED_PRIMARY_VARIABLE_SWITCH_HH
15
16#include <utility>
17
18#include <dune/common/std/type_traits.hh>
19
24
25namespace Dumux {
26
28
29template<class FluidSystem, class FluidState>
30using VaporPressureFromFluidState = decltype(FluidSystem::vaporPressure(std::declval<const FluidState&>(), 0));
31
38template<class FluidSystem, class FluidState>
39auto equilibriumVaporPressure(const FluidState& fluidState)
40{
41 if constexpr (Dune::Std::is_detected_v<VaporPressureFromFluidState, FluidSystem, FluidState>)
42 return FluidSystem::vaporPressure(fluidState, FluidSystem::comp0Idx);
43 else
44 return FluidSystem::H2O::vaporPressure(fluidState.temperature(FluidSystem::liquidPhaseIdx));
45}
46
47} // end namespace Detail::ExtendedRichards
48
54: public PrimaryVariableSwitch<ExtendedRichardsPrimaryVariableSwitch>
55{
57 friend ParentType;
58
59public:
60 using ParentType::ParentType;
61
62protected:
63
64 // perform variable switch at a degree of freedom location
65 template<class VolumeVariables, class GlobalPosition>
66 bool update_(typename VolumeVariables::PrimaryVariables& priVars,
67 const VolumeVariables& volVars,
68 std::size_t dofIdxGlobal,
69 const GlobalPosition& globalPos)
70 {
71 using Scalar = typename VolumeVariables::PrimaryVariables::value_type;
72 using Indices = typename VolumeVariables::Indices;
73 using FluidSystem = typename VolumeVariables::FluidSystem;
74
75 static const bool usePriVarSwitch = getParam<bool>("Richards.UsePrimaryVariableSwitch");
76 if (!usePriVarSwitch)
77 return false;
78
79 static constexpr int liquidCompIdx = FluidSystem::liquidPhaseIdx;
80
81 // evaluate primary variable switch
82 bool wouldSwitch = false;
83 int phasePresence = priVars.state();
84 int newPhasePresence = phasePresence;
85
86 // check if a primary var switch is necessary
87 if (phasePresence == Indices::gasPhaseOnly)
88 {
89 // if the mole fraction of water is larger than the one
90 // predicted by a liquid-vapor equilibrium
91 Scalar xnw = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx);
92 Scalar xnwPredicted = Detail::ExtendedRichards::equilibriumVaporPressure<FluidSystem>(volVars.fluidState())
93 / volVars.pressure(FluidSystem::gasPhaseIdx);
94
95 Scalar xwMax = 1.0;
96 if (xnw / xnwPredicted > xwMax)
97 wouldSwitch = true;
98 if (this->wasSwitched_[dofIdxGlobal])
99 xwMax *= 1.01;
100
101 // if the ratio of predicted mole fraction to current mole fraction is larger than
102 // 100%, wetting phase appears
103 if (xnw / xnwPredicted > xwMax)
104 {
105 // wetting phase appears
106 if (this->verbosity() > 1)
107 std::cout << "Liquid phase appears at dof " << dofIdxGlobal
108 << ", coordinates: " << globalPos << ", xnw / xnwPredicted * 100: "
109 << xnw / xnwPredicted * 100 << "%"
110 << ", at x_n^w: " << priVars[Indices::switchIdx] << std::endl;
111 newPhasePresence = Indices::bothPhases;
112 priVars[Indices::switchIdx] = 0.0;
113 }
114 }
115 else if (phasePresence == Indices::bothPhases)
116 {
117 Scalar Smin = 0.0;
118 if (this->wasSwitched_[dofIdxGlobal])
119 Smin = -0.01;
120
121 if (volVars.saturation(FluidSystem::liquidPhaseIdx) <= Smin)
122 {
123 wouldSwitch = true;
124 // wetting phase disappears
125 newPhasePresence = Indices::gasPhaseOnly;
126 priVars[Indices::switchIdx] = volVars.moleFraction(FluidSystem::gasPhaseIdx, liquidCompIdx);
127
128 if (this->verbosity() > 1)
129 std::cout << "Liquid phase disappears at dof " << dofIdxGlobal
130 << ", coordinates: " << globalPos << ", sw: "
131 << volVars.saturation(FluidSystem::liquidPhaseIdx)
132 << ", x_n^w: " << priVars[Indices::switchIdx] << std::endl;
133 }
134 }
135 else if (phasePresence == Indices::liquidPhaseOnly)
136 {
137 DUNE_THROW(Dune::NotImplemented, "Water phase only phase presence!");
138 }
139
140 priVars.setState(newPhasePresence);
141 this->wasSwitched_[dofIdxGlobal] = wouldSwitch;
142 return phasePresence != newPhasePresence;
143 }
144};
145
146} // end namespace Dumux
147
148#endif
The primary variable switch controlling the phase presence state variable.
Definition richardsextended/primaryvariableswitch.hh:55
bool update_(typename VolumeVariables::PrimaryVariables &priVars, const VolumeVariables &volVars, std::size_t dofIdxGlobal, const GlobalPosition &globalPos)
Definition richardsextended/primaryvariableswitch.hh:66
std::vector< bool > wasSwitched_
Definition compositional/primaryvariableswitch.hh:458
PrimaryVariableSwitch(int verbosity=1)
Definition compositional/primaryvariableswitch.hh:51
int verbosity() const
Definition compositional/primaryvariableswitch.hh:296
The primary variable switch base class for compositional models.
A central place for various physical constants occurring in some equations.
Some exceptions thrown in DuMux.
auto equilibriumVaporPressure(const FluidState &fluidState)
The vapor pressure of water in equilibrium with the liquid phase.
Definition richardsextended/primaryvariableswitch.hh:39
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:155
Definition richardsextended/primaryvariableswitch.hh:27
decltype(FluidSystem::vaporPressure(std::declval< const FluidState & >(), 0)) VaporPressureFromFluidState
Definition richardsextended/primaryvariableswitch.hh:30
Definition adapt.hh:17
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.