3#ifndef DUNE_MMESH_INTERFACE_INDEXSETS_HH
4#define DUNE_MMESH_INTERFACE_INDEXSETS_HH
11#include <dune/grid/common/indexidset.hh>
16template <
class Gr
idImp>
17class MMeshInterfaceGridLeafIndexSet
18 :
public IndexSet<GridImp, MMeshInterfaceGridLeafIndexSet<GridImp>> {
19 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
22 using HostGridEntity =
typename GridImp::template MMeshInterfaceEntity<codim>;
25 typedef std::size_t IndexType;
26 typedef const std::vector<GeometryType> Types;
32 enum { dimensionworld = std::remove_const<GridImp>::type::dimensionworld };
33 enum { dimension = dimensionworld - 1 };
35 using LocalIndexMap = std::unordered_map<std::size_t, std::size_t>;
36 using IndexMap = std::unordered_map<std::array<std::size_t, dimension>,
37 LocalIndexMap, HashUIntArray>;
38 using EdgeIndexMap = std::unordered_map<std::array<std::size_t, dimension>,
39 std::size_t, HashUIntArray>;
40 using VertexIndexMap = std::unordered_map<std::size_t, std::size_t>;
43 MMeshInterfaceGridLeafIndexSet(
const GridImp* grid) : grid_(grid) {}
45 MMeshInterfaceGridLeafIndexSet(
46 const MMeshInterfaceGridLeafIndexSet& leafIndexSet)
47 : grid_(leafIndexSet.grid_),
48 sizeOfCodim_(leafIndexSet.sizeOfCodim_),
49 indexMap_(leafIndexSet.indexMap_),
50 edgeIndexMap_(leafIndexSet.edgeIndexMap_),
51 vertexIndices_(leafIndexSet.vertexIndices_) {}
55 std::enable_if_t<codim == 0, IndexType> index(
56 const Entity<codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
58 auto hostEntity = e.impl().hostEntity();
61 using HostGridHandle =
62 typename GridImp::MMeshType::template HostGridEntity<0>;
63 if (!grid_->canBeMirrored(hostEntity)) {
64 if constexpr (dimension == 1)
65 return (hostEntity.first->vertex(0) ==
66 grid_->getMMesh().getHostGrid().finite_faces_end()->vertex(0))
70 return (hostEntity.first->vertex(0) ==
71 grid_->getMMesh().getHostGrid().finite_cells_end()->vertex(0))
76 std::array<std::size_t, dimensionworld> ids;
77 for (
int i = 0; i < dimensionworld; ++i)
try {
78 ids[i] = vertexIndices_.at(
80 ->vertex((hostEntity.second + i + 1) % (dimensionworld + 1))
83 }
catch (std::exception& e) {
84 DUNE_THROW(InvalidStateException, e.what());
86 std::sort(ids.begin(), ids.end());
88 std::array<std::size_t, dimension> edgeIds;
89 for (
int i = 0; i < dimension; ++i) edgeIds[i] = ids[i];
92 IndexType index = indexMap_.at(edgeIds).at(ids[dimension]);
93 assert(index <= size(codim));
95 }
catch (std::exception& e) {
96 DUNE_THROW(InvalidStateException, e.what());
102 std::enable_if_t<codim == 1 && dimension == 2, IndexType> index(
103 const Entity<codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
105 auto hostEntity = e.impl().hostEntity();
107 std::array<std::size_t, 2> ids;
109 ids[0] = vertexIndices_.at(
110 hostEntity.first->vertex(hostEntity.second)->info().id);
111 ids[1] = vertexIndices_.at(
112 hostEntity.first->vertex(hostEntity.third)->info().id);
113 }
catch (std::exception& e) {
114 DUNE_THROW(InvalidStateException, e.what());
116 std::sort(ids.begin(), ids.end());
119 IndexType index = edgeIndexMap_.at(ids);
120 assert(index <= size(codim));
122 }
catch (std::exception& e) {
123 DUNE_THROW(InvalidStateException, e.what());
129 std::enable_if_t<codim == dimension, IndexType> index(
130 const Entity<codim, dimension, GridImp, MMeshInterfaceGridEntity>& e)
132 auto hostEntity = e.impl().hostEntity();
135 index = vertexIndices_.at(hostEntity->info().id);
136 }
catch (std::exception& e) {
137 DUNE_THROW(InvalidStateException, e.what());
139 assert(index <= size(codim));
144 template <
class Entity>
145 IndexType subIndex(
const Entity& e,
int i,
int codim) {
146 return subIndex<Entity::codimension>(e, i, codim);
151 std::enable_if_t<cc == dimension, IndexType> subIndex(
152 const typename std::remove_const<GridImp>::type::Traits::template Codim<
154 int i,
int codim)
const {
155 assert(i == 0 && codim == dimension);
156 const HostGridEntity<dimension> hostEntity = e.impl().hostEntity();
158 return vertexIndices_.at(hostEntity->info().id);
159 }
catch (std::exception& e) {
160 DUNE_THROW(InvalidStateException, e.what());
166 std::enable_if_t<cc == 0, IndexType> subIndex(
167 const typename std::remove_const<GridImp>::type::Traits::template Codim<
169 int i,
int codim)
const {
170 assert(codim >= 0 && codim <= dimension);
174 else if (codim == dimension)
175 return index(e.template subEntity<dimension>(i));
176 else if (codim == 1 && dimension == 2)
177 return index(e.template subEntity<1>(i));
179 DUNE_THROW(NotImplemented,
"SubIndices for codim == "
181 <<
" and dimension == " << dimension);
188 std::enable_if_t<cc != 0 && cc != dimension, IndexType> subIndex(
189 const typename std::remove_const<GridImp>::type::Traits::template Codim<
191 int i,
int codim)
const {
192 DUNE_THROW(NotImplemented,
"SubIndex for cc != 0.");
196 std::size_t size(GeometryType type)
const {
197 if (type == GeometryTypes::vertex)
198 return size(dimension);
199 else if (type == GeometryTypes::line)
200 return size(dimension - 1);
201 else if (type == GeometryTypes::triangle)
202 return size(dimension - 2);
208 std::size_t size(
int codim)
const {
209 assert((0 <= codim) && (codim <= dimension));
210 return sizeOfCodim_[codim];
214 const Types geomTypes(
int codim)
const {
return types(codim); }
217 Types types(
int codim)
const {
218 switch (dimension - codim) {
220 return {{GeometryTypes::vertex}};
222 return {{GeometryTypes::line}};
224 return {{GeometryTypes::triangle}};
226 DUNE_THROW(InvalidStateException,
227 "Codim is not within 0 <= codim <= dimension.");
233 template <
class EntityType>
234 bool contains(
const EntityType& e)
const {
235 return grid_->isInterface(e);
239 template <
int d = dimensionworld>
240 std::enable_if_t<d == 2, void> update(
const GridImp* grid) {
242 const auto& hostgrid = grid_->getHostGrid();
244 vertexIndices_.clear();
248 std::size_t vertexCount = 0;
249 std::size_t elementCount = 0;
250 for (
const auto& element :
251 elements(grid_->leafGridView(), Partitions::all)) {
252 auto eh = &element.impl().hostEntity();
253 auto vh0 = eh->first->vertex((eh->second + 1) % 3);
254 auto vh1 = eh->first->vertex((eh->second + 2) % 3);
256 std::size_t idx0 = vh0->info().id;
257 std::size_t idx1 = vh1->info().id;
259 addVertexIndex(idx0, vertexCount);
260 addVertexIndex(idx1, vertexCount);
263 std::size_t id0 = vertexIndices_.at(idx0);
264 std::size_t id1 = vertexIndices_.at(idx1);
267 indexMap_[{id0}].insert({id1, elementCount});
268 indexMap_[{id1}].insert({id0, elementCount++});
269 }
catch (std::exception& e) {
270 DUNE_THROW(InvalidStateException, e.what());
275 sizeOfCodim_[0] = elementCount;
276 sizeOfCodim_[1] = vertexCount;
280 void addVertexIndex(std::size_t index, std::size_t& vertexCount) {
281 auto it = vertexIndices_.find(index);
282 if (it == vertexIndices_.end())
283 vertexIndices_.insert({index, vertexCount++});
288 template <
int d = dimensionworld>
289 std::enable_if_t<d == 3, void> update(
const GridImp* grid) {
291 const auto& hostgrid = grid_->getHostGrid();
293 vertexIndices_.clear();
295 edgeIndexMap_.clear();
298 std::size_t vertexCount = 0;
299 std::size_t edgeCount = 0;
300 std::size_t elementCount = 0;
301 for (
const auto& element :
302 elements(grid_->leafGridView(), Partitions::all)) {
303 auto eh = &element.impl().hostEntity();
304 std::array<std::size_t, dimensionworld> ids;
305 for (
int i = 0; i < dimensionworld; ++i) {
307 eh->first->vertex((eh->second + i + 1) % 4)->info().id;
308 addVertexIndex(idx, vertexCount);
310 ids[i] = vertexIndices_.at(idx);
311 }
catch (std::exception& e) {
312 DUNE_THROW(InvalidStateException, e.what());
315 std::sort(ids.begin(), ids.end());
318 indexMap_[{ids[0], ids[1]}].insert({ids[2], elementCount});
319 indexMap_[{ids[1], ids[2]}].insert({ids[0], elementCount});
320 indexMap_[{ids[0], ids[2]}].insert({ids[1], elementCount++});
323 for (
int i = 0; i < 3; ++i) {
324 std::array<std::size_t, dimension> edgeIds;
326 edgeIds[1] = ids[(i + 1) % 3];
327 std::sort(edgeIds.begin(), edgeIds.end());
329 if (edgeIndexMap_.count(edgeIds) == 0)
330 edgeIndexMap_.insert({edgeIds, edgeCount++});
335 sizeOfCodim_[0] = elementCount;
336 sizeOfCodim_[1] = edgeCount;
337 sizeOfCodim_[2] = vertexCount;
340 const IndexMap& indexMap()
const {
return indexMap_; }
342 const VertexIndexMap& vertexIndexMap()
const {
return vertexIndices_; }
346 std::array<std::size_t, dimension + 1> sizeOfCodim_;
348 EdgeIndexMap edgeIndexMap_;
349 VertexIndexMap vertexIndices_;
352template <
class Gr
idImp>
353class MMeshInterfaceGridGlobalIdSet
354 :
public IdSet<GridImp, MMeshInterfaceGridGlobalIdSet<GridImp>,
355 MMeshImpl::MultiId> {
356 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
362 enum { dimensionworld = std::remove_const<GridImp>::type::dimensionworld };
363 enum { dimension = dimensionworld - 1 };
367 MMeshInterfaceGridGlobalIdSet(
const GridImp* g) {}
370 using IdType = MMeshImpl::MultiId;
378 IdType id(
const typename std::remove_const<
379 GridImp>::type::Traits::template Codim<cd>::Entity& e)
const {
383 IdType id(
const typename std::remove_const<
384 GridImp>::type::Traits::template Codim<0>::Entity& e)
const {
385 return IdType(e.impl().id());
388 template <
int d = dimension>
389 std::enable_if_t<d == 2, IdType> id(
390 const typename std::remove_const<GridImp>::type::Traits::template Codim<
391 1>::Entity& e)
const {
392 const auto& host = e.impl().hostEntity();
398 IdType id(
const typename std::remove_const<GridImp>::type::MMeshType::Traits::
399 template Codim<cd>::Entity& e)
const {
400 static_assert(cd == dimension);
401 const auto& host = e.impl().hostEntity();
405 template <
int d = dimensionworld>
406 std::enable_if_t<d == 3, IdType> id(
407 const typename std::remove_const<
408 GridImp>::type::template MMeshInterfaceEntity<1>& host)
const {
409 std::vector<std::size_t> ids(2);
410 ids[0] = host.first->vertex(host.second)->info().id;
411 ids[1] = host.first->vertex(host.third)->info().id;
412 std::sort(ids.begin(), ids.end());
417 const typename std::remove_const<GridImp>::type::Traits::template Codim<
418 dimension>::Entity& e)
const {
419 return {e.impl().hostEntity()->info().id};
427 IdType subId(
const typename std::remove_const<
428 GridImp>::type::Traits::template Codim<0>::Entity& e,
429 int i,
int codim)
const {
430 assert(0 <= codim && codim <= dimension);
431 IdType dummyId({std::size_t(-3), std::size_t(-2)});
433 if (codim == 0)
return e.impl().id();
435 if constexpr (dimension == 1) {
438 if (e.impl().id() != dummyId)
439 return e.impl().id().vt()[i];
441 return IdType(std::size_t(-3 + i));
445 if (codim == 1)
return id<1>(e.impl().template subEntity<1>(i));
447 if (codim == 2)
return id<2>(e.impl().template subEntity<2>(i));
452 "InterfaceGrid: subId of codim != 0 or codim != 1 or codim != 2");
457 void update(
const GridImp* grid) {}