DUNE-FEM (unstable)

genericadaptivedofmapper.hh
1#ifndef DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
2#define DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
3
5
7
8#include <dune/grid/utility/persistentcontainer.hh>
9
10#include <dune/fem/common/forloop.hh>
11#include <dune/fem/misc/capabilities.hh>
12#include <dune/fem/misc/metaprogramming.hh>
13#include <dune/fem/misc/functor.hh>
14#include <dune/fem/space/common/dofmanager.hh>
15#include <dune/fem/space/mapper/localkey.hh>
16#include <dune/fem/space/lagrange/lagrangepoints.hh>
17#include <dune/fem/space/mapper/dofmapper.hh>
18#include <dune/fem/space/mapper/codimensionmapper.hh>
19
20namespace Dune
21{
22
23 namespace Fem
24 {
25
26 // GenericAdaptiveDofMapper
27 // ------------------------
28
29 template< class TraitsImp >
30 class GenericAdaptiveDofMapper
31 : public AdaptiveDofMapper< TraitsImp >
32 {
33 typedef GenericAdaptiveDofMapper< TraitsImp > ThisType;
34 typedef AdaptiveDofMapper< TraitsImp > BaseType;
35
36 public:
37 typedef TraitsImp Traits;
38 typedef std::size_t SizeType;
39
40 // true if all dofs are associated with entities of codim 0
41 static const bool discontinuousMapper = Traits :: discontinuousMapper ;
42
43 protected:
44 using BaseType::asImp;
45
46 public:
48 typedef typename Traits::GridPartType GridPartType;
49
51 typedef typename Traits::ElementType ElementType;
52
54 typedef typename GridPartType::GridType GridType;
55
57 typedef typename GridPartType::IndexSetType IndexSetType;
58
60 typedef typename Traits :: GlobalKeyType GlobalKeyType ;
61
63 typedef typename GridType::ctype FieldType;
64
66 static const int dimension = GridType::dimension;
67
69 static const int highestDimension = ( discontinuousMapper ) ? 0 : dimension ;
70
72 static const int polynomialOrder = Traits::polynomialOrder;
73
75 static const PartitionIteratorType pitype = GridPartType :: indexSetPartitionType ;
76
78 typedef typename Traits :: CompiledLocalKeyVectorType CompiledLocalKeyVectorType;
79
81 typedef typename CompiledLocalKeyVectorType :: value_type :: value_type CompiledLocalKeyType;
82
84 typedef DofManager< GridType > DofManagerType;
85
86 enum { minOrder = 1, maxOrder = polynomialOrder, numOrders = maxOrder - minOrder + 1 };
87
88 struct EntityDofStorage
89 {
90 typedef std::vector< int > DofVectorType;
91 std::vector< DofVectorType > dofs_;
92
93 GeometryType type_;
94 char used_[ numOrders ];
95
96 EntityDofStorage() :
97 dofs_( numOrders, DofVectorType() ),
98 type_()
99 {
100 // set used to zero
101 for( int i=0; i<numOrders; ++i )
102 used_[ i ] = 0;
103 }
104
105 void assign( const EntityDofStorage& other )
106 {
107 assert( dofs_.size() == other.dofs_.size() );
108 type_ = other.type_;
109
110 // set used to zero
111 for( int k=0; k<numOrders; ++k )
112 {
113 used_[ k ] = other.used_[ k ];
114 DofVectorType& dofs = dofs_[ k ];
115 const DofVectorType& otherDofs = other.dofs_[ k ];
116 const int dofSize = otherDofs.size();
117 dofs.resize( dofSize );
118 for( int d = 0; d<dofSize; ++d )
119 dofs[ d ] = otherDofs[ d ];
120 }
121 }
122
123 EntityDofStorage( const EntityDofStorage& other )
124 : dofs_( numOrders )
125 {
126 assign( other );
127 }
128
129 EntityDofStorage& operator= ( const EntityDofStorage& other )
130 {
131 assign( other );
132 return *this;
133 }
134
135 bool exists( const int codim, const int polOrd ) const
136 {
137 const int entry = determineVectorEntry( codim, polOrd );
138 return dofs_[ entry ].size() > 0 ;
139 }
140
142 bool use( const int codim, const int polOrd )
143 {
144 const int entry = determineVectorEntry( codim, polOrd ) ;
145 ++used_[ entry ];
146 return ( used_[ entry ] == 1 );
147 }
148
149 void insert( const GeometryType type,
150 const int codim,
151 const int polOrd,
152 const int numDofs, const int startDof )
153 {
154 use( codim, polOrd );
155 assert( ! exists ( codim, polOrd ) );
156 {
157 type_ = type ;
158 DofVectorType& dofs = dofs_[ determineVectorEntry( codim, polOrd ) ];
159
160 dofs.resize( numDofs );
161 for(int i=0, dof=startDof ; i<numDofs; ++i, ++dof )
162 dofs[ i ] = dof;
163 }
164 }
165
166 int determineVectorEntry( const int codim, const int polOrd ) const
167 {
168 assert( codim >= 0 );
169 assert( codim <= highestDimension );
170 // also for codim == 0 we have more then
171 // one storage because of different number of
172 // dofs per polynmomial degree
173 return (codim < dimension) ? (polOrd-minOrder) : 0;
174 }
175
176 const GeometryType& type () const { return type_ ; }
177
178 void remove( const int codim, const int polOrd )
179 {
180 const int entry = determineVectorEntry( codim, polOrd );
181 if( used_[ entry ] > 0 )
182 --used_[ entry ] ;
183 }
184
185 void reset()
186 {
187 for( int k=0; k<numOrders; ++k )
188 used_[ k ] = 0;
189 }
190
191 int dof ( const int codim, const int polOrd, const size_t dofNumber ) const
192 {
193 const unsigned int entry = determineVectorEntry( codim, polOrd );
194 assert( entry < dofs_.size() );
195 assert( type_ != GeometryType() );
196 assert( dofNumber < dofs_[ entry ].size() );
197 return dofs_[ entry ][ dofNumber ];
198 }
199
200 int entityDof ( int dofNumber ) const
201 {
202 for( int k = 0; k<numOrders; ++k )
203 {
204 const int dofSize = dofs_[ k ].size();
205 if( dofNumber < dofSize )
206 return dofs_[ k ][ dofNumber ];
207 else
208 dofNumber -= dofSize;
209 }
210 // we should not get here
211 assert( false );
212 abort();
213 return -1;
214 }
215
216 int entityDofs () const
217 {
218 int dofSize = 0;
219 for( int k = 0; k<numOrders; ++k )
220 {
221 dofSize += dofs_[ k ].size();
222 }
223 return dofSize;
224 }
225
226 template <class VectorType>
227 void detectUnusedDofs( VectorType& isHole,
228 const int actSize )
229 {
230 for( int k=0; k<numOrders; ++k )
231 {
232 DofVectorType& dofs = dofs_[ k ];
233 const int dofSize = dofs.size();
234
235 if( dofSize > 0 )
236 {
237 if( used_[ k ] )
238 {
239 for( int d = 0; d<dofSize; ++d )
240 {
241 const int dof = dofs[ d ] ;
242 if( dof < actSize )
243 {
244 assert( dof < (int)isHole.size() );
245 isHole[ dof ] = false ;
246 }
247 }
248 }
249 else
250 {
251 dofs.resize( 0 );
252 }
253 }
254 }
255 }
256
257 void printDofs() const
258 {
259 for( int k = 0; k<numOrders; ++k )
260 {
261 const DofVectorType& dofs = dofs_[ k ];
262 const int dofSize = dofs.size();
263 for( int d = 0; d<dofSize; ++d )
264 std::cout << dofs[ d ] << " dofs " << std::endl;
265 }
266 }
267
268 template <class VectorType>
269 bool removeHoles( VectorType& oldIdx, VectorType& newIdx,
270 VectorType& holesVec, int& currentHole,
271 const int usedSize, int& holes )
272 {
273 bool haveToCopy = false ;
274 for( int k=0; k<numOrders; ++k )
275 {
276 DofVectorType& dofs = dofs_[ k ];
277 const int dofSize = dofs.size();
278 for( int dof = 0; dof<dofSize; ++dof )
279 {
280 assert( used_[ k ] );
281 // get global DoF number
282 int& currDof = dofs[ dof ] ;
283
284 // if dof >= usedSize it has to be migrated to a hole
285 if( currDof >= usedSize )
286 {
287 // serach next hole that is smaler than actual size
288 --currentHole;
289
290 // if currentHole < 0 then error, because we have index larger then
291 // actual size
292 assert(currentHole >= 0);
293 assert( holesVec[currentHole] < usedSize );
294
295 // remember old and new index
296 oldIdx[ holes ] = currDof;
297 currDof = holesVec[ currentHole ];
298 newIdx[ holes ] = currDof ;
299
300 // increase number of holes
301 ++holes;
302
303 haveToCopy = true;
304 }
305 }
306 }
307 return haveToCopy;
308 }
309 };
310
311 typedef EntityDofStorage EntityDofStorageType;
312
313 struct PolynomialOrderStorage
314 {
315 private:
316 // PolynomialOrderStorage() : k_( minOrder ), active_( -std::abs(k_) ) {}
317 signed char k_; // stores current polynomial order
318 signed char active_ ; // stores active/non-active and suggested pol order
319
320 public:
321 // PolynomialOrderStorage() : k_( minOrder ), active_( -std::abs(k_) ) {}
322 PolynomialOrderStorage( const int k ) : k_( k ), active_( -std::abs(k_) ) {}
323 int order () const { return k_; }
324 void suggest ( const int k )
325 {
326 if( active() )
327 active_ = std::abs( k );
328 else
329 active_ = -std::abs( k );
330 }
331 void set ( const int k ) { k_ = k; active_ = std::abs( k ) ; }
332 void activate() { active_ = std::abs( active_ ); }
333 bool active () const { return active_ > 0; }
334 bool deactivate ( int& k )
335 {
336 k = k_;
337 if( active() )
338 {
339 active_ = -active_;
340 return true ;
341 }
342 return false;
343 }
344
345 int suggested () const { return std::abs( active_ ); }
346 void update() { set( suggested() ); }
347 };
348
349 typedef PolynomialOrderStorage PolynomialOrderStorageType;
350
351 typedef PersistentContainer< GridType, EntityDofStorageType > DofContainerType ;
352
354 protected:
355 template <int codim, bool dg>
356 struct NumDofs
357 {
358 static int numDofs( const ElementType& entity,
359 const CompiledLocalKeyType& clk,
360 const int subEntity )
361 {
362 return clk.numDofs( codim, subEntity );
363 }
364 };
365
366 template <int codim>
367 struct NumDofs<codim, true>
368 {
369 static int numDofs( const ElementType& entity,
370 const CompiledLocalKeyType& clk,
371 const int subEntity )
372 {
373 if( codim == 0 )
374 return clk.size();
375 else
376 return 0;
377 }
378 };
379
380 template < int codim >
381 struct InsertSubEntities
382 {
383 static void insertDofs( const ElementType& entity,
384 const CompiledLocalKeyType& clk,
385 const int polOrd,
386 const int subEntity,
387 unsigned int& globalSize,
388 unsigned int& notAlreadyCounted,
389 EntityDofStorage& entityDofs )
390 {
391 const int numDofs = NumDofs<codim, discontinuousMapper>::numDofs( entity, clk, subEntity );
392
393 // only if dofs exists on this entity do something
394 if( numDofs > 0 )
395 {
396 bool notCountedYet = false ;
397 if( ! entityDofs.exists( codim, polOrd ) )
398 {
399 entityDofs.insert( entity.type(), codim, polOrd, numDofs, globalSize );
400 globalSize += numDofs;
401 notCountedYet = true ;
402 }
403 else
404 {
405 // if refcount is only 1 then true is returned
406 notCountedYet = entityDofs.use( codim, polOrd );
407 }
408
409 // if not counted yet, count !
410 if( notCountedYet )
411 {
412 notAlreadyCounted += numDofs;
413 }
414 }
415 }
416
417 static void apply( const ElementType& entity,
418 const CompiledLocalKeyType& clk,
419 const int polOrd,
420 unsigned int& globalSize,
421 unsigned int& notAlreadyCounted,
422 std::vector< DofContainerType* > dofContainers )
423 {
424 DofContainerType &dofContainer = *dofContainers[ codim ];
425 if( codim == 0 )
426 {
427 insertDofs( entity, clk, polOrd, 0, globalSize,
428 notAlreadyCounted, dofContainer[ entity ] );
429 }
430 else
431 {
432 const int count = entity.subEntities( codim );
433 for(int i=0; i<count; ++i )
434 {
435 insertDofs( entity, clk, polOrd, i, globalSize,
436 notAlreadyCounted, dofContainer( entity, i ) );
437 }
438 }
439 }
440 };
441
442 template < int codim >
443 struct RemoveSubEntities
444 {
445 static void apply( const ElementType& entity,
446 const int polOrd,
447 std::vector< DofContainerType* > dofContainers )
448 {
449 DofContainerType &dofContainer = *dofContainers[ codim ];
450 const int count = entity.subEntities( codim );
451 for(int i=0; i<count; ++i )
452 {
453 EntityDofStorage& entityDofs = dofContainer( entity, i );
454 entityDofs.remove( codim, polOrd );
455 }
456 }
457 };
458
459 public:
461 GenericAdaptiveDofMapper ( const GridPartType &gridPart,
462 const int order,
463 CompiledLocalKeyVectorType &compiledLocalKeyVector )
464 : gridPart_( gridPart ),
465 dm_( DofManagerType :: instance(gridPart.grid()) ),
466 compiledLocalKeys_( compiledLocalKeyVector ),
467 order_( ( order >= minOrder && order <= maxOrder ) ? order : maxOrder ),
468 entityPolynomOrder_( gridPart.grid(), 0, PolynomialOrderStorageType( order_ ) ),
469 dofContainer_( dimension+1, nullptr ),
470 numberOfHoles_( 0 ),
471 oldIndex_(),
472 newIndex_(),
473 size_(0),
474 maxNumDofs_( 0 ),
475 sequence_( dm_.sequence() )
476 {
477 for( int codim = 0; codim <= highestDimension; ++codim )
478 dofContainer_[ codim ] = new DofContainerType( gridPart.grid(), codim );
479
480 for( size_t i=0; i<compiledLocalKeys_.size(); ++i )
481 {
482 maxNumDofs_ = std :: max( maxNumDofs_, compiledLocalKeys_[ i ].maxSize() );
483 }
484
485 resize();
486 // register to DofManager for adaptation
487 dm_.addIndexSet( asImp() );
488 }
489
491 GenericAdaptiveDofMapper ( const GenericAdaptiveDofMapper& other,
492 const int order,
493 CompiledLocalKeyVectorType &compiledLocalKeyVector )
494 : gridPart_( other.gridPart_ ),
495 dm_( other.dm_ ),
496 compiledLocalKeys_( compiledLocalKeyVector ),
497 order_( ( order >= minOrder && order <= maxOrder ) ? order : maxOrder ),
498 entityPolynomOrder_( other.entityPolynomOrder_ ),
499 dofContainer_( dimension+1, nullptr ),
500 numberOfHoles_( other.numberOfHoles_ ),
501 oldIndex_( other.oldIndex_ ),
502 newIndex_( other.newIndex_ ),
503 size_( other.size_ ),
504 maxNumDofs_( other.maxNumDofs_ ),
505 sequence_( other.sequence_ )
506 {
507 for( int codim = 0; codim <= highestDimension; ++codim )
508 dofContainer_[ codim ] = new DofContainerType( *(other.dofContainer_[ codim ]) );
509
510 dm_.addIndexSet( asImp() );
511 }
512
513 int polynomOrder( const ElementType& entity ) const
514 {
515 return entityPolynomOrder_[ entity ].order();
516 }
517
518 int suggestedOrder( const ElementType& entity ) const
519 {
520 return entityPolynomOrder_[ entity ].suggestedOrder();
521 }
522
523 void suggestPolynomOrder( const ElementType& entity, const int polOrd )
524 {
525 // minOrder is static but order_ is dynamically set
526 if( polOrd < minOrder || polOrd > order_ )
527 return ;
528
529 entityPolynomOrder_[ entity ].suggest( polOrd );
530 }
531
532 DofContainerType &dofContainer ( const std::size_t codim ) const
533 {
534 assert( codim < dofContainer_.size() );
535 assert( dofContainer_[ codim ] );
536 return *(dofContainer_[ codim ]);
537 }
538
539 const CompiledLocalKeyType&
540 compiledLocalKey( const int polOrd, const GeometryType type ) const
541 {
542 // add polOrd here
543 return compiledLocalKeys_[ polOrd ][ type ];
544 }
545
547 virtual ~GenericAdaptiveDofMapper ()
548 {
549 dm_.removeIndexSet( asImp() );
550 }
551
553 int size () const
554 {
555 return size_;
556 }
557
558 template< class Functor >
559 void mapEach ( const ElementType &element, Functor f ) const
560 {
561 const int n = numDofs( element );
562 for( int i = 0; i < n; ++i )
563 f( i, mapToGlobal( element, i ) );
564 }
565
567 int mapToGlobal ( const ElementType &entity, const int localDof ) const
568 {
569 if( discontinuousMapper )
570 {
571 // get polynomial order
572 const int polOrd = polynomOrder( entity );
573
574 // return global dof
575 return dofContainer( 0 )[ entity ].dof( 0, polOrd, localDof );
576 }
577 else
578 {
579 // the continuous case
580 const int polOrd = polynomOrder( entity );
581
582 const CompiledLocalKeyType& compLocalKey = compiledLocalKey( polOrd, entity.type() );
583 // get dof info for entity and local dof
584 const Fem::LocalKey &dofInfo = compLocalKey.localKey( localDof );
585
586 const unsigned int codim = dofInfo.codim();
587 const unsigned int subEntity = dofInfo.subEntity();
588
589 unsigned int index = dofInfo.index() ;
590
591 // account for possible twists in the grid (only 2d)
592 if( dimension == 2 && codim == 1 )
593 {
594 auto refElem = referenceElement< FieldType, dimension >( entity.type() );
595
596#ifndef NDEBUG
597 const int vxSize = refElem.size( subEntity, codim, dimension );
598 // two vertices per edge in 2d
599 assert( vxSize == 2 );
600#endif
601 const int vx[ 2 ] = { refElem.subEntity ( subEntity, codim, 0, dimension ),
602 refElem.subEntity ( subEntity, codim, 1, dimension ) };
603
604 // flip index if face is twisted
605 if( gridPart_.grid().localIdSet().subId( entity, vx[ 0 ], dimension ) >
606 gridPart_.grid().localIdSet().subId( entity, vx[ 1 ], dimension ) )
607 {
608 const unsigned int numDofsSubEntity = compLocalKey.numDofs( codim, subEntity );
609 index = numDofsSubEntity - index - 1;
610 }
611 }
612
613 assert( index < compLocalKey.numDofs( codim, subEntity ) );
614 return dofContainer( codim )( entity, subEntity ).dof( codim, polOrd, index );
615 }
616 }
617
619 template< class Entity, class Functor >
620 void mapEachEntityDof ( const Entity &entity, Functor f ) const
621 {
622 const int n = numEntityDofs( entity );
623 for( int i = 0; i < n; ++i )
624 f( i, dofContainer( Entity::codimension )[ entity ].entityDof( i ) );
625 }
626
627 [[deprecated("Use onSubEntity method with char vector instead")]]
628 void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const
629 {
630 std::vector< char > _idx;
631 onSubEntity(element, i, c, _idx);
632 indices.resize( _idx.size() );
633 for (std::size_t i=0; i<_idx.size();++i)
634 _idx[i] = indices[i] > 0;
635 }
636 // this method returns which local dofs are attached to the given subentity.
637 // indices[locDofNr] =
638 // 0 : not attached, not equal to 0 : attached
639 // (so this method can still be used in the way the deprecated method was).
640 // New: In case the dof can be associated to a component of the
641 // space, the value returned is that component+1. In other
642 // cases (normal velocity for RT for example) the value is -1).
643 // So indices[i] is in [-1,dimRange+1]
644 void onSubEntity ( const ElementType &element, int i, int c, std::vector< char > &indices ) const
645 {
646 indices.resize( numDofs(element) );
647 if( discontinuousMapper )
648 {
649 if (c == 0)
650 std::fill(indices.begin(),indices.end(),1);
651 else
652 std::fill(indices.begin(),indices.end(),0);
653 }
654 else
655 {
656 DUNE_THROW( NotImplemented, "Method onSubEntity(...) not yet implemented for continuous mappers" );
657 }
658 }
659
660 void map ( const ElementType &element, std::vector< SizeType > &indices ) const
661 {
662 indices.resize( numDofs( element ) );
663 mapEach( element, AssignFunctor< std::vector< SizeType > >( indices ) );
664 }
665
666 template< class Entity >
667 void mapEntityDofs ( const Entity &entity, std::vector< SizeType > &indices ) const
668 {
669 indices.resize( numEntityDofs( entity ) );
670 mapEachEntityDof( entity, AssignFunctor< std::vector< SizeType > >( indices ) );
671 }
672
674 int maxNumDofs () const
675 {
676 return maxNumDofs_;
677 }
678
680 int numDofs ( const ElementType &entity ) const
681 {
682 const int polOrd = polynomOrder( entity );
683 return compiledLocalKey( polOrd, entity.type() ).size();
684 }
685
687 template< class Entity >
688 int numEntityDofs ( const Entity &entity ) const
689 {
690 if( discontinuousMapper )
691 {
692 if( Entity :: codimension == 0 )
693 return dofContainer( 0 )[ entity ].entityDofs();
694 else
695 return 0;
696 }
697 else
698 {
699 // !!! to be revised
700 // This implementation only works for nonhybrid grids (simplices or cubes)
701 return dofContainer( Entity :: codimension )[ entity ].entityDofs();
702 }
703 }
704
706 bool contains ( int codim ) const
707 {
708 return (discontinuousMapper) ? (codim == 0) : true;
709 }
710
712 bool fixedDataSize ( int codim ) const
713 {
714 return false;
715 }
716
718 int oldIndex ( const int hole, const int block ) const
719 {
720 assert( oldIndex_[ hole ] >= 0 );
721 return oldIndex_[ hole ];
722 }
723
725 int newIndex ( const int hole, const int block ) const
726 {
727 assert( newIndex_[ hole ] >= 0 );
728 return newIndex_[ hole ];
729 }
730
732 int numberOfHoles ( const int block ) const
733 {
734 return numberOfHoles_;
735 }
736
739 int numBlocks () const
740 {
741 return 1;
742 }
743
746 int oldOffSet ( const int block ) const
747 {
748 return 0;
749 }
750
753 int offSet ( const int block ) const
754 {
755 return 0;
756 }
757
759 bool consecutive () const
760 {
761 return true;
762 }
763
764 // Adaptation Methods (as for Index Sets)
765 void resizeContainers()
766 {
767 entityPolynomOrder_.resize( PolynomialOrderStorageType( order_ ) );
768 entityPolynomOrder_.shrinkToFit();
769 for( int codim = 0; codim <= highestDimension; ++codim )
770 {
771 dofContainer( codim ).resize();
772 dofContainer( codim ).shrinkToFit();
773 }
774 }
775
776 void insertEntity ( const ElementType &entity )
777 {
778 resizeContainers();
779 insertEntityDofs( entity );
780 }
781
782 // return number of local dofs that were not visited yet
783 unsigned int insertEntityDofs( const ElementType &entity )
784 {
785 PolynomialOrderStorageType& polyStorage = entityPolynomOrder_[ entity ];
786 if( ! polyStorage.active() )
787 {
788 unsigned int notAlreadyCounted = 0;
789
790 const int polOrd = polyStorage.order();
791 // get lagrange point set
792 const CompiledLocalKeyType& clk = compiledLocalKey( polOrd, entity.type() );
793
794 //std::cout << "Insert Entity " << gridPart_.grid().localIdSet().id( entity ) << std::endl;
795
796 // activate dofs for this entity
797 polyStorage.activate();
798
799 // insert for all sub entities
800 Fem::ForLoop< InsertSubEntities, 0, highestDimension>::
801 apply( entity, clk, polOrd, size_, notAlreadyCounted, dofContainer_ );
802
803 //printEntityDofs( entity );
804 return notAlreadyCounted ;
805 }
806
807 return 0;
808 }
809
810 void removeEntity ( const ElementType &entity )
811 {
812 int polOrd;
813 // polOrd ist set on call of deactivate
814 if( entityPolynomOrder_[ entity ].deactivate( polOrd ) )
815 {
816 Fem::ForLoop< RemoveSubEntities, 0, highestDimension>::
817 apply( entity, polOrd, dofContainer_ );
818 }
819 }
820
821 void resize ()
822 {
823 resizeContainers();
824 insertAllUsed();
825 }
826
828 void adapt()
829 {
830 // set new polynomial orders for entities
831 for( auto& pol : entityPolynomOrder_ )
832 pol.update();
833
834 sequence_ = -1;
835 compress();
836 }
837
838 // insert father element when conforming refinement is enabled
839 // (due to refinement of more than one level)
840 unsigned int insertFather( const ElementType &entity )
841 {
842 if( entity.hasFather() )
843 {
844 // if father is a new element, insert it
845 ElementType dad = entity.father();
846 if( dad.isNew() )
847 {
848 unsigned int usedSize = insertEntityDofs( dad );
849 // also insert dad's fathers
850 usedSize += insertFather( dad );
851 return usedSize;
852 }
853 }
854 return 0;
855 }
856
858 bool considerHierarchy () const
859 {
862 }
863
865 size_t insertAllUsed()
866 {
867 // reset all dof entries
868 setUnused();
869
870 // count current size
871 size_t usedSize = 0;
872
873 const bool considerHierarchyOfElements = considerHierarchy();
874
875 // pitype is determined by the GridPart, see above
876 const auto end = gridPart_.template end<0, pitype>();
877 for( auto it = gridPart_.template begin<0, pitype>();
878 it != end ; ++it )
879 {
880 const ElementType &element = *it;
881 if( considerHierarchyOfElements )
882 {
883 // insert father elements (conforming and hybrid grids only)
884 usedSize += insertFather( element );
885 }
886
887 // number of new dofs (not already counted) is returned
888 usedSize += insertEntityDofs( element );
889 }
890
891 //std::cout << "Insert Size = " << size_ << std::endl;
892 //printDofs();
893 //std::cout << "Insert done! " << std::endl;
894 return usedSize ;
895 }
896
897 void printDofs() const
898 {
899 //std::cout << "Size " << size_ << std::endl;
900 typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType;
901 const IteratorType end = gridPart_.template end<0>();
902 for( IteratorType it = gridPart_.template begin<0>();
903 it != end ; ++it )
904 {
905 printEntityDofs( *it );
906 }
907 }
908
909 void printEntityDofs( const ElementType& entity ) const
910 {
911 std::cout << "Print entity " << gridPart_.grid().localIdSet().id( entity ) << " with " << std::endl;
912 for( int i = 0; i<numDofs( entity ); ++i )
913 {
914 std::cout << "en[ " << i << " ] = " << mapToGlobal( entity, i ) << std::endl;
915 }
916 }
917
919 void setUnused()
920 {
921 // deactivate all entries in the polynomial order container
922 {
923 typedef typename PolyOrderContainerType :: Iterator Iterator;
924 const Iterator endit = entityPolynomOrder_.end();
925 for( Iterator it = entityPolynomOrder_.begin(); it != endit; ++it )
926 {
927 PolynomialOrderStorageType& p = *it;
928 int pOrd;
929 p.deactivate( pOrd );
930 }
931 }
932
933 for( int codim = 0; codim <= highestDimension; ++codim )
934 {
935 DofContainerType& codimContainer = dofContainer( codim );
936 typedef typename DofContainerType :: Iterator Iterator;
937 const Iterator endit = codimContainer.end();
938 for( Iterator it = codimContainer.begin(); it != endit; ++it )
939 {
940 it->reset();
941 }
942 }
943 }
944
945 // --compress
946 bool compress ()
947 {
948 if( sequence_ == dm_.sequence() )
949 {
950 numberOfHoles_ = 0;
951 return false ;
952 }
953
954 // adjust size of containers
955 resizeContainers();
956
957 // make all dofs that are currently used
958 // (corresponding to GridPart's iterator)
959 const size_t usedSize = insertAllUsed();
960
961 //std::cout << "Size " << size_ << " holes " << numberOfHoles_ << std::endl;
962 //printDofs();
963
964 // reset number of holes
965 numberOfHoles_ = 0;
966
967 // true if a least one dof must be copied
968 bool haveToCopy = false;
969
970 std::vector<int> validHoles;
971
972 {
973 // default is true which means entry is hole
974 std::vector< bool > holeMarker( size_, true );
975
976 // mark holes
977 for( int codim = 0; codim <= highestDimension; ++codim )
978 {
979 DofContainerType& codimContainer = dofContainer( codim );
980 typedef typename DofContainerType :: Iterator Iterator;
981 const Iterator endit = codimContainer.end();
982 for( Iterator it = codimContainer.begin(); it != endit; ++it )
983 {
984 EntityDofStorageType& dof = *it;
985 // store holes if unused dofs exits, otherwise increase actSize
986 dof.detectUnusedDofs( holeMarker, usedSize );
987 }
988 }
989
990 // check for real holes
991 validHoles.reserve( usedSize );
992 validHoles.resize( 0 );
993
994 // check the vector of hole flags and store numbers
995 for( size_t i=0; i<usedSize; ++i )
996 {
997 // it's only a valid hole, if it was not marked otherwise
998 if( holeMarker[ i ] )
999 {
1000 //std::cout << "Dof number " << i << " is not used" << std::endl;
1001 validHoles.push_back( i );
1002 }
1003 }
1004 }
1005
1006 if( validHoles.size() > 0 )
1007 {
1008 // counter for current hole to use
1009 int currentHole = validHoles.size();
1010
1011 // resize old-new index storage to correct size
1012 oldIndex_.resize( currentHole, -1) ;
1013 newIndex_.resize( currentHole, -1) ;
1014
1015 for( int codim = 0; codim <= highestDimension; ++codim )
1016 {
1017 DofContainerType& codimContainer = dofContainer( codim );
1018 typedef typename DofContainerType :: Iterator Iterator;
1019 const Iterator endit = codimContainer.end();
1020 for( Iterator it = codimContainer.begin(); it != endit; ++it )
1021 {
1022 // get dof storage
1023 EntityDofStorageType& dof = *it;
1024
1025 // replace DoF larger than size with DoF from holes
1026 // set haveToCopy to true if true is returned
1027 haveToCopy |= dof.removeHoles( oldIndex_, newIndex_,
1028 validHoles, currentHole,
1029 usedSize, numberOfHoles_ );
1030 }
1031 }
1032 }
1033
1034 // store new size
1035 size_ = usedSize ;
1036
1037 //std::cout << "Size " << size_ << " holes " << numberOfHoles_ << std::endl;
1038 //printDofs();
1039
1040 sequence_ = dm_.sequence();
1041
1042 return haveToCopy;
1043 }
1044
1045 void backup () const
1046 {}
1047
1048 void restore ()
1049 {}
1050
1051 template< class InStream >
1052 void read ( InStream &in )
1053 {}
1054
1055 template< class OutStream >
1056 void write ( OutStream &out )
1057 {}
1058
1059 GenericAdaptiveDofMapper ( const ThisType& ) = delete;
1060 ThisType& operator=( const ThisType& ) = delete;
1061
1062 private:
1063
1064 const GridPartType& gridPart_;
1065 // reference to dof manager
1066 DofManagerType& dm_;
1067
1068 CompiledLocalKeyVectorType &compiledLocalKeys_;
1069
1070 // default polynomial order to be set to newly inserted elements
1071 const int order_;
1072
1073 PolyOrderContainerType entityPolynomOrder_;
1074
1075 mutable std::vector< DofContainerType* > dofContainer_;
1076
1077 int numberOfHoles_ ;
1078 std::vector< int > oldIndex_ ;
1079 std::vector< int > newIndex_ ;
1080
1081 mutable unsigned int size_;
1082 unsigned int maxNumDofs_;
1083 int sequence_ ;
1084 }; // class GenericAdaptiveDofMapper
1085
1086
1087 namespace Capabilities
1088 {
1089 // isConsecutiveIndexSet
1090 // ---------------------
1091
1092 template< class Traits >
1093 struct isConsecutiveIndexSet< GenericAdaptiveDofMapper< Traits > >
1094 {
1095 static const bool v = true;
1096 };
1097
1098 template< class Traits >
1099 struct isAdaptiveDofMapper< GenericAdaptiveDofMapper< Traits > >
1100 {
1101 static const bool v = true;
1102 };
1103
1104 } // namespace Capabilities
1105
1106 } // namespace Fem
1107
1108} // namespace Dune
1109
1110#endif // #ifndef DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
static constexpr int codimension
Know your own codimension.
Definition: entity.hh:106
consecutive, persistent index set for the leaf level based on the grid's hierarchy index set
Definition: adaptiveleafindexset.hh:1351
A few common exception classes.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
PartitionIteratorType
Parameter to be used for the parallel level- and leaf iterators.
Definition: gridenums.hh:136
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137
STL namespace.
Specialize with 'true' for if the codimension 0 entity of the grid has only one possible geometry typ...
Definition: capabilities.hh:27
static int refineStepsForHalf()
number of globalRefine steps needed to refuce h by 0.5
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 13, 23:29, 2024)