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>
24 template<
class Gr
id >
25 struct HostGridAccess;
35 template<
class Gr
idImp>
40 friend struct HostGridAccess< typename
std::remove_const< GridImp >
::type >;
42 enum {dim=GridImp::dimension};
44 enum {dimworld=GridImp::dimensionworld};
47 typedef typename GridImp::ctype ctype;
49 typedef typename GridImp::template MMeshInterfaceEntity<0> MMeshInterfaceEntity;
50 typedef typename GridImp::template MMeshInterfaceEntity<1> HostLeafIntersection;
52 typedef typename GridImp::MMeshType::template Codim<0>::Entity MMeshEntity;
54 using LocalIndexMap = std::unordered_map< std::size_t, std::size_t >;
55 typedef typename GridImp::MMeshType::template Codim<dimworld>::Entity MMeshVertex;
58 enum {dimension=GridImp::dimension};
59 enum {dimensionworld=GridImp::dimensionworld};
60 typedef typename GridImp::template Codim<1>::Geometry Geometry;
61 typedef typename GridImp::template Codim<1>::LocalGeometry LocalGeometry;
62 typedef typename GridImp::template Codim<0>::Entity Entity;
63 typedef FieldVector<ctype, dimensionworld> NormalVector;
69 const MMeshInterfaceEntity& hostEntity,
70 const std::size_t index,
71 const std::size_t nbIdx)
73 interfaceEntity_(hostEntity),
76 cgalIndex_( MMeshInterfaceImpl::computeCGALIndices<MMeshInterfaceEntity, dim>( interfaceEntity_ ) )
78 const auto& indexSet = grid_->leafIndexSet();
80 std::array< std::size_t, dimension > ids;
82 if constexpr (dim == 1)
84 ids[0] = indexSet.vertexIndexMap().at( interfaceEntity_.first->vertex( cgalIndex_[index_] )->info().id );
88 ids[0] = indexSet.vertexIndexMap().at( interfaceEntity_.first->vertex( cgalIndex_[index_==2 ? 1 : 0] )->info().id );
89 ids[1] = indexSet.vertexIndexMap().at( interfaceEntity_.first->vertex( cgalIndex_[index_==0 ? 1 : 2] )->info().id );
91 std::sort(ids.begin(), ids.end());
93 localIndexMap_ = indexSet.indexMap().at( ids );
94 }
catch (std::exception &e) {
95 DUNE_THROW(InvalidStateException, e.what());
103 return interfaceEntity_ == other.interfaceEntity_
104 && index_ == other.index_
105 && nbIdx_ == other.nbIdx_;
117 return localIndexMap_.size() - 1;
126 const auto& vertexIndexMap = grid_->leafIndexSet().vertexIndexMap();
128 std::size_t myLastVertexIndex = vertexIndexMap.at(
129 interfaceEntity_.first->vertex(cgalIndex_[dim-index_])->info().id
133 auto it = localIndexMap_.begin();
135 while ( it->first == myLastVertexIndex )
138 for( std::size_t count = 0; count < nbIdx_; count++ )
143 if ( it->first == myLastVertexIndex )
148 std::size_t v0idx = index_;
149 if constexpr (dim == 2)
153 const auto& vertex0 = interfaceEntity_.first->vertex( cgalIndex_[v0idx] );
155 std::array< std::size_t, dimensionworld > vIdx;
156 vIdx[0] = vertexIndexMap.at( vertex0->info().id );
159 if constexpr ( dimensionworld == 3 )
161 std::size_t v1idx = (index_ == 1) ? 2 : 1;
162 vIdx[2] = vertexIndexMap.at( interfaceEntity_.first->vertex( cgalIndex_[v1idx] )->info().id );
163 }
catch (std::exception &e) {
164 DUNE_THROW(InvalidStateException, e.what());
166 std::sort(vIdx.begin(), vIdx.end());
169 for(
const auto& facet : incidentFacets( MMeshVertex {{ &grid_->getMMesh(), vertex0 }} ) )
171 std::array< std::size_t, dimensionworld > tmpIdx;
172 bool notInterface =
false;
173 for( std::size_t i = 0; i < facet.subEntities(dimensionworld); ++i )
175 std::size_t idx = facet.impl().template subEntity<dimensionworld>(i).impl().hostEntity()->info().id;
176 auto it = vertexIndexMap.find( idx );
177 if( it != vertexIndexMap.end() )
178 tmpIdx[i] = it->second;
184 std::sort(tmpIdx.begin(), tmpIdx.end());
186 if ( vIdx == tmpIdx )
189 DUNE_THROW( InvalidStateException,
"Neighbor could not be determined!" );
194 return localIndexMap_.size() == 1;
214 auto iid = grid_->globalIdSet().id( grid_->entity( getHostIntersection() ) );
215 auto it = grid_->boundarySegments().find( iid );
216 if( it == grid_->boundarySegments().end() )
236 return GeometryTypes::simplex(dimension-1);
258 template<
int d = dimension >
259 typename std::enable_if_t< d == 1, Geometry >
262 return Geometry( interfaceEntity_.first->vertex( cgalIndex_[index_] ) );
265 template<
int d = dimension >
266 typename std::enable_if_t< d == 2, Geometry >
269 int vIdx0 = cgalIndex_[index_==2 ? 1 : 0];
270 int vIdx1 = cgalIndex_[index_==0 ? 1 : 2];
272 return Geometry( {{ interfaceEntity_.first, vIdx0, vIdx1 }} );
284 const auto& subEn =
inside().template subEntity<1>( index_ );
287 for (
int i = 0; i < dimensionworld; ++i )
288 if (
neighbor.template subEntity<1>( i ) == subEn )
291 DUNE_THROW( InvalidStateException,
"indexInOutside() could not be determined!" );
295 FieldVector<ctype, GridImp::dimensionworld>
outerNormal (
const FieldVector<ctype, GridImp::dimension-1>& local)
const {
300 template<
int d = dimension >
301 typename std::enable_if_t< d == 1, NormalVector >
304 auto face = interfaceEntity_.first;
306 const auto& p1 = face->vertex( cgalIndex_[ index_ ] )->point();
307 const auto& p2 = face->vertex( cgalIndex_[1-index_] )->point();
309 NormalVector n ( { p1.x() - p2.x(), p1.y() - p2.y() } );
314 template<
int d = dimension >
315 typename std::enable_if_t< d == 2, NormalVector >
318 const auto& cell = interfaceEntity_.first;
320 int vIdx0 = cgalIndex_[index_==2 ? 1 : 0];
321 int vIdx1 = cgalIndex_[index_==0 ? 1 : 2];
322 int vIdxLast = cgalIndex_[2-index_];
324 auto a = makeFieldVector( cell->vertex( vIdx0 )->point() );
325 auto b = makeFieldVector( cell->vertex( vIdx1 )->point() );
326 auto v = makeFieldVector( cell->vertex( vIdxLast )->point() );
329 NormalVector ab = b - a;
330 NormalVector vb = b - v;
332 NormalVector elementNormal;
333 elementNormal[0] = ab[1]*vb[2] - ab[2]*vb[1];
334 elementNormal[1] = ab[2]*vb[0] - ab[0]*vb[2];
335 elementNormal[2] = ab[0]*vb[1] - ab[1]*vb[0];
338 outerNormal[0] = ab[1]*elementNormal[2] - ab[2]*elementNormal[1];
339 outerNormal[1] = ab[2]*elementNormal[0] - ab[0]*elementNormal[2];
340 outerNormal[2] = ab[0]*elementNormal[1] - ab[1]*elementNormal[0];
349 FieldVector<ctype, GridImp::dimensionworld>
unitOuterNormal (
const FieldVector<ctype, GridImp::dimension-1>& local)
const {
355 const auto getHostVertex()
const
357 return interfaceEntity_.first->vertex((interfaceEntity_.second+index_+1)%(dimensionworld+1));
360 const MMeshInterfaceEntity& getHostIntersection()
const
362 return interfaceEntity_;
367 const GridImp* grid_;
368 MMeshInterfaceEntity interfaceEntity_;
371 LocalIndexMap localIndexMap_;
372 std::array< std::size_t, dim+1 > cgalIndex_;
The implementation of entities in a MMesh interface grid.
Definition: entity.hh:35
Iterator over all element neighborsMesh entities of codimension 0 ("elements") allow to visit all nei...
Definition: intersectioniterator.hh:30
An intersection with a leaf neighbor elementMesh entities of codimension 0 ("elements") allow to visi...
Definition: intersections.hh:37
std::size_t numOutside() const
Definition: intersections.hh:116
GeometryType type() const
Geometry type of an intersection.
Definition: intersections.hh:235
bool equals(const MMeshInterfaceGridLeafIntersection &other) const
returns true if the host entities are equal
Definition: intersections.hh:101
Entity inside() const
Definition: intersections.hh:110
FieldVector< ctype, GridImp::dimensionworld > unitOuterNormal(const FieldVector< ctype, GridImp::dimension-1 > &local) const
return unit outer normal
Definition: intersections.hh:349
std::enable_if_t< d==1, Geometry > geometry() const
Definition: intersections.hh:260
FieldVector< ctype, GridImp::dimensionworld > outerNormal(const FieldVector< ctype, GridImp::dimension-1 > &local) const
return outer normal
Definition: intersections.hh:295
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:302
bool boundary() const
return true if intersection is with boundary.
Definition: intersections.hh:193
std::size_t boundaryId() const
Return the boundary id.
Definition: intersections.hh:223
int indexInInside() const
local number of codim 1 entity in self where intersection is contained in
Definition: intersections.hh:276
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:229
size_t boundarySegmentIndex() const
return the boundary segment index
Definition: intersections.hh:212
LocalGeometry geometryInOutside() const
Definition: intersections.hh:250
Entity outside() const
Definition: intersections.hh:122
int indexInOutside() const
local number of codim 1 entity in neighbor where intersection is contained
Definition: intersections.hh:282
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:243
The MMeshLeafIterator class.
Helpers for conversion from CGAL::Point_x to DUNE::FieldVector.