3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
evalcflfluxdefault.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#ifndef DUMUX_EVALCFLFLUX_DEFAULT_HH
25#define DUMUX_EVALCFLFLUX_DEFAULT_HH
26
28#include "evalcflflux.hh"
29
31
32namespace Dumux {
41template<class TypeTag>
42class EvalCflFluxDefault: public EvalCflFlux<TypeTag>
43{
44private:
48
50
51 enum
52 {
53 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx
54 };
55
56 enum
57 {
58 vt = Indices::velocityTotal
59 };
60
61 using Element = typename GridView::Traits::template Codim<0>::Entity;
62 using Intersection = typename GridView::Intersection;
63
64public:
65
71 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux,
72 const Element& element, int phaseIdx = -1)
73 {
74 addFlux(lambdaW, lambdaNw, viscosityW, viscosityNw, flux, phaseIdx);
75 }
76
82 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux,
83 const Intersection& intersection, int phaseIdx = -1)
84 {
85 addFlux(lambdaW, lambdaNw, viscosityW, viscosityNw, flux, phaseIdx);
86 }
87
93 Scalar getCflFluxFunction(const Element& element);
94
100 Scalar getDt(const Element& element)
101 {
102 using std::max;
103 Scalar porosity = max(problem_.spatialParams().porosity(element), porosityThreshold_);
104
105 return (getCflFluxFunction(element) * porosity * element.geometry().volume());
106 }
107
109 void reset()
110 {
111 fluxWettingOut_ = 0;
112 fluxNonwettingOut_ = 0;
113 fluxIn_ = 0;
114 fluxOut_ = 0;
115 }
116
122 EvalCflFluxDefault (Problem& problem)
123 : problem_(problem)
124 {
125 porosityThreshold_ = getParam<Scalar>("Impet.PorosityThreshold");
126 reset();
127 }
128
129private:
130 // TODO doc me!
131 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux, int phaseIdx = -1)
132 {
133 using std::abs;
134 Scalar krSum = lambdaW * viscosityW + lambdaNw * viscosityNw;
135 Scalar viscosityRatio = 1 - abs(0.5 - viscosityNw / (viscosityW + viscosityNw));
136 //1 - abs(viscosityWI-viscosityNwI)/(viscosityWI+viscosityNwI);
137
138 switch (phaseIdx)
139 {
140 case wPhaseIdx:
141 {
142 //for time step criterion
143 if (flux >= 0)
144 {
145 fluxWettingOut_ += flux / (krSum * viscosityRatio);
146 }
147 if (flux < 0)
148 {
149 fluxIn_ -= flux / (krSum * viscosityRatio);
150 }
151
152 break;
153 }
154
155 //for time step criterion if the nonwetting phase velocity is used
156 case nPhaseIdx:
157 {
158 if (flux >= 0)
159 {
160 fluxNonwettingOut_ += flux / (krSum * viscosityRatio);
161 }
162 if (flux < 0)
163 {
164 fluxIn_ -= flux / (krSum * viscosityRatio);
165 }
166
167 break;
168 }
169 default:
170 {
171 if (flux >= 0)
172 {
173 fluxOut_ += flux / (krSum * viscosityRatio);
174 }
175 if (flux < 0)
176 {
177 fluxIn_ -= flux / (krSum * viscosityRatio);
178 }
179
180 break;
181 }
182 }
183 }
184
185 // TODO doc me!
186 Scalar getCFLFluxIn(int phaseIdx = 0)
187 {
188 using std::isnan;
189 using std::isinf;
190 if (isnan(fluxIn_) || isinf(fluxIn_))
191 {
192 fluxIn_ = 1e-100;
193 }
194
195 return fluxIn_;
196 }
197
198 // TODO doc me!
199 Scalar getCFLFluxOut(int phaseIdx = 0)
200 {
201 using std::isnan;
202 using std::isinf;
203 if (isnan(fluxWettingOut_) || isinf(fluxWettingOut_))
204 {
205 fluxWettingOut_ = 1e-100;
206 }
207
208 if (isnan(fluxNonwettingOut_) || isinf(fluxNonwettingOut_))
209 {
210 fluxNonwettingOut_ = 1e-100;
211 }
212 if (isnan(fluxOut_) || isinf(fluxOut_))
213 {
214 fluxOut_ = 1e-100;
215 }
216
217 if (phaseIdx == wPhaseIdx)
218 return fluxWettingOut_;
219 else if (phaseIdx == nPhaseIdx)
220 return fluxNonwettingOut_;
221 else
222 return fluxOut_;
223 }
224
225 Problem& problem_;//problem data
226 Scalar fluxWettingOut_;
227 Scalar fluxNonwettingOut_;
228 Scalar fluxOut_;
229 Scalar fluxIn_;
230 Scalar porosityThreshold_;
231 static const int velocityType_ = getPropValue<TypeTag, Properties::VelocityFormulation>();
232 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
233};
234
236template<class TypeTag>
237typename EvalCflFluxDefault<TypeTag>::Scalar EvalCflFluxDefault<TypeTag>::getCflFluxFunction(const Element& element)
238{
239 // old material law interface is deprecated: Replace this by
240 // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center());
241 // after the release of 3.3, when the deprecated interface is no longer supported
242 const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem_.spatialParams(), element);
243
244 const Scalar residualSatW = fluidMatrixInteraction.pcSwCurve().effToAbsParams().swr();
245 const Scalar residualSatNw = fluidMatrixInteraction.pcSwCurve().effToAbsParams().snr();
246
247 // compute dt restriction
248 const Scalar volumeCorrectionFactor = 1 - residualSatW - residualSatNw;
249 Scalar volumeCorrectionFactorOutW = 0;
250 Scalar volumeCorrectionFactorOutNw = 0;
251
252 Scalar satW = problem_.variables().cellData(problem_.variables().index(element)).saturation(wPhaseIdx);
253 using std::max;
254 volumeCorrectionFactorOutW = max((satW - residualSatW), 1e-2);
255 volumeCorrectionFactorOutNw = max((1 - satW - residualSatNw), 1e-2);
256
257 //make sure correction is in the right range. If not: force dt to be not min-dt!
258 if (volumeCorrectionFactorOutW <= 0)
259 {
260 volumeCorrectionFactorOutW = 1e100;
261 }
262 if (volumeCorrectionFactorOutNw <= 0)
263 {
264 volumeCorrectionFactorOutNw = 1e100;
265 }
266
267 //correct volume
268 Scalar cFLFluxIn = volumeCorrectionFactor / getCFLFluxIn();
269 Scalar cFLFluxOut = 0;
270
271 using std::min;
272 if (velocityType_ == vt)
273 {
274 cFLFluxOut = volumeCorrectionFactor / getCFLFluxOut(-1);
275 }
276 else
277 {
278 cFLFluxOut = min(volumeCorrectionFactorOutW / getCFLFluxOut(wPhaseIdx),
279 volumeCorrectionFactorOutNw / getCFLFluxOut(nPhaseIdx));
280 }
281
282 //determine timestep
283 const Scalar cFLFluxFunction = min(cFLFluxIn, cFLFluxOut);
284
285 return cFLFluxFunction;
286}
287
288} // end namespace Dumux
289
290#endif
Helpers for deprecation.
Base class for implementations of different kinds of fluxes to evaluate a CFL-Condition.
Base file for properties related to sequential IMPET algorithms.
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
std::string porosity() noexcept
I/O name of porosity.
Definition: name.hh:139
Base class for implementations of different kinds of fluxes to evaluate a CFL-Condition.
Definition: evalcflflux.hh:52
Default implementation of cfl-fluxes to evaluate a CFL-Condition.
Definition: evalcflfluxdefault.hh:43
EvalCflFluxDefault(Problem &problem)
Constructs an EvalCflFluxDefault object.
Definition: evalcflfluxdefault.hh:122
Scalar getCflFluxFunction(const Element &element)
Returns the CFL flux-function.
Definition: evalcflfluxdefault.hh:237
void addFlux(Scalar &lambdaW, Scalar &lambdaNw, Scalar &viscosityW, Scalar &viscosityNw, Scalar flux, const Element &element, int phaseIdx=-1)
adds a flux to the cfl-criterion evaluation
Definition: evalcflfluxdefault.hh:71
void reset()
resets the accumulated CFL-fluxes to zero
Definition: evalcflfluxdefault.hh:109
Scalar getDt(const Element &element)
Returns the CFL time-step.
Definition: evalcflfluxdefault.hh:100
void addFlux(Scalar &lambdaW, Scalar &lambdaNw, Scalar &viscosityW, Scalar &viscosityNw, Scalar flux, const Intersection &intersection, int phaseIdx=-1)
adds a flux to the cfl-criterion evaluation
Definition: evalcflfluxdefault.hh:82