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-saturation-interfacial-area relations | ||
11 | */ | ||
12 | #ifndef DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_HH | ||
13 | #define DUMUX_MATERIAL_FLUIDMATRIX_TWO_P_INTERFACIAL_AREA_HH | ||
14 | |||
15 | #include <dumux/common/parameters.hh> | ||
16 | #include <dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh> | ||
17 | #include <dumux/material/fluidmatrixinteractions/2p/efftoabsdefaultpolicy.hh> | ||
18 | #include <dumux/material/fluidmatrixinteractions/2p/noregularization.hh> | ||
19 | |||
20 | namespace Dumux::FluidMatrix { | ||
21 | |||
22 | /*! | ||
23 | * \ingroup Fluidmatrixinteractions | ||
24 | * \brief Wrapper class to implement regularized laws (pc-sw-a) | ||
25 | * with a conversion policy between absolution and effective saturations | ||
26 | * \tparam ScalarType the scalar type | ||
27 | * \tparam BaseLaw the base law (e.g. VanGenuchten, BrooksCorey, Linear, ...) | ||
28 | * \tparam Regularization the regularization type (set to NoAwnRegularization to turn it off) | ||
29 | * \tparam EffToAbsPolicy the policy how to convert effective <-> absolute saturations | ||
30 | * | ||
31 | * \note The regularization interface is expected to return Dumux::OptionalScalars which | ||
32 | * are wrappers around a Scalar type that provide a boolean operator to | ||
33 | * check whether the result is valid. If the regularization returns | ||
34 | * a non-valid value, it means that the given parameter | ||
35 | * range is outside the regularized region. | ||
36 | * For that case we forward to the call to the standard law. | ||
37 | */ | ||
38 | template<class ScalarType, | ||
39 | class BaseLaw, | ||
40 | template<class> class InterfaceType, | ||
41 | class Regularization = NoRegularization, | ||
42 | class EffToAbsPolicy = TwoPEffToAbsDefaultPolicy> | ||
43 | class InterfacialArea : public Adapter<InterfacialArea<ScalarType, BaseLaw, InterfaceType, Regularization, EffToAbsPolicy>, InterfaceType> | ||
44 | { | ||
45 | public: | ||
46 | |||
47 | using Scalar = ScalarType; | ||
48 | |||
49 | using BasicParams = typename BaseLaw::template Params<Scalar>; | ||
50 | using EffToAbsParams = typename EffToAbsPolicy::template Params<Scalar>; | ||
51 | using RegularizationParams = typename Regularization::template Params<Scalar>; | ||
52 | |||
53 | using EffToAbs = EffToAbsPolicy; | ||
54 | |||
55 | /*! | ||
56 | * \brief Return whether this law is regularized | ||
57 | */ | ||
58 | static constexpr bool isRegularized() | ||
59 | { return !std::is_same<Regularization, NoRegularization>::value; } | ||
60 | |||
61 | /*! | ||
62 | * \brief Deleted default constructor (so we are never in an undefined state) | ||
63 | * \note store owning pointers to laws instead if you need default-constructible objects | ||
64 | */ | ||
65 | InterfacialArea() = delete; | ||
66 | |||
67 | /*! | ||
68 | * \brief Construct from a subgroup from the global parameter tree | ||
69 | * \note This will give you nice error messages if a mandatory parameter is missing | ||
70 | */ | ||
71 | explicit InterfacialArea(const std::string& paramGroup) | ||
72 | : basicParams_(makeBasicParams(paramGroup)) | ||
73 | , effToAbsParams_(makeEffToAbsParams(paramGroup)) | ||
74 | { | ||
75 | if constexpr (isRegularized()) | ||
76 | regularization_.init(this, paramGroup); | ||
77 | } | ||
78 | |||
79 | /*! | ||
80 | * \brief Construct from parameter structs | ||
81 | * \note More efficient constructor but you need to ensure all parameters are initialized | ||
82 | */ | ||
83 | 6 | InterfacialArea(const BasicParams& baseParams, | |
84 | const EffToAbsParams& effToAbsParams = {}, | ||
85 | const RegularizationParams& regParams = {}) | ||
86 | : basicParams_(baseParams) | ||
87 |
4/8✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
6 | , effToAbsParams_(effToAbsParams) |
88 | { | ||
89 | if constexpr (isRegularized()) | ||
90 | regularization_.init(this, baseParams, effToAbsParams, regParams); | ||
91 | } | ||
92 | |||
93 | /*! | ||
94 | * \brief The capillary pressure-saturation curve | ||
95 | */ | ||
96 | template<bool enableRegularization = isRegularized()> | ||
97 | 3144960 | Scalar area(const Scalar sw, const Scalar pc) const | |
98 | { | ||
99 | 7864696 | const auto swe = EffToAbs::swToSwe(sw, effToAbsParams_); | |
100 | if constexpr (enableRegularization) | ||
101 | { | ||
102 | const auto regularized = regularization_.area(swe, pc); | ||
103 | if (regularized) | ||
104 | return regularized.value(); | ||
105 | } | ||
106 | |||
107 | 8650936 | return BaseLaw::area(swe, pc, basicParams_); | |
108 | } | ||
109 | |||
110 | /*! | ||
111 | * \brief The partial derivative of the capillary pressure w.r.t. the saturation | ||
112 | */ | ||
113 | template<bool enableRegularization = isRegularized()> | ||
114 | Scalar darea_dpc(const Scalar sw, const Scalar pc) const | ||
115 | { | ||
116 | if constexpr (enableRegularization) | ||
117 | { | ||
118 | const auto regularized = regularization_.darea_dpc(sw, pc); | ||
119 | if (regularized) | ||
120 | return regularized.value(); | ||
121 | } | ||
122 | |||
123 | return BaseLaw::darea_dpc(sw, pc, basicParams_); | ||
124 | } | ||
125 | |||
126 | /*! | ||
127 | * \brief The partial derivative of the saturation to the capillary pressure | ||
128 | */ | ||
129 | template<bool enableRegularization = isRegularized()> | ||
130 | Scalar darea_dsw(const Scalar sw, const Scalar pc) const | ||
131 | { | ||
132 | if constexpr (enableRegularization) | ||
133 | { | ||
134 | const auto regularized = regularization_.darea_dsw(sw, pc); | ||
135 | if (regularized) | ||
136 | return regularized.value(); | ||
137 | } | ||
138 | |||
139 | return BaseLaw::darea_dsw(sw, pc, basicParams_); | ||
140 | } | ||
141 | |||
142 | /*! | ||
143 | * \brief Equality comparison with another instance | ||
144 | */ | ||
145 | bool operator== (const InterfacialArea& o) const | ||
146 | { | ||
147 | return basicParams_ == o.basicParams_ | ||
148 | && effToAbsParams_ == o.effToAbsParams_ | ||
149 | && regularization_ == o.regularization_; | ||
150 | } | ||
151 | |||
152 | /*! | ||
153 | * \brief Create the base law's parameters using | ||
154 | * input file parameters | ||
155 | */ | ||
156 | static BasicParams makeBasicParams(const std::string& paramGroup) | ||
157 | { | ||
158 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
2 | return BaseLaw::template makeParams<Scalar>(paramGroup); |
159 | } | ||
160 | |||
161 | /*! | ||
162 | * \brief Return the base law's parameters | ||
163 | */ | ||
164 | const BasicParams& basicParams() const | ||
165 | 786240 | { return basicParams_; } | |
166 | |||
167 | /*! | ||
168 | * \brief Create the parameters of the EffToAbs policy using | ||
169 | * input file parameters | ||
170 | */ | ||
171 | static EffToAbsParams makeEffToAbsParams(const std::string& paramGroup) | ||
172 | { | ||
173 | return EffToAbs::template makeParams<Scalar>(paramGroup); | ||
174 | } | ||
175 | |||
176 | /*! | ||
177 | * \brief Return the parameters of the EffToAbs policy | ||
178 | */ | ||
179 | const EffToAbsParams& effToAbsParams() const | ||
180 | { return effToAbsParams_; } | ||
181 | |||
182 | private: | ||
183 | BasicParams basicParams_; | ||
184 | EffToAbsParams effToAbsParams_; | ||
185 | Regularization regularization_; | ||
186 | }; | ||
187 | |||
188 | } // end namespace Dumux::FluidMatrix | ||
189 | |||
190 | #endif | ||
191 |