Dune Core Modules (2.9.1)

indexsets.hh
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
6#define DUNE_ALBERTAGRIDINDEXSETS_HH
7
8#include <array>
9#include <utility>
10
11#include <dune/common/hybridutilities.hh>
13
16
18#include <dune/grid/albertagrid/misc.hh>
19#include <dune/grid/albertagrid/dofadmin.hh>
20#include <dune/grid/albertagrid/dofvector.hh>
23
24#if HAVE_ALBERTA
25
26namespace Dune
27{
28
29 namespace Alberta
30 {
31 typedef Dune::IndexStack< int, 100000 > IndexStack;
32 }
33
34
35
36 // AlbertaGridHierarchicIndexSet
37 // -----------------------------
38
39 template< int dim, int dimworld >
40 class AlbertaGridHierarchicIndexSet
41 : public IndexSet< AlbertaGridFamily< dim, dimworld >, AlbertaGridHierarchicIndexSet< dim,dimworld >, int, std::array< GeometryType, 1 > >
42 {
43 typedef AlbertaGridHierarchicIndexSet< dim, dimworld > This;
44 typedef IndexSet< AlbertaGridFamily< dim, dimworld >, AlbertaGridHierarchicIndexSet< dim,dimworld >, int, std::array< GeometryType, 1 > > Base;
45
46 friend class AlbertaGrid< dim, dimworld >;
47
48 public:
50 typedef AlbertaGridFamily< dim, dimworld > GridFamily;
51
52 typedef typename Base::IndexType IndexType;
53
54 typedef typename Base::Types Types;
55
56 static const int dimension = GridFamily::dimension;
57
58 typedef Alberta::ElementInfo< dimension > ElementInfo;
59 typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
60
61 private:
62 typedef typename GridFamily::Traits Traits;
63
64 typedef Alberta::DofVectorPointer< IndexType > IndexVectorPointer;
65
66 class InitEntityNumber;
67
68 template< int codim >
69 struct CreateEntityNumbers;
70
71 template< int codim >
72 struct RefineNumbering;
73
74 template< int codim >
75 struct CoarsenNumbering;
76
77 explicit AlbertaGridHierarchicIndexSet ( const DofNumbering &dofNumbering );
78
79 static Alberta::IndexStack *currentIndexStack;
80
81 public:
82 typedef Alberta::IndexStack IndexStack;
83
85 template< class Entity >
86 bool contains ( const Entity & ) const
87 {
88 return true;
89 }
90
91 using Base::index;
92 using Base::subIndex;
93
95 template< int cc >
96 IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const
97 {
98 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
99 const EntityImp &entityImp = entity.impl();
100 return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc );
101 }
102
104 template< int cc >
105 IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const
106 {
107 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
108 const EntityImp &entityImp = entity.impl();
109
110 int k = i;
111 if( cc > 0 )
112 {
114 k = refElement.subEntity( entityImp.subEntity(), cc, i, codim );
115 }
116
117 const int j = entityImp.grid().generic2alberta( codim, k );
118 return subIndex( entityImp.elementInfo(), j, codim );
119 }
120
122 std::size_t size ( const GeometryType &type ) const
123 {
124 return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
125 }
126
128 std::size_t size ( int codim ) const
129 {
130 assert( (codim >= 0) && (codim <= dimension) );
131 return indexStack_[ codim ].size();
132 }
133
134 Types types ( int codim ) const
135 {
136 assert( (codim >= 0) && (codim <= dimension) );
137 return {{ GeometryTypes::simplex( dimension - codim ) }};
138 }
139
141 const std::vector< GeometryType > &geomTypes( int codim ) const
142 {
143 assert( (codim >= 0) && (codim <= dimension) );
144 return geomTypes_[ codim ];
145 }
146
147 IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const
148 {
149 assert( !elementInfo == false );
150 return subIndex( elementInfo.element(), i, codim );
151 }
152
159 IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const
160 {
161 IndexType *array = (IndexType *)entityNumbers_[ codim ];
162 const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ];
163 assert( (subIndex >= 0) && (subIndex < IndexType(size( codim ))) );
164 return subIndex;
165 }
166
167 void preAdapt ()
168 {
169 // set global pointer to index stack
170 if( !IndexVectorPointer::supportsAdaptationData )
171 {
172 assert( currentIndexStack == nullptr );
173 currentIndexStack = indexStack_;
174 }
175 }
176
177 void postAdapt ()
178 {
179 // remove global pointer to index stack
180 if( !IndexVectorPointer::supportsAdaptationData )
181 currentIndexStack = nullptr;
182 }
183
184 void create ();
185 void read ( const std::string &filename );
186 bool write ( const std::string &filename ) const;
187
188 void release ()
189 {
190 for( int i = 0; i <= dimension; ++i )
191 entityNumbers_[ i ].release();
192 }
193
194 private:
195 template< int codim >
196 static IndexStack &getIndexStack ( const IndexVectorPointer &dofVector )
197 {
198 IndexStack *indexStack;
199 if( IndexVectorPointer::supportsAdaptationData )
200 indexStack = dofVector.template getAdaptationData< IndexStack >();
201 else
202 indexStack = &currentIndexStack[ codim ];
203 assert( indexStack != 0 );
204 return *indexStack;
205 }
206
207 // access to the dof vectors
208 const DofNumbering &dofNumbering_;
209
210 // index stacks providing new numbers during adaptation
211 IndexStack indexStack_[ dimension+1 ];
212
213 // dof vectors storing the (persistent) numbering
214 IndexVectorPointer entityNumbers_[ dimension+1 ];
215
216 // all geometry types contained in the grid
217 std::vector< GeometryType > geomTypes_[ dimension+1 ];
218 };
219
220 template< int dim, int dimworld >
221 Alberta::IndexStack* AlbertaGridHierarchicIndexSet<dim,dimworld>::currentIndexStack = nullptr;
222
223
224
225 // AlbertaGridHierarchicIndexSet::InitEntityNumber
226 // -----------------------------------------------
227
228 template< int dim, int dimworld >
229 class AlbertaGridHierarchicIndexSet< dim, dimworld >::InitEntityNumber
230 {
231 IndexStack &indexStack_;
232
233 public:
234 InitEntityNumber ( IndexStack &indexStack )
235 : indexStack_( indexStack )
236 {}
237
238 void operator() ( int &dof )
239 {
240 dof = indexStack_.getIndex();
241 }
242 };
243
244
245
246 // AlbertaGridHierarchicIndexSet::CreateEntityNumbers
247 // --------------------------------------------------
248
249 template< int dim, int dimworld >
250 template< int codim >
251 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CreateEntityNumbers
252 {
253 static void setup ( AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
254
255 static void apply ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering,
256 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
257
258 static void apply ( const std::string &filename,
259 const Alberta::MeshPointer< dimension > &mesh,
260 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet );
261 };
262
263
264
265 // AlbertaGridHierarchicIndexSet::RefineNumbering
266 // ----------------------------------------------
267
268 template< int dim, int dimworld >
269 template< int codim >
270 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::RefineNumbering
271 {
272 static const int dimension = dim;
273 static const int codimension = codim;
274
275 private:
276 typedef Alberta::DofAccess< dimension, codimension > DofAccess;
277
278 explicit RefineNumbering ( const IndexVectorPointer &dofVector )
279 : indexStack_( getIndexStack< codimension >( dofVector ) ),
280 dofVector_( dofVector ),
281 dofAccess_( dofVector.dofSpace() )
282 {}
283
284 public:
285 void operator() ( const Alberta::Element *child, int subEntity );
286
287 typedef Alberta::Patch< dimension > Patch;
288 static void interpolateVector ( const IndexVectorPointer &dofVector,
289 const Patch &patch );
290
291 private:
292 IndexStack &indexStack_;
293 IndexVectorPointer dofVector_;
294 DofAccess dofAccess_;
295 };
296
297
298
299 // AlbertaGridHierarchicIndexSet::CoarsenNumbering
300 // -----------------------------------------------
301
302 template< int dim, int dimworld >
303 template< int codim >
304 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CoarsenNumbering
305 {
306 static const int dimension = dim;
307 static const int codimension = codim;
308
309 private:
310 typedef Alberta::DofAccess< dimension, codimension > DofAccess;
311
312 explicit CoarsenNumbering ( const IndexVectorPointer &dofVector )
313 : indexStack_( getIndexStack< codimension >( dofVector ) ),
314 dofVector_( dofVector ),
315 dofAccess_( dofVector.dofSpace() )
316 {}
317
318 public:
319 void operator() ( const Alberta::Element *child, int subEntity );
320
321 typedef Alberta::Patch< dimension > Patch;
322 static void restrictVector ( const IndexVectorPointer &dofVector,
323 const Patch &patch );
324 private:
325 IndexStack &indexStack_;
326 IndexVectorPointer dofVector_;
327 DofAccess dofAccess_;
328 };
329
330
331
332 // AlbertaGridIndexSet
333 // -------------------
334
335 template< int dim, int dimworld >
336 class AlbertaGridIndexSet
337 : public IndexSet< AlbertaGrid< dim, dimworld >, AlbertaGridIndexSet< dim, dimworld >, int, std::array< GeometryType, 1 > >
338 {
339 typedef AlbertaGridIndexSet< dim, dimworld > This;
340 typedef IndexSet< AlbertaGrid< dim, dimworld >, AlbertaGridIndexSet< dim, dimworld >, int, std::array< GeometryType, 1 > > Base;
341
342 public:
343 typedef AlbertaGrid< dim, dimworld > Grid;
344
345 typedef typename Base::IndexType IndexType;
346
347 typedef typename Base::Types Types;
348
349 static const int dimension = Grid::dimension;
350
351 typedef Alberta::ElementInfo< dimension > ElementInfo;
352 typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering;
353
354 private:
355 typedef typename Grid::Traits Traits;
356
357 template< int codim >
358 struct Insert;
359
360 public:
361 explicit AlbertaGridIndexSet ( const DofNumbering &dofNumbering )
362 : dofNumbering_( dofNumbering )
363 {
364 for( int codim = 0; codim <= dimension; ++codim )
365 {
366 indices_[ codim ] = 0;
367 geomTypes_[ codim ].push_back( GeometryTypes::simplex( dimension - codim ) );
368 }
369 }
370
371 ~AlbertaGridIndexSet ()
372 {
373 for( int codim = 0; codim <= dimension; ++codim )
374 delete[] indices_[ codim ];
375 }
376
377 template< class Entity >
378 bool contains ( const Entity &entity ) const
379 {
380 const int codim = Entity::codimension;
381
382 const AlbertaGridEntity< codim, dim, const Grid > &entityImp
383 = entity.impl();
384 const Alberta::Element *element = entityImp.elementInfo().el();
385
386 const IndexType *const array = indices_[ codim ];
387 const IndexType subIndex = array[ dofNumbering_( element, codim, entityImp.subEntity() ) ];
388
389 return (subIndex >= 0);
390 }
391
392 using Base::index;
393 using Base::subIndex;
394
396 template< int cc >
397 IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const
398 {
399 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
400 const EntityImp &entityImp = entity.impl();
401 return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc );
402 }
403
405 template< int cc >
406 IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const
407 {
408 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp;
409 const EntityImp &entityImp = entity.impl();
410
411 int k = i;
412 if( cc > 0 )
413 {
415 k = refElement.subEntity( entityImp.subEntity(), cc, i, codim );
416 }
417
418 const int j = entityImp.grid().generic2alberta( codim, k );
419 return subIndex( entityImp.elementInfo(), j, codim );
420 }
421
422 std::size_t size ( const GeometryType &type ) const
423 {
424 return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
425 }
426
427 std::size_t size ( int codim ) const
428 {
429 assert( (codim >= 0) && (codim <= dimension) );
430 return size_[ codim ];
431 }
432
433 Types types ( int codim ) const
434 {
435 assert( (codim >= 0) && (codim <= dimension) );
436 return {{ GeometryTypes::simplex( dimension - codim ) }};
437 }
438
439 const std::vector< GeometryType > &geomTypes( int codim ) const
440 {
441 assert( (codim >= 0) && (codim <= dimension) );
442 return geomTypes_[ codim ];
443 }
444
445 template< class Iterator >
446 void update ( const Iterator &begin, const Iterator &end )
447 {
448 for( int codim = 0; codim <= dimension; ++codim )
449 {
450 delete[] indices_[ codim ];
451
452 const unsigned int dofSize = dofNumbering_.size( codim );
453 indices_[ codim ] = new IndexType[ dofSize ];
454 for( unsigned int i = 0; i < dofSize; ++i )
455 indices_[ codim ][ i ] = -1;
456
457 size_[ codim ] = 0;
458 }
459
460 for( Iterator it = begin; it != end; ++it )
461 {
462 const AlbertaGridEntity< 0, dim, const Grid > &entityImp
463 = it->impl();
464 const Alberta::Element *element = entityImp.elementInfo().el();
465 Hybrid::forEach( std::make_index_sequence< dimension+1 >{},
466 [ & ]( auto i ){ Insert< i >::apply( element, *this ); } );
467 }
468 }
469
470 private:
471 IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const
472 {
473 assert( !elementInfo == false );
474 return subIndex( elementInfo.element(), i, codim );
475 }
476
483 IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const
484 {
485 const IndexType *const array = indices_[ codim ];
486 const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ];
487 assert( (subIndex >= 0) && (static_cast<unsigned int>(subIndex) < size( codim )) );
488 return subIndex;
489 }
490
491 // access to the dof vectors
492 const DofNumbering &dofNumbering_;
493
494 // an array of indices for each codimension
495 IndexType *indices_[ dimension+1 ];
496
497 // the size of each codimension
498 IndexType size_[ dimension+1 ];
499
500 // all geometry types contained in the grid
501 std::vector< GeometryType > geomTypes_[ dimension+1 ];
502 };
503
504
505
506 // AlbertaGridIndexSet::Insert
507 // ---------------------------
508
509 template< int dim, int dimworld >
510 template< int codim >
511 struct AlbertaGridIndexSet< dim, dimworld >::Insert
512 {
513 static void apply ( const Alberta::Element *const element,
514 AlbertaGridIndexSet< dim, dimworld > &indexSet )
515 {
516 int *const array = indexSet.indices_[ codim ];
517 IndexType &size = indexSet.size_[ codim ];
518
519 for( int i = 0; i < Alberta::NumSubEntities< dim, codim >::value; ++i )
520 {
521 int &index = array[ indexSet.dofNumbering_( element, codim, i ) ];
522 if( index < 0 )
523 index = size++;
524 }
525 }
526 };
527
528
529
530 // AlbertaGridIdSet
531 // ----------------
532
534 template< int dim, int dimworld >
536 : public IdSet< AlbertaGrid< dim, dimworld >, AlbertaGridIdSet< dim, dimworld >, unsigned int >
537 {
539 typedef IdSet< AlbertaGrid< dim, dimworld >, This, unsigned int > Base;
540
541 friend class AlbertaGrid< dim, dimworld >;
542
543 public:
545 typedef typename Base::IdType IdType;
546
547 private:
549
550 static const int dimension = Grid::dimension;
551
552 typedef typename Grid::HierarchicIndexSet HierarchicIndexSet;
553
554 // create id set, only allowed for AlbertaGrid
555 AlbertaGridIdSet ( const HierarchicIndexSet &hIndexSet )
556 : hIndexSet_( hIndexSet )
557 {}
558
559 public:
561 template< class Entity >
562 IdType id ( const Entity &e ) const
563 {
564 const int codim = Entity::codimension;
565 return id< codim >( e );
566 }
567
569 template< int codim >
570 IdType id ( const typename Grid::template Codim< codim >::Entity &e ) const
571 {
572 assert( (codim >= 0) && (codim <= dimension) );
573 const IdType index = hIndexSet_.index( e );
574 return (index << 2) | IdType( codim );
575 }
576
578 IdType subId ( const typename Grid::template Codim< 0 >::Entity &e, int i, unsigned int subcodim ) const
579 {
580 assert( int( subcodim ) <= dimension );
581 const IdType index = hIndexSet_.subIndex( e, i, subcodim );
582 return (index << 2) | IdType( subcodim );
583 }
584
585 template< int codim >
586 IdType subId ( const typename Grid::template Codim< codim >::Entity &e, int i, unsigned int subcodim ) const
587 {
588 assert( (codim >= 0) && (codim <= dimension) && (int( codim + subcodim ) <= dimension) );
589 const IdType index = hIndexSet_.subIndex( e, i, subcodim );
590 return (index << 2) | IdType( codim + subcodim );
591 }
592
593 template< class Entity >
594 IdType subId ( const Entity &e, int i, unsigned int subcodim ) const
595 {
596 return subId< Entity::codimension >( e, i, subcodim );
597 }
598
599 private:
600 // prohibit copying
601 AlbertaGridIdSet ( const This & );
602
603 const HierarchicIndexSet &hIndexSet_;
604 };
605
606} // namespace Dune
607
608#endif // #if HAVE_ALBERTA
609
610#endif // #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
provides the GridFamily for AlbertaGrid
hierarchic index set of AlbertaGrid
Definition: indexsets.hh:537
IdType id(const typename Grid::template Codim< codim >::Entity &e) const
Definition: indexsets.hh:570
IdType id(const Entity &e) const
Definition: indexsets.hh:562
Base::IdType IdType
export type of id
Definition: indexsets.hh:545
IdType subId(const typename Grid::template Codim< 0 >::Entity &e, int i, unsigned int subcodim) const
Definition: indexsets.hh:578
Traits::HierarchicIndexSet HierarchicIndexSet
type of hierarchic index set
Definition: agrid.hh:157
Wrapper class for entities.
Definition: entity.hh:66
static constexpr int codimension
Know your own codimension.
Definition: entity.hh:106
Id Set Interface.
Definition: indexidset.hh:452
IdTypeImp IdType
Type used to represent an id.
Definition: indexidset.hh:458
auto size(GeometryType type) const
Return total number of entities of given geometry type in entity set .
Definition: indexidset.hh:223
IndexType subIndex(const Entity &e, int i, unsigned int codim) const
Map a subentity to an index.
Definition: indexidset.hh:182
IndexType subIndex(const typename Traits::template Codim< cc >::Entity &e, int i, unsigned int codim) const
Map a subentity to an index.
Definition: indexidset.hh:153
std::array< GeometryType, 1 > Types
iterator range for geometry types in domain
Definition: indexidset.hh:95
IndexType index(const typename Traits::template Codim< cc >::Entity &e) const
Map entity to index. The result of calling this method with an entity that is not in the index set is...
Definition: indexidset.hh:113
IndexType index(const Entity &e) const
Map entity to index. Easier to use than the above because codimension template parameter need not be ...
Definition: indexidset.hh:129
Definition: indexstack.hh:26
Different resources needed by all grid implementations.
provides a wrapper for ALBERTA's el_info structure
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:464
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:268
Provides base classes for index and id sets.
Provides an index stack that supplies indices for element numbering for a grid (i....
Dune namespace.
Definition: alignedallocator.hh:13
Standard Dune debug streams.
Static tag representing a codimension.
Definition: dimension.hh:24
static const ReferenceElement & simplex()
get simplex reference elements
Definition: referenceelements.hh:204
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)