version 3.11-dev
porousmediumflow/boxdfm/geometryhelper.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-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_POROUSMEDIUMFLOW_BOXDFM_GEOMETRY_HELPER_HH
14#define DUMUX_POROUSMEDIUMFLOW_BOXDFM_GEOMETRY_HELPER_HH
15
16#include <dune/common/fvector.hh>
17#include <dune/common/reservedvector.hh>
18#include <dune/geometry/multilineargeometry.hh>
19
21
22namespace Dumux {
23
24template <class ct>
25struct BoxDfmMLGeometryTraits : public Dune::MultiLinearGeometryTraits<ct>
26{
27 // we use static vectors to store the corners as we know
28 // the number of corners in advance (2^(mydim) corners (1<<(mydim))
29 // However, on fracture scvs the number might be smaller (use ReservedVector)
30 template< int mydim, int cdim >
32 {
33 using Type = Dune::ReservedVector< Dune::FieldVector< ct, cdim >, (1<<(mydim)) >;
34 };
35
36 // we know all scvfs will have the same geometry type
37 template< int mydim >
39 {
40 static const bool v = true;
41 static const unsigned int topologyId = Dune::GeometryTypes::cube(mydim).id();
42 };
43};
44
46template<class GridView, int dim, class ScvType, class ScvfType>
48
50template <class GridView, class ScvType, class ScvfType>
51class BoxDfmGeometryHelper<GridView, 2, ScvType, ScvfType> : public BoxGeometryHelper<GridView, 2, ScvType, ScvfType>
52{
54
55 using Intersection = typename GridView::Intersection;
56 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
57
58 static constexpr auto dim = GridView::dimension;
59 using Scalar = typename GridView::ctype;
60
61public:
62
64 using ParentType::ParentType;
65
67 ScvfCornerStorage getFractureScvfCorners(unsigned int localFacetIndex,
68 unsigned int) const
69 {
70 const auto& geo = this->elementGeometry();
71 const auto ref = referenceElement(geo);
72 return ScvfCornerStorage({ geo.global(ref.position(localFacetIndex, 1)) });
73 }
74
77 typename ScvfType::Traits::GlobalPosition
78 fractureNormal(const ScvfCornerStorage& p,
79 const Intersection& is,
80 unsigned int edgeIndexInIntersection) const
81 {
82 const auto& geo = this->elementGeometry();
83 const auto ref = referenceElement(geo);
84 const auto v0 = ref.subEntity(is.indexInInside(), 1, 0, dim);
85 const auto v1 = ref.subEntity(is.indexInInside(), 1, 1, dim);
86 auto normal = geo.corner(v1) - geo.corner(v0);
87 normal /= normal.two_norm();
88 return normal;
89 }
90};
91
93template <class GridView, class ScvType, class ScvfType>
94class BoxDfmGeometryHelper<GridView, 3, ScvType, ScvfType> : public BoxGeometryHelper<GridView, 3, ScvType, ScvfType>
95{
97
98 using Intersection = typename GridView::Intersection;
99 using ScvfCornerStorage = typename ScvfType::Traits::CornerStorage;
100
101 static constexpr auto dim = GridView::dimension;
102 static constexpr auto dimWorld = GridView::dimensionworld;
103 using Scalar = typename GridView::ctype;
104
105public:
106
108 using ParentType::ParentType;
109
111 ScvfCornerStorage getFractureScvfCorners(unsigned int localFacetIndex,
112 unsigned int indexInFacet) const
113 {
114 constexpr int facetCodim = 1;
115
116 // we have to use the corresponding facet geometry as the intersection geometry
117 // might be rotated or flipped. This makes sure that the corners (dof location)
118 // and corresponding scvfs are sorted in the same way
119 const auto& geo = this->elementGeometry();
120 const auto& ref = referenceElement(geo);
121 const auto type = ref.type(localFacetIndex, facetCodim);
122 if (type == Dune::GeometryTypes::triangle)
123 {
125 return Detail::Box::subEntityKeyToCornerStorage<ScvfCornerStorage>(ref, [&](const auto& local){ return geo.global(local); },
126 localFacetIndex, facetCodim, Corners::keys[indexInFacet]);
127
128 }
129 else if (type == Dune::GeometryTypes::quadrilateral)
130 {
132 return Detail::Box::subEntityKeyToCornerStorage<ScvfCornerStorage>(ref, [&](const auto& local){ return geo.global(local); },
133 localFacetIndex, facetCodim, Corners::keys[indexInFacet]);
134 }
135 else
136 DUNE_THROW(Dune::NotImplemented, "Box fracture scvf geometries for dim=" << dim
137 << " dimWorld=" << dimWorld
138 << " type=" << type);
139 }
140
142 typename ScvfType::Traits::GlobalPosition
143 fractureNormal(const ScvfCornerStorage& scvfCorners,
144 const Intersection& is,
145 unsigned int edgeIndexInIntersection) const
146 {
147 const auto& geo = this->elementGeometry();
148 const auto refElement = referenceElement(geo);
149
150 // first get the intersection corners (maximum "4" is for quadrilateral face)
151 typename ScvfType::Traits::GlobalPosition c[4];
152
153 const auto corners = refElement.size(is.indexInInside(), 1, dim);
154 for (int i = 0; i < corners; ++i)
155 {
156 const auto vIdxLocal = refElement.subEntity(is.indexInInside(), 1, i, dim);
157 c[i] = geo.corner(vIdxLocal);
158 }
159
160 // compute edge vector depending on number of corners
161 const auto gridEdge = [&] ()
162 {
163 // triangles
164 if (corners == 3)
165 {
166 if (edgeIndexInIntersection == 0) return c[1]-c[0];
167 else if (edgeIndexInIntersection == 1) return c[2]-c[0];
168 else if (edgeIndexInIntersection == 2) return c[2]-c[1];
169 else DUNE_THROW(Dune::InvalidStateException, "Invalid edge index");
170 }
171 else if (corners == 4)
172 {
173 if (edgeIndexInIntersection == 0) return c[2]-c[0];
174 else if (edgeIndexInIntersection == 1) return c[3]-c[1];
175 else if (edgeIndexInIntersection == 2) return c[1]-c[0];
176 else if (edgeIndexInIntersection == 3) return c[3]-c[2];
177 else DUNE_THROW(Dune::InvalidStateException, "Invalid edge index");
178 }
179 else
180 DUNE_THROW(Dune::InvalidStateException, "Invalid face geometry");
181 } ();
182
183 // compute lower edge of the scvf
184 assert(scvfCorners.size() == 2);
185 const auto scvfEdge = scvfCorners[1]-scvfCorners[0];
186
187 // compute scvf normal via 2 cross products
188 const auto faceN = crossProduct(gridEdge, scvfEdge);
189 auto n = crossProduct(scvfEdge, faceN);
190 n /= n.two_norm();
191 return n;
192 }
193};
194
195} // end namespace Dumux
196
197#endif
Helper class constructing the dual grid finite volume geometries for the box discretizazion method.
ScvfCornerStorage getFractureScvfCorners(unsigned int localFacetIndex, unsigned int) const
Get the corners of the (d-1)-dimensional fracture scvf.
Definition: porousmediumflow/boxdfm/geometryhelper.hh:67
ScvfType::Traits::GlobalPosition fractureNormal(const ScvfCornerStorage &p, const Intersection &is, unsigned int edgeIndexInIntersection) const
Definition: porousmediumflow/boxdfm/geometryhelper.hh:78
ScvfCornerStorage getFractureScvfCorners(unsigned int localFacetIndex, unsigned int indexInFacet) const
Create the sub control volume face geometries on an intersection marked as fracture.
Definition: porousmediumflow/boxdfm/geometryhelper.hh:111
ScvfType::Traits::GlobalPosition fractureNormal(const ScvfCornerStorage &scvfCorners, const Intersection &is, unsigned int edgeIndexInIntersection) const
get fracture scvf normal vector
Definition: porousmediumflow/boxdfm/geometryhelper.hh:143
Create sub control volumes and sub control volume face geometries.
Definition: porousmediumflow/boxdfm/geometryhelper.hh:47
A class to create sub control volume and sub control volume face geometries per element.
Definition: boxgeometryhelper.hh:392
A class to create sub control volume and sub control volume face geometries per element.
Definition: boxgeometryhelper.hh:579
Create sub control volumes and sub control volume face geometries.
Definition: boxgeometryhelper.hh:257
Dune::FieldVector< Scalar, 3 > crossProduct(const Dune::FieldVector< Scalar, 3 > &vec1, const Dune::FieldVector< Scalar, 3 > &vec2)
Cross product of two vectors in three-dimensional Euclidean space.
Definition: math.hh:671
Vector normal(const Vector &v)
Create a vector normal to the given one (v is expected to be non-zero)
Definition: normal.hh:26
Definition: adapt.hh:17
Definition: porousmediumflow/boxdfm/geometryhelper.hh:32
Dune::ReservedVector< Dune::FieldVector< ct, cdim >,(1<<(mydim)) > Type
Definition: porousmediumflow/boxdfm/geometryhelper.hh:33
Definition: porousmediumflow/boxdfm/geometryhelper.hh:39
static const bool v
Definition: porousmediumflow/boxdfm/geometryhelper.hh:40
static const unsigned int topologyId
Definition: porousmediumflow/boxdfm/geometryhelper.hh:41
Definition: porousmediumflow/boxdfm/geometryhelper.hh:26