3.4
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
porenetworkbase.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_PNM_SPATIAL_PARAMS_BASE_HH
26#define DUMUX_PNM_SPATIAL_PARAMS_BASE_HH
27
28#include <type_traits>
29#include <memory>
30
31#include <dune/common/fvector.hh>
32
34
35namespace Dumux::PoreNetwork {
36
37#ifndef DOXYGEN
38namespace Detail {
39// helper struct detecting if the user-defined spatial params class has a materialLawParamsAtPos function
40// for g++ > 5.3, this can be replaced by a lambda
41template<class GlobalPosition>
42struct hasMaterialLawParamsAtPos
43{
44 template<class SpatialParams>
45 auto operator()(const SpatialParams& a)
46 -> decltype(a.materialLawParamsAtPos(std::declval<GlobalPosition>()))
47 {}
48};
49
50// helper struct detecting if the user-defined spatial params class has a permeabilityAtPos function
51// for g++ > 5.3, this can be replaced by a lambda
52template<class GlobalPosition>
53struct hasPermeabilityAtPos
54{
55 template<class SpatialParams>
56 auto operator()(const SpatialParams& a)
57 -> decltype(a.permeabilityAtPos(std::declval<GlobalPosition>()))
58 {}
59};
60
61template<class GlobalPosition, class SolidSystem>
62struct hasInertVolumeFractionAtPos
63{
64 template<class SpatialParams>
65 auto operator()(const SpatialParams& a)
66 -> decltype(a.template inertVolumeFractionAtPos<SolidSystem>(std::declval<GlobalPosition>(), 0))
67 {}
68};
69
70template<class GlobalPosition>
71struct hasPorosityAtPos
72{
73 template<class SpatialParams>
74 auto operator()(const SpatialParams& a)
75 -> decltype(a.porosityAtPos(std::declval<GlobalPosition>()))
76 {}
77};
78
79} // end namespace Detail
80#endif
81
90template<class GridGeometry, class Scalar, class Implementation>
92{
93 using GridView = typename GridGeometry::GridView;
94 using SubControlVolume = typename GridGeometry::SubControlVolume;
95 using Element = typename GridView::template Codim<0>::Entity;
96
97 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
98 static constexpr auto dimWorld = GridView::dimensionworld;
99
100public:
101 using PermeabilityType = Scalar;
102
103 BaseSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
104 : gridGeometry_(gridGeometry)
105 , gravity_(0.0)
106 {
107 const bool enableGravity = getParam<bool>("Problem.EnableGravity");
108 if (enableGravity)
109 gravity_[dimWorld-1] = -9.81;
110 }
111
119 template<class ElementVolumeVariables>
120 Scalar throatLength(const Element& element,
121 const ElementVolumeVariables& elemVolVars) const
122 {
123 const auto eIdx = gridGeometry().elementMapper().index(element);
124 return gridGeometry().throatLength(eIdx);
125 }
126
134 template<class ElementVolumeVariables>
135 Scalar throatInscribedRadius(const Element& element,
136 const ElementVolumeVariables& elemVolVars) const
137 {
138 const auto eIdx = gridGeometry().elementMapper().index(element);
139 return gridGeometry().throatInscribedRadius(eIdx);
140 }
141
149 template<class ElementVolumeVariables>
150 Scalar throatCrossSectionalArea(const Element& element,
151 const ElementVolumeVariables& elemVolVars) const
152 {
153 const auto eIdx = gridGeometry().elementMapper().index(element);
154 return gridGeometry().throatCrossSectionalArea(eIdx);
155 }
156
165 template<class ElementSolutionVector>
166 Scalar poreInscribedRadius(const Element& element,
167 const SubControlVolume& scv,
168 const ElementSolutionVector& elemSol) const
169 {
170 return gridGeometry().poreInscribedRadius(scv.dofIndex());
171 }
172
176 const GridView& gridView() const
177 { return gridGeometry().gridView(); }
178
179
183 template<class ElementSolutionVector>
184 Scalar permeability(const Element& element,
185 const SubControlVolume& scv,
186 const ElementSolutionVector& elemSol) const
187 { return 1.0; }
188
199 const GlobalPosition& gravity(const GlobalPosition& pos) const
200 { return gravity_; }
201
204 { return *gridGeometry_; }
205
216 template<class ElementSolution>
217 Scalar porosity(const Element& element,
218 const SubControlVolume& scv,
219 const ElementSolution& elemSol) const
220 {
221 static_assert(decltype(isValid(Detail::hasPorosityAtPos<GlobalPosition>())(this->asImp_()))::value," \n\n"
222 " Your spatial params class has to either implement\n\n"
223 " Scalar porosityAtPos(const GlobalPosition& globalPos) const\n\n"
224 " or overload this function\n\n"
225 " template<class ElementSolution>\n"
226 " Scalar porosity(const Element& element,\n"
227 " const SubControlVolume& scv,\n"
228 " const ElementSolution& elemSol) const\n\n");
229
230 return asImp_().porosityAtPos(scv.center());
231 }
232
233 Scalar porosityAtPos(const GlobalPosition& globalPos) const
234 { return 1.0; }
235
252 template<class SolidSystem, class ElementSolution,
253 typename std::enable_if_t<SolidSystem::isInert()
254 && SolidSystem::numInertComponents == 1
255 && !decltype(isValid(Detail::hasInertVolumeFractionAtPos<GlobalPosition, SolidSystem>())(std::declval<Implementation>()))::value,
256 int> = 0>
257 Scalar inertVolumeFraction(const Element& element,
258 const SubControlVolume& scv,
259 const ElementSolution& elemSol,
260 int compIdx) const
261 {
262 return 1.0 - asImp_().porosity(element, scv, elemSol);
263 }
264
265 // specialization if there are no inert components at all
266 template<class SolidSystem, class ElementSolution,
267 typename std::enable_if_t<SolidSystem::numInertComponents == 0, int> = 0>
268 Scalar inertVolumeFraction(const Element& element,
269 const SubControlVolume& scv,
270 const ElementSolution& elemSol,
271 int compIdx) const
272 {
273 return 0.0;
274 }
275
276 // the more general interface forwarding to inertVolumeFractionAtPos
277 template<class SolidSystem, class ElementSolution,
278 typename std::enable_if_t<(SolidSystem::numInertComponents > 1) ||
279 (
280 (SolidSystem::numInertComponents > 0) &&
281 (
282 !SolidSystem::isInert()
283 || decltype(isValid(Detail::hasInertVolumeFractionAtPos<GlobalPosition, SolidSystem>())
284 (std::declval<Implementation>()))::value
285 )
286 ),
287 int> = 0>
288 Scalar inertVolumeFraction(const Element& element,
289 const SubControlVolume& scv,
290 const ElementSolution& elemSol,
291 int compIdx) const
292 {
293 static_assert(decltype(isValid(Detail::hasInertVolumeFractionAtPos<GlobalPosition, SolidSystem>())(this->asImp_()))::value," \n\n"
294 " Your spatial params class has to either implement\n\n"
295 " template<class SolidSystem>\n"
296 " Scalar inertVolumeFractionAtPos(const GlobalPosition& globalPos, int compIdx) const\n\n"
297 " or overload this function\n\n"
298 " template<class SolidSystem, class ElementSolution>\n"
299 " Scalar inertVolumeFraction(const Element& element,\n"
300 " const SubControlVolume& scv,\n"
301 " const ElementSolution& elemSol,\n"
302 " int compIdx) const\n\n");
303
304 return asImp_().template inertVolumeFractionAtPos<SolidSystem>(scv.center(), compIdx);
305 }
306
307protected:
308 Implementation &asImp_()
309 { return *static_cast<Implementation*>(this); }
310
311 const Implementation &asImp_() const
312 { return *static_cast<const Implementation*>(this); }
313
314private:
315 std::shared_ptr<const GridGeometry> gridGeometry_;
316 GlobalPosition gravity_;
317};
318
319} // namespace Dumux::PoreNetwork
320
321#endif
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
constexpr auto isValid(const Expression &t)
A function that creates a test functor to do class member introspection at compile time.
Definition: isvalid.hh:93
Definition: discretization/porenetwork/fvelementgeometry.hh:33
Base class for the finite volume geometry for porenetwork models.
Definition: discretization/porenetwork/gridgeometry.hh:488
The base class for spatial parameters for pore-network models.
Definition: porenetworkbase.hh:92
Implementation & asImp_()
Definition: porenetworkbase.hh:308
Scalar porosityAtPos(const GlobalPosition &globalPos) const
Definition: porenetworkbase.hh:233
Scalar throatLength(const Element &element, const ElementVolumeVariables &elemVolVars) const
Length of the throat . Can be solution-dependent.
Definition: porenetworkbase.hh:120
const Implementation & asImp_() const
Definition: porenetworkbase.hh:311
Scalar permeability(const Element &element, const SubControlVolume &scv, const ElementSolutionVector &elemSol) const
Definition: porenetworkbase.hh:184
Scalar throatInscribedRadius(const Element &element, const ElementVolumeVariables &elemVolVars) const
Inscribed radius of the throat . Can be solution-dependent.
Definition: porenetworkbase.hh:135
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: porenetworkbase.hh:203
const GlobalPosition & gravity(const GlobalPosition &pos) const
Returns the acceleration due to gravity .
Definition: porenetworkbase.hh:199
Scalar throatCrossSectionalArea(const Element &element, const ElementVolumeVariables &elemVolVars) const
Cross-sectional area of the throat . Can be solution-dependent.
Definition: porenetworkbase.hh:150
Scalar porosity(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol) const
Function for defining the porosity. That is possibly solution dependent.
Definition: porenetworkbase.hh:217
Scalar inertVolumeFraction(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol, int compIdx) const
Function for defining the solid volume fraction. That is possibly solution dependent.
Definition: porenetworkbase.hh:257
Scalar PermeabilityType
Definition: porenetworkbase.hh:101
BaseSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetworkbase.hh:103
const GridView & gridView() const
Returns a reference to the gridview.
Definition: porenetworkbase.hh:176
Scalar poreInscribedRadius(const Element &element, const SubControlVolume &scv, const ElementSolutionVector &elemSol) const
Inscribed radius of the pore body . Can be solution-dependent.
Definition: porenetworkbase.hh:166