3.2-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
regularizedvangenuchten.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 REGULARIZED_VAN_GENUCHTEN_HH
26#define REGULARIZED_VAN_GENUCHTEN_HH
27
28#include "vangenuchten.hh"
30
31#include <algorithm>
32
34
35namespace Dumux {
36
69template <class ScalarT, class ParamsT = RegularizedVanGenuchtenParams<ScalarT> >
71{
73
74public:
75 using Params = ParamsT;
76 using Scalar = typename Params::Scalar;
77
91 static Scalar pc(const Params &params, Scalar swe)
92 {
93 // retrieve the low and the high threshold saturations for the
94 // unregularized capillary pressure curve from the parameters
95 const Scalar swThLow = params.pcLowSw();
96 const Scalar swThHigh = params.pcHighSw();
97
98 // make sure that the capillary pressure observes a derivative
99 // != 0 for 'illegal' saturations. This is favourable for the
100 // newton solver (if the derivative is calculated numerically)
101 // in order to get the saturation moving to the right
102 // direction if it temporarily is in an 'illegal' range.
103 if (swe < swThLow) {
104 return VanGenuchten::pc(params, swThLow) + mLow_(params)*(swe - swThLow);
105 }
106 else if (swe > swThHigh)
107 {
108 Scalar yTh = VanGenuchten::pc(params, swThHigh);
109 Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
110
111 if (swe < 1.0) {
112 // use spline between threshold swe and 1.0
113 Scalar mTh = VanGenuchten::dpc_dswe(params, swThHigh);
114 Spline<Scalar> sp(swThHigh, 1.0, // x0, x1
115 yTh, 0, // y0, y1
116 mTh, m1); // m0, m1
117 return sp.eval(swe);
118 }
119 else {
120 // straight line for swe > 1.0
121 return m1*(swe - 1.0) + 0.0;
122 }
123 }
124
125 // if the effective saturation is in an 'reasonable'
126 // range, we use the real van genuchten law...
127 return VanGenuchten::pc(params, swe);
128 }
129
145 static Scalar sw(const Params &params, Scalar pc)
146 {
147 // retrieve the low and the high threshold saturations for the
148 // unregularized capillary pressure curve from the parameters
149 const Scalar swThLow = params.pcLowSw();
150 const Scalar swThHigh = params.pcHighSw();
151
152 // calculate the saturation which corrosponds to the
153 // saturation in the non-regularized verision of van
154 // Genuchten's law
155 Scalar sw;
156 if (pc <= 0) {
157 // for swThHigh = 1.0 the slope would get infinity
158 // swThHigh > 1.0 are not sensible threshold values
159 // setting swThHigh = 1.0 is a way to disable regularization
160 if (swThHigh > 1.0 - std::numeric_limits<Scalar>::epsilon())
161 return 1.0;
162
163 // invert straight line for swe > 1.0
164 Scalar yTh = VanGenuchten::pc(params, swThHigh);
165 Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
166 return pc/m1 + 1.0;
167 }
168 else
169 sw = VanGenuchten::sw(params, pc);
170
171 // invert the regularization if necessary
172 if (sw <= swThLow) {
173 // invert the low saturation regularization of pc()
174 Scalar pcswLow = VanGenuchten::pc(params, swThLow);
175 return (pc - pcswLow)/mLow_(params) + swThLow;
176 }
177 else if (sw > swThHigh)
178 {
179 Scalar yTh = VanGenuchten::pc(params, swThHigh);
180 Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
181
182 // invert spline between threshold swe and 1.0
183 Scalar mTh = VanGenuchten::dpc_dswe(params, swThHigh);
184 Spline<Scalar> sp(swThHigh, 1.0, // x0, x1
185 yTh, 0, // m0, m1
186 mTh, m1); // m0, m1
187 return sp.intersectInterval(swThHigh, 1.0,
188 0, 0, 0, pc);
189 }
190
191 return sw;
192 }
193
201 static Scalar endPointPc(const Params &params)
202 { return 0.0; }
203
218 static Scalar dpc_dswe(const Params &params, Scalar swe)
219 {
220 // retrieve the low and the high threshold saturations for the
221 // unregularized capillary pressure curve from the parameters
222 const Scalar swThLow = params.pcLowSw();
223 const Scalar swThHigh = params.pcHighSw();
224
225 // derivative of the regularization
226 if (swe < swThLow) {
227 // the slope of the straight line used in pc()
228 return mLow_(params);
229 }
230 else if (swe > swThHigh)
231 {
232 Scalar yTh = VanGenuchten::pc(params, swThHigh);
233 Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
234
235 if (swe < 1.0) {
236 // use spline between threshold swe and 1.0
237 Scalar mTh = VanGenuchten::dpc_dswe(params, swThHigh);
238 Spline<Scalar> sp(swThHigh, 1.0, // x0, x1
239 yTh, 0, // y0, y1
240 mTh, m1); // m0, m1
241 return sp.evalDerivative(swe);
242 }
243 else {
244 // straight line for swe > 1.0
245 return m1;
246 }
247 }
248
249 return VanGenuchten::dpc_dswe(params, swe);
250 }
251
265 static Scalar dswe_dpc(const Params &params, Scalar pc)
266 {
267 const Scalar swThLow = params.pcLowSw();
268 const Scalar swThHigh = params.pcHighSw();
269
270 if (pc <= 0)
271 {
272 // for swThHigh = 1.0 the slope gets infinity
273 // swThHigh > 1.0 are not sensible threshold values
274 // setting swThHigh = 1.0 is a way to disable regularization
275 // return the maximum representable number with the given precision
276 if (swThHigh > 1.0 - std::numeric_limits<Scalar>::epsilon())
277 return std::numeric_limits<Scalar>::max();
278
279 Scalar yTh = VanGenuchten::pc(params, swThHigh);
280 Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
281 return 1.0/m1;
282 }
283
284 const auto sw = VanGenuchten::sw(params, pc);
285
286 // derivative of the regularization
287 if (sw <= swThLow)
288 return 1/mLow_(params);
289
290 if (sw > swThHigh)
291 {
292 const Scalar yTh = VanGenuchten::pc(params, swThHigh);
293 const Scalar m1 = (0.0 - yTh)/(1.0 - swThHigh)*2;
294
295 // invert spline between threshold swe and 1.0
296 const Scalar mTh = VanGenuchten::dpc_dswe(params, swThHigh);
297 const Spline<Scalar> sp(swThHigh, 1.0, // x0, x1
298 yTh, 0, // m0, m1
299 mTh, m1); // m0, m1
300 const auto swReg = sp.intersectInterval(swThHigh, 1.0,
301 0, 0, 0, pc);
302 // derivative of the inverse of the function is one over derivative of the function
303 return 1.0/sp.evalDerivative(swReg);
304 }
305
306 return VanGenuchten::dswe_dpc(params, pc);
307 }
308
323 static Scalar krw(const Params &params, Scalar swe)
324 {
325 // retrieve the high threshold saturation for the
326 // unregularized relative permeability curve of the wetting
327 // phase from the parameters
328 const Scalar swThHigh = params.krwHighSw();
329
330 if (swe < 0)
331 return 0;
332 else if (swe > 1 - std::numeric_limits<Scalar>::epsilon())
333 return 1;
334 else if (swe > swThHigh) {
336 Spline sp(swThHigh, 1.0, // x1, x2
337 VanGenuchten::krw(params, swThHigh), 1.0, // y1, y2
338 VanGenuchten::dkrw_dswe(params, swThHigh), 0); // m1, m2
339 return sp.eval(swe);
340 }
341
342 return VanGenuchten::krw(params, swe);
343 }
344
352 static Scalar dkrw_dswe(const Params &params, Scalar swe)
353 {
354 // retrieve the high threshold saturation for the
355 // unregularized relative permeability curve of the wetting
356 // phase from the parameters
357 const Scalar swThHigh = params.krwHighSw();
358
359 // derivative of the regularization
360 // the slope is zero below sw=0.0 and above sw=1.0
361 if (swe < 0)
362 return 0.0;
363 else if (swe > 1 - std::numeric_limits<Scalar>::epsilon())
364 return 0.0;
365
366 // for high sw we need the slope of the interpolation spline
367 else if (swe > swThHigh) {
369 Spline sp(swThHigh, 1.0, // x1, x2
370 VanGenuchten::krw(params, swThHigh), 1.0, // y1, y2
371 VanGenuchten::dkrw_dswe(params, swThHigh), 0); // m1, m2
372 return sp.evalDerivative(swe);
373 }
374
375 return VanGenuchten::dkrw_dswe(params, swe);
376 }
377
392 static Scalar krn(const Params &params, Scalar swe)
393 {
394 // retrieve the low threshold saturation for the unregularized
395 // relative permeability curve of the non-wetting phase from
396 // the parameters
397 const Scalar swThLow = params.krnLowSw();
398
399 if (swe <= 0)
400 return 1;
401 else if (swe >= 1)
402 return 0;
403 else if (swe < swThLow) {
405 Spline sp(0.0, swThLow, // x1, x2
406 1.0, VanGenuchten::krn(params, swThLow), // y1, y2
407 0.0, VanGenuchten::dkrn_dswe(params, swThLow)); // m1, m2
408 return sp.eval(swe);
409 }
410
411 return VanGenuchten::krn(params, swe);
412 }
413
421 static Scalar dkrn_dswe(const Params &params, Scalar swe)
422 {
423 // retrieve the low threshold saturation for the unregularized
424 // relative permeability curve of the non-wetting phase from
425 // the parameters
426 const Scalar swThLow = params.krnLowSw();
427
428 if (swe <= 0)
429 return 0.0;
430 else if (swe >= 1)
431 return 0.0;
432 else if (swe < swThLow) {
434 Spline sp(0.0, swThLow, // x1, x2
435 1.0, VanGenuchten::krn(params, swThLow), // y1, y2
436 0.0, VanGenuchten::dkrn_dswe(params, swThLow)); // m1, m2
437 return sp.evalDerivative(swe);
438 }
439
440 return VanGenuchten::dkrn_dswe(params, swe);
441 }
442
443private:
444 // the slope of the straight line used to regularize saturations
445 // below the minimum saturation
446
455 static Scalar mLow_(const Params &params)
456 {
457 const Scalar swThLow = params.pcLowSw();
458
459 return VanGenuchten::dpc_dswe(params, swThLow);
460 }
461
470 static Scalar mHigh_(const Params &params)
471 {
472 const Scalar swThHigh = params.pcHighSw();
473
474 // for swThHigh = 1.0 the slope would get infinity
475 // swThHigh > 1.0 are not sensible threshold values
476 // setting swThHigh = 1.0 is a way to disable regularization
477 if (swThHigh > 1.0 - std::numeric_limits<Scalar>::epsilon())
478 return 0.0;
479
480 Scalar pcswHigh = VanGenuchten::pc(params, swThHigh);
481 return (0 - pcswHigh)/(1.0 - swThHigh);
482 }
483};
484
485} // end namespace Dumux
486
487#endif
Provides 3rd order polynomial splines.
Parameters that are necessary for the regularization of VanGenuchten "material law".
Implementation of the capillary pressure and relative permeability <-> saturation relations according...
Definition: adapt.hh:29
A 3rd order polynomial spline.
Definition: spline.hh:55
Scalar evalDerivative(Scalar x, bool extrapolate=false) const
Evaluate the spline's derivative at a given position.
Definition: splinecommon_.hh:176
Scalar intersectInterval(Scalar x0, Scalar x1, Scalar a, Scalar b, Scalar c, Scalar d) const
Find the intersections of the spline with a cubic polynomial in a sub-intervall of the spline,...
Definition: splinecommon_.hh:206
Scalar eval(Scalar x, bool extrapolate=false) const
Evaluate the spline at a given position.
Definition: splinecommon_.hh:142
Implementation of the regularized van Genuchten's capillary pressure / relative permeability <-> satu...
Definition: regularizedvangenuchten.hh:71
static Scalar dpc_dswe(const Params &params, Scalar swe)
A regularized version of the partial derivative of the w.r.t. effective saturation according to van ...
Definition: regularizedvangenuchten.hh:218
static Scalar dkrw_dswe(const Params &params, Scalar swe)
A regularized version of the derivative of the relative permeability for the wetting phase in regard ...
Definition: regularizedvangenuchten.hh:352
static Scalar endPointPc(const Params &params)
The capillary pressure at Swe = 1.0 also called end point capillary pressure.
Definition: regularizedvangenuchten.hh:201
typename Params::Scalar Scalar
Definition: regularizedvangenuchten.hh:76
static Scalar sw(const Params &params, Scalar pc)
A regularized van Genuchten saturation-capillary pressure curve.
Definition: regularizedvangenuchten.hh:145
static Scalar pc(const Params &params, Scalar swe)
A regularized van Genuchten capillary pressure-saturation curve.
Definition: regularizedvangenuchten.hh:91
static Scalar krn(const Params &params, Scalar swe)
Regularized version of the relative permeability for the non-wetting phase of the medium implied by t...
Definition: regularizedvangenuchten.hh:392
static Scalar dswe_dpc(const Params &params, Scalar pc)
A regularized version of the partial derivative of the w.r.t. cap.pressure according to van Genuchte...
Definition: regularizedvangenuchten.hh:265
ParamsT Params
Definition: regularizedvangenuchten.hh:75
static Scalar krw(const Params &params, Scalar swe)
Regularized version of the relative permeability for the wetting phase of the medium implied by the v...
Definition: regularizedvangenuchten.hh:323
static Scalar dkrn_dswe(const Params &params, Scalar swe)
A regularized version of the derivative of the relative permeability for the non-wetting phase in reg...
Definition: regularizedvangenuchten.hh:421
Implementation of the van Genuchten capillary pressure <-> saturation relation. This class bundles th...
Definition: vangenuchten.hh:52
static Scalar dkrw_dswe(const Params &params, Scalar swe)
The derivative of the relative permeability for the wetting phase in regard to the wetting saturation...
Definition: vangenuchten.hh:219
static Scalar sw(const Params &params, Scalar pc)
The saturation-capillary pressure curve according to van Genuchten.
Definition: vangenuchten.hh:100
static Scalar dpc_dswe(const Params &params, Scalar swe)
The partial derivative of the capillary pressure w.r.t. the effective saturation according to van Gen...
Definition: vangenuchten.hh:142
static Scalar krw(const Params &params, Scalar swe)
The relative permeability for the wetting phase of the medium implied by van Genuchten / Mualem param...
Definition: vangenuchten.hh:193
static Scalar dswe_dpc(const Params &params, Scalar pc)
The partial derivative of the effective saturation to the capillary pressure according to van Genucht...
Definition: vangenuchten.hh:168
static Scalar krn(const Params &params, Scalar swe)
The relative permeability for the non-wetting phase of the medium implied by van Genuchten's paramete...
Definition: vangenuchten.hh:247
static Scalar pc(const Params &params, Scalar swe)
The capillary pressure-saturation curve according to van Genuchten.
Definition: vangenuchten.hh:72
static Scalar dkrn_dswe(const Params &params, Scalar swe)
The derivative of the relative permeability for the non-wetting phase in regard to the wetting satura...
Definition: vangenuchten.hh:273