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 | * \ingroup PoreNetworkModels | ||
11 | * \brief Implementation of capillary pressure curves for multiple pore body geometries | ||
12 | */ | ||
13 | #ifndef DUMUX_PNM_2P_LOCAL_RULES_HH | ||
14 | #define DUMUX_PNM_2P_LOCAL_RULES_HH | ||
15 | |||
16 | #include <dumux/material/fluidmatrixinteractions/fluidmatrixinteraction.hh> | ||
17 | #include <dumux/porenetwork/common/poreproperties.hh> | ||
18 | #include "localrulesforplatonicbody.hh" | ||
19 | |||
20 | namespace Dumux::PoreNetwork::FluidMatrix { | ||
21 | /*! | ||
22 | * \ingroup Fluidmatrixinteractions | ||
23 | * \ingroup PoreNetworkModels | ||
24 | * \brief LocalRulesTraits for implementation of capillary pressure curves for multiple pore body geometries | ||
25 | */ | ||
26 | template<class ScalarT> | ||
27 | struct LocalRulesTraits | ||
28 | { | ||
29 | using Tetrahedron = TwoPLocalRulesPlatonicBodyDefault<Pore::Shape::tetrahedron, ScalarT>; | ||
30 | using Cube = TwoPLocalRulesPlatonicBodyDefault<Pore::Shape::cube, ScalarT>; | ||
31 | using Octahedron = TwoPLocalRulesPlatonicBodyDefault<Pore::Shape::octahedron, ScalarT>; | ||
32 | using Icosahedron = TwoPLocalRulesPlatonicBodyDefault<Pore::Shape::icosahedron, ScalarT>; | ||
33 | using Dodecahedron = TwoPLocalRulesPlatonicBodyDefault<Pore::Shape::dodecahedron, ScalarT>; | ||
34 | }; | ||
35 | |||
36 | /*! | ||
37 | * \ingroup Fluidmatrixinteractions | ||
38 | * \ingroup PoreNetworkModels | ||
39 | * \brief Implementation of capillary pressure curves for multiple pore body geometries | ||
40 | */ | ||
41 | template<class ScalarT> | ||
42 | class MultiShapeTwoPLocalRules : public Dumux::FluidMatrix::Adapter<MultiShapeTwoPLocalRules<ScalarT>, Dumux::FluidMatrix::PcKrSw> | ||
43 | { | ||
44 | public: | ||
45 | using Scalar = ScalarT; | ||
46 | using LocalRules = LocalRulesTraits<Scalar>; | ||
47 | |||
48 |
2/8✓ Branch 0 taken 83325 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2979476 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
6125602 | struct BasicParams |
49 | { | ||
50 |
2/4✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
|
10 | BasicParams() {} |
51 | |||
52 | template<class SpatialParams, class Element, class SubControlVolume, class ElemSol> | ||
53 | 6042272 | BasicParams(const SpatialParams& spatialParams, | |
54 | const Element& element, | ||
55 | const SubControlVolume& scv, | ||
56 | const ElemSol& elemSol) | ||
57 | 6042272 | { | |
58 |
3/6✓ Branch 0 taken 3062796 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3062796 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3062796 times.
✗ Branch 5 not taken.
|
18126816 | shape_ = spatialParams.gridGeometry().poreGeometry(scv.dofIndex()); |
59 | |||
60 | switch (shape_) | ||
61 | { | ||
62 | 6042272 | case Pore::Shape::tetrahedron: | |
63 | case Pore::Shape::cube: | ||
64 | case Pore::Shape::octahedron: | ||
65 | case Pore::Shape::icosahedron: | ||
66 | case Pore::Shape::dodecahedron: | ||
67 |
3/6✓ Branch 1 taken 3062796 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3062796 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3062796 times.
|
6042272 | platonicBodyParams_ = std::make_unique<PlatonicBodyParams<Scalar>>(spatialParams, element, scv, elemSol); |
68 | break; | ||
69 | ✗ | default: | |
70 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
71 | } | ||
72 | 6042272 | } | |
73 | |||
74 | // we use cube specialization here, but all platonic bodies have the same params | ||
75 | PlatonicBodyParams<Scalar> platonicBodyParams() const | ||
76 | 6125602 | { return *platonicBodyParams_; } | |
77 | |||
78 | ✗ | Pore::Shape poreShape() const | |
79 | ✗ | { return shape_; } | |
80 | |||
81 | 5 | void setParams(const PlatonicBodyParams<Scalar>& platonicBodyParams) | |
82 | { | ||
83 | 5 | shape_ = platonicBodyParams.poreShape(); | |
84 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
|
5 | platonicBodyParams_ = std::make_unique<PlatonicBodyParams<Scalar>>(platonicBodyParams); |
85 | 5 | } | |
86 | |||
87 | private: | ||
88 | std::unique_ptr<PlatonicBodyParams<Scalar>> platonicBodyParams_; | ||
89 | Pore::Shape shape_; | ||
90 | }; | ||
91 | |||
92 | static constexpr bool supportsMultipleGeometries() | ||
93 | { return true; } | ||
94 | |||
95 | /*! | ||
96 | * \brief Return the number of fluid phases | ||
97 | */ | ||
98 | static constexpr int numFluidPhases() | ||
99 | { return 2; } | ||
100 | |||
101 | 3062801 | MultiShapeTwoPLocalRules(const BasicParams& baseParams, | |
102 | //const RegularizationParams& regParams = {}, TODO | ||
103 | const std::string& paramGroup = "") | ||
104 | 15314005 | { | |
105 | 3062801 | shape_ = baseParams.poreShape(); | |
106 |
5/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3062797 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
3062801 | switch (shape_) |
107 | { | ||
108 | 1 | case Pore::Shape::tetrahedron: | |
109 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
|
3 | localRulesForTetrahedron_ = std::make_shared<typename LocalRules::Tetrahedron>(baseParams.platonicBodyParams(), |
110 | typename LocalRules::Tetrahedron::RegularizationParams{}, | ||
111 | paramGroup); | ||
112 | 1 | break; | |
113 | 3062797 | case Pore::Shape::cube: | |
114 |
5/10✓ Branch 1 taken 3062797 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3062797 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3062797 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3062797 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 3062797 times.
|
9188391 | localRulesForCube_ = std::make_shared<typename LocalRules::Cube>(baseParams.platonicBodyParams(), |
115 | typename LocalRules::Cube::RegularizationParams{}, | ||
116 | paramGroup); | ||
117 | 3062797 | break; | |
118 | 1 | case Pore::Shape::octahedron: | |
119 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
|
3 | localRulesForOctahedron_ = std::make_shared<typename LocalRules::Octahedron>(baseParams.platonicBodyParams(), |
120 | typename LocalRules::Octahedron::RegularizationParams{}, | ||
121 | paramGroup); | ||
122 | 1 | break; | |
123 | 1 | case Pore::Shape::icosahedron: | |
124 |
5/10✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
|
3 | localRulesForIcosahedron_ = std::make_shared<typename LocalRules::Icosahedron>(baseParams.platonicBodyParams(), |
125 | typename LocalRules::Icosahedron::RegularizationParams{}, | ||
126 | paramGroup); | ||
127 | 1 | break; | |
128 | 1 | case Pore::Shape::dodecahedron: | |
129 |
5/12✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
3 | localRulesForDodecahedron_ = std::make_shared<typename LocalRules::Dodecahedron>(baseParams.platonicBodyParams(), |
130 | typename LocalRules::Dodecahedron::RegularizationParams{}, | ||
131 | paramGroup); | ||
132 | 1 | break; | |
133 | ✗ | default: | |
134 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
135 | } | ||
136 | 3062801 | } | |
137 | |||
138 | |||
139 | template<class SpatialParams, class Element, class SubControlVolume, class ElemSol> | ||
140 | void updateParams(const SpatialParams& spatialParams, | ||
141 | const Element& element, | ||
142 | const SubControlVolume& scv, | ||
143 | const ElemSol& elemSol) | ||
144 | { | ||
145 | shape_ = spatialParams.gridGeometry().poreGeometry(scv.dofIndex()); | ||
146 | switch (shape_) | ||
147 | { | ||
148 | case Pore::Shape::tetrahedron: | ||
149 | return localRulesForTetrahedron_->updateParams(spatialParams, element, scv, elemSol); | ||
150 | case Pore::Shape::cube: | ||
151 | return localRulesForCube_->updateParams(spatialParams, element, scv, elemSol); | ||
152 | case Pore::Shape::octahedron: | ||
153 | return localRulesForOctahedron_->updateParams(spatialParams, element, scv, elemSol); | ||
154 | case Pore::Shape::icosahedron: | ||
155 | return localRulesForIcosahedron_->updateParams(spatialParams, element, scv, elemSol); | ||
156 | case Pore::Shape::dodecahedron: | ||
157 | return localRulesForDodecahedron_->updateParams(spatialParams, element, scv, elemSol); | ||
158 | default: | ||
159 | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | /*! | ||
164 | * \brief The capillary pressure-saturation curve | ||
165 | */ | ||
166 | 1534398 | Scalar pc(const Scalar sw) const | |
167 | { | ||
168 |
5/6✓ Branch 0 taken 600 times.
✓ Branch 1 taken 1531998 times.
✓ Branch 2 taken 600 times.
✓ Branch 3 taken 600 times.
✓ Branch 4 taken 600 times.
✗ Branch 5 not taken.
|
1534398 | switch (shape_) |
169 | { | ||
170 | 600 | case Pore::Shape::tetrahedron: | |
171 | 1200 | return localRulesForTetrahedron_->pc(sw); | |
172 | 1531998 | case Pore::Shape::cube: | |
173 | 3063996 | return localRulesForCube_->pc(sw); | |
174 | 600 | case Pore::Shape::octahedron: | |
175 | 1200 | return localRulesForOctahedron_->pc(sw); | |
176 | 600 | case Pore::Shape::icosahedron: | |
177 | 1200 | return localRulesForIcosahedron_->pc(sw); | |
178 | 600 | case Pore::Shape::dodecahedron: | |
179 | 1200 | return localRulesForDodecahedron_->pc(sw); | |
180 | ✗ | default: | |
181 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
182 | } | ||
183 | } | ||
184 | |||
185 | /*! | ||
186 | * \brief The saturation-capilllary-pressure curve | ||
187 | */ | ||
188 | 500 | Scalar sw(const Scalar pc) const | |
189 | { | ||
190 |
5/6✓ Branch 0 taken 100 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
500 | switch (shape_) |
191 | { | ||
192 | 100 | case Pore::Shape::tetrahedron: | |
193 | 200 | return localRulesForTetrahedron_->sw(pc); | |
194 | 100 | case Pore::Shape::cube: | |
195 | 200 | return localRulesForCube_->sw(pc); | |
196 | 100 | case Pore::Shape::octahedron: | |
197 | 200 | return localRulesForOctahedron_->sw(pc); | |
198 | 100 | case Pore::Shape::icosahedron: | |
199 | 200 | return localRulesForIcosahedron_->sw(pc); | |
200 | 100 | case Pore::Shape::dodecahedron: | |
201 | 200 | return localRulesForDodecahedron_->sw(pc); | |
202 | ✗ | default: | |
203 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
204 | } | ||
205 | } | ||
206 | |||
207 | /*! | ||
208 | * \brief The partial derivative of the capillary pressure w.r.t. the saturation | ||
209 | */ | ||
210 | 1000 | Scalar dpc_dsw(const Scalar sw) const | |
211 | { | ||
212 |
5/6✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
✓ Branch 2 taken 200 times.
✓ Branch 3 taken 200 times.
✓ Branch 4 taken 200 times.
✗ Branch 5 not taken.
|
1000 | switch (shape_) |
213 | { | ||
214 | 200 | case Pore::Shape::tetrahedron: | |
215 | 400 | return localRulesForTetrahedron_->dpc_dsw(sw); | |
216 | 200 | case Pore::Shape::cube: | |
217 | 400 | return localRulesForCube_->dpc_dsw(sw); | |
218 | 200 | case Pore::Shape::octahedron: | |
219 | 400 | return localRulesForOctahedron_->dpc_dsw(sw); | |
220 | 200 | case Pore::Shape::icosahedron: | |
221 | 400 | return localRulesForIcosahedron_->dpc_dsw(sw); | |
222 | 200 | case Pore::Shape::dodecahedron: | |
223 | 400 | return localRulesForDodecahedron_->dpc_dsw(sw); | |
224 | ✗ | default: | |
225 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
226 | } | ||
227 | } | ||
228 | |||
229 | /*! | ||
230 | * \brief The partial derivative of the saturation to the capillary pressure | ||
231 | */ | ||
232 | 500 | Scalar dsw_dpc(const Scalar pc) const | |
233 | { | ||
234 |
5/6✓ Branch 0 taken 100 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 100 times.
✓ Branch 4 taken 100 times.
✗ Branch 5 not taken.
|
500 | switch (shape_) |
235 | { | ||
236 | 100 | case Pore::Shape::tetrahedron: | |
237 | 200 | return localRulesForTetrahedron_->dsw_dpc(pc); | |
238 | 100 | case Pore::Shape::cube: | |
239 | 200 | return localRulesForCube_->dsw_dpc(pc); | |
240 | 100 | case Pore::Shape::octahedron: | |
241 | 200 | return localRulesForOctahedron_->dsw_dpc(pc); | |
242 | 100 | case Pore::Shape::icosahedron: | |
243 | 200 | return localRulesForIcosahedron_->dsw_dpc(pc); | |
244 | 100 | case Pore::Shape::dodecahedron: | |
245 | 200 | return localRulesForDodecahedron_->dsw_dpc(pc); | |
246 | ✗ | default: | |
247 | ✗ | DUNE_THROW(Dune::NotImplemented, "Invalid shape"); | |
248 | } | ||
249 | } | ||
250 | |||
251 | /*! | ||
252 | * \brief The relative permeability for the wetting phase. | ||
253 | * \note This is only for compatibility. Will not be used. | ||
254 | */ | ||
255 | ✗ | Scalar krw(const Scalar sw) const | |
256 | ✗ | { return 1.0; } | |
257 | |||
258 | /*! | ||
259 | * \brief The derivative of the relative permeability for the wetting phase w.r.t. saturation | ||
260 | * \note This is only for compatibility. Will not be used. | ||
261 | */ | ||
262 | Scalar dkrw_dsw(const Scalar sw) const | ||
263 | { return 0; } | ||
264 | |||
265 | /*! | ||
266 | * \brief The relative permeability for the non-wetting phase | ||
267 | * \note This is only for compatibility. Will not be used. | ||
268 | */ | ||
269 | ✗ | Scalar krn(const Scalar sw) const | |
270 | ✗ | { return 1.0; } | |
271 | |||
272 | /*! | ||
273 | * \brief The derivative of the relative permeability for the non-wetting phase w.r.t. saturation | ||
274 | * \note This is only for compatibility. Will not be used. | ||
275 | */ | ||
276 | Scalar dkrn_dsw(const Scalar sw) const | ||
277 | { return 0.0; } | ||
278 | |||
279 | private: | ||
280 | std::shared_ptr<typename LocalRules::Tetrahedron> localRulesForTetrahedron_; | ||
281 | std::shared_ptr<typename LocalRules::Cube> localRulesForCube_; | ||
282 | std::shared_ptr<typename LocalRules::Octahedron> localRulesForOctahedron_; | ||
283 | std::shared_ptr<typename LocalRules::Icosahedron> localRulesForIcosahedron_; | ||
284 | std::shared_ptr<typename LocalRules::Dodecahedron> localRulesForDodecahedron_; | ||
285 | |||
286 | // TODO add more shapes here | ||
287 | |||
288 | Pore::Shape shape_; | ||
289 | }; | ||
290 | |||
291 | } // end namespace Dumux::FluidMatrix | ||
292 | |||
293 | #endif | ||
294 |