dune-fem  2.4.1-rc
genericdofmapper.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_GENERICDOFMAPPER_HH
2 #define DUNE_FEM_GENERICDOFMAPPER_HH
3 
4 #if HAVE_DUNE_LOCALFUNCTIONS
5 
6 #include <type_traits>
7 
8 #include <dune/geometry/referenceelements.hh>
9 
10 #include <dune/grid/common/indexidset.hh>
11 
12 #include <dune/localfunctions/common/localkey.hh>
13 
14 #include <dune/fem/misc/functor.hh>
17 
18 namespace Dune
19 {
20 
21  namespace Fem
22  {
23 
24  // Internal Forward Declarations
25  // -----------------------------
26 
27  template< class GridPart, class LocalCoefficientsMap >
28  class GenericDofMapper;
29 
30  template< class GridPart, class LocalCoefficientsMap >
31  class GenericDofMapIterator;
32 
33 
34 
35  // GenericDofMapperTraits
36  // ----------------------
37 
38  template< class GridPart, class LocalCoefficientsMap >
39  struct GenericDofMapperTraits
40  {
41  typedef GenericDofMapper< GridPart, LocalCoefficientsMap > DofMapperType;
42 
43  typedef typename GridPart::template Codim< 0 >::EntityType EntityType;
44 
45  typedef GenericDofMapIterator< GridPart, LocalCoefficientsMap > DofMapIteratorType;
46  };
47 
48 
49 
50  // GenericDofMapper
51  // ----------------
52 
53  template< class GridPart, class LocalCoefficientsMap >
54  class GenericDofMapper
55  : public DofMapper< GenericDofMapperTraits< GridPart, LocalCoefficientsMap > >
56  {
57  typedef GenericDofMapper< GridPart, LocalCoefficientsMap > ThisType;
58  typedef DofMapper< GenericDofMapperTraits< GridPart, LocalCoefficientsMap > > BaseType;
59 
60  friend class GenericDofMapIterator< GridPart, LocalCoefficientsMap >;
61 
62  public:
63  typedef typename BaseType::EntityType EntityType;
64  typedef typename BaseType::DofMapIteratorType DofMapIteratorType;
65 
66  typedef GridPart GridPartType;
67  typedef LocalCoefficientsMap LocalCoefficientsMapType;
68 
69  typedef typename LocalCoefficientsMapType::LocalCoefficientsType LocalCoefficientsType;
70 
71  struct SubEntityInfo
72  {
73  unsigned int codim;
74  unsigned int subEntity;
75  unsigned int topologyId;
76  unsigned int blockIdx;
77  unsigned int numDofs;
78  unsigned int offset;
79  };
80 
81  struct MapInfo
82  {
83  typedef typename std::vector< SubEntityInfo >::const_iterator Iterator;
84 
85  Iterator begin() const
86  {
87  return subEntityInfo.begin();
88  }
89 
90  Iterator end() const
91  {
92  return subEntityInfo.end();
93  }
94 
95  unsigned int localDofPermutation( unsigned int i ) const
96  {
97  assert( i < localDof.size() );
98  return localDof[ i ];
99  }
100 
101  unsigned int size () const
102  {
103  return numDofs;
104  }
105 
106  unsigned int numDofs;
107  std::vector< unsigned int > localDof;
108  std::vector< SubEntityInfo > subEntityInfo;
109  };
110 
111  private:
112  typedef typename GridPartType::IndexSetType IndexSetType;
113  typedef Fem::DofManager< typename GridPartType::GridType > DofManagerType;
114 
115  struct Block
116  {
117  unsigned int codim;
118  unsigned int topologyId;
119  unsigned int numDofs;
120  unsigned int offset;
121  unsigned int oldOffset;
122 
123  Block ( const unsigned int cd, const unsigned int tid, const unsigned int nDofs )
124  : codim( cd ), topologyId( tid ), numDofs( nDofs )
125  {}
126  };
127 
128  template< int topologyId >
129  struct Build;
130 
131  public:
132  static const int dimension = GridPartType::GridType::dimension;
133  static const unsigned int numTopologies = (1 << dimension);
134 
135  GenericDofMapper ( const GridPartType &gridPart,
136  const LocalCoefficientsMapType &localCoefficientsMap );
137 
138  ~GenericDofMapper ()
139  {
140  dofManager_.removeIndexSet( *this );
141  }
142 
143  const IndexSetType &indexSet () const
144  {
145  return indexSet_;
146  }
147 
148  DofMapIteratorType begin ( const EntityType &entity ) const
149  {
150  typename DofMapIteratorType::Begin begin;
151  return DofMapIteratorType( *this, entity, begin );
152  }
153 
154  DofMapIteratorType end ( const EntityType &entity ) const
155  {
156  typename DofMapIteratorType::End end;
157  return DofMapIteratorType( *this, entity, end );
158  }
159 
160  const MapInfo &mapInfo ( const EntityType &entity ) const;
161 
162  template< class Functor >
163  void mapEach ( const EntityType &element, Functor functor ) const;
164 
165  void map ( const EntityType &element, std::vector< std::size_t > &indices ) const;
166 
167  int mapToGlobal( const EntityType &entity, const int localDof ) const
168  {
169  static std::vector< unsigned int > indices;
170  map( entity, indices );
171  return indices[ localDof ];
172  }
173 
174  template< class Entity, class Functor >
175  void mapEachEntityDof ( const Entity &entity, Functor f ) const;
176 
177  unsigned int size () const
178  {
179  return size_;
180  }
181 
182  int maxNumDofs () const
183  {
184  return maxNumDofs_;
185  }
186 
187  int numDofs ( const EntityType &entity ) const
188  {
189  return mapInfo( entity ).numDofs;
190  }
191 
192  template< class Entity >
193  int numEntityDofs ( const Entity &entity ) const
194  {
195  const int codim = Entity::codimension;
196  const unsigned int topologyId = entity.type().id();
197  const int blockIndex = blockIndex_[ codim ][ topologyId >> 1 ];
198  return (blockIndex >= 0 ? blocks_[ blockIndex ].numDofs : 0);
199  }
200 
201  bool contains ( const int codim ) const;
202 
203  const int numBlocks () const
204  {
205  return blocks_.size();
206  }
207 
208  int offSet ( const int blockIdx ) const
209  {
210  assert( (blockIdx >= 0) && (blockIdx < numBlocks()) );
211  return blocks_[ blockIdx ].offset;
212  }
213 
214  int oldOffSet ( const int blockIdx ) const
215  {
216  assert( (blockIdx >= 0) && (blockIdx < numBlocks()) );
217  return blocks_[ blockIdx ].oldOffset;
218  }
219 
220  int numberOfHoles ( const int blockIdx ) const;
221  int oldIndex ( const int hole, const int blockIdx ) const;
222  int newIndex ( const int hole, const int blockIdx ) const;
223 
224  bool consecutive () const
225  {
226  return true;
227  }
228 
229  bool fixedDataSize( const int codim ) const;
230 
231 
232  // Adaptation Methods (as for Index Sets)
233 
234  template< class Entity >
235  void insertEntity ( const Entity &entity )
236  {
237  update();
238  }
239 
240  template< class Entity >
241  void removeEntity ( const Entity &entity )
242  {}
243 
244  void resize ()
245  {
246  update();
247  }
248 
249  bool compress ()
250  {
251  update();
252  return true;
253  }
254 
255  private:
256  GenericDofMapper ( const ThisType & );
257  ThisType &operator= ( const ThisType & );
258 
259  void update ();
260 
261  template< class Topology >
262  void build ( const LocalCoefficientsType &localCoefficients,
263  MapInfo &mapInfo );
264 
265  template< class Topology >
266  void build ();
267 
268  DofManagerType &dofManager_;
269  const IndexSetType &indexSet_;
270  const LocalCoefficientsMapType &localCoefficientsMap_;
271  std::vector< MapInfo > mapInfo_[ numTopologies ];
272  std::vector< Block > blocks_;
273  unsigned int maxNumDofs_;
274  unsigned int size_;
275  std::vector< int > blockIndex_[ dimension+1 ];
276  };
277 
278 
279  template< class GridPart, class LocalCoefficientsMap >
280  inline GenericDofMapper< GridPart, LocalCoefficientsMap >
281  ::GenericDofMapper ( const GridPartType &gridPart,
282  const LocalCoefficientsMapType &localCoefficientsMap )
283  : dofManager_( DofManagerType::instance( gridPart.grid() ) ),
284  indexSet_( gridPart.indexSet() ),
285  localCoefficientsMap_( localCoefficientsMap ),
286  maxNumDofs_( 0 )
287  {
288  for( int codim = 0; codim <= dimension; ++codim )
289  {
290  const int subdimension = dimension-codim;
291  // The last bit of the topology id is insignificat, hence store only
292  // (1 << subdimension-1) many indexInfos.
293  blockIndex_[ codim ].resize( subdimension > 0 ? 1 << (subdimension-1) : 1, -1 );
294  }
295  ForLoop< Build, 0, numTopologies-1 >::apply( *this );
296  update();
297  dofManager_.addIndexSet( *this );
298  }
299 
300 
301  template< class GridPart, class LocalCoefficientsMap >
302  inline bool
303  GenericDofMapper< GridPart, LocalCoefficientsMap >::contains ( const int codim ) const
304  {
305  typedef typename std::vector< int >::const_iterator Iterator;
306  assert( (codim >= 0) && (codim <= dimension) );
307 
308  bool contains = false;
309  const Iterator end = blockIndex_[ codim ].end();
310  for( Iterator it = blockIndex_[ codim ].begin(); it != end; ++it )
311  contains |= (*it >= 0);
312  return contains;
313  }
314 
315 
316  template< class GridPart, class LocalCoefficientsMap >
317  const typename GenericDofMapper< GridPart, LocalCoefficientsMap >::MapInfo &
318  GenericDofMapper< GridPart, LocalCoefficientsMap >::mapInfo ( const EntityType &entity ) const
319  {
320  const unsigned int topologyId = entity.type().id();
321  const unsigned int i = localCoefficientsMap_( entity );
322  assert( i <= mapInfo_[ topologyId ].size() );
323  return mapInfo_[ topologyId ][ i ];
324  }
325 
326 
327  template< class GridPart, class LocalCoefficientsMap >
328  template< class Functor >
329  inline void
330  GenericDofMapper< GridPart, LocalCoefficientsMap >
331  ::mapEach ( const EntityType &entity, Functor functor ) const
332  {
333  typedef typename std::vector< SubEntityInfo >::const_iterator Iterator;
334 
335  const MapInfo &info = mapInfo( entity );
336 
337  const unsigned int *localDof = &(info.localDof[ 0 ]);
338 
339  const Iterator end = info.subEntityInfo.end();
340  for( Iterator it = info.subEntityInfo.begin(); it != end; ++it )
341  {
342  const unsigned int index = indexSet().subIndex( entity, it->subEntity, it->codim );
343  const unsigned int offset = it->offset + index*it->numDofs;
344  for( unsigned int j = 0; j < it->numDofs; ++j )
345  functor( *(localDof++), offset + j );
346  }
347  }
348 
349 
350  template< class GridPart, class LocalCoefficientsMap >
351  inline void
352  GenericDofMapper< GridPart, LocalCoefficientsMap >
353  ::map ( const EntityType &element, std::vector< std::size_t > &indices ) const
354  {
355  indices.resize( numDofs( element ) );
356  mapEach( element, Fem::AssignFunctor< std::vector< std::size_t > >( indices ) );
357  }
358 
359 
360  template< class GridPart, class LocalCoefficientsMap >
361  template< class Entity, class Functor >
362  inline void
363  GenericDofMapper< GridPart, LocalCoefficientsMap >
364  ::mapEachEntityDof ( const Entity &entity, Functor f ) const
365  {
366  const int codim = Entity::codimension;
367  const unsigned int topologyId = entity.type().id();
368  const int blockIndex = blockIndex_[ codim ][ topologyId >> 1 ];
369  assert( blockIndex >= 0 );
370 
371  const Block &block = blocks_[ blockIndex ];
372  const unsigned int baseIndex = block.offset + block.numDofs*indexSet_.index( entity );
373  for( unsigned int index = baseIndex; index != baseIndex + block.numDofs; ++index )
374  f( index );
375  }
376 
377 
378  template< class GridPart, class LocalCoefficientsMap >
379  inline void
380  GenericDofMapper< GridPart, LocalCoefficientsMap >::update ()
381  {
382  size_ = 0;
383  const unsigned int numBlocks = blocks_.size();
384  for( unsigned int i = 0; i < numBlocks; ++i )
385  {
386  Block &block = blocks_[ i ];
387 
388  unsigned int idxSize = 0;
389  const GeometryType type( block.topologyId, dimension - block.codim);
390  if (!type.isNone())
391  idxSize = indexSet().size( type );
392  block.oldOffset = block.offset;
393  block.offset = size_;
394  size_ += idxSize * block.numDofs;
395  }
396 
397  for( unsigned int topologyId = 0; topologyId < numTopologies; ++topologyId )
398  {
399  typedef typename std::vector< MapInfo >::iterator Iterator;
400  const Iterator mend = mapInfo_[ topologyId ].end();
401  for( Iterator mit = mapInfo_[ topologyId ].begin(); mit != mend; ++mit )
402  {
403  typedef typename std::vector< SubEntityInfo >::iterator Iterator;
404  const Iterator send = mit->subEntityInfo.end();
405  for( Iterator sit = mit->subEntityInfo.begin(); sit != send; ++sit )
406  sit->offset = blocks_[ sit->blockIdx ].offset;
407  }
408  }
409  }
410 
411 
412  template< class GridPart, class LocalCoefficientsMap >
413  inline int
414  GenericDofMapper< GridPart, LocalCoefficientsMap >::numberOfHoles ( const int blockIdx ) const
415  {
416  assert( (blockIdx >= 0) && (blockIdx < numBlocks()) );
417  const Block &block = blocks_[ blockIdx ];
418  return block.numDofs * indexSet().numberOfHoles( block.codim );
419  }
420 
421 
422  template< class GridPart, class LocalCoefficientsMap >
423  inline int
424  GenericDofMapper< GridPart, LocalCoefficientsMap >
425  ::oldIndex ( const int hole, const int blockIdx ) const
426  {
427  assert( (hole >= 0) && (hole < numberOfHoles( blockIdx )) );
428  const Block &block = blocks_[ blockIdx ];
429  const int numDofs = block.numDofs;
430  return block.offset + numDofs * indexSet().oldIndex( hole / numDofs, block.codim ) + (hole % numDofs);
431  }
432 
433 
434  template< class GridPart, class LocalCoefficientsMap >
435  inline int
436  GenericDofMapper< GridPart, LocalCoefficientsMap >
437  ::newIndex ( const int hole, const int blockIdx ) const
438  {
439  assert( (hole >= 0) && (hole < numberOfHoles( blockIdx )) );
440  const Block &block = blocks_[ blockIdx ];
441  const int numDofs = block.numDofs;
442  return block.offset + numDofs * indexSet().newIndex( hole / numDofs, block.codim ) + (hole % numDofs);
443  }
444 
445 
446  template< class GridPart, class LocalCoefficientsMap >
447  inline bool
448  GenericDofMapper< GridPart, LocalCoefficientsMap >::fixedDataSize( const int codim ) const
449  {
450  typedef typename std::vector< int >::const_iterator Iterator;
451  assert( (codim >= 0) && (codim <= dimension) );
452 
453  Iterator begin = blockIndex_[ codim ].begin();
454  const Iterator end = blockIndex_[ codim ].end();
455  if( begin == end )
456  return true;
457 
458  unsigned int numDofs = (*begin >= 0 ? blocks_[ *begin ].numDofs : 0);
459  bool fixedSize = true;
460  for( Iterator it = begin++; it != end; ++it )
461  fixedSize &= (numDofs == (*it >= 0 ? blocks_[ *it ].numDofs : 0));
462  return fixedSize;
463  }
464 
465 
466  template< class GridPart, class LocalCoefficientsMap >
467  template< class Topology >
468  inline void
469  GenericDofMapper< GridPart, LocalCoefficientsMap >
470  ::build ( const LocalCoefficientsType &localCoefficients, MapInfo &mapInfo )
471  {
472  const Dune::ReferenceElement< void, dimension > &refElement
473  = Dune::ReferenceElements< void, dimension >::general( GeometryType( Topology() ) );
474 
475  mapInfo.numDofs = localCoefficients.size();
476  mapInfo.localDof.resize( mapInfo.numDofs );
477  maxNumDofs_ = std::max( maxNumDofs_, mapInfo.numDofs );
478 
479  // count the number of DoFs on each subentity
480  GenericGeometry::SubTopologyMapper< Topology > mapper;
481  std::vector< unsigned int > counts( mapper.size(), (unsigned int)0 );
482  for( unsigned int i = 0; i < mapInfo.numDofs; ++i )
483  {
484  const LocalKey &key = localCoefficients.localKey( i );
485  ++counts[ mapper( key.codim(), key.subEntity() ) ];
486  }
487 
488  // build subentity information
489  for( int codim = 0; codim <= dimension; ++codim )
490  {
491  const unsigned int codimSize = refElement.size( codim );
492  for( unsigned int subEntity = 0; subEntity < codimSize; ++subEntity )
493  {
494  const unsigned int topologyId = refElement.type( subEntity, codim ).id();
495 
496  int &blockIdx = blockIndex_[ codim ][ topologyId >> 1 ];
497  const unsigned int numDofs = counts[ mapper( codim, subEntity ) ];
498  if( blockIdx == -1 )
499  {
500  if( numDofs > 0 )
501  {
502  blockIdx = blocks_.size();
503  blocks_.push_back( Block( codim, topologyId, numDofs ) );
504  }
505  else
506  blockIdx = -2;
507  }
508  else if( numDofs != (blockIdx >= 0 ? blocks_[ blockIdx ].numDofs : 0) )
509  DUNE_THROW( InvalidStateException, "Inconsistent LocalCoefficients." );
510 
511  if( numDofs > 0 )
512  {
513  SubEntityInfo subEntityInfo;
514  subEntityInfo.codim = codim;
515  subEntityInfo.subEntity = subEntity;
516  subEntityInfo.topologyId = topologyId;
517  subEntityInfo.blockIdx = blockIdx;
518  subEntityInfo.numDofs = numDofs;
519  mapInfo.subEntityInfo.push_back( subEntityInfo );
520  }
521  }
522  }
523 
524  // build permutation of local dofs
525  for( unsigned int i = 0; i < mapInfo.numDofs; ++i )
526  {
527  typedef typename std::vector< SubEntityInfo >::iterator Iterator;
528  const LocalKey &key = localCoefficients.localKey( i );
529 
530  unsigned int *localDof = &(mapInfo.localDof[ 0 ]);
531  const Iterator end = mapInfo.subEntityInfo.end();
532  for( Iterator it = mapInfo.subEntityInfo.begin(); true; ++it )
533  {
534  if( it == end )
535  {
536  std::cerr << "Error: (subEntity = " << key.subEntity()
537  << ", codim = " << key.codim()
538  << ") not found in subEntityInfo" << std::endl;
539  std::cerr << "SubEntityInfo contains:" << std::endl;
540  for( it = mapInfo.subEntityInfo.begin(); it != end; ++it )
541  {
542  std::cerr << " (subEntity = " << it->subEntity
543  << ", codim = " << it->codim << ")" << std::endl;
544  }
545  abort();
546  }
547 
548  if( (it->codim == key.codim()) && (it->subEntity == key.subEntity()) )
549  {
550  *(localDof + key.index()) = i;
551  break;
552  }
553  localDof += it->numDofs;
554  }
555  }
556  }
557 
558 
559  template< class GridPart, class LocalCoefficientsMap >
560  template< class Topology >
561  inline void
562  GenericDofMapper< GridPart, LocalCoefficientsMap >::build ()
563  {
564  const unsigned int size = localCoefficientsMap_.template size< Topology >();
565  mapInfo_[ Topology::id ].resize( size );
566  for( unsigned int i = 0; i < size; ++i )
567  {
568  MapInfo &mapInfo = mapInfo_[ Topology::id ][ i ];
569  const LocalCoefficientsType &localCoefficients
570  = localCoefficientsMap_.template localCoefficients< Topology >( i );
571  build< Topology >( localCoefficients, mapInfo );
572  }
573  }
574 
575 
576 
577  template< class GridPart, class LocalCoefficientsMap >
578  template< int topologyId >
579  struct GenericDofMapper< GridPart, LocalCoefficientsMap >::Build
580  {
581  typedef typename GenericGeometry::Topology< topologyId, dimension >::type Topology;
582 
583  static void apply ( ThisType &dofMapper )
584  {
585  dofMapper.template build< Topology >();
586  }
587  };
588 
589 
590 
591  // GenericDofMapIterator
592  // ---------------------
593 
594  template< class GridPart, class LocalCoefficientsMap >
595  class GenericDofMapIterator
596  {
597  typedef GenericDofMapIterator< GridPart, LocalCoefficientsMap > ThisType;
598 
599  public:
600  typedef GenericDofMapper< GridPart, LocalCoefficientsMap > DofMapperType;
601 
602  typedef typename DofMapperType::EntityType EntityType;
603  typedef typename DofMapperType::IndexSetType IndexSetType;
604 
605  typedef std::integral_constant<int, 0 > Begin;
606  typedef std::integral_constant<int, 1 > End;
607 
608  private:
609  typedef typename DofMapperType::SubEntityInfo SubEntityInfo;
610  typedef typename DofMapperType::MapInfo MapInfo;
611  typedef typename std::vector< SubEntityInfo >::const_iterator SubEntityInfoIterator;
612 
613  public:
614  GenericDofMapIterator ( const DofMapperType &dofMapper,
615  const EntityType &entity,
616  const Begin &begin )
617  : indexSet_( dofMapper.indexSet() ),
618  entity_( entity ),
619  mapInfo_( dofMapper.mapInfo( entity ) ),
620  subEntityInfoIt_( mapInfo_.subEntityInfo.begin() ),
621  localDof_( &(mapInfo_.localDof[ 0 ]) )
622  {
623  initSubEntity ( subEntityInfoIt_ );
624  }
625 
626  GenericDofMapIterator ( const DofMapperType &dofMapper,
627  const EntityType &entity,
628  const End &end )
629  : indexSet_( dofMapper.indexSet() ),
630  entity_( entity ),
631  mapInfo_( dofMapper.mapInfo( entity ) ),
632  subEntityInfoIt_( mapInfo_.subEntityInfo.end() ),
633  localDof_( &(mapInfo_.localDof[ mapInfo_.numDofs ]) )
634  {}
635 
636  ThisType &operator++ ()
637  {
638  ++localDof_;
639  ++dof_;
640  if( dof_ >= subEntityInfoIt_->numDofs )
641  initSubEntity( ++subEntityInfoIt_ );
642  return *this;
643  }
644 
645  bool operator== ( const ThisType &other ) const
646  {
647  return (localDof_ == other.localDof_);
648  }
649 
650  bool operator!= ( const ThisType &other ) const
651  {
652  return (localDof_ != other.localDof_);
653  }
654 
655  int local () const
656  {
657  return *localDof_;
658  }
659 
660  int global () const
661  {
662  return offset_ + dof_;
663  }
664 
665  private:
666  void initSubEntity ( const SubEntityInfoIterator &it )
667  {
668  if( it != mapInfo_.subEntityInfo.end() )
669  {
670  assert( it->numDofs > 0 );
671  dof_ = 0;
672  const unsigned int index = indexSet_.subIndex( entity_, it->subEntity, it->codim );
673  offset_ = it->offset + index * it->numDofs;
674  }
675  }
676 
677  protected:
678  const IndexSetType &indexSet_;
679  const EntityType &entity_;
680  const MapInfo &mapInfo_;
681  SubEntityInfoIterator subEntityInfoIt_;
682  const unsigned int *localDof_;
683  int offset_;
684  unsigned int dof_;
685  };
686 
687  } // namespace Fem
688 
689 } // namespace Dune
690 
691 #endif // #if HAVE_DUNE_LOCALFUNCTIONS
692 
693 #endif // #ifndef DUNE_FEM_GENERICDOFMAPPER_HH
694 
695 /* vim: set sw=2 et: */
static constexpr T max(T a)
Definition: utility.hh:65
bool operator!=(const Double &a, const Double &b)
Definition: double.hh:629
bool operator==(const Double &a, const Double &b)
Definition: double.hh:589
Definition: coordinate.hh:4