dune-fem 2.8.0
Loading...
Searching...
No Matches
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
16namespace 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 {
316 DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).addIndexSet( *this );
317 }
318
319 AdaptiveDofMapper ( GridPartType &gridPart, Mapper && ... mapper )
320 : BaseType( gridPart, std::move( mapper ) ... )
321 {
322 DofManager< typename GridPartType::GridType >::instance( gridPart_.grid() ).addIndexSet( *this );
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<
483 Std::And( Capabilities::isAdaptiveDofMapper< Mapper >::v ... ),
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
STL namespace.
Definition: bindguard.hh:11
static constexpr bool And()
Definition: utility.hh:125
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