dune-fem  2.4.1-rc
genericadaptivedofmapper.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
2 #define DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
3 
4 #include <dune/common/exceptions.hh>
5 #include <dune/common/nullptr.hh>
6 
7 #include <dune/geometry/type.hh>
8 
9 #include <dune/grid/utility/persistentcontainer.hh>
10 
12 #include <dune/fem/misc/metaprogramming.hh>
18 
19 namespace Dune
20 {
21 
22  namespace Fem
23  {
24 
25  // GenericAdaptiveDofMapper
26  // ------------------------
27 
28  template< class TraitsImp >
30  : public AdaptiveDofMapper< TraitsImp >
31  {
34 
35  public:
36  typedef TraitsImp Traits;
37 
38  // true if all dofs are associated with entities of codim 0
39  static const bool discontinuousMapper = Traits :: discontinuousMapper ;
40 
41  protected:
42  using BaseType::asImp;
43 
44  public:
47 
49  typedef typename Traits::ElementType ElementType;
50 
52  typedef typename GridPartType::GridType GridType;
53 
55  typedef typename GridPartType::IndexSetType IndexSetType;
56 
59 
61  typedef typename GridType::ctype FieldType;
62 
64  static const int dimension = GridType::dimension;
65 
67  static const int highestDimension = ( discontinuousMapper ) ? 0 : dimension ;
68 
70  static const int polynomialOrder = Traits::polynomialOrder;
71 
74 
76  typedef typename CompiledLocalKeyVectorType :: value_type :: value_type CompiledLocalKeyType;
77 
80 
81  enum { minOrder = 1 };
82  enum { maxOrder = polynomialOrder };
83  enum { numOrders = maxOrder - minOrder + 1 };
84 
86  {
87  typedef std::vector< int > DofVectorType;
88  std::vector< DofVectorType > dofs_;
89 
90  GeometryType type_;
91  char used_[ numOrders ];
92 
94  dofs_( numOrders, DofVectorType() ),
95  type_()
96  {
97  // set used to zero
98  for( int i=0; i<numOrders; ++i )
99  used_[ i ] = 0;
100  }
101 
102  void assign( const EntityDofStorage& other )
103  {
104  assert( dofs_.size() == other.dofs_.size() );
105  type_ = other.type_;
106 
107  // set used to zero
108  for( int k=0; k<numOrders; ++k )
109  {
110  used_[ k ] = other.used_[ k ];
111  DofVectorType& dofs = dofs_[ k ];
112  const DofVectorType& otherDofs = other.dofs_[ k ];
113  const int dofSize = otherDofs.size();
114  dofs.resize( dofSize );
115  for( int d = 0; d<dofSize; ++d )
116  dofs[ d ] = otherDofs[ d ];
117  }
118  }
119 
121  : dofs_( numOrders )
122  {
123  assign( other );
124  }
125 
127  {
128  assign( other );
129  return *this;
130  }
131 
132  bool exists( const int codim, const int polOrd ) const
133  {
134  const int entry = determineVectorEntry( codim, polOrd );
135  return dofs_[ entry ].size() > 0 ;
136  }
137 
139  bool use( const int codim, const int polOrd )
140  {
141  const int entry = determineVectorEntry( codim, polOrd ) ;
142  ++used_[ entry ];
143  return ( used_[ entry ] == 1 );
144  }
145 
146  void insert( const GeometryType type,
147  const int codim,
148  const int polOrd,
149  const int numDofs, const int startDof )
150  {
151  use( codim, polOrd );
152  assert( ! exists ( codim, polOrd ) );
153  {
154  type_ = type ;
155  DofVectorType& dofs = dofs_[ determineVectorEntry( codim, polOrd ) ];
156 
157  dofs.resize( numDofs );
158  for(int i=0, dof=startDof ; i<numDofs; ++i, ++dof )
159  dofs[ i ] = dof;
160  }
161  }
162 
163  int determineVectorEntry( const int codim, const int polOrd ) const
164  {
165  assert( codim >= 0 );
166  assert( codim <= highestDimension );
167  // also for codim == 0 we have more then
168  // one storage because of different number of
169  // dofs per polynmomial degree
170  return (codim < dimension) ? (polOrd-minOrder) : 0;
171  }
172 
173  const GeometryType& type () const { return type_ ; }
174 
175  void remove( const int codim, const int polOrd )
176  {
177  const int entry = determineVectorEntry( codim, polOrd );
178  if( used_[ entry ] > 0 )
179  --used_[ entry ] ;
180  }
181 
182  void reset()
183  {
184  for( int k=0; k<numOrders; ++k )
185  used_[ k ] = 0;
186  }
187 
188  int dof ( const int codim, const int polOrd, const size_t dofNumber ) const
189  {
190  const unsigned int entry = determineVectorEntry( codim, polOrd );
191  assert( entry < dofs_.size() );
192  assert( type_ != GeometryType() );
193  assert( dofNumber < dofs_[ entry ].size() );
194  return dofs_[ entry ][ dofNumber ];
195  }
196 
197  int entityDof ( int dofNumber ) const
198  {
199  for( int k = 0; k<numOrders; ++k )
200  {
201  const int dofSize = dofs_[ k ].size();
202  if( dofNumber < dofSize )
203  return dofs_[ k ][ dofNumber ];
204  else
205  dofNumber -= dofSize;
206  }
207  // we should not get here
208  assert( false );
209  abort();
210  return -1;
211  }
212 
213  int entityDofs () const
214  {
215  int dofSize = 0;
216  for( int k = 0; k<numOrders; ++k )
217  {
218  dofSize += dofs_[ k ].size();
219  }
220  return dofSize;
221  }
222 
223  template <class VectorType>
224  void detectUnusedDofs( VectorType& isHole,
225  const int actSize )
226  {
227  for( int k=0; k<numOrders; ++k )
228  {
229  DofVectorType& dofs = dofs_[ k ];
230  const int dofSize = dofs.size();
231 
232  if( dofSize > 0 )
233  {
234  if( used_[ k ] )
235  {
236  for( int d = 0; d<dofSize; ++d )
237  {
238  const int dof = dofs[ d ] ;
239  if( dof < actSize )
240  {
241  assert( dof < (int)isHole.size() );
242  isHole[ dof ] = false ;
243  }
244  }
245  }
246  else
247  {
248  dofs.resize( 0 );
249  }
250  }
251  }
252  }
253 
254  void printDofs() const
255  {
256  for( int k = 0; k<numOrders; ++k )
257  {
258  const DofVectorType& dofs = dofs_[ k ];
259  const int dofSize = dofs.size();
260  for( int d = 0; d<dofSize; ++d )
261  std::cout << dofs[ d ] << " dofs " << std::endl;
262  }
263  }
264 
265  template <class VectorType>
266  bool removeHoles( VectorType& oldIdx, VectorType& newIdx,
267  VectorType& holesVec, int& currentHole,
268  const int usedSize, int& holes )
269  {
270  bool haveToCopy = false ;
271  for( int k=0; k<numOrders; ++k )
272  {
273  DofVectorType& dofs = dofs_[ k ];
274  const int dofSize = dofs.size();
275  for( int dof = 0; dof<dofSize; ++dof )
276  {
277  assert( used_[ k ] );
278  // get global DoF number
279  int& currDof = dofs[ dof ] ;
280 
281  // if dof >= usedSize it has to be migrated to a hole
282  if( currDof >= usedSize )
283  {
284  // serach next hole that is smaler than actual size
285  --currentHole;
286 
287  // if currentHole < 0 then error, because we have index larger then
288  // actual size
289  assert(currentHole >= 0);
290  assert( holesVec[currentHole] < usedSize );
291 
292  // remember old and new index
293  oldIdx[ holes ] = currDof;
294  currDof = holesVec[ currentHole ];
295  newIdx[ holes ] = currDof ;
296 
297  // increase number of holes
298  ++holes;
299 
300  haveToCopy = true;
301  }
302  }
303  }
304  return haveToCopy;
305  }
306  };
307 
309 
311  {
312  unsigned char k_;
313  unsigned char active_ ;
314  PolynomOrderStorage() : k_( maxOrder ), active_( 0 ) {}
315  PolynomOrderStorage( const int k ) : k_( k ), active_( 0 ) {}
316  int order () const { return k_;}
317  void set ( const int k ) { k_ = k; active_ = 1 ; }
318  void activate() { active_ = 1; }
319  bool active () const { return active_; }
320  bool deactivate ( int& k )
321  {
322  k = k_;
323  if( active_ )
324  {
325  active_ = 0 ;
326  return true ;
327  }
328  return false;
329  }
330  };
331 
332  typedef PolynomOrderStorage PolynomOrderStorageType;
333 
334  typedef PersistentContainer< GridType, EntityDofStorageType > DofContainerType ;
335 
336  typedef PersistentContainer< GridType, PolynomOrderStorageType > PolyOrderContainerType ;
337  protected:
338  template <int codim, bool dg>
339  struct NumDofs
340  {
341  static int numDofs( const ElementType& entity,
342  const CompiledLocalKeyType& clk,
343  const int subEntity )
344  {
345  return clk.numDofs( codim, subEntity );
346  }
347  };
348 
349  template <int codim>
350  struct NumDofs<codim, true>
351  {
352  static int numDofs( const ElementType& entity,
353  const CompiledLocalKeyType& clk,
354  const int subEntity )
355  {
356  if( codim == 0 )
357  return clk.size();
358  else
359  return 0;
360  }
361  };
362 
363  template < int codim >
365  {
366  static void insertDofs( const ElementType& entity,
367  const CompiledLocalKeyType& clk,
368  const int polOrd,
369  const int subEntity,
370  unsigned int& globalSize,
371  unsigned int& notAlreadyCounted,
373  {
374  const int numDofs = NumDofs<codim, discontinuousMapper>::numDofs( entity, clk, subEntity );
375 
376  // only if dofs exists on this entity do something
377  if( numDofs > 0 )
378  {
379  bool notCountedYet = false ;
380  if( ! entityDofs.exists( codim, polOrd ) )
381  {
382  entityDofs.insert( entity.type(), codim, polOrd, numDofs, globalSize );
383  globalSize += numDofs;
384  notCountedYet = true ;
385  }
386  else
387  {
388  // if refcount is only 1 then true is returned
389  notCountedYet = entityDofs.use( codim, polOrd );
390  }
391 
392  // if not counted yet, count !
393  if( notCountedYet )
394  {
395  notAlreadyCounted += numDofs;
396  }
397  }
398  }
399 
400  static void apply( const ElementType& entity,
401  const CompiledLocalKeyType& clk,
402  const int polOrd,
403  unsigned int& globalSize,
404  unsigned int& notAlreadyCounted,
405  std::vector< DofContainerType* > dofContainers )
406  {
407  DofContainerType &dofContainer = *dofContainers[ codim ];
408  if( codim == 0 )
409  {
410  insertDofs( entity, clk, polOrd, 0, globalSize,
411  notAlreadyCounted, dofContainer[ entity ] );
412  }
413  else
414  {
415  const int count = entity.subEntities( codim );
416  for(int i=0; i<count; ++i )
417  {
418  insertDofs( entity, clk, polOrd, i, globalSize,
419  notAlreadyCounted, dofContainer( entity, i ) );
420  }
421  }
422  }
423  };
424 
425  template < int codim >
427  {
428  static void apply( const ElementType& entity,
429  const int polOrd,
430  std::vector< DofContainerType* > dofContainers )
431  {
432  DofContainerType &dofContainer = *dofContainers[ codim ];
433  const int count = entity.subEntities( codim );
434  for(int i=0; i<count; ++i )
435  {
436  EntityDofStorage& entityDofs = dofContainer( entity, i );
437  entityDofs.remove( codim, polOrd );
438  }
439  }
440  };
441 
442  public:
444  GenericAdaptiveDofMapper ( const GridPartType &gridPart,
445  CompiledLocalKeyVectorType &compiledLocalKeyVector )
446  : gridPart_( gridPart ),
447  dm_( DofManagerType :: instance(gridPart.grid()) ),
448  compiledLocalKeys_( compiledLocalKeyVector ),
449  entityPolynomOrder_( gridPart.grid(), 0 ),
450  dofContainer_( dimension+1, nullptr ),
451  numberOfHoles_( 0 ),
452  oldIndex_(),
453  newIndex_(),
454  size_(0),
455  maxNumDofs_( 0 ),
456  sequence_( dm_.sequence() )
457  {
458  /*
459  PolynomOrderStorage p;
460  std::cout << sizeof( p ) << " size of polStorage" << std::endl;
461  EntityDofStorage en;
462  std::cout << sizeof( en ) << " size of enStorage" << std::endl;
463  GeometryType type;
464  std::cout << sizeof( type) << " size of GeomType " << std::endl;
465  */
466 
467  for( int codim = 0; codim <= highestDimension; ++codim )
468  dofContainer_[ codim ] = new DofContainerType( gridPart.grid(), codim );
469 
470  for( size_t i=0; i<compiledLocalKeys_.size(); ++i )
471  {
472  maxNumDofs_ = std :: max( maxNumDofs_, compiledLocalKeys_[ i ].maxSize() );
473  }
474 
475  resize();
476  // register to DofManager for adaptation
477  dm_.addIndexSet( asImp() );
478  }
479 
482  CompiledLocalKeyVectorType &compiledLocalKeyVector )
483  : gridPart_( other.gridPart_ ),
484  dm_( other.dm_ ),
485  compiledLocalKeys_( compiledLocalKeyVector ),
486  entityPolynomOrder_( other.entityPolynomOrder_ ),
487  dofContainer_( dimension+1, nullptr ),
488  numberOfHoles_( other.numberOfHoles_ ),
489  oldIndex_( other.oldIndex_ ),
490  newIndex_( other.newIndex_ ),
491  size_( other.size_ ),
492  maxNumDofs_( other.maxNumDofs_ ),
493  sequence_( other.sequence_ )
494  {
495  for( int codim = 0; codim <= highestDimension; ++codim )
496  dofContainer_[ codim ] = new DofContainerType( *(other.dofContainer_[ codim ]) );
497 
498  dm_.addIndexSet( asImp() );
499  }
500 
501  int polynomOrder( const ElementType& entity ) const
502  {
503  return entityPolynomOrder_[ entity ].order();
504  }
505 
506  void setPolynomOrder( const ElementType& entity, const int polOrd )
507  {
508  if( polOrd < 1 || polOrd > polynomialOrder )
509  return ;
510 
511  entityPolynomOrder_[ entity ].set( polOrd );
512  }
513 
514  DofContainerType &dofContainer ( const std::size_t codim ) const
515  {
516  assert( codim < dofContainer_.size() );
517  assert( dofContainer_[ codim ] );
518  return *(dofContainer_[ codim ]);
519  }
520 
521  const CompiledLocalKeyType&
522  compiledLocalKey( const int polOrd, const GeometryType type ) const
523  {
524  // add polOrd here
525  return compiledLocalKeys_[ polOrd ][ type ];
526  }
527 
530  {
531  dm_.removeIndexSet( asImp() );
532  }
533 
535  int size () const
536  {
537  return size_;
538  }
539 
540  template< class Functor >
541  void mapEach ( const ElementType &element, Functor f ) const
542  {
543  const int n = numDofs( element );
544  for( int i = 0; i < n; ++i )
545  f( i, mapToGlobal( element, i ) );
546  }
547 
549  int mapToGlobal ( const ElementType &entity, const int localDof ) const
550  {
551  if( discontinuousMapper )
552  {
553  // get polynomial order
554  const int polOrd = polynomOrder( entity );
555 
556  // return global dof
557  return dofContainer( 0 )[ entity ].dof( 0, polOrd, localDof );
558  }
559  else
560  {
561  // the continuous case
562  const int polOrd = polynomOrder( entity );
563 
564  const CompiledLocalKeyType& compLocalKey = compiledLocalKey( polOrd, entity.type() );
565  // get dof info for entity and local dof
566  const Fem::LocalKey &dofInfo = compLocalKey.localKey( localDof );
567 
568  const unsigned int codim = dofInfo.codim();
569  const unsigned int subEntity = dofInfo.subEntity();
570 
571  unsigned int index = dofInfo.index() ;
572 
573  // account for possible twists in the grid (only 2d)
574  if( dimension == 2 && codim == 1 )
575  {
576  const Dune::ReferenceElement< FieldType, dimension > &refElem
577  = Dune::ReferenceElements< FieldType, dimension >::general( entity.type() );
578 
579 #ifndef NDEBUG
580  const int vxSize = refElem.size( subEntity, codim, dimension );
581  // two vertices per edge in 2d
582  assert( vxSize == 2 );
583 #endif
584  const int vx[ 2 ] = { refElem.subEntity ( subEntity, codim, 0, dimension ),
585  refElem.subEntity ( subEntity, codim, 1, dimension ) };
586 
587  // flip index if face is twisted
588  if( gridPart_.grid().localIdSet().subId( entity, vx[ 0 ], dimension ) >
589  gridPart_.grid().localIdSet().subId( entity, vx[ 1 ], dimension ) )
590  {
591  const unsigned int numDofsSubEntity = compLocalKey.numDofs( codim, subEntity );
592  index = numDofsSubEntity - index - 1;
593  }
594  }
595 
596  assert( index < compLocalKey.numDofs( codim, subEntity ) );
597  return dofContainer( codim )( entity, subEntity ).dof( codim, polOrd, index );
598  }
599  }
600 
602  template< class Entity, class Functor >
603  void mapEachEntityDof ( const Entity &entity, Functor f ) const
604  {
605  const int n = numEntityDofs( entity );
606  for( int i = 0; i < n; ++i )
607  f( i, dofContainer( Entity::codimension )[ entity ].entityDof( i ) );
608  }
609 
611  int maxNumDofs () const
612  {
613  return maxNumDofs_;
614  }
615 
617  int numDofs ( const ElementType &entity ) const
618  {
619  const int polOrd = polynomOrder( entity );
620  return compiledLocalKey( polOrd, entity.type() ).size();
621  }
622 
624  template< class Entity >
625  int numEntityDofs ( const Entity &entity ) const
626  {
627  if( discontinuousMapper )
628  {
629  if( Entity :: codimension == 0 )
630  return dofContainer( 0 )[ entity ].entityDofs();
631  else
632  return 0;
633  }
634  else
635  {
636  // !!! to be revised
637  // This implementation only works for nonhybrid grids (simplices or cubes)
638  return dofContainer( Entity :: codimension )[ entity ].entityDofs();
639  }
640  }
641 
643  bool contains ( int codim ) const
644  {
645  return (discontinuousMapper) ? (codim == 0) : true;
646  }
647 
649  bool fixedDataSize ( int codim ) const
650  {
651  return false;
652  }
653 
655  int oldIndex ( const int hole, const int block ) const
656  {
657  assert( oldIndex_[ hole ] >= 0 );
658  return oldIndex_[ hole ];
659  }
660 
662  int newIndex ( const int hole, const int block ) const
663  {
664  assert( newIndex_[ hole ] >= 0 );
665  return newIndex_[ hole ];
666  }
667 
669  int numberOfHoles ( const int block ) const
670  {
671  return numberOfHoles_;
672  }
673 
676  int numBlocks () const
677  {
678  return 1;
679  }
680 
683  int oldOffSet ( const int block ) const
684  {
685  return 0;
686  }
687 
690  int offSet ( const int block ) const
691  {
692  return 0;
693  }
694 
696  bool consecutive () const
697  {
698  return true;
699  }
700 
701  // Adaptation Methods (as for Index Sets)
703  {
704  entityPolynomOrder_.resize();
705  entityPolynomOrder_.shrinkToFit();
706  for( int codim = 0; codim <= highestDimension; ++codim )
707  {
708  dofContainer( codim ).resize();
709  dofContainer( codim ).shrinkToFit();
710  }
711  }
712 
713  void insertEntity ( const ElementType &entity )
714  {
716  insertEntityDofs( entity );
717  }
718 
719  // return number of local dofs that were not visited yet
720  unsigned int insertEntityDofs( const ElementType &entity )
721  {
722  PolynomOrderStorageType& polyStorage = entityPolynomOrder_[ entity ];
723  if( ! polyStorage.active() )
724  {
725  unsigned int notAlreadyCounted = 0;
726 
727  const int polOrd = polyStorage.order();
728  // get lagrange point set
729  const CompiledLocalKeyType& clk = compiledLocalKey( polOrd, entity.type() );
730 
731  //std::cout << "Insert Entity " << gridPart_.grid().localIdSet().id( entity ) << std::endl;
732 
733  // activate dofs for this entity
734  polyStorage.activate();
735 
736  // insert for all sub entities
737  ForLoop< InsertSubEntities, 0, highestDimension>::
738  apply( entity, clk, polOrd, size_, notAlreadyCounted, dofContainer_ );
739 
740  //printEntityDofs( entity );
741  return notAlreadyCounted ;
742  }
743 
744  return 0;
745  }
746 
747  void removeEntity ( const ElementType &entity )
748  {
749  int polOrd;
750  // polOrd ist set on call of deactivate
751  if( entityPolynomOrder_[ entity ].deactivate( polOrd ) )
752  {
753  ForLoop< RemoveSubEntities, 0, highestDimension>::
754  apply( entity, polOrd, dofContainer_ );
755  }
756  }
757 
758  void resize ()
759  {
761  insertAllUsed();
762  }
763 
765  void adapt()
766  {
767  sequence_ = -1;
768  compress();
769  }
770 
771  // insert father element when conforming refinement is enabled
772  // (due to refinement of more than one level)
773  unsigned int insertFather( const ElementType &entity )
774  {
775  if( entity.hasFather() )
776  {
777  // if father is a new element, insert it
778  ElementType dad = make_entity( entity.father() );
779  if( dad.isNew() )
780  {
781  unsigned int usedSize = insertEntityDofs( dad );
782  // also insert dad's fathers
783  usedSize += insertFather( dad );
784  return usedSize;
785  }
786  }
787  return 0;
788  }
789 
791  bool considerHierarchy () const
792  {
793  return DGFGridInfo< GridType > :: refineStepsForHalf() > 1 ||
794  ! Dune::Capabilities::hasSingleGeometryType<GridType> :: v ;
795  }
796 
798  size_t insertAllUsed()
799  {
800  // reset all dof entries
801  setUnused();
802 
803  // count current size
804  size_t usedSize = 0;
805 
806  const bool considerHierarchyOfElements = considerHierarchy();
807 
808  typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType;
809  const IteratorType end = gridPart_.template end<0>();
810  for( IteratorType it = gridPart_.template begin<0>();
811  it != end ; ++it )
812  {
813  const ElementType &element = *it;
814  if( considerHierarchyOfElements )
815  {
816  // insert father elements (conforming and hybrid grids only)
817  usedSize += insertFather( element );
818  }
819 
820  // number of new dofs (not already counted) is returned
821  usedSize += insertEntityDofs( element );
822  }
823 
824  //std::cout << "Insert Size = " << size_ << std::endl;
825  //printDofs();
826  //std::cout << "Insert done! " << std::endl;
827  return usedSize ;
828  }
829 
830  void printDofs() const
831  {
832  //std::cout << "Size " << size_ << std::endl;
833  typedef typename GridPartType :: template Codim< 0 > :: IteratorType IteratorType;
834  const IteratorType end = gridPart_.template end<0>();
835  for( IteratorType it = gridPart_.template begin<0>();
836  it != end ; ++it )
837  {
838  printEntityDofs( *it );
839  }
840  }
841 
842  void printEntityDofs( const ElementType& entity ) const
843  {
844  std::cout << "Print entity " << gridPart_.grid().localIdSet().id( entity ) << " with " << std::endl;
845  for( int i = 0; i<numDofs( entity ); ++i )
846  {
847  std::cout << "en[ " << i << " ] = " << mapToGlobal( entity, i ) << std::endl;
848  }
849  }
850 
852  void setUnused()
853  {
854  // deactivate all entries in the polynomial order container
855  {
856  typedef typename PolyOrderContainerType :: Iterator Iterator;
857  const Iterator endit = entityPolynomOrder_.end();
858  for( Iterator it = entityPolynomOrder_.begin(); it != endit; ++it )
859  {
860  PolynomOrderStorageType& p = *it;
861  int pOrd;
862  p.deactivate( pOrd );
863  }
864  }
865 
866  for( int codim = 0; codim <= highestDimension; ++codim )
867  {
868  DofContainerType& codimContainer = dofContainer( codim );
869  typedef typename DofContainerType :: Iterator Iterator;
870  const Iterator endit = codimContainer.end();
871  for( Iterator it = codimContainer.begin(); it != endit; ++it )
872  {
873  it->reset();
874  }
875  }
876  }
877 
878  // --compress
879  bool compress ()
880  {
881  if( sequence_ == dm_.sequence() )
882  {
883  numberOfHoles_ = 0;
884  return false ;
885  }
886 
887  // adjust size of containers
889 
890  // make all dofs that are currently used
891  // (corresponding to GridPart's iterator)
892  const size_t usedSize = insertAllUsed();
893 
894  //std::cout << "Size " << size_ << " holes " << numberOfHoles_ << std::endl;
895  //printDofs();
896 
897  // reset number of holes
898  numberOfHoles_ = 0;
899 
900  // true if a least one dof must be copied
901  bool haveToCopy = false;
902 
903  std::vector<int> validHoles;
904 
905  {
906  // default is true which means entry is hole
907  std::vector< bool > holeMarker( size_, true );
908 
909  // mark holes
910  for( int codim = 0; codim <= highestDimension; ++codim )
911  {
912  DofContainerType& codimContainer = dofContainer( codim );
913  typedef typename DofContainerType :: Iterator Iterator;
914  const Iterator endit = codimContainer.end();
915  for( Iterator it = codimContainer.begin(); it != endit; ++it )
916  {
917  EntityDofStorageType& dof = *it;
918  // store holes if unused dofs exits, otherwise increase actSize
919  dof.detectUnusedDofs( holeMarker, usedSize );
920  }
921  }
922 
923  // check for real holes
924  validHoles.reserve( usedSize );
925  validHoles.resize( 0 );
926 
927  // check the vector of hole flags and store numbers
928  for( size_t i=0; i<usedSize; ++i )
929  {
930  // it's only a valid hole, if it was not marked otherwise
931  if( holeMarker[ i ] )
932  {
933  //std::cout << "Dof number " << i << " is not used" << std::endl;
934  validHoles.push_back( i );
935  }
936  }
937  }
938 
939  if( validHoles.size() > 0 )
940  {
941  // counter for current hole to use
942  int currentHole = validHoles.size();
943 
944  // resize old-new index storage to correct size
945  oldIndex_.resize( currentHole, -1) ;
946  newIndex_.resize( currentHole, -1) ;
947 
948  for( int codim = 0; codim <= highestDimension; ++codim )
949  {
950  DofContainerType& codimContainer = dofContainer( codim );
951  typedef typename DofContainerType :: Iterator Iterator;
952  const Iterator endit = codimContainer.end();
953  for( Iterator it = codimContainer.begin(); it != endit; ++it )
954  {
955  // get dof storage
956  EntityDofStorageType& dof = *it;
957 
958  // replace DoF larger than size with DoF from holes
959  // set haveToCopy to true if true is returned
960  haveToCopy |= dof.removeHoles( oldIndex_, newIndex_,
961  validHoles, currentHole,
962  usedSize, numberOfHoles_ );
963  }
964  }
965  }
966 
967  // store new size
968  size_ = usedSize ;
969 
970  //std::cout << "Size " << size_ << " holes " << numberOfHoles_ << std::endl;
971  //printDofs();
972 
973  sequence_ = dm_.sequence();
974 
975  return haveToCopy;
976  }
977 
978  void backup () const
979  {}
980 
981  void restore ()
982  {}
983 
984  template< class InStream >
985  void read ( InStream &in )
986  {}
987 
988  template< class OutStream >
989  void write ( OutStream &out )
990  {}
991 
992  private:
993  // prohibit copying and assignment
994  GenericAdaptiveDofMapper ( const ThisType & );
995  ThisType &operator=( const ThisType & );
996 
997  const GridPartType& gridPart_;
998  // reference to dof manager
999  DofManagerType& dm_;
1000 
1001  CompiledLocalKeyVectorType &compiledLocalKeys_;
1002 
1003  PolyOrderContainerType entityPolynomOrder_;
1004 
1005  mutable std::vector< DofContainerType* > dofContainer_;
1006 
1007  int numberOfHoles_ ;
1008  std::vector< int > oldIndex_ ;
1009  std::vector< int > newIndex_ ;
1010 
1011  mutable unsigned int size_;
1012  unsigned int maxNumDofs_;
1013  int sequence_ ;
1014  }; // class GenericAdaptiveDofMapper
1015 
1016  } // namespace Fem
1017 
1018 } // namespace Dune
1019 
1020 #endif // #ifndef DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
void assign(const EntityDofStorage &other)
Definition: genericadaptivedofmapper.hh:102
Extended interface for adaptive DoF mappers.
Definition: mapper/dofmapper.hh:204
void mapEachEntityDof(const Entity &entity, Functor f) const
map each local DoF number to a global key
Definition: genericadaptivedofmapper.hh:603
unsigned int codim() const
Definition: localkey.hh:27
EntityDofStorage & operator=(const EntityDofStorage &other)
Definition: genericadaptivedofmapper.hh:126
PolynomOrderStorage PolynomOrderStorageType
Definition: genericadaptivedofmapper.hh:332
Traits::CompiledLocalKeyVectorType CompiledLocalKeyVectorType
type of vector containing compiled local keys
Definition: genericadaptivedofmapper.hh:73
static const int highestDimension
highest codimension used to attach dofs
Definition: genericadaptivedofmapper.hh:67
int entityDofs() const
Definition: genericadaptivedofmapper.hh:213
std::vector< BaseSetLocalKeyStorageType > CompiledLocalKeyVectorType
Definition: mapper.hh:53
void printDofs() const
Definition: genericadaptivedofmapper.hh:254
unsigned char k_
Definition: genericadaptivedofmapper.hh:312
Definition: genericadaptivedofmapper.hh:364
void reset()
Definition: genericadaptivedofmapper.hh:182
unsigned char active_
Definition: genericadaptivedofmapper.hh:313
Definition: genericadaptivedofmapper.hh:81
void activate()
Definition: genericadaptivedofmapper.hh:318
static const int polynomialOrder
order of the Lagrange polynoms
Definition: genericadaptivedofmapper.hh:70
int entityDof(int dofNumber) const
Definition: genericadaptivedofmapper.hh:197
EntityDofStorage()
Definition: genericadaptivedofmapper.hh:93
Definition: genericadaptivedofmapper.hh:29
static constexpr T max(T a)
Definition: utility.hh:65
void resizeContainers()
Definition: genericadaptivedofmapper.hh:702
void resize()
Definition: genericadaptivedofmapper.hh:758
Definition: genericadaptivedofmapper.hh:310
void insert(const GeometryType type, const int codim, const int polOrd, const int numDofs, const int startDof)
Definition: genericadaptivedofmapper.hh:146
int oldIndex(const int hole, const int block) const
Definition: genericadaptivedofmapper.hh:655
static const int dimension
dimension of the grid
Definition: genericadaptivedofmapper.hh:64
int oldOffSet(const int block) const
Definition: genericadaptivedofmapper.hh:683
void setPolynomOrder(const ElementType &entity, const int polOrd)
Definition: genericadaptivedofmapper.hh:506
int order() const
Definition: genericadaptivedofmapper.hh:316
Traits::ElementType ElementType
type of entities (codim 0)
Definition: genericadaptivedofmapper.hh:49
Definition: datacollector.hh:45
const TraitsImp::DofMapperType & asImp() const
Definition: bartonnackmaninterface.hh:37
static int numDofs(const ElementType &entity, const CompiledLocalKeyType &clk, const int subEntity)
Definition: genericadaptivedofmapper.hh:352
DofContainerType & dofContainer(const std::size_t codim) const
Definition: genericadaptivedofmapper.hh:514
int determineVectorEntry(const int codim, const int polOrd) const
Definition: genericadaptivedofmapper.hh:163
bool contains(int codim) const
Check, whether any DoFs are associated with a codimension.
Definition: genericadaptivedofmapper.hh:643
const GeometryType & type() const
Definition: genericadaptivedofmapper.hh:173
GridPart GridPartType
Definition: mapper.hh:40
int numBlocks() const
Definition: genericadaptivedofmapper.hh:676
GridPartType::GridType GridType
type of the underlying grid
Definition: genericadaptivedofmapper.hh:52
const CompiledLocalKeyType & compiledLocalKey(const int polOrd, const GeometryType type) const
Definition: genericadaptivedofmapper.hh:522
std::vector< DofVectorType > dofs_
Definition: genericadaptivedofmapper.hh:88
static void apply(const ElementType &entity, const CompiledLocalKeyType &clk, const int polOrd, unsigned int &globalSize, unsigned int &notAlreadyCounted, std::vector< DofContainerType * > dofContainers)
Definition: genericadaptivedofmapper.hh:400
Dune::EntityPointer< Grid, Implementation >::Entity make_entity(const Dune::EntityPointer< Grid, Implementation > &entityPointer)
Definition: compatibility.hh:23
int polynomOrder(const ElementType &entity) const
Definition: genericadaptivedofmapper.hh:501
bool exists(const int codim, const int polOrd) const
Definition: genericadaptivedofmapper.hh:132
int numberOfHoles(const int block) const
Definition: genericadaptivedofmapper.hh:669
int numEntityDofs(const Entity &entity) const
obtain number of DoFs actually belonging to an entity
Definition: genericadaptivedofmapper.hh:625
std::vector< int > DofVectorType
Definition: genericadaptivedofmapper.hh:87
Definition: genericadaptivedofmapper.hh:83
Definition: coordinate.hh:4
GridPartType::template Codim< 0 >::EntityType ElementType
Definition: mapper.hh:46
static void apply(const ElementType &entity, const int polOrd, std::vector< DofContainerType * > dofContainers)
Definition: genericadaptivedofmapper.hh:428
EntityDofStorage EntityDofStorageType
Definition: genericadaptivedofmapper.hh:308
GenericAdaptiveDofMapper(const GenericAdaptiveDofMapper &other, CompiledLocalKeyVectorType &compiledLocalKeyVector)
sort of copy constructor
Definition: genericadaptivedofmapper.hh:481
void write(OutStream &out)
Definition: genericadaptivedofmapper.hh:989
size_t insertAllUsed()
return number of DoFs currently used for space
Definition: genericadaptivedofmapper.hh:798
void detectUnusedDofs(VectorType &isHole, const int actSize)
Definition: genericadaptivedofmapper.hh:224
void adapt()
adjust mapper to newly set polynomial orders
Definition: genericadaptivedofmapper.hh:765
void remove(const int codim, const int polOrd)
Definition: genericadaptivedofmapper.hh:175
PersistentContainer< GridType, EntityDofStorageType > DofContainerType
Definition: genericadaptivedofmapper.hh:334
int mapToGlobal(const ElementType &entity, const int localDof) const
Definition: genericadaptivedofmapper.hh:549
static int numDofs(const ElementType &entity, const CompiledLocalKeyType &clk, const int subEntity)
Definition: genericadaptivedofmapper.hh:341
void read(InStream &in)
Definition: genericadaptivedofmapper.hh:985
Definition: genericadaptivedofmapper.hh:85
int maxNumDofs() const
obtain maximal number of DoFs on one entity
Definition: genericadaptivedofmapper.hh:611
void mapEach(const ElementType &element, Functor f) const
Definition: genericadaptivedofmapper.hh:541
bool use(const int codim, const int polOrd)
returns true if entry has a reference count of 1
Definition: genericadaptivedofmapper.hh:139
bool active() const
Definition: genericadaptivedofmapper.hh:319
int offSet(const int block) const
Definition: genericadaptivedofmapper.hh:690
bool deactivate(int &k)
Definition: genericadaptivedofmapper.hh:320
void restore()
Definition: genericadaptivedofmapper.hh:981
GenericAdaptiveDofMapper(const GridPartType &gridPart, CompiledLocalKeyVectorType &compiledLocalKeyVector)
constructor
Definition: genericadaptivedofmapper.hh:444
Traits::GridPartType GridPartType
type of the grid part
Definition: genericadaptivedofmapper.hh:46
static void insertDofs(const ElementType &entity, const CompiledLocalKeyType &clk, const int polOrd, const int subEntity, unsigned int &globalSize, unsigned int &notAlreadyCounted, EntityDofStorage &entityDofs)
Definition: genericadaptivedofmapper.hh:366
unsigned int insertFather(const ElementType &entity)
Definition: genericadaptivedofmapper.hh:773
GeometryType type_
Definition: genericadaptivedofmapper.hh:90
bool removeHoles(VectorType &oldIdx, VectorType &newIdx, VectorType &holesVec, int &currentHole, const int usedSize, int &holes)
Definition: genericadaptivedofmapper.hh:266
bool consecutive() const
Definition: genericadaptivedofmapper.hh:696
unsigned int insertEntityDofs(const ElementType &entity)
Definition: genericadaptivedofmapper.hh:720
PersistentContainer< GridType, PolynomOrderStorageType > PolyOrderContainerType
Definition: genericadaptivedofmapper.hh:336
Traits::GlobalKeyType GlobalKeyType
type of global key
Definition: genericadaptivedofmapper.hh:58
TraitsImp Traits
Definition: genericadaptivedofmapper.hh:36
int numDofs(const ElementType &entity) const
obtain number of DoFs on an entity
Definition: genericadaptivedofmapper.hh:617
CompiledLocalKeyVectorType::value_type::value_type CompiledLocalKeyType
compiled local key type
Definition: genericadaptivedofmapper.hh:76
int newIndex(const int hole, const int block) const
Definition: genericadaptivedofmapper.hh:662
bool compress()
Definition: genericadaptivedofmapper.hh:879
DofManager< GridType > DofManagerType
type of the DoF manager
Definition: genericadaptivedofmapper.hh:79
Definition: genericadaptivedofmapper.hh:426
int size() const
return overall number of degrees of freedom
Definition: genericadaptivedofmapper.hh:535
GridType::ctype FieldType
type of coordinates within the grid
Definition: genericadaptivedofmapper.hh:61
static const bool discontinuousMapper
Definition: genericadaptivedofmapper.hh:39
int dof(const int codim, const int polOrd, const size_t dofNumber) const
Definition: genericadaptivedofmapper.hh:188
bool fixedDataSize(int codim) const
Check, whether the data in a codimension has fixed size.
Definition: genericadaptivedofmapper.hh:649
int GlobalKeyType
Definition: mapper.hh:56
void printDofs() const
Definition: genericadaptivedofmapper.hh:830
char used_[numOrders]
Definition: genericadaptivedofmapper.hh:91
EntityDofStorage(const EntityDofStorage &other)
Definition: genericadaptivedofmapper.hh:120
void printEntityDofs(const ElementType &entity) const
Definition: genericadaptivedofmapper.hh:842
Definition: genericadaptivedofmapper.hh:339
PolynomOrderStorage(const int k)
Definition: genericadaptivedofmapper.hh:315
Definition: genericadaptivedofmapper.hh:82
void removeEntity(const ElementType &entity)
Definition: genericadaptivedofmapper.hh:747
bool considerHierarchy() const
return true if elements can be refined more than once during adaptation
Definition: genericadaptivedofmapper.hh:791
virtual ~GenericAdaptiveDofMapper()
destructor
Definition: genericadaptivedofmapper.hh:529
GridPartType::IndexSetType IndexSetType
type of the index set
Definition: genericadaptivedofmapper.hh:55
PolynomOrderStorage()
Definition: genericadaptivedofmapper.hh:314
void backup() const
Definition: genericadaptivedofmapper.hh:978
Definition: localkey.hh:20
void insertEntity(const ElementType &entity)
Definition: genericadaptivedofmapper.hh:713
void setUnused()
reset all used flags of all DoF entries
Definition: genericadaptivedofmapper.hh:852