3#ifndef DUNE_MMESH_INTERFACE_INDEXSETS_HH
4#define DUNE_MMESH_INTERFACE_INDEXSETS_HH
11#include <dune/grid/common/indexidset.hh>
17 template<
class Gr
idImp>
18 class MMeshInterfaceGridLeafIndexSet :
19 public IndexSet<GridImp, MMeshInterfaceGridLeafIndexSet<GridImp>>
21 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
24 using HostGridEntity =
typename GridImp::template MMeshInterfaceEntity<codim>;
27 typedef std::size_t IndexType;
28 typedef const std::vector< GeometryType > Types;
34 enum {dimensionworld = std::remove_const<GridImp>::type::dimensionworld};
35 enum {dimension = dimensionworld-1};
37 using LocalIndexMap = std::unordered_map< std::size_t, std::size_t >;
38 using IndexMap = std::unordered_map< std::array< std::size_t, dimension >, LocalIndexMap, HashUIntArray >;
39 using EdgeIndexMap = std::unordered_map< std::array< std::size_t, dimension >, std::size_t, HashUIntArray >;
40 using VertexIndexMap = std::unordered_map< std::size_t, std::size_t >;
43 MMeshInterfaceGridLeafIndexSet (
const GridImp* grid)
47 MMeshInterfaceGridLeafIndexSet (
const MMeshInterfaceGridLeafIndexSet& leafIndexSet)
48 : grid_(leafIndexSet.grid_),
49 sizeOfCodim_(leafIndexSet.sizeOfCodim_),
50 indexMap_(leafIndexSet.indexMap_),
51 edgeIndexMap_(leafIndexSet.edgeIndexMap_),
52 vertexIndices_(leafIndexSet.vertexIndices_)
57 std::enable_if_t< codim == 0, IndexType >
58 index (
const Entity< codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
const
60 auto hostEntity = e.impl().hostEntity();
63 using HostGridHandle =
typename GridImp::MMeshType::template HostGridEntity<0>;
64 if (!grid_->canBeMirrored(hostEntity))
66 if constexpr (dimension == 1)
67 return (hostEntity.first->vertex(0) == grid_->getMMesh().getHostGrid().finite_faces_end()->vertex(0)) ? 1 : 0;
69 return (hostEntity.first->vertex(0) == grid_->getMMesh().getHostGrid().finite_cells_end()->vertex(0)) ? 1 : 0;
72 std::array<std::size_t, dimensionworld> ids;
73 for(
int i = 0; i < dimensionworld; ++i )
75 ids[i] = vertexIndices_.at( hostEntity.first->vertex((hostEntity.second+i+1)%(dimensionworld+1))->info().id );
76 }
catch (std::exception &e) {
77 DUNE_THROW(InvalidStateException, e.what());
79 std::sort(ids.begin(), ids.end());
81 std::array<std::size_t, dimension> edgeIds;
82 for(
int i = 0; i < dimension; ++i )
86 IndexType index = indexMap_.at( edgeIds ).at( ids[dimension] );
87 assert( index <= size(codim) );
89 }
catch (std::exception &e) {
90 DUNE_THROW(InvalidStateException, e.what());
96 std::enable_if_t< codim == 1 && dimension == 2, IndexType >
97 index (
const Entity< codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
const
99 auto hostEntity = e.impl().hostEntity();
101 std::array<std::size_t, 2> ids;
103 ids[0] = vertexIndices_.at( hostEntity.first->vertex(hostEntity.second)->info().id );
104 ids[1] = vertexIndices_.at( hostEntity.first->vertex(hostEntity.third)->info().id );
105 }
catch (std::exception &e) {
106 DUNE_THROW(InvalidStateException, e.what());
108 std::sort(ids.begin(), ids.end());
111 IndexType index = edgeIndexMap_.at( ids );
112 assert( index <= size(codim) );
114 }
catch (std::exception &e) {
115 DUNE_THROW(InvalidStateException, e.what());
121 std::enable_if_t< codim == dimension, IndexType >
122 index (
const Entity< codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
const
124 auto hostEntity = e.impl().hostEntity();
127 index = vertexIndices_.at( hostEntity->info().id );
128 }
catch (std::exception &e) {
129 DUNE_THROW(InvalidStateException, e.what());
131 assert( index <= size(codim) );
136 template<
class Entity>
137 IndexType subIndex (
const Entity& e,
int i,
int codim)
139 return subIndex< Entity::codimension >( e, i, codim );
144 std::enable_if_t< cc == dimension, IndexType >
145 subIndex (
const typename std::remove_const<GridImp>::type::Traits::template Codim<cc>::Entity& e,
int i,
int codim)
const
147 assert( i == 0 && codim == dimension );
148 const HostGridEntity<dimension> hostEntity = e.impl().hostEntity();
150 return vertexIndices_.at( hostEntity->info().id );
151 }
catch (std::exception &e) {
152 DUNE_THROW(InvalidStateException, e.what());
158 std::enable_if_t< cc == 0, IndexType > subIndex (
const typename std::remove_const<GridImp>::type::Traits::template Codim<cc>::Entity& e,
int i,
int codim)
const
160 assert ( codim >= 0 && codim <= dimension );
164 else if ( codim == dimension )
165 return index( e.template subEntity<dimension>( i ) );
166 else if ( codim == 1 && dimension == 2)
167 return index( e.template subEntity<1>( i ) );
169 DUNE_THROW( NotImplemented,
"SubIndices for codim == " << codim <<
" and dimension == " << dimension );
176 std::enable_if_t< cc != 0 && cc != dimension, IndexType > subIndex (
const typename std::remove_const<GridImp>::type::Traits::template Codim<cc>::Entity& e,
int i,
int codim)
const
178 DUNE_THROW( NotImplemented,
"SubIndex for cc != 0." );
182 std::size_t size (GeometryType type)
const
184 if( type == GeometryTypes::vertex )
185 return size(dimension);
186 else if( type == GeometryTypes::line )
187 return size(dimension-1);
188 else if( type == GeometryTypes::triangle )
189 return size(dimension-2);
195 std::size_t size (
int codim)
const
197 assert( (0 <= codim) && (codim <= dimension) );
198 return sizeOfCodim_[codim];
202 const Types geomTypes (
int codim)
const
204 return types( codim );
208 Types types (
int codim)
const
210 switch ( dimension - codim ) {
212 return {{ GeometryTypes::vertex }};
214 return {{ GeometryTypes::line }};
216 return {{ GeometryTypes::triangle }};
218 DUNE_THROW(InvalidStateException,
"Codim is not within 0 <= codim <= dimension.");
223 template<
class EntityType >
224 bool contains (
const EntityType& e)
const
226 return grid_->isInterface( e );
230 template<
int d = dimensionworld >
231 std::enable_if_t< d == 2, void >
232 update(
const GridImp* grid)
235 const auto& hostgrid = grid_->getHostGrid();
237 vertexIndices_.clear();
241 std::size_t vertexCount = 0;
242 std::size_t elementCount = 0;
243 for (
const auto& element : elements(grid_->leafGridView(), Partitions::all))
245 auto eh = &element.impl().hostEntity();
246 auto vh0 = eh->first->vertex((eh->second+1)%3);
247 auto vh1 = eh->first->vertex((eh->second+2)%3);
249 std::size_t idx0 = vh0->info().id;
250 std::size_t idx1 = vh1->info().id;
252 addVertexIndex( idx0, vertexCount );
253 addVertexIndex( idx1, vertexCount );
256 std::size_t id0 = vertexIndices_.at( idx0 );
257 std::size_t id1 = vertexIndices_.at( idx1 );
260 indexMap_[{id0}].insert( { id1, elementCount } );
261 indexMap_[{id1}].insert( { id0, elementCount++ } );
262 }
catch (std::exception &e) {
263 DUNE_THROW(InvalidStateException, e.what());
268 sizeOfCodim_[0] = elementCount;
269 sizeOfCodim_[1] = vertexCount;
273 void addVertexIndex( std::size_t index, std::size_t& vertexCount )
275 auto it = vertexIndices_.find( index );
276 if ( it == vertexIndices_.end() )
277 vertexIndices_.insert( { index, vertexCount++ } );
282 template<
int d = dimensionworld >
283 std::enable_if_t< d == 3, void >
284 update(
const GridImp* grid)
287 const auto& hostgrid = grid_->getHostGrid();
289 vertexIndices_.clear();
291 edgeIndexMap_.clear();
294 std::size_t vertexCount = 0;
295 std::size_t edgeCount = 0;
296 std::size_t elementCount = 0;
297 for (
const auto& element : elements(grid_->leafGridView(), Partitions::all))
299 auto eh = &element.impl().hostEntity();
300 std::array<std::size_t, dimensionworld> ids;
301 for(
int i = 0; i < dimensionworld; ++i )
303 std::size_t idx = eh->first->vertex((eh->second+i+1)%4)->info().id;
304 addVertexIndex( idx, vertexCount );
306 ids[i] = vertexIndices_.at( idx );
307 }
catch (std::exception &e) {
308 DUNE_THROW(InvalidStateException, e.what());
311 std::sort(ids.begin(), ids.end());
314 indexMap_[{ids[0], ids[1]}].insert( { ids[2], elementCount } );
315 indexMap_[{ids[1], ids[2]}].insert( { ids[0], elementCount } );
316 indexMap_[{ids[0], ids[2]}].insert( { ids[1], elementCount++ } );
319 for(
int i = 0; i < 3; ++ i )
321 std::array<std::size_t, dimension> edgeIds;
323 edgeIds[1] = ids[(i+1)%3];
324 std::sort(edgeIds.begin(), edgeIds.end());
326 if ( edgeIndexMap_.count( edgeIds ) == 0 )
327 edgeIndexMap_.insert( { edgeIds, edgeCount++ } );
332 sizeOfCodim_[0] = elementCount;
333 sizeOfCodim_[1] = edgeCount;
334 sizeOfCodim_[2] = vertexCount;
337 const IndexMap& indexMap()
const
342 const VertexIndexMap& vertexIndexMap()
const
344 return vertexIndices_;
349 std::array<std::size_t, dimension+1> sizeOfCodim_;
351 EdgeIndexMap edgeIndexMap_;
352 VertexIndexMap vertexIndices_;
355 template <
class Gr
idImp>
356 class MMeshInterfaceGridGlobalIdSet :
357 public IdSet<GridImp, MMeshInterfaceGridGlobalIdSet<GridImp>, MMeshImpl::MultiId>
359 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
365 enum {dimensionworld = std::remove_const<GridImp>::type::dimensionworld};
366 enum {dimension = dimensionworld-1};
369 using HostGridEntity =
typename GridImp::template MMeshInterfaceEntity<codim>;
373 MMeshInterfaceGridGlobalIdSet (
const GridImp* g)
377 using IdType = MMeshImpl::MultiId;
385 IdType id (
const typename std::remove_const<GridImp>::type::Traits::template Codim<cd>::Entity& e)
const
390 IdType id (
const typename std::remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e)
const
392 return IdType( e.impl().id() );
395 template<
int d = dimension >
396 std::enable_if_t< d == 2, IdType > id (
const typename std::remove_const<GridImp>::type::Traits::template Codim<1>::Entity& e)
const
398 const auto& host = e.impl().hostEntity();
404 IdType id (
const typename std::remove_const<GridImp>::type::MMeshType::Traits::template Codim<cd>::Entity& e)
const
406 static_assert( cd == dimension );
407 const auto& host = e.impl().hostEntity();
411 template<
int d = dimensionworld >
412 std::enable_if_t< d == 3, IdType >
413 id (
const typename std::remove_const<GridImp>::type::template MMeshInterfaceEntity<1>& host)
const
415 std::vector< std::size_t > ids ( 2 );
416 ids[0] = host.first->vertex(host.second)->info().id;
417 ids[1] = host.first->vertex(host.third)->info().id;
418 std::sort( ids.begin(), ids.end() );
419 return IdType( ids );
422 IdType id (
const typename std::remove_const<GridImp>::type::Traits::template Codim<dimension>::Entity& e)
const
424 return { e.impl().hostEntity()->info().id };
432 IdType subId (
const typename std::remove_const<GridImp>::type::Traits::template Codim<0>::Entity& e,
int i,
int codim)
const
434 assert( 0 <= codim && codim <= dimension );
435 IdType dummyId ( { std::size_t(-3), std::size_t(-2) } );
438 return e.impl().id();
440 if constexpr (dimension == 1)
444 if (e.impl().id() != dummyId )
445 return e.impl().id().vt()[i];
447 return IdType( std::size_t(-3 + i) );
453 return id<1>( e.impl().template subEntity<1>( i ) );
456 return id<2>( e.impl().template subEntity<2>( i ) );
459 DUNE_THROW( NotImplemented,
"InterfaceGrid: subId of codim != 0 or codim != 1 or codim != 2" );
464 void update(
const GridImp* grid) {}