3#ifndef DUNE_MMESH_INTERFACE_INTERSECTIONS_HH
4#define DUNE_MMESH_INTERFACE_INTERSECTIONS_HH
6#include <unordered_set>
12#include <dune/mmesh/misc/twistutility.hh>
35template <
class Gr
idImp>
39 friend struct HostGridAccess<typename
std::remove_const<GridImp>
::type>;
41 enum { dim = GridImp::dimension };
43 enum { dimworld = GridImp::dimensionworld };
46 typedef typename GridImp::ctype ctype;
48 typedef typename GridImp::template MMeshInterfaceEntity<0>
50 typedef typename GridImp::template MMeshInterfaceEntity<1>
53 typedef typename GridImp::MMeshType::template Codim<0>::Entity MMeshEntity;
55 using LocalIndexMap = std::unordered_map<std::size_t, std::size_t>;
57 typename GridImp::MMeshType::template Codim<dimworld>::Entity MMeshVertex;
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;
70 const MMeshInterfaceEntity& hostEntity,
71 const std::size_t index,
72 const std::size_t nbIdx)
74 interfaceEntity_(hostEntity),
78 MMeshInterfaceImpl::computeCGALIndices<MMeshInterfaceEntity, dim>(
80 const auto& indexSet = grid_->leafIndexSet();
82 std::array<std::size_t, dimension> ids;
84 if constexpr (dim == 1) {
85 ids[0] = indexSet.vertexIndexMap().at(
86 interfaceEntity_.first->vertex(cgalIndex_[index_])->info().id);
89 ids[0] = indexSet.vertexIndexMap().at(
90 interfaceEntity_.first->vertex(cgalIndex_[index_ == 2 ? 1 : 0])
93 ids[1] = indexSet.vertexIndexMap().at(
94 interfaceEntity_.first->vertex(cgalIndex_[index_ == 0 ? 1 : 2])
98 std::sort(ids.begin(), ids.end());
100 localIndexMap_ = indexSet.indexMap().at(ids);
101 }
catch (std::exception& e) {
102 DUNE_THROW(InvalidStateException, e.what());
109 return interfaceEntity_ == other.interfaceEntity_ &&
110 index_ == other.index_ && nbIdx_ == other.nbIdx_;
122 std::size_t
numOutside()
const {
return localIndexMap_.size() - 1; }
129 const auto& vertexIndexMap = grid_->leafIndexSet().vertexIndexMap();
131 std::size_t myLastVertexIndex = vertexIndexMap.at(
132 interfaceEntity_.first->vertex(cgalIndex_[dim - index_])->info().id);
135 auto it = localIndexMap_.begin();
137 while (it->first == myLastVertexIndex) ++it;
139 for (std::size_t count = 0; count < nbIdx_; count++) {
143 if (it->first == myLastVertexIndex) count--;
147 std::size_t v0idx = index_;
148 if constexpr (dim == 2)
149 if (index_ == 1) v0idx = 0;
151 const auto& vertex0 = interfaceEntity_.first->vertex(cgalIndex_[v0idx]);
153 std::array<std::size_t, dimensionworld> vIdx;
154 vIdx[0] = vertexIndexMap.at(vertex0->info().id);
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());
164 std::sort(vIdx.begin(), vIdx.end());
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)
178 auto it = vertexIndexMap.find(idx);
179 if (it != vertexIndexMap.end())
180 tmpIdx[i] = it->second;
184 if (notInterface)
continue;
185 std::sort(tmpIdx.begin(), tmpIdx.end());
189 grid_, facet.impl().hostEntity());
191 DUNE_THROW(InvalidStateException,
"Neighbor could not be determined!");
195 bool boundary()
const {
return localIndexMap_.size() == 1; }
211 auto iid = grid_->globalIdSet().id(grid_->entity(getHostIntersection()));
212 auto it = grid_->boundarySegments().find(iid);
213 if (it == grid_->boundarySegments().end())
return 0;
230 GeometryType
type()
const {
return GeometryTypes::simplex(dimension - 1); }
251 template <
int d = dimension>
252 typename std::enable_if_t<d == 1, Geometry>
geometry()
const {
253 return Geometry(interfaceEntity_.first->vertex(cgalIndex_[index_]));
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];
261 return Geometry({{interfaceEntity_.first, vIdx0, vIdx1}});
269 const auto& subEn =
inside().template subEntity<1>(index_);
272 for (
int i = 0; i < dimensionworld; ++i)
273 if (
neighbor.template subEntity<1>(i) == subEn)
return i;
275 DUNE_THROW(InvalidStateException,
276 "indexInOutside() could not be determined!");
281 const FieldVector<ctype, GridImp::dimension - 1>& local)
const {
286 template <
int d = dimension>
288 const FieldVector<ctype, dimension - 1>& local)
const {
289 auto face = interfaceEntity_.first;
291 const auto& p1 = face->vertex(cgalIndex_[index_])->point();
292 const auto& p2 = face->vertex(cgalIndex_[1 - index_])->point();
294 NormalVector n({p1.x() - p2.x(), p1.y() - p2.y()});
299 template <
int d = dimension>
301 const FieldVector<ctype, dimension - 1>& local)
const {
302 const auto& cell = interfaceEntity_.first;
304 int vIdx0 = cgalIndex_[index_ == 2 ? 1 : 0];
305 int vIdx1 = cgalIndex_[index_ == 0 ? 1 : 2];
306 int vIdxLast = cgalIndex_[2 - index_];
308 auto a = makeFieldVector(cell->vertex(vIdx0)->point());
309 auto b = makeFieldVector(cell->vertex(vIdx1)->point());
310 auto v = makeFieldVector(cell->vertex(vIdxLast)->point());
313 NormalVector ab = b - a;
314 NormalVector vb = b - v;
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];
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];
333 const FieldVector<ctype, GridImp::dimension - 1>& local)
const {
339 const auto getHostVertex()
const {
340 return interfaceEntity_.first->vertex(
341 (interfaceEntity_.second + index_ + 1) % (dimensionworld + 1));
344 const MMeshInterfaceEntity& getHostIntersection()
const {
345 return interfaceEntity_;
350 const GridImp* grid_;
351 MMeshInterfaceEntity interfaceEntity_;
354 LocalIndexMap localIndexMap_;
355 std::array<std::size_t, dim + 1> cgalIndex_;
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 MMeshLeafIterator class.
Helpers for conversion from CGAL::Point_x to DUNE::FieldVector.