dune-mmesh (unstable)

intersections.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_MMESH_INTERFACE_INTERSECTIONS_HH
4#define DUNE_MMESH_INTERFACE_INTERSECTIONS_HH
5
6#include <unordered_set>
7
8// Dune MMesh includes
12#include <dune/mmesh/misc/twistutility.hh>
13
14// local includes
15
21namespace Dune {
22
23// External forward declarations
24template <class Grid>
25struct HostGridAccess;
26
35template <class GridImp>
38
39 friend struct HostGridAccess<typename std::remove_const<GridImp>::type>;
40
41 enum { dim = GridImp::dimension };
42
43 enum { dimworld = GridImp::dimensionworld };
44
45 // The type used to store coordinates
46 typedef typename GridImp::ctype ctype;
47
48 typedef typename GridImp::template MMeshInterfaceEntity<0>
49 MMeshInterfaceEntity;
50 typedef typename GridImp::template MMeshInterfaceEntity<1>
51 HostLeafIntersection;
52
53 typedef typename GridImp::MMeshType::template Codim<0>::Entity MMeshEntity;
54
55 using LocalIndexMap = std::unordered_map<std::size_t, std::size_t>;
56 typedef
57 typename GridImp::MMeshType::template Codim<dimworld>::Entity MMeshVertex;
58
59 public:
60 enum { dimension = GridImp::dimension };
61 enum { dimensionworld = GridImp::dimensionworld };
62 typedef typename GridImp::template Codim<1>::Geometry Geometry;
63 typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
64 typedef typename GridImp::template Codim<0>::Entity Entity;
65 typedef FieldVector<ctype, dimensionworld> NormalVector;
66
68
69 MMeshInterfaceGridLeafIntersection(const GridImp* grid,
70 const MMeshInterfaceEntity& hostEntity,
71 const std::size_t index,
72 const std::size_t nbIdx)
73 : grid_(grid),
74 interfaceEntity_(hostEntity),
75 index_(index),
76 nbIdx_(nbIdx),
77 cgalIndex_(
78 MMeshInterfaceImpl::computeCGALIndices<MMeshInterfaceEntity, dim>(
79 interfaceEntity_)) {
80 const auto& indexSet = grid_->leafIndexSet();
81
82 std::array<std::size_t, dimension> ids;
83
84 if constexpr (dim == 1) {
85 ids[0] = indexSet.vertexIndexMap().at(
86 interfaceEntity_.first->vertex(cgalIndex_[index_])->info().id);
87 } else // dim == 2
88 {
89 ids[0] = indexSet.vertexIndexMap().at(
90 interfaceEntity_.first->vertex(cgalIndex_[index_ == 2 ? 1 : 0])
91 ->info()
92 .id);
93 ids[1] = indexSet.vertexIndexMap().at(
94 interfaceEntity_.first->vertex(cgalIndex_[index_ == 0 ? 1 : 2])
95 ->info()
96 .id);
97 }
98 std::sort(ids.begin(), ids.end());
99 try {
100 localIndexMap_ = indexSet.indexMap().at(ids);
101 } catch (std::exception& e) {
102 DUNE_THROW(InvalidStateException, e.what());
103 }
104 assert(0 <= nbIdx_ && (nbIdx_ < numOutside() || boundary()));
105 }
106
109 return interfaceEntity_ == other.interfaceEntity_ &&
110 index_ == other.index_ && nbIdx_ == other.nbIdx_;
111 }
112
115 Entity inside() const {
117 interfaceEntity_);
118 }
119
122 std::size_t numOutside() const { return localIndexMap_.size() - 1; }
123
126 Entity outside() const {
127 assert(neighbor());
128
129 const auto& vertexIndexMap = grid_->leafIndexSet().vertexIndexMap();
130
131 std::size_t myLastVertexIndex = vertexIndexMap.at(
132 interfaceEntity_.first->vertex(cgalIndex_[dim - index_])->info().id);
133
134 // get the i-th index map entry
135 auto it = localIndexMap_.begin();
136 // exclude myself
137 while (it->first == myLastVertexIndex) ++it;
138
139 for (std::size_t count = 0; count < nbIdx_; count++) {
140 ++it;
141
142 // exclude myself
143 if (it->first == myLastVertexIndex) count--;
144 }
145
146 // obtain neighbor by searching in incident elements of intersection vertex
147 std::size_t v0idx = index_;
148 if constexpr (dim == 2)
149 if (index_ == 1) v0idx = 0;
150
151 const auto& vertex0 = interfaceEntity_.first->vertex(cgalIndex_[v0idx]);
152
153 std::array<std::size_t, dimensionworld> vIdx;
154 vIdx[0] = vertexIndexMap.at(vertex0->info().id);
155 vIdx[1] = it->first;
156
157 if constexpr (dimensionworld == 3) try {
158 std::size_t v1idx = (index_ == 1) ? 2 : 1;
159 vIdx[2] = vertexIndexMap.at(
160 interfaceEntity_.first->vertex(cgalIndex_[v1idx])->info().id);
161 } catch (std::exception& e) {
162 DUNE_THROW(InvalidStateException, e.what());
163 }
164 std::sort(vIdx.begin(), vIdx.end());
165
166 // search in incident facets for the right entity
167 for (const auto& facet :
168 incidentFacets(MMeshVertex{{&grid_->getMMesh(), vertex0}})) {
169 std::array<std::size_t, dimensionworld> tmpIdx;
170 bool notInterface = false;
171 for (std::size_t i = 0; i < facet.subEntities(dimensionworld); ++i) {
172 std::size_t idx = facet.impl()
173 .template subEntity<dimensionworld>(i)
174 .impl()
175 .hostEntity()
176 ->info()
177 .id;
178 auto it = vertexIndexMap.find(idx);
179 if (it != vertexIndexMap.end())
180 tmpIdx[i] = it->second;
181 else
182 notInterface = true;
183 }
184 if (notInterface) continue;
185 std::sort(tmpIdx.begin(), tmpIdx.end());
186
187 if (vIdx == tmpIdx)
189 grid_, facet.impl().hostEntity());
190 }
191 DUNE_THROW(InvalidStateException, "Neighbor could not be determined!");
192 }
193
195 bool boundary() const { return localIndexMap_.size() == 1; }
196
202 NormalVector centerUnitOuterNormal() const {
203 return unitOuterNormal(FieldVector<ctype, dimension - 1>(0));
204 }
205
207 bool neighbor() const { return !boundary(); }
208
210 size_t boundarySegmentIndex() const {
211 auto iid = grid_->globalIdSet().id(grid_->entity(getHostIntersection()));
212 auto it = grid_->boundarySegments().find(iid);
213 if (it == grid_->boundarySegments().end()) return 0;
214
215 return it->second;
216 }
217
219 std::size_t boundaryId() const {
220 return 0; // TODO
221 }
222
224 bool conforming() const {
225 // we are always conforming
226 return true;
227 }
228
230 GeometryType type() const { return GeometryTypes::simplex(dimension - 1); }
231
236 LocalGeometry geometryInInside() const {
237 return LocalGeometry(indexInInside());
238 }
239
243 LocalGeometry geometryInOutside() const {
244 assert(neighbor());
245 return LocalGeometry(indexInOutside());
246 }
247
251 template <int d = dimension>
252 typename std::enable_if_t<d == 1, Geometry> geometry() const {
253 return Geometry(interfaceEntity_.first->vertex(cgalIndex_[index_]));
254 }
255
256 template <int d = dimension>
257 typename std::enable_if_t<d == 2, Geometry> geometry() const {
258 int vIdx0 = cgalIndex_[index_ == 2 ? 1 : 0];
259 int vIdx1 = cgalIndex_[index_ == 0 ? 1 : 2];
260
261 return Geometry({{interfaceEntity_.first, vIdx0, vIdx1}});
262 }
263
265 int indexInInside() const { return index_; }
266
268 int indexInOutside() const {
269 const auto& subEn = inside().template subEntity<1>(index_);
270
271 const auto neighbor = outside();
272 for (int i = 0; i < dimensionworld; ++i)
273 if (neighbor.template subEntity<1>(i) == subEn) return i;
274
275 DUNE_THROW(InvalidStateException,
276 "indexInOutside() could not be determined!");
277 }
278
280 FieldVector<ctype, GridImp::dimensionworld> outerNormal(
281 const FieldVector<ctype, GridImp::dimension - 1>& local) const {
282 return integrationOuterNormal(local);
283 }
284
286 template <int d = dimension>
287 typename std::enable_if_t<d == 1, NormalVector> integrationOuterNormal(
288 const FieldVector<ctype, dimension - 1>& local) const {
289 auto face = interfaceEntity_.first;
290
291 const auto& p1 = face->vertex(cgalIndex_[index_])->point();
292 const auto& p2 = face->vertex(cgalIndex_[1 - index_])->point();
293
294 NormalVector n({p1.x() - p2.x(), p1.y() - p2.y()});
295 n /= n.two_norm();
296 return n;
297 }
298
299 template <int d = dimension>
300 typename std::enable_if_t<d == 2, NormalVector> integrationOuterNormal(
301 const FieldVector<ctype, dimension - 1>& local) const {
302 const auto& cell = interfaceEntity_.first;
303
304 int vIdx0 = cgalIndex_[index_ == 2 ? 1 : 0];
305 int vIdx1 = cgalIndex_[index_ == 0 ? 1 : 2];
306 int vIdxLast = cgalIndex_[2 - index_];
307
308 auto a = makeFieldVector(cell->vertex(vIdx0)->point());
309 auto b = makeFieldVector(cell->vertex(vIdx1)->point());
310 auto v = makeFieldVector(cell->vertex(vIdxLast)->point());
311
312 // return vector that is orthogonal to edge a-b and triangle a-b-v
313 NormalVector ab = b - a;
314 NormalVector vb = b - v;
315
316 NormalVector elementNormal;
317 elementNormal[0] = ab[1] * vb[2] - ab[2] * vb[1];
318 elementNormal[1] = ab[2] * vb[0] - ab[0] * vb[2];
319 elementNormal[2] = ab[0] * vb[1] - ab[1] * vb[0];
320
321 NormalVector outerNormal;
322 outerNormal[0] = ab[1] * elementNormal[2] - ab[2] * elementNormal[1];
323 outerNormal[1] = ab[2] * elementNormal[0] - ab[0] * elementNormal[2];
324 outerNormal[2] = ab[0] * elementNormal[1] - ab[1] * elementNormal[0];
325
326 if (outerNormal * vb < 0.0) outerNormal *= -1.0;
327
328 return outerNormal;
329 }
330
332 FieldVector<ctype, GridImp::dimensionworld> unitOuterNormal(
333 const FieldVector<ctype, GridImp::dimension - 1>& local) const {
334 NormalVector n = integrationOuterNormal(local);
335 n /= n.two_norm();
336 return n;
337 }
338
339 const auto getHostVertex() const {
340 return interfaceEntity_.first->vertex(
341 (interfaceEntity_.second + index_ + 1) % (dimensionworld + 1));
342 }
343
344 const MMeshInterfaceEntity& getHostIntersection() const {
345 return interfaceEntity_;
346 }
347
348 private:
350 const GridImp* grid_;
351 MMeshInterfaceEntity interfaceEntity_;
352 std::size_t index_;
353 std::size_t nbIdx_;
354 LocalIndexMap localIndexMap_;
355 std::array<std::size_t, dim + 1> cgalIndex_;
356};
357
358} // namespace Dune
359
360#endif
The implementation of entities in a MMesh interface grid.
Definition: entity.hh:34
Iterator over all element neighborsMesh entities of codimension 0 ("elements") allow to visit all nei...
Definition: intersectioniterator.hh:28
An intersection with a leaf neighbor elementMesh entities of codimension 0 ("elements") allow to visi...
Definition: intersections.hh:36
std::enable_if_t< d==1, NormalVector > integrationOuterNormal(const FieldVector< ctype, dimension - 1 > &local) const
return outer normal multiplied by the integration element
Definition: intersections.hh:287
std::size_t numOutside() const
Definition: intersections.hh:122
GeometryType type() const
Geometry type of an intersection.
Definition: intersections.hh:230
bool equals(const MMeshInterfaceGridLeafIntersection &other) const
returns true if the host entities are equal
Definition: intersections.hh:108
Entity inside() const
Definition: intersections.hh:115
FieldVector< ctype, GridImp::dimensionworld > unitOuterNormal(const FieldVector< ctype, GridImp::dimension - 1 > &local) const
return unit outer normal
Definition: intersections.hh:332
std::enable_if_t< d==1, Geometry > geometry() const
Definition: intersections.hh:252
bool boundary() const
return true if intersection is with boundary.
Definition: intersections.hh:195
std::size_t boundaryId() const
Return the boundary id.
Definition: intersections.hh:219
int indexInInside() const
local number of codim 1 entity in self where intersection is contained in
Definition: intersections.hh:265
FieldVector< ctype, GridImp::dimensionworld > outerNormal(const FieldVector< ctype, GridImp::dimension - 1 > &local) const
return outer normal
Definition: intersections.hh:280
NormalVector centerUnitOuterNormal() const
Return unit outer normal (length == 1)
Definition: intersections.hh:202
bool conforming() const
Return true if this is a conforming intersection.
Definition: intersections.hh:224
size_t boundarySegmentIndex() const
return the boundary segment index
Definition: intersections.hh:210
LocalGeometry geometryInOutside() const
Definition: intersections.hh:243
Entity outside() const
Definition: intersections.hh:126
int indexInOutside() const
local number of codim 1 entity in neighbor where intersection is contained
Definition: intersections.hh:268
bool neighbor() const
return true if across the edge an neighbor on this level exists
Definition: intersections.hh:207
LocalGeometry geometryInInside() const
Definition: intersections.hh:236
The MMeshEntity class.
The MMeshLeafIterator class.
STL namespace.
Helpers for conversion from CGAL::Point_x to DUNE::FieldVector.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 4, 22:38, 2025)