3.2-git
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
30namespace Dumux {
39template<class TypeTag>
40class EvalCflFluxDefault: public EvalCflFlux<TypeTag>
41{
42private:
46
48
49 enum
50 {
51 wPhaseIdx = Indices::wPhaseIdx, nPhaseIdx = Indices::nPhaseIdx
52 };
53
54 enum
55 {
56 vt = Indices::velocityTotal
57 };
58
59 using Element = typename GridView::Traits::template Codim<0>::Entity;
60 using Intersection = typename GridView::Intersection;
61
62public:
63
69 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux,
70 const Element& element, int phaseIdx = -1)
71 {
72 addFlux(lambdaW, lambdaNw, viscosityW, viscosityNw, flux, phaseIdx);
73 }
74
80 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux,
81 const Intersection& intersection, int phaseIdx = -1)
82 {
83 addFlux(lambdaW, lambdaNw, viscosityW, viscosityNw, flux, phaseIdx);
84 }
85
91 Scalar getCflFluxFunction(const Element& element);
92
98 Scalar getDt(const Element& element)
99 {
100 using std::max;
101 Scalar porosity = max(problem_.spatialParams().porosity(element), porosityThreshold_);
102
103 return (getCflFluxFunction(element) * porosity * element.geometry().volume());
104 }
105
107 void reset()
108 {
109 fluxWettingOut_ = 0;
110 fluxNonwettingOut_ = 0;
111 fluxIn_ = 0;
112 fluxOut_ = 0;
113 }
114
120 EvalCflFluxDefault (Problem& problem)
121 : problem_(problem)
122 {
123 porosityThreshold_ = getParam<Scalar>("Impet.PorosityThreshold");
124 reset();
125 }
126
127private:
128 // TODO doc me!
129 void addFlux(Scalar& lambdaW, Scalar& lambdaNw, Scalar& viscosityW, Scalar& viscosityNw, Scalar flux, int phaseIdx = -1)
130 {
131 using std::abs;
132 Scalar krSum = lambdaW * viscosityW + lambdaNw * viscosityNw;
133 Scalar viscosityRatio = 1 - abs(0.5 - viscosityNw / (viscosityW + viscosityNw));
134 //1 - abs(viscosityWI-viscosityNwI)/(viscosityWI+viscosityNwI);
135
136 switch (phaseIdx)
137 {
138 case wPhaseIdx:
139 {
140 //for time step criterion
141 if (flux >= 0)
142 {
143 fluxWettingOut_ += flux / (krSum * viscosityRatio);
144 }
145 if (flux < 0)
146 {
147 fluxIn_ -= flux / (krSum * viscosityRatio);
148 }
149
150 break;
151 }
152
153 //for time step criterion if the non-wetting phase velocity is used
154 case nPhaseIdx:
155 {
156 if (flux >= 0)
157 {
158 fluxNonwettingOut_ += flux / (krSum * viscosityRatio);
159 }
160 if (flux < 0)
161 {
162 fluxIn_ -= flux / (krSum * viscosityRatio);
163 }
164
165 break;
166 }
167 default:
168 {
169 if (flux >= 0)
170 {
171 fluxOut_ += flux / (krSum * viscosityRatio);
172 }
173 if (flux < 0)
174 {
175 fluxIn_ -= flux / (krSum * viscosityRatio);
176 }
177
178 break;
179 }
180 }
181 }
182
183 // TODO doc me!
184 Scalar getCFLFluxIn(int phaseIdx = 0)
185 {
186 using std::isnan;
187 using std::isinf;
188 if (isnan(fluxIn_) || isinf(fluxIn_))
189 {
190 fluxIn_ = 1e-100;
191 }
192
193 return fluxIn_;
194 }
195
196 // TODO doc me!
197 Scalar getCFLFluxOut(int phaseIdx = 0)
198 {
199 using std::isnan;
200 using std::isinf;
201 if (isnan(fluxWettingOut_) || isinf(fluxWettingOut_))
202 {
203 fluxWettingOut_ = 1e-100;
204 }
205
206 if (isnan(fluxNonwettingOut_) || isinf(fluxNonwettingOut_))
207 {
208 fluxNonwettingOut_ = 1e-100;
209 }
210 if (isnan(fluxOut_) || isinf(fluxOut_))
211 {
212 fluxOut_ = 1e-100;
213 }
214
215 if (phaseIdx == wPhaseIdx)
216 return fluxWettingOut_;
217 else if (phaseIdx == nPhaseIdx)
218 return fluxNonwettingOut_;
219 else
220 return fluxOut_;
221 }
222
223 Problem& problem_;//problem data
224 Scalar fluxWettingOut_;
225 Scalar fluxNonwettingOut_;
226 Scalar fluxOut_;
227 Scalar fluxIn_;
228 Scalar porosityThreshold_;
229 static const int velocityType_ = getPropValue<TypeTag, Properties::VelocityFormulation>();
230 static const int saturationType_ = getPropValue<TypeTag, Properties::SaturationFormulation>();
231};
232
234template<class TypeTag>
235typename EvalCflFluxDefault<TypeTag>::Scalar EvalCflFluxDefault<TypeTag>::getCflFluxFunction(const Element& element)
236{
237 Scalar residualSatW = problem_.spatialParams().materialLawParams(element).swr();
238 Scalar residualSatNw = problem_.spatialParams().materialLawParams(element).snr();
239
240 // compute dt restriction
241 Scalar volumeCorrectionFactor = 1 - residualSatW - residualSatNw;
242 Scalar volumeCorrectionFactorOutW = 0;
243 Scalar volumeCorrectionFactorOutNw = 0;
244
245 Scalar satW = problem_.variables().cellData(problem_.variables().index(element)).saturation(wPhaseIdx);
246 using std::max;
247 volumeCorrectionFactorOutW = max((satW - residualSatW), 1e-2);
248 volumeCorrectionFactorOutNw = max((1 - satW - residualSatNw), 1e-2);
249
250 //make sure correction is in the right range. If not: force dt to be not min-dt!
251 if (volumeCorrectionFactorOutW <= 0)
252 {
253 volumeCorrectionFactorOutW = 1e100;
254 }
255 if (volumeCorrectionFactorOutNw <= 0)
256 {
257 volumeCorrectionFactorOutNw = 1e100;
258 }
259
260 //correct volume
261 Scalar cFLFluxIn = volumeCorrectionFactor / getCFLFluxIn();
262 Scalar cFLFluxOut = 0;
263
264 using std::min;
265 if (velocityType_ == vt)
266 {
267 cFLFluxOut = volumeCorrectionFactor / getCFLFluxOut(-1);
268 }
269 else
270 {
271 cFLFluxOut = min(volumeCorrectionFactorOutW / getCFLFluxOut(wPhaseIdx),
272 volumeCorrectionFactorOutNw / getCFLFluxOut(nPhaseIdx));
273 }
274
275 //determine timestep
276 Scalar cFLFluxFunction = min(cFLFluxIn, cFLFluxOut);
277
278 return cFLFluxFunction;
279}
280
281} // end namespace Dumux
282
283#endif
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:41
EvalCflFluxDefault(Problem &problem)
Constructs an EvalCflFluxDefault object.
Definition: evalcflfluxdefault.hh:120
Scalar getCflFluxFunction(const Element &element)
Returns the CFL flux-function.
Definition: evalcflfluxdefault.hh:235
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:69
void reset()
resets the accumulated CFL-fluxes to zero
Definition: evalcflfluxdefault.hh:107
Scalar getDt(const Element &element)
Returns the CFL time-step.
Definition: evalcflfluxdefault.hh:98
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:80