3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * 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_2P_SPATIAL_PARAMS_HH
26#define DUMUX_PNM_2P_SPATIAL_PARAMS_HH
27
30
34
35namespace Dumux::PoreNetwork {
36
42template<class GridGeometry, class Scalar, class LocalRules, class Implementation>
44: public SpatialParams<GridGeometry, Scalar, Implementation>
45{
47 using GridView = typename GridGeometry::GridView;
48 using SubControlVolume = typename GridGeometry::SubControlVolume;
49 using Element = typename GridView::template Codim<0>::Entity;
50 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
51
52public:
53
54 TwoPSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
56 {
57 if (!gridGeometry->useSameGeometryForAllPores() && LocalRules::supportsMultipleGeometries())
58 DUNE_THROW(Dune::InvalidStateException, "Your MaterialLaw does not support multiple pore body shapes.");
59
60 if (this->gridGeometry().useSameShapeForAllThroats())
61 {
62 cornerHalfAngles_.resize(1);
63 const auto& shape = this->gridGeometry().throatCrossSectionShape(/*eIdx*/0);
64 cornerHalfAngles_[0] = Throat::cornerHalfAngles<Scalar>(shape);
65 }
66 else
67 {
68 cornerHalfAngles_.resize(this->gridGeometry().gridView().size(0));
69 for (auto&& element : elements(this->gridGeometry().gridView()))
70 {
71 const auto eIdx = this->gridGeometry().elementMapper().index(element);
72 const auto& shape = this->gridGeometry().throatCrossSectionShape(eIdx);
73 cornerHalfAngles_[eIdx] = Throat::cornerHalfAngles<Scalar>(shape);
74 }
75 }
76 }
77
81 template<class FS, class ElementVolumeVariables>
82 int wettingPhase(const Element& element,
83 const ElementVolumeVariables& elemVolVars) const
84 { return this->asImp_().template wettingPhaseAtPos<FS>(element.geometry().center()); }
85
89 template<class FS, class ElementSolutionVector>
90 int wettingPhase(const Element& element,
91 const SubControlVolume& scv,
92 const ElementSolutionVector& elemSol) const
93 { return this->asImp_().template wettingPhaseAtPos<FS>(scv.center()); }
94
101 template<class FluidSystem>
102 int wettingPhaseAtPos(const GlobalPosition& globalPos) const
103 {
104 DUNE_THROW(Dune::InvalidStateException,
105 "The spatial parameters do not provide "
106 "a wettingPhaseAtPos() method.");
107 }
108
116 template<class ElementVolumeVariables>
117 Scalar contactAngle(const Element& element,
118 const ElementVolumeVariables& elemVolVars) const
119 { return this->asImp_().contactAngleAtPos(element.geometry().center()); }
120
129 template<class ElementSolutionVector>
130 Scalar contactAngle(const Element& element,
131 const SubControlVolume& scv,
132 const ElementSolutionVector& elemSol) const
133 { return this->asImp_().contactAngleAtPos(scv.center()); }
134
136 int contactAngleAtPos(const GlobalPosition& globalPos) const
137 {
138 DUNE_THROW(Dune::InvalidStateException,
139 "The spatial parameters do not provide "
140 "a contactAngleAtPos() method.");
141 }
142
150 template<class ElementSolution>
151 Scalar surfaceTension(const Element& element,
152 const SubControlVolume& scv,
153 const ElementSolution& elemSol) const
154 { return this->asImp_().surfaceTensionAtPos(scv.center()); }
155
157 Scalar surfaceTensionAtPos(const GlobalPosition& globalPos) const
158 {
159 DUNE_THROW(Dune::InvalidStateException,
160 "The spatial parameters do not provide "
161 "a surfaceTensionAtPos() method.");
162 }
163
169 template<class ElementVolumeVariables>
170 const Scalar pcEntry(const Element& element,
171 const ElementVolumeVariables& elemVolVars) const
172 {
173 const auto eIdx = this->gridGeometry().elementMapper().index(element);
174 // take the average of both adjacent pores TODO: is this correct?
175 const Scalar surfaceTension = 0.5*(elemVolVars[0].surfaceTension() + elemVolVars[1].surfaceTension());
177 this->asImp_().contactAngle(element, elemVolVars),
178 this->asImp_().throatInscribedRadius(element, elemVolVars),
179 this->gridGeometry().throatShapeFactor(eIdx));
180 }
181
187 template<class ElementVolumeVariables>
188 const Scalar pcSnapoff(const Element& element,
189 const ElementVolumeVariables& elemVolVars) const
190 {
191 // take the average of both adjacent pores TODO: is this correct?
192 const Scalar surfaceTension = 0.5*(elemVolVars[0].surfaceTension() + elemVolVars[1].surfaceTension());
194 this->asImp_().contactAngle(element, elemVolVars),
195 this->asImp_().throatInscribedRadius(element, elemVolVars),
196 this->gridGeometry().throatCrossSectionShape(/*eIdx*/ 0));
197 }
198
207 template<class ElementSolution>
208 auto fluidMatrixInteraction(const Element& element,
209 const SubControlVolume& scv,
210 const ElementSolution& elemSol) const
211 {
212 const auto params = typename LocalRules::BasicParams(*this, element, scv, elemSol);
213 return makeFluidMatrixInteraction(LocalRules(params, "SpatialParams"));
214 }
215
216 const Dune::ReservedVector<Scalar, 4>& cornerHalfAngles(const Element& element) const
217 {
218 if (this->gridGeometry().useSameShapeForAllThroats())
219 return cornerHalfAngles_[0];
220 else
221 {
222 const auto eIdx = this->gridGeometry().gridView().indexSet().index(element);
223 return cornerHalfAngles_[eIdx];
224 }
225 }
226
227private:
228 std::vector<Dune::ReservedVector<Scalar, 4>> cornerHalfAngles_;
229};
230
236template<class GridGeometry, class Scalar, class LocalRules>
238: public TwoPSpatialParams<GridGeometry, Scalar, LocalRules, TwoPDefaultSpatialParams<GridGeometry, Scalar, LocalRules>>
239{
240 using ParentType = TwoPSpatialParams<GridGeometry, Scalar, LocalRules,
242 using GridView = typename GridGeometry::GridView;
243 using Element = typename GridView::template Codim<0>::Entity;
244 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
245public:
247
248 TwoPDefaultSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
250 { }
251
258 template<class FluidSystem>
259 int wettingPhaseAtPos(const GlobalPosition& globalPos) const
260 { return FluidSystem::phase0Idx; }
261
268 int contactAngleAtPos(const GlobalPosition& globalPos) const
269 {
270 static const Scalar theta = getParam<Scalar>("SpatialParams.ContactAngle", 0.0);
271 return theta;
272 }
273
280 Scalar surfaceTensionAtPos(const GlobalPosition& globalPos) const
281 {
282 static const Scalar gamma = getParam<Scalar>("SpatialParams.SurfaceTension", 0.0725); // default to surface tension of water/air
283 return gamma;
284 }
285
286};
287
288} // namespace Dumux::PoreNetwork
289
290#endif
Wrapper type to combine an arbitrary number of different laws for fluid-matrix interaction (e....
Specification of threshold capillary pressures for the PNM.
This file contains functions related to calculate pore-body properties.
This file contains functions related to calculate pore-throat properties.
auto makeFluidMatrixInteraction(Laws &&... laws)
Helper function to create an FluidMatrixInteraction object containing an arbitrary number of fluid ma...
Definition: fluidmatrixinteraction.hh:51
Definition: discretization/porenetwork/fvelementgeometry.hh:34
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:77
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:94
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition: throatproperties.hh:177
The base class for spatial parameters used with finite-volume schemes.
Definition: common/fvspatialparams.hh:46
Implementation & asImp_()
Returns the implementation of the spatial parameters (static polymorphism)
Definition: common/fvspatialparams.hh:147
const GridGeometry & gridGeometry() const
The finite volume grid geometry.
Definition: common/fvspatialparams.hh:142
Base class for the finite volume geometry for porenetwork models.
Definition: discretization/porenetwork/gridgeometry.hh:489
The base class for spatial parameters for pore-network models.
Definition: porenetwork/2p/spatialparams.hh:45
int wettingPhase(const Element &element, const ElementVolumeVariables &elemVolVars) const
The index of the wetting phase within a pore throat.
Definition: porenetwork/2p/spatialparams.hh:82
Scalar contactAngle(const Element &element, const ElementVolumeVariables &elemVolVars) const
The contact angle within a pore throat .
Definition: porenetwork/2p/spatialparams.hh:117
Scalar surfaceTension(const Element &element, const SubControlVolume &scv, const ElementSolution &elemSol) const
Returns the surface tension .
Definition: porenetwork/2p/spatialparams.hh:151
int contactAngleAtPos(const GlobalPosition &globalPos) const
Function for defining the Contact Angle.
Definition: porenetwork/2p/spatialparams.hh:136
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:90
TwoPSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetwork/2p/spatialparams.hh:54
Scalar surfaceTensionAtPos(const GlobalPosition &globalPos) const
Function for defining the surface Tension.
Definition: porenetwork/2p/spatialparams.hh:157
const Scalar pcEntry(const Element &element, const ElementVolumeVariables &elemVolVars) const
Return the element (throat) specific entry capillary pressure .
Definition: porenetwork/2p/spatialparams.hh:170
int wettingPhaseAtPos(const GlobalPosition &globalPos) const
Function for defining which phase is to be considered as the wetting phase.
Definition: porenetwork/2p/spatialparams.hh:102
Scalar contactAngle(const Element &element, const SubControlVolume &scv, const ElementSolutionVector &elemSol) const
The contact angle within a pore body .
Definition: porenetwork/2p/spatialparams.hh:130
const Scalar pcSnapoff(const Element &element, const ElementVolumeVariables &elemVolVars) const
Return the element (throat) specific snap-off capillary pressure .
Definition: porenetwork/2p/spatialparams.hh:188
const Dune::ReservedVector< Scalar, 4 > & cornerHalfAngles(const Element &element) const
Definition: porenetwork/2p/spatialparams.hh:216
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:208
The default class for spatial parameters for two-phase pore-network models.
Definition: porenetwork/2p/spatialparams.hh:239
Scalar surfaceTensionAtPos(const GlobalPosition &globalPos) const
Function for defining the surface Tension.
Definition: porenetwork/2p/spatialparams.hh:280
int contactAngleAtPos(const GlobalPosition &globalPos) const
Function for defining the Contact Angle.
Definition: porenetwork/2p/spatialparams.hh:268
int wettingPhaseAtPos(const GlobalPosition &globalPos) const
Function for defining which phase is to be considered as the wetting phase.
Definition: porenetwork/2p/spatialparams.hh:259
TwoPDefaultSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetwork/2p/spatialparams.hh:248
The base class for spatial parameters for pore-network models.
Definition: porenetwork/common/spatialparams.hh:45
Scalar throatInscribedRadius(const Element &element, const ElementVolumeVariables &elemVolVars) const
Inscribed radius of the throat . Can be solution-dependent.
Definition: porenetwork/common/spatialparams.hh:84
const GridView & gridView() const
Returns a reference to the gridview.
Definition: porenetwork/common/spatialparams.hh:123
The base class for spatial parameters for pore-network models.