3.5-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 }
197
206 template<class ElementSolution>
207 auto fluidMatrixInteraction(const Element& element,
208 const SubControlVolume& scv,
209 const ElementSolution& elemSol) const
210 {
211 const auto params = typename LocalRules::BasicParams(*this, element, scv, elemSol);
212 return makeFluidMatrixInteraction(LocalRules(params, "SpatialParams"));
213 }
214
215 const Dune::ReservedVector<Scalar, 4>& cornerHalfAngles(const Element& element) const
216 {
217 if (this->gridGeometry().useSameShapeForAllThroats())
218 return cornerHalfAngles_[0];
219 else
220 {
221 const auto eIdx = this->gridGeometry().gridView().indexSet().index(element);
222 return cornerHalfAngles_[eIdx];
223 }
224 }
225
226private:
227 std::vector<Dune::ReservedVector<Scalar, 4>> cornerHalfAngles_;
228};
229
235template<class GridGeometry, class Scalar, class LocalRules>
236class TwoPDefaultSpatialParams
237: public TwoPSpatialParams<GridGeometry, Scalar, LocalRules, TwoPDefaultSpatialParams<GridGeometry, Scalar, LocalRules>>
238{
239 using ParentType = TwoPSpatialParams<GridGeometry, Scalar, LocalRules,
240 TwoPDefaultSpatialParams<GridGeometry, Scalar, LocalRules>>;
241 using GridView = typename GridGeometry::GridView;
242 using Element = typename GridView::template Codim<0>::Entity;
243 using GlobalPosition = typename Element::Geometry::GlobalCoordinate;
244public:
245 using ParentType::ParentType;
246
247 TwoPDefaultSpatialParams(std::shared_ptr<const GridGeometry> gridGeometry)
249 { }
250
257 template<class FluidSystem>
258 int wettingPhaseAtPos(const GlobalPosition& globalPos) const
259 { return FluidSystem::phase0Idx; }
260
267 int contactAngleAtPos(const GlobalPosition& globalPos) const
268 {
269 static const Scalar theta = getParam<Scalar>("SpatialParams.ContactAngle", 0.0);
270 return theta;
271 }
272
279 Scalar surfaceTensionAtPos(const GlobalPosition& globalPos) const
280 {
281 static const Scalar gamma = getParam<Scalar>("SpatialParams.SurfaceTension", 0.0725); // default to surface tension of water/air
282 return gamma;
283 }
284
285};
286
287} // namespace Dumux::PoreNetwork
288
289#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
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition: throatproperties.hh:176
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
static constexpr Scalar pcSnapoff(const Scalar surfaceTension, const Scalar contactAngle, const Scalar inscribedRadius) noexcept
The snap-off capillary pressure of a pore throat.
Definition: thresholdcapillarypressures.hh:37
static constexpr 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:55
TwoPDefaultSpatialParams(std::shared_ptr< const GridGeometry > gridGeometry)
Definition: porenetwork/2p/spatialparams.hh:247
int wettingPhaseAtPos(const GlobalPosition &globalPos) const
Function for defining which phase is to be considered as the wetting phase.
Definition: porenetwork/2p/spatialparams.hh:258
Scalar surfaceTensionAtPos(const GlobalPosition &globalPos) const
Function for defining the surface Tension.
Definition: porenetwork/2p/spatialparams.hh:279
int contactAngleAtPos(const GlobalPosition &globalPos) const
Function for defining the Contact Angle.
Definition: porenetwork/2p/spatialparams.hh:267
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:215
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:207
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.