3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
brookscorey.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_MATERIAL_FLUIDMATRIX_BROOKS_COREY_HH
26#define DUMUX_MATERIAL_FLUIDMATRIX_BROOKS_COREY_HH
27
28// remove from here after release 3.3 /////////////
29#include "brookscoreyparams.hh"
30
31#include <algorithm>
32#include <cmath>
33
34namespace Dumux {
35
48template <class ScalarT, class ParamsT = BrooksCoreyParams<ScalarT> >
49class [[deprecated("Use new material laws and FluidMatrix::BrooksCorey instead!")]] BrooksCorey
50{
51public:
52 using Params = ParamsT;
53 using Scalar = typename Params::Scalar;
54
73 static Scalar pc(const Params &params, Scalar swe)
74 {
75 using std::pow;
76 using std::clamp;
77
78 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
79
80 return params.pe()*pow(swe, -1.0/params.lambda());
81 }
82
98 static Scalar sw(const Params &params, Scalar pc)
99 {
100 using std::pow;
101 using std::max;
102
103 pc = max(pc, 0.0); // the equation below is undefined for negative pcs
104
105 return pow(pc/params.pe(), -params.lambda());
106 }
107
115 static Scalar endPointPc(const Params &params)
116 { return params.pe(); }
117
136 static Scalar dpc_dswe(const Params &params, Scalar swe)
137 {
138 using std::pow;
139 using std::clamp;
140
141 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
142
143 return - params.pe()/params.lambda() * pow(swe, -1/params.lambda() - 1);
144 }
145
159 static Scalar dswe_dpc(const Params &params, Scalar pc)
160 {
161 using std::pow;
162 using std::max;
163
164 pc = max(pc, 0.0); // the equation below is undefined for negative pcs
165
166 return -params.lambda()/params.pe() * pow(pc/params.pe(), - params.lambda() - 1);
167 }
168
183 static Scalar krw(const Params &params, Scalar swe)
184 {
185 using std::pow;
186 using std::clamp;
187
188 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
189
190 return pow(swe, 2.0/params.lambda() + 3);
191 }
192
208 static Scalar dkrw_dswe(const Params &params, Scalar swe)
209 {
210 using std::pow;
211 using std::clamp;
212
213 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
214
215 return (2.0/params.lambda() + 3)*pow(swe, 2.0/params.lambda() + 2);
216 }
217
232 static Scalar krn(const Params &params, Scalar swe)
233 {
234 using std::pow;
235 using std::clamp;
236
237 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
238
239 const Scalar exponent = 2.0/params.lambda() + 1;
240 const Scalar tmp = 1.0 - swe;
241 return tmp*tmp*(1.0 - pow(swe, exponent));
242 }
243
260 static Scalar dkrn_dswe(const Params &params, Scalar swe)
261 {
262 using std::pow;
263 using std::clamp;
264
265 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
266
267 const auto lambdaInv = 1.0/params.lambda();
268 const auto swePow = pow(swe, 2*lambdaInv);
269 return 2*(swe - 1.0)*(1.0 + (0.5 + lambdaInv)*swePow - (1.5 + lambdaInv)*swePow*swe);
270
271 }
272
273};
274
275} // end namespace Dumux
276// remove until here after release 3.3 /////////////
277
278#include <cmath>
279#include <algorithm>
280
282#include <dumux/common/spline.hh>
285
287
301{
302public:
309 template<class Scalar>
310 struct Params
311 {
312 Params(Scalar pcEntry, Scalar lambda)
313 : pcEntry_(pcEntry), lambda_(lambda)
314 {}
315
316 Scalar pcEntry() const{ return pcEntry_; }
317 void setPcEntry(Scalar pcEntry){ pcEntry_ = pcEntry; }
318
319 Scalar lambda() const { return lambda_; }
320 void setLambda(Scalar lambda) { lambda_ = lambda; }
321
322 bool operator== (const Params& p) const
323 {
324 return Dune::FloatCmp::eq(pcEntry(), p.pcEntry(), 1e-6)
325 && Dune::FloatCmp::eq(lambda(), p.lambda(), 1e-6);
326 }
327
328 private:
329 Scalar pcEntry_, lambda_;
330 };
331
336 template<class Scalar = double>
337 static Params<Scalar> makeParams(const std::string& paramGroup)
338 {
339 const auto pcEntry = getParamFromGroup<Scalar>(paramGroup, "BrooksCoreyPcEntry");
340 const auto lambda = getParamFromGroup<Scalar>(paramGroup, "BrooksCoreyLambda");
341 return {pcEntry, lambda};
342 }
343
362 template<class Scalar>
363 static Scalar pc(Scalar swe, const Params<Scalar>& params)
364 {
365 using std::pow;
366 using std::clamp;
367
368 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
369
370 return params.pcEntry()*pow(swe, -1.0/params.lambda());
371 }
372
388 template<class Scalar>
389 static Scalar swe(Scalar pc, const Params<Scalar>& params)
390 {
391 using std::pow;
392 using std::max;
393
394 pc = max(pc, 0.0); // the equation below is undefined for negative pcs
395
396 return pow(pc/params.pcEntry(), -params.lambda());
397 }
398
406 template<class Scalar>
407 static Scalar endPointPc(const Params<Scalar>& params)
408 { return params.pcEntry(); }
409
428 template<class Scalar>
429 static Scalar dpc_dswe(Scalar swe, const Params<Scalar>& params)
430 {
431 using std::pow;
432 using std::clamp;
433
434 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
435
436 return -params.pcEntry()/params.lambda() * pow(swe, -1.0/params.lambda() - 1.0);
437 }
438
452 template<class Scalar>
453 static Scalar dswe_dpc(Scalar pc, const Params<Scalar>& params)
454 {
455 using std::pow;
456 using std::max;
457
458 pc = max(pc, 0.0); // the equation below is undefined for negative pcs
459
460 return -params.lambda()/params.pcEntry() * pow(pc/params.pcEntry(), - params.lambda() - 1.0);
461 }
462
477 template<class Scalar>
478 static Scalar krw(Scalar swe, const Params<Scalar>& params)
479 {
480 using std::pow;
481 using std::clamp;
482
483 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
484
485 return pow(swe, 2.0/params.lambda() + 3.0);
486 }
487
503 template<class Scalar>
504 static Scalar dkrw_dswe(Scalar swe, const Params<Scalar>& params)
505 {
506 using std::pow;
507 using std::clamp;
508
509 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
510
511 return (2.0/params.lambda() + 3.0)*pow(swe, 2.0/params.lambda() + 2.0);
512 }
513
528 template<class Scalar>
529 static Scalar krn(Scalar swe, const Params<Scalar>& params)
530 {
531 using std::pow;
532 using std::clamp;
533
534 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
535
536 const Scalar exponent = 2.0/params.lambda() + 1.0;
537 const Scalar sne = 1.0 - swe;
538 return sne*sne*(1.0 - pow(swe, exponent));
539 }
540
557 template<class Scalar>
558 static Scalar dkrn_dswe(Scalar swe, const Params<Scalar>& params)
559 {
560 using std::pow;
561 using std::clamp;
562
563 swe = clamp(swe, 0.0, 1.0); // the equation below is only defined for 0.0 <= sw <= 1.0
564
565 const auto lambdaInv = 1.0/params.lambda();
566 const auto swePow = pow(swe, 2*lambdaInv);
567 return 2.0*(swe - 1.0)*(1.0 + (0.5 + lambdaInv)*swePow - (1.5 + lambdaInv)*swePow*swe);
568 }
569};
570
578template <class Scalar>
580{
581public:
583 template<class S>
584 struct Params
585 {
586 Params(S pcLowSwe = 0.01) : pcLowSwe_(pcLowSwe) {}
587
588 S pcLowSwe() const { return pcLowSwe_; }
589 void setPcLowSwe(S pcLowSwe) { pcLowSwe_ = pcLowSwe; }
590
591 private:
592 S pcLowSwe_ = 0.01;
593 };
594
596 template<class MaterialLaw>
597 void init(const MaterialLaw* m, const std::string& paramGroup)
598 {
599 pcLowSwe_ = getParamFromGroup<Scalar>(paramGroup, "BrooksCoreyPcLowSweThreshold", 0.01);
600 entryPressure_ = getParamFromGroup<Scalar>(paramGroup, "BrooksCoreyPcEntry");
601
602 initPcParameters_(m, pcLowSwe_);
603 }
604
605 template<class MaterialLaw, class BaseParams, class EffToAbsParams>
606 void init(const MaterialLaw* m, const BaseParams& bp, const EffToAbsParams& etap, const Params<Scalar>& p)
607 {
608 pcLowSwe_ = p.pcLowSwe();
609 entryPressure_ = bp.pcEntry();
610
611 initPcParameters_(m, pcLowSwe_);
612 }
613
618 {
619 return Dune::FloatCmp::eq(pcLowSwe_, o.pcLowSwe_, 1e-6)
620 && Dune::FloatCmp::eq(entryPressure_, o.entryPressure_, 1e-6);
621 }
622
630 OptionalScalar<Scalar> pc(const Scalar swe) const
631 {
632 // make sure that the capillary pressure observes a derivative
633 // != 0 for 'illegal' saturations. This is favourable for the
634 // newton solver (if the derivative is calculated numerically)
635 // in order to get the saturation moving to the right
636 // direction if it temporarily is in an 'illegal' range.
637 if (swe <= pcLowSwe_)
638 return pcLowSwePcValue_ + pcDerivativeLowSw_*(swe - pcLowSwe_);
639
640 else if (swe > 1.0)
641 return pcDerivativeHighSwEnd_*(swe - 1.0) + entryPressure_;
642
643 else
644 return {}; // no regularization
645 }
646
651 {
652 if (swe < pcLowSwe_)
653 return pcDerivativeLowSw_;
654
655 else if (swe > 1.0)
656 return pcDerivativeHighSwEnd_;
657
658 else
659 return {}; // no regularization
660 }
661
665 OptionalScalar<Scalar> swe(const Scalar pc) const
666 {
667 if (pc <= entryPressure_)
668 return 1.0 + (pc - entryPressure_)/pcDerivativeHighSwEnd_;
669
670 else if (pc >= pcLowSwePcValue_)
671 return (pc - pcLowSwePcValue_)/pcDerivativeLowSw_ + pcLowSwe_;
672
673 else
674 return {}; // no regularization
675 }
676
681 {
682 if (pc <= entryPressure_)
683 return 1.0/pcDerivativeHighSwEnd_;
684
685 else if (pc >= pcLowSwePcValue_)
686 return 1.0/pcDerivativeLowSw_;
687
688 else
689 return {}; // no regularization
690 }
691
695 OptionalScalar<Scalar> krw(const Scalar swe) const
696 {
697 if (swe <= 0.0)
698 return 0.0;
699 else if (swe >= 1.0)
700 return 1.0;
701 else
702 return {}; // no regularization
703 }
704
709 {
710 if (swe < 0.0)
711 return 0.0;
712 else if (swe >= 1.0)
713 return 0.0;
714 else
715 return {}; // no regularization
716 }
717
721 OptionalScalar<Scalar> krn(const Scalar swe) const
722 {
723 if (swe <= 0.0)
724 return 1.0;
725 else if (swe >= 1.0)
726 return 0.0;
727 else
728 return {}; // no regularization
729 }
730
735 {
736 if (swe <= 0.0)
737 return 0.0;
738 else if (swe >= 1.0)
739 return 0.0;
740 else
741 return {}; // no regularization
742 }
743
744private:
745 template<class MaterialLaw>
746 void initPcParameters_(const MaterialLaw* m, const Scalar lowSwe)
747 {
748 const auto lowSw = MaterialLaw::EffToAbs::sweToSw(lowSwe, m->effToAbsParams());
749 const auto highSw = MaterialLaw::EffToAbs::sweToSw(1.0, m->effToAbsParams());
750 const auto dsw_dswe = MaterialLaw::EffToAbs::dsw_dswe(m->effToAbsParams());
751 pcDerivativeLowSw_ = m->template dpc_dsw<false>(lowSw)*dsw_dswe;
752 pcDerivativeHighSwEnd_ = m->template dpc_dsw<false>(highSw)*dsw_dswe;
753 pcLowSwePcValue_ = m->template pc<false>(lowSw);
754 }
755
756 Scalar pcLowSwe_;
757 Scalar pcLowSwePcValue_;
758 Scalar entryPressure_;
759 Scalar pcDerivativeLowSw_;
760 Scalar pcDerivativeHighSwEnd_;
761};
762
767template<typename Scalar = double>
769
774template<typename Scalar = double>
776
777} // end namespace Dumux::FluidMatrix
778
779#endif
Provides 3rd order polynomial splines.
A wrapper that can either contain a valid Scalar or NaN.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Specification of the material parameters for the Brooks Corey constitutive relations.
Implementation helper for capillary pressure and relative permeability <-> saturation relations for t...
Definition: adapt.hh:29
Definition: brookscorey.hh:286
Implementation of the Brooks-Corey capillary pressure <-> saturation relation. This class bundles the...
Definition: brookscorey.hh:50
static Scalar dkrw_dswe(const Params &params, Scalar swe)
The derivative of the relative permeability for the wetting phase with regard to the wetting saturati...
Definition: brookscorey.hh:208
static Scalar dswe_dpc(const Params &params, Scalar pc)
The partial derivative of the effective saturation w.r.t. the capillary pressure according to Brooks ...
Definition: brookscorey.hh:159
ParamsT Params
Definition: brookscorey.hh:52
static Scalar dpc_dswe(const Params &params, Scalar swe)
The partial derivative of the capillary pressure w.r.t. the effective saturation according to Brooks ...
Definition: brookscorey.hh:136
static Scalar krw(const Params &params, Scalar swe)
The relative permeability for the wetting phase of the medium implied by the Brooks-Corey parameteriz...
Definition: brookscorey.hh:183
static Scalar pc(const Params &params, Scalar swe)
The capillary pressure-saturation curve according to Brooks & Corey.
Definition: brookscorey.hh:73
typename Params::Scalar Scalar
Definition: brookscorey.hh:53
static Scalar endPointPc(const Params &params)
The capillary pressure at Swe = 1.0 also called end point capillary pressure.
Definition: brookscorey.hh:115
static Scalar sw(const Params &params, Scalar pc)
The saturation-capillary pressure curve according to Brooks & Corey.
Definition: brookscorey.hh:98
static Scalar krn(const Params &params, Scalar swe)
The relative permeability for the nonwetting phase of the medium as implied by the Brooks-Corey param...
Definition: brookscorey.hh:232
static Scalar dkrn_dswe(const Params &params, Scalar swe)
The derivative of the relative permeability for the nonwetting phase in regard to the wetting saturat...
Definition: brookscorey.hh:260
Implementation of the Brooks-Corey capillary pressure <-> saturation relation. This class bundles the...
Definition: brookscorey.hh:301
static Scalar dkrw_dswe(Scalar swe, const Params< Scalar > &params)
The derivative of the relative permeability for the wetting phase with regard to the wetting saturati...
Definition: brookscorey.hh:504
static Scalar pc(Scalar swe, const Params< Scalar > &params)
The capillary pressure-saturation curve according to Brooks & Corey.
Definition: brookscorey.hh:363
static Scalar dswe_dpc(Scalar pc, const Params< Scalar > &params)
The partial derivative of the effective saturation w.r.t. the capillary pressure according to Brooks ...
Definition: brookscorey.hh:453
static Scalar swe(Scalar pc, const Params< Scalar > &params)
The saturation-capillary pressure curve according to Brooks & Corey.
Definition: brookscorey.hh:389
static Scalar dpc_dswe(Scalar swe, const Params< Scalar > &params)
The partial derivative of the capillary pressure w.r.t. the effective saturation according to Brooks ...
Definition: brookscorey.hh:429
static Params< Scalar > makeParams(const std::string &paramGroup)
Construct from a subgroup from the global parameter tree.
Definition: brookscorey.hh:337
static Scalar dkrn_dswe(Scalar swe, const Params< Scalar > &params)
The derivative of the relative permeability for the non-wetting phase in regard to the wetting satura...
Definition: brookscorey.hh:558
static Scalar krn(Scalar swe, const Params< Scalar > &params)
The relative permeability for the non-wetting phase of the medium as implied by the Brooks-Corey para...
Definition: brookscorey.hh:529
static Scalar endPointPc(const Params< Scalar > &params)
The capillary pressure at Swe = 1.0 also called end point capillary pressure.
Definition: brookscorey.hh:407
static Scalar krw(Scalar swe, const Params< Scalar > &params)
The relative permeability for the wetting phase of the medium implied by the Brooks-Corey parameteriz...
Definition: brookscorey.hh:478
The parameter type.
Definition: brookscorey.hh:311
Scalar pcEntry() const
Definition: brookscorey.hh:316
void setPcEntry(Scalar pcEntry)
Definition: brookscorey.hh:317
bool operator==(const Params &p) const
Definition: brookscorey.hh:322
Scalar lambda() const
Definition: brookscorey.hh:319
Params(Scalar pcEntry, Scalar lambda)
Definition: brookscorey.hh:312
void setLambda(Scalar lambda)
Definition: brookscorey.hh:320
A regularization for the BrooksCorey material law.
Definition: brookscorey.hh:580
OptionalScalar< Scalar > pc(const Scalar swe) const
The regularized capillary pressure-saturation curve regularized part:
Definition: brookscorey.hh:630
OptionalScalar< Scalar > krn(const Scalar swe) const
The regularized relative permeability for the non-wetting phase.
Definition: brookscorey.hh:721
OptionalScalar< Scalar > dswe_dpc(const Scalar pc) const
The regularized partial derivative of the saturation to the capillary pressure.
Definition: brookscorey.hh:680
void init(const MaterialLaw *m, const std::string &paramGroup)
Initialize the spline.
Definition: brookscorey.hh:597
OptionalScalar< Scalar > dkrn_dswe(const Scalar swe) const
The regularized derivative of the relative permeability for the non-wetting phase w....
Definition: brookscorey.hh:734
OptionalScalar< Scalar > dpc_dswe(const Scalar swe) const
The regularized partial derivative of the capillary pressure w.r.t. the saturation.
Definition: brookscorey.hh:650
OptionalScalar< Scalar > krw(const Scalar swe) const
The regularized relative permeability for the wetting phase.
Definition: brookscorey.hh:695
OptionalScalar< Scalar > dkrw_dswe(const Scalar swe) const
The regularized derivative of the relative permeability for the wetting phase w.r....
Definition: brookscorey.hh:708
OptionalScalar< Scalar > swe(const Scalar pc) const
The regularized saturation-capillary pressure curve.
Definition: brookscorey.hh:665
bool operator==(const BrooksCoreyRegularization &o) const
Equality comparison with another instance.
Definition: brookscorey.hh:617
void init(const MaterialLaw *m, const BaseParams &bp, const EffToAbsParams &etap, const Params< Scalar > &p)
Definition: brookscorey.hh:606
Regularization parameters.
Definition: brookscorey.hh:585
Params(S pcLowSwe=0.01)
Definition: brookscorey.hh:586
S pcLowSwe() const
Definition: brookscorey.hh:588
void setPcLowSwe(S pcLowSwe)
Definition: brookscorey.hh:589
This is a policy for 2p material laws how to convert absolute to relative saturations and vice versa.
Definition: efftoabsdefaultpolicy.hh:46
Wrapper class to implement regularized material laws (pc-sw, kr-sw) with a conversion policy between ...
Definition: materiallaw.hh:57