version 3.10-dev
porenetwork/2p/spatialparams.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// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_PNM_2P_SPATIAL_PARAMS_HH
14#define DUMUX_PNM_2P_SPATIAL_PARAMS_HH
15
18
22
23namespace Dumux::PoreNetwork {
24
30template<class GridGeometry, class Scalar, class LocalRules, class Implementation>
32: public SpatialParams<GridGeometry, Scalar, Implementation>
33{
35 using GridView = typename GridGeometry::GridView;
36 using SubControlVolume = typename GridGeometry::SubControlVolume;
37 using Element = typename GridView::template Codim<0>::Entity;
38 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
39
40public:
41
42 TwoPSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
44 {
45 if (!gridGeometry->useSameGeometryForAllPores() && LocalRules::supportsMultipleGeometries())
46 DUNE_THROW(Dune::InvalidStateException, "Your MaterialLaw does not support multiple pore body shapes.");
47
48 if (this->gridGeometry().useSameShapeForAllThroats())
49 {
50 cornerHalfAngles_.resize(1);
51 const auto& shape = this->gridGeometry().throatCrossSectionShape(/*eIdx*/0);
52 cornerHalfAngles_[0] = Throat::cornerHalfAngles<Scalar>(shape);
53 }
54 else
55 {
56 cornerHalfAngles_.resize(this->gridGeometry().gridView().size(0));
57 for (auto&& element : elements(this->gridGeometry().gridView()))
58 {
59 const auto eIdx = this->gridGeometry().elementMapper().index(element);
60 const auto& shape = this->gridGeometry().throatCrossSectionShape(eIdx);
61 cornerHalfAngles_[eIdx] = Throat::cornerHalfAngles<Scalar>(shape);
62 }
63 }
64 }
65
69 template<class FS, class ElementVolumeVariables>
70 int wettingPhase(const Element& element,
71 const ElementVolumeVariables& elemVolVars) const
72 { return this->asImp_().template wettingPhaseAtPos<FS>(element.geometry().center()); }
73
77 template<class FS, class ElementSolutionVector>
78 int wettingPhase(const Element& element,
79 const SubControlVolume& scv,
80 const ElementSolutionVector& elemSol) const
81 { return this->asImp_().template wettingPhaseAtPos<FS>(scv.center()); }
82
89 template<class FluidSystem>
90 int wettingPhaseAtPos(const GlobalPosition& globalPos) const
91 {
92 DUNE_THROW(Dune::InvalidStateException,
93 "The spatial parameters do not provide "
94 "a wettingPhaseAtPos() method.");
95 }
96
104 template<class ElementVolumeVariables>
105 Scalar contactAngle(const Element& element,
106 const ElementVolumeVariables& elemVolVars) const
107 { return this->asImp_().contactAngleAtPos(element.geometry().center()); }
108
117 template<class ElementSolutionVector>
118 Scalar contactAngle(const Element& element,
119 const SubControlVolume& scv,
120 const ElementSolutionVector& elemSol) const
121 { return this->asImp_().contactAngleAtPos(scv.center()); }
122
124 int contactAngleAtPos(const GlobalPosition& globalPos) const
125 {
126 DUNE_THROW(Dune::InvalidStateException,
127 "The spatial parameters do not provide "
128 "a contactAngleAtPos() method.");
129 }
130
138 template<class ElementSolution>
139 Scalar surfaceTension(const Element& element,
140 const SubControlVolume& scv,
141 const ElementSolution& elemSol) const
142 { return this->asImp_().surfaceTensionAtPos(scv.center()); }
143
145 Scalar surfaceTensionAtPos(const GlobalPosition& globalPos) const
146 {
147 DUNE_THROW(Dune::InvalidStateException,
148 "The spatial parameters do not provide "
149 "a surfaceTensionAtPos() method.");
150 }
151
157 template<class ElementVolumeVariables>
158 const Scalar pcEntry(const Element& element,
159 const ElementVolumeVariables& elemVolVars) const
160 {
161 const auto eIdx = this->gridGeometry().elementMapper().index(element);
162 // take the average of both adjacent pores TODO: is this correct?
163 const Scalar surfaceTension = 0.5*(elemVolVars[0].surfaceTension() + elemVolVars[1].surfaceTension());
165 this->asImp_().contactAngle(element, elemVolVars),
166 this->asImp_().throatInscribedRadius(element, elemVolVars),
167 this->gridGeometry().throatShapeFactor(eIdx));
168 }
169
175 template<class ElementVolumeVariables>
176 const Scalar pcSnapoff(const Element& element,
177 const ElementVolumeVariables& elemVolVars) const
178 {
179 // take the average of both adjacent pores TODO: is this correct?
180 const Scalar surfaceTension = 0.5*(elemVolVars[0].surfaceTension() + elemVolVars[1].surfaceTension());
182 this->asImp_().contactAngle(element, elemVolVars),
183 this->asImp_().throatInscribedRadius(element, elemVolVars),
184 this->gridGeometry().throatCrossSectionShape(/*eIdx*/ 0));
185 }
186
195 template<class ElementSolution>
196 auto fluidMatrixInteraction(const Element& element,
197 const SubControlVolume& scv,
198 const ElementSolution& elemSol) const
199 {
200 const auto params = typename LocalRules::BasicParams(this->asImp_(), element, scv, elemSol);
201 return makeFluidMatrixInteraction(LocalRules(params, "SpatialParams"));
202 }
203
204 const Dune::ReservedVector<Scalar, 4>& cornerHalfAngles(const Element& element) const
205 {
206 if (this->gridGeometry().useSameShapeForAllThroats())
207 return cornerHalfAngles_[0];
208 else
209 {
210 const auto eIdx = this->gridGeometry().gridView().indexSet().index(element);
211 return cornerHalfAngles_[eIdx];
212 }
213 }
214
215private:
216 std::vector<Dune::ReservedVector<Scalar, 4>> cornerHalfAngles_;
217};
218
224template<class GridGeometry, class Scalar, class LocalRules>
226: public TwoPSpatialParams<GridGeometry, Scalar, LocalRules, TwoPDefaultSpatialParams<GridGeometry, Scalar, LocalRules>>
227{
228 using ParentType = TwoPSpatialParams<GridGeometry, Scalar, LocalRules,
230 using GridView = typename GridGeometry::GridView;
231 using Element = typename GridView::template Codim<0>::Entity;
232 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
233public:
235
236 TwoPDefaultSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
238 { }
239
246 template<class FluidSystem>
247 int wettingPhaseAtPos(const GlobalPosition& globalPos) const
248 { return FluidSystem::phase0Idx; }
249
256 int contactAngleAtPos(const GlobalPosition& globalPos) const
257 {
258 static const Scalar theta = getParam<Scalar>("SpatialParams.ContactAngle", 0.0);
259 return theta;
260 }
261
268 Scalar surfaceTensionAtPos(const GlobalPosition& globalPos) const
269 {
270 static const Scalar gamma = getParam<Scalar>("SpatialParams.SurfaceTension", 0.0725); // default to surface tension of water/air
271 return gamma;
272 }
273
274};
275
276} // namespace Dumux::PoreNetwork
277
278#endif
The base class for spatial parameters used with finite-volume schemes.
Definition: common/fvspatialparams.hh:34
Implementation & asImp_()
Returns the implementation of the spatial parameters (static polymorphism)
Definition: common/fvspatialparams.hh:135
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: common/fvspatialparams.hh:130
Base class for the finite volume geometry for porenetwork models.
Definition: discretization/porenetwork/gridgeometry.hh:477
The base class for spatial parameters for pore-network models.
Definition: porenetwork/common/spatialparams.hh:33
Scalar throatInscribedRadius(const Element &element, const ElementVolumeVariables &elemVolVars) const
Inscribed radius of the throat . Can be solution-dependent.
Definition: porenetwork/common/spatialparams.hh:72
const GridView & gridView() const
Returns a reference to the gridview.
Definition: porenetwork/common/spatialparams.hh:111
The default class for spatial parameters for two-phase pore-network models.
Definition: porenetwork/2p/spatialparams.hh:227
Scalar surfaceTensionAtPos(const GlobalPosition &globalPos) const
Function for defining the surface Tension.
Definition: porenetwork/2p/spatialparams.hh:268
int contactAngleAtPos(const GlobalPosition &globalPos) const
Function for defining the Contact Angle.
Definition: porenetwork/2p/spatialparams.hh:256
int wettingPhaseAtPos(const GlobalPosition &globalPos) const
Function for defining which phase is to be considered as the wetting phase.
Definition: porenetwork/2p/spatialparams.hh:247
TwoPDefaultSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetwork/2p/spatialparams.hh:236
The base class for spatial parameters for pore-network models.
Definition: porenetwork/2p/spatialparams.hh:33
int wettingPhase(const Element &element, const ElementVolumeVariables &elemVolVars) const
The index of the wetting phase within a pore throat.
Definition: porenetwork/2p/spatialparams.hh:70
Scalar contactAngle(const Element &element, const ElementVolumeVariables &elemVolVars) const
The contact angle within a pore throat .
Definition: porenetwork/2p/spatialparams.hh:105
Scalar surfaceTension(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol) const
Returns the surface tension .
Definition: porenetwork/2p/spatialparams.hh:139
int contactAngleAtPos(const GlobalPosition &globalPos) const
Function for defining the Contact Angle.
Definition: porenetwork/2p/spatialparams.hh:124
int wettingPhase(const Element &element, const SubControlVolume &scv, const ElementSolutionVector &elemSol) const
The index of the wetting phase within a pore body.
Definition: porenetwork/2p/spatialparams.hh:78
TwoPSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetwork/2p/spatialparams.hh:42
Scalar surfaceTensionAtPos(const GlobalPosition &globalPos) const
Function for defining the surface Tension.
Definition: porenetwork/2p/spatialparams.hh:145
const Scalar pcEntry(const Element &element, const ElementVolumeVariables &elemVolVars) const
Return the element (throat) specific entry capillary pressure .
Definition: porenetwork/2p/spatialparams.hh:158
int wettingPhaseAtPos(const GlobalPosition &globalPos) const
Function for defining which phase is to be considered as the wetting phase.
Definition: porenetwork/2p/spatialparams.hh:90
Scalar contactAngle(const Element &element, const SubControlVolume &scv, const ElementSolutionVector &elemSol) const
The contact angle within a pore body .
Definition: porenetwork/2p/spatialparams.hh:118
const Scalar pcSnapoff(const Element &element, const ElementVolumeVariables &elemVolVars) const
Return the element (throat) specific snap-off capillary pressure .
Definition: porenetwork/2p/spatialparams.hh:176
const Dune::ReservedVector< Scalar, 4 > & cornerHalfAngles(const Element &element) const
Definition: porenetwork/2p/spatialparams.hh:204
auto fluidMatrixInteraction(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol) const
Returns the parameter object for the pore-local pc-Sw law.
Definition: porenetwork/2p/spatialparams.hh:196
Wrapper type to combine an arbitrary number of different laws for fluid-matrix interaction (e....
auto makeFluidMatrixInteraction(Laws &&... laws)
Helper function to create an FluidMatrixInteraction object containing an arbitrary number of fluid ma...
Definition: fluidmatrixinteraction.hh:39
Scalar pcSnapoff(const Scalar surfaceTension, const Scalar contactAngle, const Scalar inscribedRadius, const Throat::Shape shape)
The snap-off capillary pressure of a pore throat It checks if the cross section shape of the throat i...
Definition: thresholdcapillarypressures.hh:65
Scalar pcEntry(const Scalar surfaceTension, const Scalar contactAngle, const Scalar inscribedRadius, const Scalar shapeFactor) noexcept
The entry capillary pressure of a pore throat.
Definition: thresholdcapillarypressures.hh:82
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition: throatproperties.hh:165
Definition: discretization/porenetwork/fvelementgeometry.hh:24
The base class for spatial parameters for pore-network models.
This file contains functions related to calculate pore-body properties.
Specification of threshold capillary pressures for the PNM.
This file contains functions related to calculate pore-throat properties.