3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
throatproperties.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 *****************************************************************************/
24#ifndef DUMUX_PNM_BASE_THROAT_PROPERTIES_HH
25#define DUMUX_PNM_BASE_THROAT_PROPERTIES_HH
26
27#include <string>
28#include <cmath>
29#include <numeric>
30
31#include <dune/common/exceptions.hh>
32#include <dune/common/reservedvector.hh>
33
35
37enum class Shape
39
41inline std::string shapeToString(Shape s)
42{
43 switch (s)
44 {
45 case Shape::scaleneTriangle: return "ScaleneTriangle";
46 case Shape::equilateralTriangle: return "EquilateralTriangle";
47 case Shape::square: return "Square";
48 case Shape::rectangle: return "Rectangle";
49 case Shape::circle: return "Circle";
50 case Shape::twoPlates: return "TwoPlates";
51 case Shape::polygon: return "Polygon";
52 default: DUNE_THROW(Dune::InvalidStateException, "Unknown shape!");
53 }
54}
55
57inline Shape shapeFromString(const std::string& s)
58{
61 else if (s == shapeToString(Shape::square)) return Shape::square;
62 else if (s == shapeToString(Shape::rectangle)) return Shape::rectangle;
63 else if (s == shapeToString(Shape::circle)) return Shape::circle;
64 else if (s == shapeToString(Shape::twoPlates)) return Shape::twoPlates;
65 else if (s == shapeToString(Shape::polygon)) return Shape::polygon;
66 else DUNE_THROW(Dune::InvalidStateException, s << " is not a valid shape");
67}
68
79template<class Scalar>
80inline Scalar averagedRadius(const Scalar poreRadiusOne, const Scalar poreRadiusTwo, const Scalar centerTocenterDist, const Scalar n = 0.1)
81{
82 assert(n > 0.0);
83 using std::sin; using std::cos; using std::pow;
84 const Scalar rOneTilde = poreRadiusOne/centerTocenterDist;
85 const Scalar rTwoTilde = poreRadiusTwo/centerTocenterDist;
86 const Scalar a = sin(M_PI/4.0);
87 const Scalar b = cos(M_PI/4.0);
88 const Scalar rhoOne = rOneTilde*a / pow((1.0 - rOneTilde*b), n);
89 const Scalar rhoTwo = rTwoTilde*a / pow((1.0 - rTwoTilde*b), n);
90 const Scalar rTilde = rhoOne*rhoTwo * pow((pow(rhoOne, 1.0/n) + pow(rhoTwo, 1.0/n)), -n);
91 return rTilde * centerTocenterDist;
92}
93
94
96template<class Scalar>
97inline Dune::ReservedVector<Scalar, 4> cornerHalfAngles(Shape shape)
98{
99 switch(shape)
100 {
102 {
103 const Scalar value = M_PI/6.0;
104 return Dune::ReservedVector<Scalar, 4>{value, value, value};
105 }
106 case Shape::square:
107 {
108 const Scalar value = M_PI/4.0;
109 return Dune::ReservedVector<Scalar, 4>{value, value, value, value};
110 }
111 case Shape::rectangle:
112 {
113 const Scalar value = M_PI/4.0;
114 return Dune::ReservedVector<Scalar, 4>{value, value, value, value};
115 }
116 case Shape::circle:
117 {
118 const Scalar value = 0.5*M_PI; // we define the (single) corner angle of a circle as 180°
119 return { value };
120 }
121 case Shape::polygon: DUNE_THROW(Dune::InvalidStateException, "Corner half angles for polygons must be calculated explicitly");
122 default: DUNE_THROW(Dune::InvalidStateException, "Unknown shape");
123 // TODO implement angles for scaleneTriangle as given by Valvatne & Blunt (2004)
124 }
125}
126
128template<class Scalar>
129inline constexpr Scalar shapeFactorEquilateralTriangle() noexcept
130{
131 using std::sqrt;
132 return sqrt(3.0)/36.0;
133}
134
136template<class Scalar>
137inline constexpr Scalar shapeFactorSquare() noexcept
138{
139 return 1.0/16.0;
140}
141
143template<class Scalar>
144inline constexpr Scalar shapeFactorRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
145{
146 const Scalar a = 2.0*inscribedRadius; // shorter side length
147 const Scalar b = height; // longer side length
148 const Scalar area = a*b;
149 const Scalar perimeter = 2.0*a + 2.0*b;
150 return area / (perimeter*perimeter);
151}
152
154template<class Scalar>
155inline constexpr Scalar shapeFactorCircle() noexcept
156{
157 return 1.0/(4.0*M_PI);
158}
159
161template<class Scalar>
162inline Scalar shapeFactor(Shape shape, const Scalar inscribedRadius)
163{
164 switch(shape)
165 {
166 case Shape::equilateralTriangle: return shapeFactorEquilateralTriangle<Scalar>();
167 case Shape::square: return shapeFactorSquare<Scalar>();
168 case Shape::circle: return shapeFactorCircle<Scalar>();
169 case Shape::twoPlates: return 0.0; // TODO is this a good idea?
170 case Shape::polygon: DUNE_THROW(Dune::InvalidStateException, "The shape factor for a polygon has to be defined by the input data");
171 default: DUNE_THROW(Dune::InvalidStateException, "Unknown shape");
172 }
173}
174
176template<class Scalar>
177inline constexpr Shape shape(const Scalar shapeFactor) noexcept
178{
179 if (shapeFactor < shapeFactorEquilateralTriangle<Scalar>())
181 else if (shapeFactor <= shapeFactorEquilateralTriangle<Scalar>())
183 else if (shapeFactor < shapeFactorSquare<Scalar>())
184 return Shape::rectangle;
185 else if (shapeFactor == shapeFactorSquare<Scalar>())
186 return Shape::square;
187 else if (shapeFactor == shapeFactorCircle<Scalar>())
188 return Shape::circle;
189 else
190 return Shape::polygon;
191}
192
195{
196 switch (shape)
197 {
198 case Shape::equilateralTriangle: return true;
199 case Shape::square: return true;
200 case Shape::circle: return true;
201 case Shape::rectangle: return false;
202 case Shape::scaleneTriangle: return false;
203 case Shape::polygon: DUNE_THROW(Dune::InvalidStateException, "Equality of Corner half angles for polygons must be determined explicitly");
204 default:
205 DUNE_THROW(Dune::InvalidStateException, "Unknown shape");
206 }
207}
208
210template<class Scalar>
211inline Scalar totalCrossSectionalArea(const Shape shape, const Scalar inscribedRadius)
212{
213 using std::sqrt;
214 switch(shape)
215 {
216 case Shape::equilateralTriangle: return 3.0*sqrt(3.0)*inscribedRadius*inscribedRadius;
217 case Shape::square: return 4.0*inscribedRadius*inscribedRadius;
218 case Shape::circle: return M_PI*inscribedRadius*inscribedRadius;
219 case Shape::twoPlates: return 2.0*inscribedRadius;
220 default : DUNE_THROW(Dune::InvalidStateException, "Unsupported geometry: " << shapeToString(shape));
221 }
222}
223
225template<class Scalar>
226inline constexpr Scalar totalCrossSectionalAreaForRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
227{
228 return 2.0*inscribedRadius * height;
229}
230
232inline std::size_t numCorners(Shape shape)
233{
234 switch(shape)
235 {
236 case Shape::scaleneTriangle: return 3;
237 case Shape::equilateralTriangle: return 3;
238 case Shape::square: return 4;
239 case Shape::rectangle: return 4;
240 case Shape::circle: return 0;
241 default : DUNE_THROW(Dune::InvalidStateException, "Unsupported geometry: " << shapeToString(shape));
242 }
243}
244
254template<class Scalar>
255inline constexpr Scalar wettingLayerCrossSectionalArea(const Scalar curvatureRadius,
256 const Scalar contactAngle,
257 const Scalar cornerHalfAngle) noexcept
258{
259 using std::sin;
260 using std::cos;
261 return curvatureRadius*curvatureRadius *(cos(contactAngle) * cos(contactAngle + cornerHalfAngle) / sin(cornerHalfAngle)
262 + cornerHalfAngle + contactAngle - M_PI/2.0);
263}
264
265} // end Dumux::PoreNetwork::Throat
266
267#endif
Definition: throatproperties.hh:34
constexpr Scalar totalCrossSectionalAreaForRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the cross-sectional area of a rectangle.
Definition: throatproperties.hh:226
constexpr Scalar shapeFactorSquare() noexcept
Returns the value of the shape factor for a square.
Definition: throatproperties.hh:137
constexpr Shape shape(const Scalar shapeFactor) noexcept
Returns the shape for a given shape factor.
Definition: throatproperties.hh:177
constexpr Scalar shapeFactorRectangle(const Scalar inscribedRadius, const Scalar height) noexcept
Returns the value of the shape factor for a rectangle.
Definition: throatproperties.hh:144
constexpr Scalar shapeFactorEquilateralTriangle() noexcept
Returns the value of the shape factor for an equilateral triangle.
Definition: throatproperties.hh:129
std::size_t numCorners(Shape shape)
Returns the number of corners of a given geometry.
Definition: throatproperties.hh:232
constexpr Scalar wettingLayerCrossSectionalArea(const Scalar curvatureRadius, const Scalar contactAngle, const Scalar cornerHalfAngle) noexcept
Return the cross-sectional area of a wetting layer residing in a corner of a throat.
Definition: throatproperties.hh:255
Dune::ReservedVector< Scalar, 4 > cornerHalfAngles(Shape shape)
Returns the corner half angle.
Definition: throatproperties.hh:97
Scalar totalCrossSectionalArea(const Shape shape, const Scalar inscribedRadius)
Returns the cross-sectional area of a given geometry.
Definition: throatproperties.hh:211
Shape shapeFromString(const std::string &s)
Get the shape from a string description of the shape.
Definition: throatproperties.hh:57
Shape
Collection of different pore-throat shapes.
Definition: throatproperties.hh:38
constexpr Scalar shapeFactorCircle() noexcept
Returns the value of the shape factor for a circle.
Definition: throatproperties.hh:155
Scalar shapeFactor(Shape shape, const Scalar inscribedRadius)
Returns the value of the shape factor for a given shape.
Definition: throatproperties.hh:162
std::string shapeToString(Shape s)
Get the shape from a string description of the shape.
Definition: throatproperties.hh:41
bool isRegularShape(Shape shape)
Returns if a shape is regular.
Definition: throatproperties.hh:194
Scalar averagedRadius(const Scalar poreRadiusOne, const Scalar poreRadiusTwo, const Scalar centerTocenterDist, const Scalar n=0.1)
Returns the radius of a pore throat.
Definition: throatproperties.hh:80