Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (unstable)

indexsets.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_GRID_INDEXSETS_HH
4#define DUNE_MMESH_GRID_INDEXSETS_HH
5
10// Dune includes
11#include <dune/grid/common/indexidset.hh>
13
14namespace Dune {
15
16template <class GridImp>
17class MMeshLeafIndexSet : public IndexSet<GridImp, MMeshLeafIndexSet<GridImp>> {
18 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
19
20 template <int codim>
21 using HostGridEntity = typename GridImp::template HostGridEntity<codim>;
22
23 public:
24 typedef std::size_t IndexType;
25 typedef const std::vector<GeometryType> Types;
26
27 typedef std::unordered_map<MMeshImpl::MultiId, std::size_t> CodimIndexMap;
28
29 /*
30 * We use the remove_const to extract the Type from the mutable class,
31 * because the const class is not instantiated yet.
32 */
33 enum { dim = std::remove_const<GridImp>::type::dimension };
34
36 MMeshLeafIndexSet(const GridImp* grid) : grid_(grid) {}
37
38 MMeshLeafIndexSet(const MMeshLeafIndexSet& leafIndexSet)
39 : grid_(leafIndexSet.grid_), sizeOfCodim_(leafIndexSet.sizeOfCodim_) {}
40
42 template <int codim>
43 std::enable_if_t<codim == 0 || codim == dim, IndexType> index(
44 const Entity<codim, dim, GridImp, MMeshEntity>& e) const {
45 auto hostEntity = e.impl().hostEntity();
46 IndexType index = hostEntity->info().index;
47 assert(index <= size(codim));
48 return index;
49 }
50
52 template <int codim>
53 std::enable_if_t<codim == 1, IndexType> index(
54 const Entity<codim, dim, GridImp, MMeshEntity>& e) const {
55 try {
56 return codimIndexMap_[0].at(grid_->globalIdSet().id(e));
57 } catch (...) {
58 DUNE_THROW(InvalidStateException, "Id of codim 1 entity not found.");
59 }
60 }
61
63 template <int codim>
64 std::enable_if_t<codim == 2 && dim == 3, IndexType> index(
65 const Entity<codim, dim, GridImp, MMeshEntity>& e) const {
66 try {
67 return codimIndexMap_[1].at(grid_->globalIdSet().id(e));
68 } catch (...) {
69 DUNE_THROW(InvalidStateException, "Id of codim 2 entity not found.");
70 }
71 }
72
74 template <class Entity>
75 IndexType subIndex(const Entity& e, int i, int codim) {
76 return subIndex<Entity::codimension>(e, i, codim);
77 }
78
80 template <int cc>
81 std::enable_if_t<cc == dim, IndexType> subIndex(
82 const typename std::remove_const<GridImp>::type::Traits::template Codim<
83 cc>::Entity& e,
84 int i, int codim) const {
85 const HostGridEntity<dim> hostEntity = e.impl().hostEntity();
86 return hostEntity->info().index;
87 };
88
90 template <int cc>
91 std::enable_if_t<cc == 0, IndexType> subIndex(
92 const typename std::remove_const<GridImp>::type::Traits::template Codim<
93 cc>::Entity& e,
94 int i, int codim) const {
95 assert(codim >= 0 && codim <= dim);
96
97 if (codim == 0) return index(e);
98 if (codim == dim)
99 return e.impl()
100 .template subEntity<dim>(i)
101 .impl()
102 .hostEntity()
103 ->info()
104 .index;
105 else if (codim == 1)
106 return codimIndexMap_[0].at(
107 grid_->globalIdSet().id(e.impl().template subEntity<1>(i)));
108 else if (codim == 2)
109 return codimIndexMap_[1].at(
110 grid_->globalIdSet().id(e.impl().template subEntity<2>(i)));
111 else
112 DUNE_THROW(InvalidStateException,
113 "subIndex() was called for codim " << codim);
114
115 return 0;
116 }
117
119 template <int cc>
120 std::enable_if_t<cc != 0 && cc != dim, IndexType> subIndex(
121 const typename std::remove_const<GridImp>::type::Traits::template Codim<
122 cc>::Entity& e,
123 int i, int codim) const {
124 DUNE_THROW(NotImplemented, "SubIndices for codim != 0 || codim != dim.");
125 };
126
128 std::size_t size(GeometryType type) const {
129 if (type == GeometryTypes::vertex)
130 return size(dim);
131 else if (type == GeometryTypes::line)
132 return size(dim - 1);
133 else if (type == GeometryTypes::triangle)
134 return size(dim - 2);
135 else if (type == GeometryTypes::tetrahedron)
136 return size(dim - 3);
137 else
138 return 0;
139 }
140
142 std::size_t size(int codim) const {
143 assert((0 <= codim) && (codim <= dim));
144 return sizeOfCodim_[codim];
145 }
146
148 const Types geomTypes(int codim) const { return types(codim); }
149
151 Types types(int codim) const {
152 switch (dim - codim) {
153 case 0:
154 return {{GeometryTypes::vertex}};
155 case 1:
156 return {{GeometryTypes::line}};
157 case 2:
158 return {{GeometryTypes::triangle}};
159 case 3:
160 return {{GeometryTypes::tetrahedron}};
161 default:
162 DUNE_THROW(InvalidStateException,
163 "Codim is not within 0 <= codim <= dim.");
164 }
165 }
166
169 template <class EntityType, int d = dim>
170 std::enable_if_t<d == 2 && EntityType::codimension == 0, bool> contains(
171 const EntityType& e) const {
172 const auto hostEntity = e.impl().hostEntity();
173 return grid_->getHostGrid().is_face(
174 hostEntity->vertex(0), hostEntity->vertex(1), hostEntity->vertex(2));
175 }
176
177 template <class EntityType, int d = dim>
178 std::enable_if_t<d == 2 && EntityType::codimension == 1, bool> contains(
179 const EntityType& e) const {
180 const auto hostEntity = e.impl().hostEntity();
181 return grid_->getHostGrid().is_edge(
182 hostEntity.first->vertex((hostEntity.second + 1) % 3),
183 hostEntity.first->vertex((hostEntity.second + 2) % 3));
184 }
185
186 template <class EntityType, int d = dim>
187 std::enable_if_t<d == 2 && EntityType::codimension == 2, bool> contains(
188 const EntityType& e) const {
189 const auto hostEntity = e.impl().hostEntity();
190 return grid_->getHostGrid().tds().is_vertex(hostEntity);
191 }
192
195 template <class EntityType, int d = dim>
196 std::enable_if_t<d == 3 && EntityType::codimension == 0, bool> contains(
197 const EntityType& e) const {
198 const auto hostEntity = e.impl().hostEntity();
199 return grid_->getHostGrid().is_cell(hostEntity);
200 }
201
204 template <class EntityType, int d = dim>
205 std::enable_if_t<d == 3 && EntityType::codimension == 1, bool> contains(
206 const EntityType& e) const {
207 const auto hostEntity = e.impl().hostEntity();
208 return grid_->getHostGrid().tds().is_facet(hostEntity.first,
209 hostEntity.second);
210 }
211
214 template <class EntityType, int d = dim>
215 std::enable_if_t<d == 3 && EntityType::codimension == 2, bool> contains(
216 const EntityType& e) const {
217 const auto hostEntity = e.impl().hostEntity();
218 return grid_->getHostGrid().tds().is_edge(
219 hostEntity.first, hostEntity.second, hostEntity.third);
220 }
221
224 template <class EntityType, int d = dim>
225 std::enable_if_t<d == 3 && EntityType::codimension == 3, bool> contains(
226 const EntityType& e) const {
227 const auto hostEntity = e.impl().hostEntity();
228 return grid_->getHostGrid().tds().is_vertex(hostEntity);
229 }
230
232 template <int d = dim>
233 std::enable_if_t<d == 2, void> update(const GridImp* grid) {
234 grid_ = grid;
235 const auto& hostgrid = grid_->getHostGrid();
236
237 // Store face indices within face infos
238 std::size_t elementCount = 0;
239 for (const auto& element : elements(grid_->leafGridView(), Partitions::all))
240 element.impl().hostEntity()->info().index = elementCount++;
241
242 // Store vertex indices within vertex infos
243 std::size_t vertexCount = 0;
244 for (const auto& vertex : vertices(grid_->leafGridView(), Partitions::all))
245 vertex.impl().hostEntity()->info().index = vertexCount++;
246
247 // Store the finite edge indices in a map
248 codimIndexMap_[0].clear();
249 std::size_t edgeCount = 0;
250 for (const auto& edge : edges(grid_->leafGridView(), Partitions::all))
251 codimIndexMap_[0][grid_->globalIdSet().id(edge)] = edgeCount++;
252
253 // Cache sizes since it is expensive to compute them
254 sizeOfCodim_[0] = elementCount;
255 sizeOfCodim_[1] = edgeCount;
256 sizeOfCodim_[2] = vertexCount;
257 }
258
260 template <int d = dim>
261 std::enable_if_t<d == 3, void> update(const GridImp* grid) {
262 grid_ = grid;
263 const auto& hostgrid = grid_->getHostGrid();
264
265 // Store cell indices within cell infos
266 std::size_t elementCount = 0;
267 for (const auto& element : elements(grid_->leafGridView(), Partitions::all))
268 element.impl().hostEntity()->info().index = elementCount++;
269
270 // Store vertex indices within vertex infos
271 std::size_t vertexCount = 0;
272 for (const auto& vertex : vertices(grid_->leafGridView(), Partitions::all))
273 vertex.impl().hostEntity()->info().index = vertexCount++;
274
275 // Store the finite facet indices in a map
276 codimIndexMap_[0].clear();
277 std::size_t facetCount = 0;
278 for (const auto& facet : facets(grid_->leafGridView(), Partitions::all))
279 codimIndexMap_[0][grid_->globalIdSet().id(facet)] = facetCount++;
280
281 // Store the finite edge indices in a map
282 codimIndexMap_[1].clear();
283 std::size_t edgeCount = 0;
284 for (const auto& edge : edges(grid_->leafGridView(), Partitions::all))
285 codimIndexMap_[1][grid_->globalIdSet().id(edge)] = edgeCount++;
286
287 // Cache sizes since it is expensive to compute them
288 sizeOfCodim_[0] = elementCount;
289 sizeOfCodim_[1] = facetCount;
290 sizeOfCodim_[2] = edgeCount;
291 sizeOfCodim_[3] = vertexCount;
292 }
293
294 GridImp* grid_;
295 std::array<std::size_t, dim + 1> sizeOfCodim_;
296 std::array<CodimIndexMap, dim - 1> codimIndexMap_;
297};
298
299template <class GridImp>
300class MMeshGlobalIdSet
301 : public IdSet<GridImp, MMeshGlobalIdSet<GridImp>, MMeshImpl::MultiId> {
302 typedef typename std::remove_const<GridImp>::type::HostGridType HostGrid;
303
304 /*
305 * We use the remove_const to extract the Type from the mutable class,
306 * because the const class is not instantiated yet.
307 */
308 enum { dim = std::remove_const<GridImp>::type::dimension };
309
310 template <int codim>
311 using HostGridEntity = typename GridImp::template HostGridEntity<codim>;
312
313 public:
315 using IdType = MMeshImpl::MultiId;
316
318 MMeshGlobalIdSet(const GridImp* g) : grid_(g), nextVertexId_(0) { init(); }
319
321 void init() {
322 const auto& hostgrid = grid_->getHostGrid();
323
324 // Determine nextVertexId_
325 for (auto vh = hostgrid.finite_vertices_begin();
326 vh != hostgrid.finite_vertices_end(); ++vh)
327 if (vh->info().idWasSet && vh->info().id >= nextVertexId_)
328 nextVertexId_ = vh->info().id + 1;
329 }
330
332 /*
333 We use the remove_const to extract the Type from the mutable class,
334 because the const class is not instantiated yet.
335 */
336 template <int cd>
337 std::enable_if_t<cd == dim, IdType> id(
338 const typename std::remove_const<GridImp>::type::Traits::template Codim<
339 cd>::Entity& e) const {
340 return IdType(e.impl().hostEntity()->info().id);
341 }
342
343 template <int cd>
344 std::enable_if_t<cd != dim, IdType> id(
345 const typename std::remove_const<GridImp>::type::Traits::template Codim<
346 cd>::Entity& e) const {
347 return IdType(e.impl().id());
348 }
349
351 template <int d = dim>
352 std::enable_if_t<d == 2, IdType> subId(
353 const typename std::remove_const<GridImp>::type::Traits::template Codim<
354 0>::Entity& e,
355 int i, int codim) const {
356 assert(0 <= codim && codim <= dim);
357 IdType dummyId({std::size_t(-4), std::size_t(-3), std::size_t(-2)});
358 switch (codim) {
359 case 0:
360 return e.impl().id();
361 case 1:
362 if (e.impl().id() != dummyId) {
363 auto id0 = e.impl().id().vt()[i < 2 ? 0 : 1];
364 auto id1 = e.impl().id().vt()[i == 0 ? 1 : 2];
365 return IdType({std::min(id0, id1), std::max(id0, id1)});
366 } else {
367 std::size_t id0 = (i < 2 ? -4 : -3);
368 std::size_t id1 = (i == 0 ? -3 : -2);
369 return IdType({id0, id1});
370 }
371 case 2:
372 if (e.impl().id() != dummyId)
373 return e.impl().id().vt()[i];
374 else
375 return IdType(std::size_t(-4 + i));
376 };
377 return IdType();
378 }
379
380 template <int d = dim>
381 std::enable_if_t<d == 3, IdType> subId(
382 const typename std::remove_const<GridImp>::type::Traits::template Codim<
383 0>::Entity& e,
384 int i, int codim) const {
385 assert(0 <= codim && codim <= dim);
386 switch (codim) {
387 case 0:
388 return id<0>(e.impl().template subEntity<0>(i));
389 case 1:
390 return id<1>(e.impl().template subEntity<1>(i));
391 case 2:
392 return id<2>(e.impl().template subEntity<2>(i));
393 case 3:
394 return id<3>(e.impl().template subEntity<3>(i));
395 };
396 return IdType();
397 }
398
400 template <int d = dim>
401 std::enable_if_t<d == 2, void> update(const GridImp* grid) {
402 grid_ = grid;
403 const auto& hostgrid = grid_->getHostGrid();
404
405 // Store vertex ids within vertex infos
406 for (auto vh = hostgrid.finite_vertices_begin();
407 vh != hostgrid.finite_vertices_end(); ++vh)
408 if (!vh->info().idWasSet) {
409 vh->info().id = nextVertexId_++;
410 vh->info().idWasSet = true;
411 }
412
413 // Compute mapping DUNE vertex index to CGAL vertex index
414 for (auto fh = hostgrid.all_faces_begin(); fh != hostgrid.all_faces_end();
415 ++fh)
416 fh->info().cgalIndex = MMeshImpl::computeCGALIndices<decltype(fh), 2>(fh);
417 }
418
420 template <int d = dim>
421 std::enable_if_t<d == 3, void> update(const GridImp* grid) {
422 grid_ = grid;
423 const auto& hostgrid = grid_->getHostGrid();
424
425 // Store vertex ids within vertex infos
426 for (auto vh = hostgrid.finite_vertices_begin();
427 vh != hostgrid.finite_vertices_end(); ++vh)
428 if (!vh->info().idWasSet) {
429 vh->info().id = nextVertexId_++;
430 vh->info().idWasSet = true;
431 }
432
433 // Compute mapping DUNE vertex index to CGAL vertex index
434 for (auto ch = hostgrid.all_cells_begin(); ch != hostgrid.all_cells_end();
435 ++ch)
436 ch->info().cgalIndex = MMeshImpl::computeCGALIndices<decltype(ch), 3>(ch);
437 }
438
440 std::size_t setNextId(HostGridEntity<dim> vh) const {
441 assert(!vh->info().idWasSet);
442 vh->info().id = nextVertexId_++;
443 vh->info().idWasSet = true;
444 return vh->info().id;
445 }
446
447 GridImp* grid_;
448 mutable std::size_t nextVertexId_;
449};
450
451} // end namespace Dune
452
453#endif
The multi id class.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 17, 23:30, 2025)