Loading [MathJax]/extensions/tex2jax.js

dune-mmesh (1.4)

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