Line | Branch | Exec | Source |
---|---|---|---|
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-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup Fluidmatrixinteractions | ||
10 | * \brief Implementation helper for capillary pressure and | ||
11 | * relative permeability <-> saturation relations for two-phase models | ||
12 | */ | ||
13 | #ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWOP_MATERIAL_LAW_HH | ||
14 | #define DUMUX_MATERIAL_FLUIDMATRIX_TWOP_MATERIAL_LAW_HH | ||
15 | |||
16 | #include <dumux/common/parameters.hh> | ||
17 | #include <dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh> | ||
18 | #include <dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh> | ||
19 | #include <dumux/material/fluidmatrixinteractions/2p/noregularization.hh> | ||
20 | |||
21 | namespace Dumux::FluidMatrix { | ||
22 | |||
23 | /*! | ||
24 | * \ingroup Fluidmatrixinteractions | ||
25 | * \brief Wrapper class to implement regularized material laws (pc-sw, kr-sw) | ||
26 | * with a conversion policy between absolution and effective saturations | ||
27 | * \note See vangenuchten.hh / brookscorey.hh for default configurations using this class | ||
28 | * \tparam ScalarType the scalar type | ||
29 | * \tparam BaseLaw the base law (e.g. VanGenuchten, BrooksCorey, Linear, ...) | ||
30 | * \tparam Regularization the regularization type (set to NoRegularization to turn it off) | ||
31 | * \tparam EffToAbsPolicy the policy how to convert effective <-> absolute saturations | ||
32 | * | ||
33 | * \note The regularization interface is expected to return Dumux::OptionalScalars which | ||
34 | * are wrappers around a Scalar type that provide a boolean operator to | ||
35 | * check whether the result is valid. If the regularization returns | ||
36 | * a non-valid value, it means that the given parameter | ||
37 | * range is outside the regularized region. | ||
38 | * For that case we forward to the call to the standard law. | ||
39 | */ | ||
40 | template<class ScalarType, | ||
41 | class BaseLaw, | ||
42 | class Regularization = NoRegularization, | ||
43 | class EffToAbsPolicy = TwoPEffToAbsDefaultPolicy> | ||
44 | class TwoPMaterialLaw : public Adapter<TwoPMaterialLaw<ScalarType, BaseLaw, Regularization, EffToAbsPolicy>, PcKrSw> | ||
45 | { | ||
46 | public: | ||
47 | |||
48 | using Scalar = ScalarType; | ||
49 | |||
50 | using BasicParams = typename BaseLaw::template Params<Scalar>; | ||
51 | using EffToAbsParams = typename EffToAbsPolicy::template Params<Scalar>; | ||
52 | using RegularizationParams = typename Regularization::template Params<Scalar>; | ||
53 | |||
54 | using EffToAbs = EffToAbsPolicy; | ||
55 | |||
56 | /*! | ||
57 | * \brief Return the number of fluid phases | ||
58 | */ | ||
59 | static constexpr int numFluidPhases() | ||
60 | { return 2; } | ||
61 | |||
62 | /*! | ||
63 | * \brief Return whether this law is regularized | ||
64 | */ | ||
65 | static constexpr bool isRegularized() | ||
66 | { return !std::is_same<Regularization, NoRegularization>::value; } | ||
67 | |||
68 | /*! | ||
69 | * \brief Deleted default constructor (so we are never in an undefined state) | ||
70 | * \note store owning pointers to laws instead if you need default-constructible objects | ||
71 | */ | ||
72 | TwoPMaterialLaw() = delete; | ||
73 | |||
74 | /*! | ||
75 | * \brief Construct from a subgroup from the global parameter tree | ||
76 | * \note This will give you nice error messages if a mandatory parameter is missing | ||
77 | */ | ||
78 | 209 | explicit TwoPMaterialLaw(const std::string& paramGroup) | |
79 | 418 | : basicParams_(makeBasicParams(paramGroup)) | |
80 | 299 | , effToAbsParams_(makeEffToAbsParams(paramGroup)) | |
81 | { | ||
82 | if constexpr (isRegularized()) | ||
83 | 186 | regularization_.init(this, paramGroup); | |
84 | 209 | } | |
85 | |||
86 | /*! | ||
87 | * \brief Construct from parameter structs | ||
88 | * \note More efficient constructor but you need to ensure all parameters are initialized | ||
89 | */ | ||
90 | 11 | TwoPMaterialLaw(const BasicParams& baseParams, | |
91 | const EffToAbsParams& effToAbsParams = {}, | ||
92 | const RegularizationParams& regParams = {}) | ||
93 | : basicParams_(baseParams) | ||
94 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
10 | , effToAbsParams_(effToAbsParams) |
95 | { | ||
96 | if constexpr (isRegularized()) | ||
97 | 8 | regularization_.init(this, baseParams, effToAbsParams, regParams); | |
98 | 1 | } | |
99 | |||
100 | /*! | ||
101 | * \brief The capillary pressure-saturation curve | ||
102 | */ | ||
103 | template<bool enableRegularization = isRegularized()> | ||
104 | 173966339 | Scalar pc(const Scalar sw) const | |
105 | { | ||
106 |
4/6✗ Branch 0 not taken.
✓ Branch 1 taken 861419 times.
✓ Branch 2 taken 137317474 times.
✓ Branch 3 taken 66 times.
✓ Branch 4 taken 635 times.
✗ Branch 5 not taken.
|
177336353 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
107 | if constexpr (enableRegularization) | ||
108 | { | ||
109 |
2/2✓ Branch 0 taken 861485 times.
✓ Branch 1 taken 137318109 times.
|
173966339 | const auto regularized = regularization_.pc(swe); |
110 |
2/2✓ Branch 0 taken 34733563 times.
✓ Branch 1 taken 139232776 times.
|
173966339 | if (regularized) |
111 | return regularized.value(); | ||
112 | } | ||
113 | |||
114 |
0/12✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
38103577 | return BaseLaw::pc(swe, basicParams_); |
115 | } | ||
116 | |||
117 | /*! | ||
118 | * \brief The partial derivative of the capillary pressure w.r.t. the saturation | ||
119 | */ | ||
120 | template<bool enableRegularization = isRegularized()> | ||
121 | 25620506 | Scalar dpc_dsw(const Scalar sw) const | |
122 | { | ||
123 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 178 times.
|
25620506 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
124 | if constexpr (enableRegularization) | ||
125 | { | ||
126 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 178 times.
|
3488032 | const auto regularized = regularization_.dpc_dswe(swe); |
127 |
2/2✓ Branch 0 taken 92274 times.
✓ Branch 1 taken 1651742 times.
|
3488032 | if (regularized) |
128 | 6606968 | return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); | |
129 | } | ||
130 | |||
131 | 22317022 | return BaseLaw::dpc_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); | |
132 | } | ||
133 | |||
134 | /*! | ||
135 | * \brief The capillary pressure at Swe = 1.0 also called end point capillary pressure | ||
136 | */ | ||
137 | ✗ | Scalar endPointPc() const | |
138 | { | ||
139 |
12/12✓ Branch 0 taken 4838146 times.
✓ Branch 1 taken 6570405 times.
✓ Branch 2 taken 3400210 times.
✓ Branch 3 taken 2724319 times.
✓ Branch 4 taken 4761 times.
✓ Branch 5 taken 29505 times.
✓ Branch 6 taken 360 times.
✓ Branch 7 taken 29505 times.
✓ Branch 8 taken 360 times.
✓ Branch 9 taken 29504 times.
✓ Branch 10 taken 360 times.
✓ Branch 11 taken 29504 times.
|
93834018 | return BaseLaw::endPointPc(basicParams_); |
140 | } | ||
141 | |||
142 | /*! | ||
143 | * \brief The saturation-capillary pressure curve | ||
144 | */ | ||
145 | template<bool enableRegularization = isRegularized()> | ||
146 | 799323124 | Scalar sw(const Scalar pc) const | |
147 | { | ||
148 | if constexpr (enableRegularization) | ||
149 | { | ||
150 |
2/2✓ Branch 0 taken 842696 times.
✓ Branch 1 taken 1346804 times.
|
799323124 | const auto regularized = regularization_.swe(pc); |
151 |
2/2✓ Branch 0 taken 775304456 times.
✓ Branch 1 taken 24018668 times.
|
799323124 | if (regularized) |
152 | 48037336 | return EffToAbs::sweToSw(regularized.value(), effToAbsParams_); | |
153 | } | ||
154 | |||
155 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 1335568 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
802789501 | return EffToAbs::sweToSw(BaseLaw::swe(pc, basicParams_), effToAbsParams_); |
156 | } | ||
157 | |||
158 | /*! | ||
159 | * \brief The partial derivative of the saturation to the capillary pressure | ||
160 | */ | ||
161 | template<bool enableRegularization = isRegularized()> | ||
162 | 41607502 | Scalar dsw_dpc(const Scalar pc) const | |
163 | { | ||
164 | if constexpr (enableRegularization) | ||
165 | { | ||
166 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 180 times.
|
41607502 | const auto regularized = regularization_.dswe_dpc(pc); |
167 |
2/2✓ Branch 0 taken 37360569 times.
✓ Branch 1 taken 4246933 times.
|
41607502 | if (regularized) |
168 | 8493866 | return regularized.value()*EffToAbs::dsw_dswe(effToAbsParams_); | |
169 | } | ||
170 | |||
171 | 38360575 | return BaseLaw::dswe_dpc(pc, basicParams_)*EffToAbs::dsw_dswe(effToAbsParams_); | |
172 | } | ||
173 | |||
174 | /*! | ||
175 | * \brief The relative permeability for the wetting phase | ||
176 | */ | ||
177 | template<bool enableRegularization = isRegularized()> | ||
178 | 962770493 | Scalar krw(const Scalar sw) const | |
179 | { | ||
180 |
3/8✓ Branch 0 taken 132163249 times.
✓ Branch 1 taken 431369 times.
✓ Branch 2 taken 7174144 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
997404882 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
181 | if constexpr (enableRegularization) | ||
182 | { | ||
183 |
2/2✓ Branch 0 taken 132163249 times.
✓ Branch 1 taken 431369 times.
|
962770493 | const auto regularized = regularization_.krw(swe); |
184 |
2/2✓ Branch 0 taken 802049412 times.
✓ Branch 1 taken 160721081 times.
|
962770493 | if (regularized) |
185 | return regularized.value(); | ||
186 | } | ||
187 | |||
188 |
1/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7174144 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
836683801 | return BaseLaw::krw(swe, basicParams_); |
189 | } | ||
190 | |||
191 | /*! | ||
192 | * \brief The derivative of the relative permeability for the wetting phase w.r.t. saturation | ||
193 | */ | ||
194 | template<bool enableRegularization = isRegularized()> | ||
195 | 69615895 | Scalar dkrw_dsw(const Scalar sw) const | |
196 | { | ||
197 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 10 times.
|
69615895 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
198 | if constexpr (enableRegularization) | ||
199 | { | ||
200 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 10 times.
|
68615760 | const auto regularized = regularization_.dkrw_dswe(swe); |
201 |
2/2✓ Branch 0 taken 28567612 times.
✓ Branch 1 taken 5740318 times.
|
68615760 | if (regularized) |
202 | 22961232 | return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); | |
203 | } | ||
204 | |||
205 | 58135279 | return BaseLaw::dkrw_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); | |
206 | } | ||
207 | |||
208 | /*! | ||
209 | * \brief The relative permeability for the non-wetting phase | ||
210 | */ | ||
211 | template<bool enableRegularization = isRegularized()> | ||
212 | 166263596 | Scalar krn(const Scalar sw) const | |
213 | { | ||
214 |
2/8✓ Branch 0 taken 132163249 times.
✓ Branch 1 taken 431369 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
167633323 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
215 | if constexpr (enableRegularization) | ||
216 | { | ||
217 |
2/2✓ Branch 0 taken 132163249 times.
✓ Branch 1 taken 431369 times.
|
166263596 | const auto regularized = regularization_.krn(swe); |
218 |
2/2✓ Branch 0 taken 37837050 times.
✓ Branch 1 taken 128426546 times.
|
166263596 | if (regularized) |
219 | return regularized.value(); | ||
220 | } | ||
221 | |||
222 |
0/8✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
39206777 | return BaseLaw::krn(swe, basicParams_); |
223 | } | ||
224 | |||
225 | /*! | ||
226 | * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation | ||
227 | */ | ||
228 | template<bool enableRegularization = isRegularized()> | ||
229 | 3381732 | Scalar dkrn_dsw(const Scalar sw) const | |
230 | { | ||
231 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 10 times.
|
3381732 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); |
232 | if constexpr (enableRegularization) | ||
233 | { | ||
234 |
2/2✓ Branch 0 taken 90 times.
✓ Branch 1 taken 10 times.
|
2381612 | const auto regularized = regularization_.dkrn_dswe(swe); |
235 |
2/2✓ Branch 0 taken 123622 times.
✓ Branch 1 taken 1067234 times.
|
2381612 | if (regularized) |
236 | 4268896 | return regularized.value()*EffToAbs::dswe_dsw(effToAbsParams_); | |
237 | } | ||
238 | |||
239 | 1247284 | return BaseLaw::dkrn_dswe(swe, basicParams_)*EffToAbs::dswe_dsw(effToAbsParams_); | |
240 | } | ||
241 | |||
242 | /*! | ||
243 | * \brief Equality comparison with another instance | ||
244 | */ | ||
245 | 34031 | bool operator== (const TwoPMaterialLaw& o) const | |
246 | { | ||
247 | 34031 | return basicParams_ == o.basicParams_ | |
248 |
1/2✓ Branch 0 taken 30741 times.
✗ Branch 1 not taken.
|
30741 | && effToAbsParams_ == o.effToAbsParams_ |
249 |
3/4✓ Branch 0 taken 30741 times.
✓ Branch 1 taken 3290 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 30741 times.
|
64772 | && regularization_ == o.regularization_; |
250 | } | ||
251 | |||
252 | /*! | ||
253 | * \brief Create the base law's parameters using | ||
254 | * input file parameters | ||
255 | */ | ||
256 | static BasicParams makeBasicParams(const std::string& paramGroup) | ||
257 | { | ||
258 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
197 | return BaseLaw::template makeParams<Scalar>(paramGroup); |
259 | } | ||
260 | |||
261 | /*! | ||
262 | * \brief Return the base law's parameters | ||
263 | */ | ||
264 | const BasicParams& basicParams() const | ||
265 | { return basicParams_; } | ||
266 | |||
267 | /*! | ||
268 | * \brief Create the parameters of the EffToAbs policy using | ||
269 | * input file parameters | ||
270 | */ | ||
271 | static EffToAbsParams makeEffToAbsParams(const std::string& paramGroup) | ||
272 | { | ||
273 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
197 | return EffToAbs::template makeParams<Scalar>(paramGroup); |
274 | } | ||
275 | |||
276 | /*! | ||
277 | * \brief Return the parameters of the EffToAbs policy | ||
278 | */ | ||
279 | const EffToAbsParams& effToAbsParams() const | ||
280 | 918 | { return effToAbsParams_; } | |
281 | |||
282 | private: | ||
283 | BasicParams basicParams_; | ||
284 | EffToAbsParams effToAbsParams_; | ||
285 | Regularization regularization_; | ||
286 | }; | ||
287 | |||
288 | } // end namespace Dumux::FluidMatrix | ||
289 | |||
290 | #endif | ||
291 |