dune-fem  2.4.1-rc
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/forloop.hh>
9 #include <dune/common/tuples.hh>
10 
11 #include <dune/common/std/utility.hh>
13 
17 
18 
19 namespace Dune
20 {
21 
22  namespace Fem
23  {
24 
25  // Internal forward declaration
26  // ----------------------------
27  template< class GridPart, class ... Mapper >
28  class TupleMapper;
29 
30 
31 #ifndef DOXYGEN
32 
33  namespace __TupleMapper
34  {
35 
36  // Traits
37  // ------
38 
39  template< class GridPart, class ... Mapper >
40  struct Traits
41  {
43  "TupleMapper needs common ElementType" );
44 
45  typedef typename std::tuple_element< 0, std::tuple< Mapper ... > >::type FirstMapperType;
46  typedef typename FirstMapperType::ElementType ElementType;
47  typedef typename FirstMapperType::SizeType SizeType;
48  typedef typename FirstMapperType::GlobalKeyType GlobalKeyType;
49 
50  typedef TupleMapper< GridPart, Mapper ... > DofMapperType;
51  };
52 
53 
54  // DofMapper
55  // ---------
56 
57  template< class T, template< class > class Base = Dune::Fem::DofMapper >
58  class DofMapper;
59 
60  template< class GridPart, class ... Mapper, template< class > class Base >
61  class DofMapper< Traits< GridPart, Mapper ... >, Base >
62  : public Base< Traits< GridPart, Mapper ... > >
63  {
64  typedef Base< Traits< GridPart, Mapper ... > > BaseType;
65 
66  // helper classes
67  template< int >
68  struct ComputeOffSet;
69  template< int >
70  struct MapEach;
71  template< int >
72  struct MapEachEntityDof;
73 
74  // FunctorWrapper
75  // --------------
76 
77  template< class Functor >
78  struct FunctorWrapper
79  {
80  FunctorWrapper ( Functor functor, int localOffset, int globalOffset )
81  : functor_( functor ),
82  localOffset_( localOffset ),
83  globalOffset_( globalOffset )
84  {}
85 
86  template< class GlobalKey >
87  void operator() ( int localDof, const GlobalKey &globalKey )
88  {
89  functor_( localDof + localOffset_, globalKey + globalOffset_ );
90  }
91 
92  template< class GlobalKey >
93  void operator() ( const GlobalKey &globalKey )
94  {
95  functor_( globalKey + globalOffset_ );
96  }
97 
98  private:
99  Functor functor_;
100  const int localOffset_;
101  const int globalOffset_;
102  };
103 
104  // size of the Mapper Tuple
105  static const int mapperTupleSize = sizeof ... ( Mapper );
106 
107  typedef std::array< typename BaseType::SizeType, mapperTupleSize + 1 > OffsetType;
108 
109  public:
110  typedef typename BaseType::ElementType ElementType;
111  typedef typename BaseType::SizeType SizeType;
112  typedef typename BaseType::Traits::GlobalKeyType GlobalKeyType;
113 
114  typedef GridPart GridPartType;
115 
116  DofMapper ( GridPartType &gridPart, Mapper & ... mapper )
117  : gridPart_( gridPart ),
118  mapperTuple_( mapper ... )
119  {
120  init();
121  }
122 
123  DofMapper ( GridPartType &gridPart, Mapper && ... mapper )
124  : gridPart_( gridPart ),
125  mapperTuple_( std::move( mapper ) ... )
126  {
127  init();
128  }
129 
130  SizeType size () const { return size( Std::index_sequence_for< Mapper ... >() ); }
131 
132  bool contains ( const int codim ) const { return contains( codim, Std::index_sequence_for< Mapper ... >() ); }
133 
134  bool fixedDataSize ( int codim ) const { return fixedDataSize( codim, Std::index_sequence_for< Mapper ... >() ); }
135 
136  template< class Functor >
137  void mapEach ( const ElementType &element, Functor f ) const
138  {
139  OffsetType localOffset;
140  localOffset[ 0 ] = 0;
141  ForLoop< MapEach, 0, mapperTupleSize - 1 >::apply( localOffset, globalOffset_, element, f, mapperTuple_ );
142  }
143 
144  template< class Entity, class Functor >
145  void mapEachEntityDof ( const Entity &entity, Functor f ) const
146  {
147  OffsetType localOffset;
148  localOffset[ 0 ] = 0;
149  ForLoop< MapEachEntityDof, 0, mapperTupleSize - 1 >::apply( localOffset, globalOffset_, entity, f, mapperTuple_ );
150  }
151 
152  int maxNumDofs () const { return maxNumDofs( Std::index_sequence_for< Mapper ... >() ); }
153 
154  SizeType numDofs ( const ElementType &element ) const { return numDofs( element, Std::index_sequence_for< Mapper ... >() ); }
155 
156  template< class Entity >
157  SizeType numEntityDofs ( const Entity &entity ) const { return numEntityDofs( entity, Std::index_sequence_for< Mapper ... >() ); }
158 
159 
160  static constexpr bool consecutive () noexcept { return false; }
161 
162  SizeType numBlocks () const
163  {
164  DUNE_THROW( NotImplemented, "Method numBlocks() called on non-adaptive block mapper" );
165  }
166 
167  SizeType numberOfHoles ( int ) const
168  {
169  DUNE_THROW( NotImplemented, "Method numberOfHoles() called on non-adaptive block mapper" );
170  }
171 
172  GlobalKeyType oldIndex ( int hole, int ) const
173  {
174  DUNE_THROW( NotImplemented, "Method oldIndex() called on non-adaptive block mapper" );
175  }
176 
177  GlobalKeyType newIndex ( int hole, int ) const
178  {
179  DUNE_THROW( NotImplemented, "Method newIndex() called on non-adaptive block mapper" );
180  }
181 
182  SizeType oldOffSet ( int ) const
183  {
184  DUNE_THROW( NotImplemented, "Method oldOffSet() called on non-adaptive block mapper" );
185  }
186 
187  SizeType offSet ( int ) const
188  {
189  DUNE_THROW( NotImplemented, "Method offSet() called on non-adaptive block mapper" );
190  }
191 
192  /*** NonInterface Methods ***/
193 
194  SizeType offset ( int i ) const { return globalOffset_[ i ]; }
195 
196  template< int i >
197  SizeType subSize () const { return std::get< i >( mapperTuple_ ).size(); }
198 
199  protected:
200  template< std::size_t ... i >
201  SizeType size ( Std::index_sequence< i ... > ) const
202  {
203  return Std::sum( std::get< i >( mapperTuple_ ).size() ... );
204  }
205 
206  template< std::size_t ... i >
207  bool fixedDataSize ( const int codim, Std::index_sequence< i ... > ) const
208  {
209  return Std::And( std::get< i >( mapperTuple_ ).fixedDataSize( codim ) ... );
210  }
211 
212  template< std::size_t ... i >
213  bool contains ( const int codim, Std::index_sequence< i ... > ) const
214  {
215  return Std::Or( std::get< i >( mapperTuple_ ).contains( codim ) ... );
216  }
217 
218  template< std::size_t ... i >
219  int maxNumDofs ( Std::index_sequence< i ... > ) const
220  {
221  return Std::sum( std::get< i >( mapperTuple_ ).maxNumDofs() ... );
222  }
223 
224  template< std::size_t ... i >
225  SizeType numDofs ( const ElementType &element, Std::index_sequence< i ... > ) const
226  {
227  return Std::sum( std::get< i >( mapperTuple_ ).numDofs( element ) ... );
228  }
229 
230  template< class Entity, std::size_t ... i >
231  SizeType numEntityDofs ( const Entity &entity, Std::index_sequence< i ... > ) const
232  {
233  return Std::sum( std::get< i >( mapperTuple_ ).numEntityDofs( entity ) ... );
234  }
235 
236  void init ()
237  {
238  globalOffset_[ 0 ] = 0;
239  // compute new offsets
240  ForLoop< ComputeOffSet, 0, mapperTupleSize - 1 >::apply( globalOffset_, mapperTuple_ );
241  }
242 
243  GridPartType &gridPart_;
244  std::tuple< Mapper ... > mapperTuple_;
245  OffsetType globalOffset_;
246  };
247 
248 
249  // ComputeOffSet
250  // -------------
251 
252  template< class GridPart, class ... Mapper, template< class > class Base >
253  template< int i >
254  struct DofMapper< Traits< GridPart, Mapper ... >, Base >::
255  ComputeOffSet
256  {
257  template< class Tuple >
258  static void apply ( OffsetType &offset, const Tuple &tuple )
259  {
260  offset[ i + 1 ] = offset[ i ] + std::get< i >( tuple ).size();
261  }
262  };
263 
264 
265  // MapEachEntityDof
266  // ----------------
267 
268  template< class GridPart, class ... Mapper, template< class > class Base >
269  template< int i >
270  struct DofMapper< Traits< GridPart, Mapper ... >, Base >::
271  MapEachEntityDof
272  {
273  template< class Entity, class Functor, class Tuple >
274  static void apply ( OffsetType &localOffset, const OffsetType &globalOffset, const Entity &entity, Functor f, const Tuple &tuple )
275  {
276  FunctorWrapper< Functor > wrappedFunctor( f, localOffset[ i ], globalOffset[ i ] );
277  std::get< i >( tuple ).mapEachEntityDof( entity, wrappedFunctor );
278  localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( tuple ).numEntityDofs( entity );
279  }
280  };
281 
282 
283  // MapEach
284  // -------
285 
286  template< class GridPart, class ... Mapper, template< class > class Base >
287  template< int i >
288  struct DofMapper< Traits< GridPart, Mapper ... >, Base >::
289  MapEach
290  {
291  template< class Functor, class Tuple >
292  static void apply ( OffsetType &localOffset, const OffsetType &globalOffset, const ElementType &element, Functor f, const Tuple &tuple )
293  {
294  FunctorWrapper< Functor > wrappedFunctor( f, localOffset[ i ], globalOffset[ i ] );
295  std::get< i >( tuple ).mapEach( element, wrappedFunctor );
296  localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( tuple ).numDofs( element );
297  }
298  };
299 
300 
301  // AdaptiveDofMapper
302  // -----------------
303 
304  template< class T >
305  class AdaptiveDofMapper;
306 
307  template< class GridPart, class ... Mapper >
308  class AdaptiveDofMapper< Traits< GridPart, Mapper ... > >
309  : public DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper >
310  {
311  typedef DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper > BaseType;
312 
313  protected:
314 
315  // helper classes
316  template< int >
317  struct Offset;
318  template< int >
319  struct OldOffset;
320  template< int >
321  struct NewIndex;
322  template< int >
323  struct OldIndex;
324  template< int >
325  struct NumberOfHoles;
326 
327  // size of the Mapper Tuple
328  static const int mapperTupleSize = sizeof ... ( Mapper );
329 
330  typedef std::array< typename BaseType::Traits::SizeType, mapperTupleSize + 1 > OffsetType;
331 
332  using BaseType::mapperTuple_;
333  using BaseType::gridPart_;
334  using BaseType::globalOffset_;
335 
336  public:
337  typedef typename BaseType::ElementType ElementType;
338  typedef typename BaseType::SizeType SizeType;
339  typedef typename BaseType::GlobalKeyType GlobalKeyType;
340  typedef GridPart GridPartType;
341 
342  AdaptiveDofMapper ( GridPartType &gridPart, Mapper & ... mapper )
343  : BaseType( gridPart, mapper ... )
344  {
345  DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).addIndexSet( *this );
346  }
347 
348  AdaptiveDofMapper ( GridPartType &gridPart, Mapper && ... mapper )
349  : BaseType( gridPart, std::move( mapper ) ... )
350  {
351  DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).addIndexSet( *this );
352  }
353 
354  ~AdaptiveDofMapper () { DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).removeIndexSet( *this ); }
355 
356  AdaptiveDofMapper ( const AdaptiveDofMapper & ) = delete;
357  AdaptiveDofMapper ( AdaptiveDofMapper && ) = delete;
358 
359  static constexpr bool consecutive () noexcept { return true; }
360 
361  SizeType numBlocks () const { return numBlocks( Std::index_sequence_for< Mapper ... >() ); }
362 
363  SizeType numberOfHoles ( int block ) const
364  {
365  SizeType nHoles = 0;
366  int comp = -1;
367  ForLoop< NumberOfHoles, 0, mapperTupleSize - 1 >::apply( nHoles, comp, block, mapperTuple_ );
368  return nHoles;
369  }
370 
371  GlobalKeyType oldIndex ( int hole, int block ) const
372  {
373  int comp = -1;
374  SizeType oIndex = 0;
375  ForLoop< OldIndex, 0, mapperTupleSize - 1 >::apply( oIndex, comp, hole, block, mapperTuple_ );
376  assert( comp >= 0 );
377  return oIndex + globalOffset_[ comp ];
378  }
379 
380  GlobalKeyType newIndex ( int hole, int block ) const
381  {
382  int comp = -1;
383  SizeType nIndex = 0;
384  ForLoop< NewIndex, 0, mapperTupleSize - 1 >::apply( nIndex, comp, hole, block, mapperTuple_ );
385  assert( comp > 0 );
386  return nIndex + globalOffset_[ comp ];
387  }
388 
389  SizeType oldOffSet ( int block ) const
390  {
391  int comp = -1;
392  SizeType oOffset = 0;
393  ForLoop< OldOffset, 0, mapperTupleSize - 1 >::apply( oOffset, comp, block, mapperTuple_ );
394  assert( comp >= 0 );
395  return oOffset + oldGlobalOffset_[ comp ];
396  }
397 
398  SizeType offSet ( int block ) const
399  {
400  int comp = -1;
401  SizeType offset = 0;
402  ForLoop< Offset, 0, mapperTupleSize - 1 >::apply( offset, comp, block, mapperTuple_ );
403  assert( comp >= 0 );
404  return offset + globalOffset_[ comp ];
405  }
406 
407 
408  void resize () { update(); }
409 
410  bool compress ()
411  {
412  update();
413  return true;
414  }
415 
416  void backup () const {}
417 
418  void restore () { update(); }
419 
420  template< class IOStream >
421  void read ( IOStream &in ) { update(); }
422 
423  template< class IOStream >
424  void write ( IOStream &out ) const {}
425 
426  template< class Entity >
427  void insertEntity ( const Entity & ) { update(); }
428 
429  template< class Entity >
430  void removeEntity ( const Entity & ) { update(); }
431 
432  protected:
433 
434  void update ()
435  {
436  oldGlobalOffset_ = globalOffset_;
437  BaseType::init();
438  }
439 
440  template< std::size_t ... i >
441  SizeType numBlocks ( Std::index_sequence< i ... > ) const
442  {
443  return Std::sum( std::get< i >( mapperTuple_ ).numBlocks() ... );
444  }
445 
446  private:
447  OffsetType oldGlobalOffset_;
448  };
449 
450 
451 
452  // NumberOfHoles
453  // -------------
454 
455  template< class GridPart, class ... Mapper >
456  template< int i >
457  struct AdaptiveDofMapper< Traits< GridPart, Mapper ... > >::
458  NumberOfHoles
459  {
460  template< class Tuple >
461  static void apply ( SizeType &nHoles, int &comp, const int block, const Tuple &tuple )
462  {
463  if( comp >= 0 )
464  return;
465  const int localBlock = block - std::get< i >( tuple ).numBlocks();
466  if( localBlock >= 0 )
467  {
468  comp = i;
469  nHoles = std::get< i >( tuple ).numberOfHoles( localBlock );
470  }
471  }
472  };
473 
474 
475 
476  // OldIndex
477  // --------
478 
479  template< class GridPart, class ... Mapper >
480  template< int i >
481  struct AdaptiveDofMapper< Traits< GridPart, Mapper ... > >::
482  OldIndex
483  {
484  template< class Tuple >
485  static void apply ( SizeType &oldIndex, int &comp, const int hole, const int block, const Tuple &tuple )
486  {
487  if( comp >= 0 )
488  return;
489  const int localBlock = block - std::get< i >( tuple ).numBlocks();
490  if( localBlock >= 0 )
491  {
492  comp = i;
493  oldIndex = std::get< i >( tuple ).oldIndex( hole, localBlock );
494  }
495  }
496  };
497 
498 
499  // NewIndex
500  // --------
501 
502  template< class GridPart, class ... Mapper >
503  template< int i >
504  struct AdaptiveDofMapper< Traits< GridPart, Mapper ... > >::
505  NewIndex
506  {
507  template< class Tuple >
508  static void apply ( SizeType &nIndex, int &comp, const int hole, const int block, const Tuple &tuple )
509  {
510  if( comp >= 0 )
511  return;
512  const int localBlock = block - std::get< i >( tuple ).numBlocks();
513  if( localBlock >= 0 )
514  {
515  comp = i;
516  nIndex = std::get< i >( tuple ).newIndex( hole, localBlock );
517  }
518  }
519  };
520 
521 
522  // OldOffset
523  // ---------
524 
525  template< class GridPart, class ... Mapper >
526  template< int i >
527  struct AdaptiveDofMapper< Traits< GridPart, Mapper ... > >::
528  OldOffset
529  {
530  template< class Tuple >
531  static void apply ( SizeType &offset, int &comp, const int block, const Tuple &tuple )
532  {
533  if( comp >= 0 )
534  return;
535  const int localBlock = block - std::get< i >( tuple ).numBlocks();
536  if( localBlock >= 0 )
537  {
538  comp = i;
539  offset = std::get< i >( tuple ).oldOffSet( localBlock );
540  }
541  }
542  };
543 
544 
545  // Offset
546  // ------
547 
548  template< class GridPart, class ... Mapper >
549  template< int i >
550  struct AdaptiveDofMapper< Traits< GridPart, Mapper ... > >::
551  Offset
552  {
553  template< class Tuple >
554  static void apply ( SizeType &offset, int &comp, const int block, const Tuple &tuple )
555  {
556  if( comp >= 0 )
557  return;
558  const int localBlock = block - std::get< i >( tuple ).numBlocks();
559  if( localBlock >= 0 )
560  {
561  comp = i;
562  offset = std::get< i >( tuple ).offSet( localBlock );
563  }
564  }
565  };
566 
567 
568  // Implementation
569  // --------------
570 
571  template< class GridPart, class ... Mapper >
572  struct Implementation
573  {
574  typedef typename std::conditional<
576  AdaptiveDofMapper< Traits< GridPart, Mapper ... > >,
577  DofMapper< Traits< GridPart, Mapper ... > > >::type Type;
578  };
579 
580 
581  } // namespace __TupleMapper
582 
583 #endif // #ifndef DOXYGEN
584 
585 
586  // TupleMapper
587  // -----------
588 
599  template< class GridPart, class ... Mapper >
600  class TupleMapper
601  : public __TupleMapper::template Implementation< GridPart, Mapper ... >::Type
602  {
603  typedef typename __TupleMapper::template Implementation< GridPart, Mapper ... >::Type BaseType;
604 
605  public:
606  TupleMapper ( GridPart &gridPart, Mapper & ... mapper ) : BaseType( gridPart, mapper ... ) {}
607  TupleMapper ( GridPart &gridPart, Mapper && ... mapper ) : BaseType( gridPart, std::move( mapper ) ... ) {}
608  };
609 
610  // Capabilities
611  // ------------
612 
613  namespace Capabilities
614  {
615  template< class GridPart, class ... Mapper >
616  struct isAdaptiveDofMapper< TupleMapper< GridPart, Mapper ... > >
617  {
618  static const bool v = Std::And( isAdaptiveDofMapper< Mapper >::v ... );
619  };
620 
621  } // namespace Capabilities
622 
623  } // namespace Fem
624 
625 } // namespace Dune
626 
627 #endif // #ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
TupleMapper(GridPart &gridPart, Mapper &...mapper)
Definition: tuplemapper.hh:606
Extended interface for adaptive DoF mappers.
Definition: mapper/dofmapper.hh:204
Definition: utility.hh:135
static constexpr T sum(T a)
Definition: utility.hh:33
mapper allocating one DoF per subentity of a given codimension
Definition: tuplemapper.hh:28
Interface for calculating the size of a function space for a grid on a specified level. Furthermore the local to global mapping of dof number is done. Also during grid adaptation this mapper knows about old and new indices of entities.
Definition: mapper/dofmapper.hh:40
Definition: coordinate.hh:4
static constexpr bool Or(bool a)
Definition: utility.hh:98
STL namespace.
void move(ArrayInterface< T > &array, const unsigned int oldOffset, const unsigned int newOffset, const unsigned int length)
Definition: array_inline.hh:38
Definition: space/mapper/capabilities.hh:21
static constexpr bool And(bool a)
Definition: utility.hh:113
static ThisType & instance(const GridType &grid)
obtain a reference to the DofManager for a given grid
Definition: dofmanager.hh:1319
TupleMapper(GridPart &gridPart, Mapper &&...mapper)
Definition: tuplemapper.hh:607