dune-fem  2.8-git
tuplemapper.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
2 #define DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
3 
4 #include <array>
5 #include <tuple>
6 #include <utility>
7 
8 #include <dune/common/hybridutilities.hh>
9 
14 
15 
16 namespace Dune
17 {
18 
19  namespace Fem
20  {
21 
22  // Internal forward declaration
23  // ----------------------------
24  template< class GridPart, class ... Mapper >
25  class TupleMapper;
26 
27 
28 #ifndef DOXYGEN
29 
30  namespace __TupleMapper
31  {
32 
33  // Traits
34  // ------
35 
36  template< class GridPart, class ... Mapper >
37  struct Traits
38  {
39  static_assert( Std::are_all_same< typename Mapper::ElementType ... >::value,
40  "TupleMapper needs common ElementType" );
41 
42  typedef typename std::tuple_element< 0, std::tuple< Mapper ... > >::type FirstMapperType;
43  typedef typename FirstMapperType::ElementType ElementType;
44  typedef typename FirstMapperType::SizeType SizeType;
45  typedef typename FirstMapperType::GlobalKeyType GlobalKeyType;
46 
47  typedef TupleMapper< GridPart, Mapper ... > DofMapperType;
48  };
49 
50  // CombinedIndex
51  // -------------
52 
53  template< class Index, class Int, Int i >
54  struct CombinedIndex
55  {
56  constexpr CombinedIndex ( Index index, Index offset ) : index_( index ), offset_( offset ) {}
57 
58  static constexpr Int component () { return i; }
59 
60  constexpr operator Index () const { return index_ + offset_; }
61 
62  constexpr Index index () const { return index_; }
63 
64  constexpr Index offset () const { return offset_; }
65 
66  private:
67  Index index_, offset_;
68  };
69 
70 
71  // DofMapper
72  // ---------
73 
74  template< class T, template< class > class Base = Dune::Fem::DofMapper >
75  class DofMapper;
76 
77  template< class GridPart, class ... Mapper, template< class > class Base >
78  class DofMapper< Traits< GridPart, Mapper ... >, Base >
79  : public Base< Traits< GridPart, Mapper ... > >
80  {
81  typedef Base< Traits< GridPart, Mapper ... > > BaseType;
82 
83  // FunctorWrapper
84  // --------------
85 
86  template< class Functor, int i >
87  struct FunctorWrapper
88  {
89  FunctorWrapper ( Functor functor, int localOffset, int globalOffset )
90  : functor_( functor ),
91  localOffset_( localOffset ),
92  globalOffset_( globalOffset )
93  {}
94 
95  template< class GlobalKey >
96  void operator() ( int localDof, const GlobalKey &globalKey ) const
97  {
98  functor_( localDof + localOffset_, CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
99  }
100 
101  template< class GlobalKey >
102  void operator() ( const GlobalKey &globalKey ) const
103  {
104  functor_( CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
105  }
106 
107  private:
108  Functor functor_;
109  const int localOffset_;
110  const int globalOffset_;
111  };
112 
113  // size of the Mapper Tuple
114  static const int mapperTupleSize = sizeof ... ( Mapper );
115 
116  typedef std::array< typename BaseType::SizeType, mapperTupleSize + 1 > OffsetType;
117 
118  public:
119  typedef typename BaseType::ElementType ElementType;
120  typedef typename BaseType::SizeType SizeType;
121  typedef typename BaseType::Traits::GlobalKeyType GlobalKeyType;
122 
123  typedef GridPart GridPartType;
124 
125  DofMapper ( GridPartType &gridPart, Mapper & ... mapper )
126  : gridPart_( gridPart ),
127  mapperTuple_( mapper ... )
128  {
129  init();
130  }
131 
132  DofMapper ( GridPartType &gridPart, Mapper && ... mapper )
133  : gridPart_( gridPart ),
134  mapperTuple_( std::move( mapper ) ... )
135  {
136  init();
137  }
138 
139  SizeType size () const { return size( std::index_sequence_for< Mapper ... >() ); }
140 
141  bool contains ( const int codim ) const { return contains( codim, std::index_sequence_for< Mapper ... >() ); }
142 
143  bool fixedDataSize ( int codim ) const { return fixedDataSize( codim, std::index_sequence_for< Mapper ... >() ); }
144 
145  template< class Functor >
146  void mapEach ( const ElementType &element, Functor f ) const
147  {
148  OffsetType localOffset;
149  localOffset[ 0 ] = 0;
150  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
151  [ & ]( auto i )
152  {
153  FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
154  std::get< i >( mapperTuple_ ).mapEach( element, wrappedFunctor );
155  localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numDofs( element );
156  } );
157  }
158 
159  template< class Entity, class Functor >
160  void mapEachEntityDof ( const Entity &entity, Functor f ) const
161  {
162  OffsetType localOffset;
163  localOffset[ 0 ] = 0;
164  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
165  [ & ]( auto i )
166  {
167  FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
168  std::get< i >( mapperTuple_ ).mapEachEntityDof( entity, wrappedFunctor );
169  localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numEntityDofs( entity );
170  } );
171  }
172 
173  void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const
174  {
175  DUNE_THROW( NotImplemented, "Method onSubEntity(...) not yet implemented for TupleMapper" );
176  }
177 
178  int maxNumDofs () const { return maxNumDofs( std::index_sequence_for< Mapper ... >() ); }
179 
180  SizeType numDofs ( const ElementType &element ) const { return numDofs( element, std::index_sequence_for< Mapper ... >() ); }
181 
182  template< class Entity >
183  SizeType numEntityDofs ( const Entity &entity ) const { return numEntityDofs( entity, std::index_sequence_for< Mapper ... >() ); }
184 
185 
186  static constexpr bool consecutive () noexcept { return false; }
187 
188  SizeType numBlocks () const
189  {
190  DUNE_THROW( NotImplemented, "Method numBlocks() called on non-adaptive block mapper" );
191  }
192 
193  SizeType numberOfHoles ( int ) const
194  {
195  DUNE_THROW( NotImplemented, "Method numberOfHoles() called on non-adaptive block mapper" );
196  }
197 
198  GlobalKeyType oldIndex ( int hole, int ) const
199  {
200  DUNE_THROW( NotImplemented, "Method oldIndex() called on non-adaptive block mapper" );
201  }
202 
203  GlobalKeyType newIndex ( int hole, int ) const
204  {
205  DUNE_THROW( NotImplemented, "Method newIndex() called on non-adaptive block mapper" );
206  }
207 
208  SizeType oldOffSet ( int ) const
209  {
210  DUNE_THROW( NotImplemented, "Method oldOffSet() called on non-adaptive block mapper" );
211  }
212 
213  SizeType offSet ( int ) const
214  {
215  DUNE_THROW( NotImplemented, "Method offSet() called on non-adaptive block mapper" );
216  }
217 
218  void update()
219  {
220  // compute update for each mapper (if any)
221  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
222  [ & ](auto i){ std::get< i >( mapperTuple_ ).update(); } );
223  }
224 
225  /*** NonInterface Methods ***/
226 
227  SizeType offset ( int i ) const { return globalOffset_[ i ]; }
228 
229  template< int i >
230  SizeType subSize () const { return std::get< i >( mapperTuple_ ).size(); }
231 
232  protected:
233  template< std::size_t ... i >
234  SizeType size ( std::index_sequence< i ... > ) const
235  {
236  return Std::sum( std::get< i >( mapperTuple_ ).size() ... );
237  }
238 
239  template< std::size_t ... i >
240  bool fixedDataSize ( const int codim, std::index_sequence< i ... > ) const
241  {
242  return Std::And( std::get< i >( mapperTuple_ ).fixedDataSize( codim ) ... );
243  }
244 
245  template< std::size_t ... i >
246  bool contains ( const int codim, std::index_sequence< i ... > ) const
247  {
248  return Std::Or( std::get< i >( mapperTuple_ ).contains( codim ) ... );
249  }
250 
251  template< std::size_t ... i >
252  int maxNumDofs ( std::index_sequence< i ... > ) const
253  {
254  return Std::sum( std::get< i >( mapperTuple_ ).maxNumDofs() ... );
255  }
256 
257  template< std::size_t ... i >
258  SizeType numDofs ( const ElementType &element, std::index_sequence< i ... > ) const
259  {
260  return Std::sum( std::get< i >( mapperTuple_ ).numDofs( element ) ... );
261  }
262 
263  template< class Entity, std::size_t ... i >
264  SizeType numEntityDofs ( const Entity &entity, std::index_sequence< i ... > ) const
265  {
266  return Std::sum( std::get< i >( mapperTuple_ ).numEntityDofs( entity ) ... );
267  }
268 
269  void init ()
270  {
271  globalOffset_[ 0 ] = 0;
272  // compute new offsets
273  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
274  [ & ]( auto i ){ globalOffset_[ i + 1 ] = globalOffset_[ i ] + std::get< i >( mapperTuple_ ).size(); } );
275  }
276 
277  GridPartType &gridPart_;
278  std::tuple< Mapper ... > mapperTuple_;
279  OffsetType globalOffset_;
280  };
281 
282 
283 
284  // AdaptiveDofMapper
285  // -----------------
286 
287  template< class T >
288  class AdaptiveDofMapper;
289 
290  template< class GridPart, class ... Mapper >
291  class AdaptiveDofMapper< Traits< GridPart, Mapper ... > >
292  : public DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper >
293  {
294  typedef DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper > BaseType;
295 
296  protected:
297 
298  // size of the Mapper Tuple
299  static const int mapperTupleSize = sizeof ... ( Mapper );
300 
301  typedef std::array< typename BaseType::Traits::SizeType, mapperTupleSize + 1 > OffsetType;
302 
303  using BaseType::mapperTuple_;
304  using BaseType::gridPart_;
305  using BaseType::globalOffset_;
306 
307  public:
308  typedef typename BaseType::ElementType ElementType;
309  typedef typename BaseType::SizeType SizeType;
310  typedef typename BaseType::GlobalKeyType GlobalKeyType;
311  typedef GridPart GridPartType;
312 
313  AdaptiveDofMapper ( GridPartType &gridPart, Mapper & ... mapper )
314  : BaseType( gridPart, mapper ... )
315  {
317  }
318 
319  AdaptiveDofMapper ( GridPartType &gridPart, Mapper && ... mapper )
320  : BaseType( gridPart, std::move( mapper ) ... )
321  {
323  }
324 
325  ~AdaptiveDofMapper () { DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).removeIndexSet( *this ); }
326 
327  AdaptiveDofMapper ( const AdaptiveDofMapper & ) = delete;
328  AdaptiveDofMapper ( AdaptiveDofMapper && ) = delete;
329 
330  static constexpr bool consecutive () noexcept { return true; }
331 
332  SizeType numBlocks () const { return numBlocks( std::index_sequence_for< Mapper ... >() ); }
333 
334  SizeType numberOfHoles ( int block ) const
335  {
336  SizeType nHoles = 0;
337  int comp = -1;
338  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
339  [ & ]( auto i )
340  {
341  if( comp >= 0 )
342  return;
343  const int localBlock = block - std::get< i >( this->mapperTuple_ ).numBlocks();
344  if( localBlock >= 0 )
345  {
346  comp = i;
347  nHoles = std::get< i >( this->mapperTuple_ ).numberOfHoles( localBlock );
348  }
349  } );
350  return nHoles;
351  }
352 
353  GlobalKeyType oldIndex ( int hole, int block ) const
354  {
355  int comp = -1;
356  SizeType oIndex = 0;
357  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
358  [ & ]( auto i )
359  {
360  if( comp >= 0 )
361  return;
362  const int localBlock = block - std::get< i >( this->mapperTuple_ ).numBlocks();
363  if( localBlock >= 0 )
364  {
365  comp = i;
366  oIndex = std::get< i >( this->mapperTuple_ ).oldIndex( hole, localBlock );
367  }
368  } );
369  assert( comp >= 0 );
370  return oIndex + globalOffset_[ comp ];
371  }
372 
373  GlobalKeyType newIndex ( int hole, int block ) const
374  {
375  int comp = -1;
376  SizeType nIndex = 0;
377  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
378  [ & ]( auto i )
379  {
380  if( comp >= 0 )
381  return;
382  const int localBlock = block - std::get< i >( this->mapperTuple_ ).numBlocks();
383  if( localBlock >= 0 )
384  {
385  comp = i;
386  nIndex = std::get< i >( this->mapperTuple_ ).newIndex( hole, localBlock );
387  }
388  } );
389  assert( comp > 0 );
390  return nIndex + globalOffset_[ comp ];
391  }
392 
393  SizeType oldOffSet ( int block ) const
394  {
395  int comp = -1;
396  SizeType oOffset = 0;
397  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
398  [ & ]( auto i )
399  {
400  if( comp >= 0 )
401  return;
402  const int localBlock = block - std::get< i >( this->mapperTuple_ ).numBlocks();
403  if( localBlock >= 0 )
404  {
405  comp = i;
406  oOffset = std::get< i >( this->mapperTuple_ ).oldOffSet( localBlock );
407  }
408  } );
409  assert( comp >= 0 );
410  return oOffset + oldGlobalOffset_[ comp ];
411  }
412 
413  SizeType offSet ( int block ) const
414  {
415  int comp = -1;
416  SizeType offset = 0;
417  Hybrid::forEach( std::make_index_sequence< mapperTupleSize >{},
418  [ & ]( auto i )
419  {
420  if( comp >= 0 )
421  return;
422  const int localBlock = block - std::get< i >( this->mapperTuple_ ).numBlocks();
423  if( localBlock >= 0 )
424  {
425  comp = i;
426  offset = std::get< i >( this->mapperTuple_ ).offSet( localBlock );
427  }
428  } );
429  assert( comp >= 0 );
430  return offset + globalOffset_[ comp ];
431  }
432 
433  void resize () { update(); }
434 
435  bool compress ()
436  {
437  update();
438  return true;
439  }
440 
441  void backup () const {}
442 
443  void restore () { update(); }
444 
445  template< class IOStream >
446  void read ( IOStream &in ) { update(); }
447 
448  template< class IOStream >
449  void write ( IOStream &out ) const {}
450 
451  template< class Entity >
452  void insertEntity ( const Entity & ) { update(); }
453 
454  template< class Entity >
455  void removeEntity ( const Entity & ) { update(); }
456 
457  void update ()
458  {
459  oldGlobalOffset_ = globalOffset_;
460  BaseType::init();
461  }
462 
463  protected:
464  template< std::size_t ... i >
465  SizeType numBlocks ( std::index_sequence< i ... > ) const
466  {
467  return Std::sum( std::get< i >( mapperTuple_ ).numBlocks() ... );
468  }
469 
470  private:
471  OffsetType oldGlobalOffset_;
472  };
473 
474 
475 
476  // Implementation
477  // --------------
478 
479  template< class GridPart, class ... Mapper >
480  struct Implementation
481  {
482  typedef typename std::conditional<
484  AdaptiveDofMapper< Traits< GridPart, Mapper ... > >,
485  DofMapper< Traits< GridPart, Mapper ... > > >::type Type;
486  };
487 
488 
489  } // namespace __TupleMapper
490 
491 #endif // #ifndef DOXYGEN
492 
493 
494  // TupleMapper
495  // -----------
496 
507  template< class GridPart, class ... Mapper >
509  : public __TupleMapper::template Implementation< GridPart, Mapper ... >::Type
510  {
511  typedef typename __TupleMapper::template Implementation< GridPart, Mapper ... >::Type BaseType;
512 
513  public:
514  TupleMapper ( GridPart &gridPart, Mapper & ... mapper ) : BaseType( gridPart, mapper ... ) {}
515  TupleMapper ( GridPart &gridPart, Mapper && ... mapper ) : BaseType( gridPart, std::move( mapper ) ... ) {}
516  };
517 
518  // Capabilities
519  // ------------
520 
521  namespace Capabilities
522  {
523  template< class GridPart, class ... Mapper >
524  struct isAdaptiveDofMapper< TupleMapper< GridPart, Mapper ... > >
525  {
526  static const bool v = Std::And( isAdaptiveDofMapper< Mapper >::v ... );
527  };
528 
529  template< class GridPart, class ... Mapper >
530  struct isConsecutiveIndexSet< __TupleMapper::AdaptiveDofMapper< __TupleMapper::Traits< GridPart, Mapper ... > > >
531  {
532  static const bool v = true;
533  };
534 
535  } // namespace Capabilities
536 
537  } // namespace Fem
538 
539 } // namespace Dune
540 
541 #endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
void removeIndexSet(const IndexSetType &iset)
removed index set from dof manager's list of index sets
Definition: dofmanager.hh:1289
static ThisType & instance(const GridType &grid)
obtain a reference to the DofManager for a given grid
Definition: dofmanager.hh:1216
void addIndexSet(const IndexSetType &iset)
add index set to dof manager's list of index sets
Definition: dofmanager.hh:1259
Definition: bindguard.hh:11
static void forEach(IndexRange< T, sz > range, F &&f)
Definition: hybrid.hh:129
static constexpr std::decay_t< T > sum(T a)
Definition: utility.hh:33
static constexpr bool And()
Definition: utility.hh:125
static constexpr bool Or()
Definition: utility.hh:110
specialize with true if index set implements the interface for consecutive index sets
Definition: common/indexset.hh:42
static const bool v
Definition: common/indexset.hh:49
mapper allocating one DoF per subentity of a given codimension
Definition: tuplemapper.hh:510
TupleMapper(GridPart &gridPart, Mapper &... mapper)
Definition: tuplemapper.hh:514
TupleMapper(GridPart &gridPart, Mapper &&... mapper)
Definition: tuplemapper.hh:515
Definition: space/mapper/capabilities.hh:22
static const bool v
Definition: space/mapper/capabilities.hh:23
Interface for calculating the size of a function space for a grid on a specified level....
Definition: mapper/dofmapper.hh:43
Extended interface for adaptive DoF mappers.
Definition: mapper/dofmapper.hh:219