1#ifndef DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
2#define DUNE_FEM_SPACE_COMBINEDSPACE_TUPLEMAPPER_HH
8#include <dune/common/hybridutilities.hh>
10#include <dune/fem/common/utility.hh>
11#include <dune/fem/space/common/adaptationmanager.hh>
12#include <dune/fem/space/common/dofmanager.hh>
13#include <dune/fem/space/mapper/dofmapper.hh>
14#include <dune/fem/space/mapper/nonblockmapper.hh>
15#include <dune/fem/misc/functor.hh>
18#pragma GCC diagnostic push
20#pragma GCC diagnostic ignored "-Wattributes"
30 template<
class GridPart,
class ... Mapper >
36 namespace __TupleMapper
42 template<
class GridPart,
class ... Mapper >
45 static_assert( Std::are_all_same<
typename Mapper::ElementType ... >::value,
46 "TupleMapper needs common ElementType" );
48 typedef typename std::tuple_element< 0, std::tuple< Mapper ... > >::type FirstMapperType;
49 typedef typename FirstMapperType::ElementType ElementType;
50 typedef typename FirstMapperType::SizeType SizeType;
51 typedef typename FirstMapperType::GlobalKeyType GlobalKeyType;
53 typedef TupleMapper< GridPart, Mapper ... > DofMapperType;
59 template<
class Index,
class Int, Int i >
62 constexpr CombinedIndex ( Index index, Index offset ) : index_( index ), offset_( offset ) {}
64 static constexpr Int component () {
return i; }
66 constexpr operator Index ()
const {
return index_ + offset_; }
68 constexpr Index index ()
const {
return index_; }
70 constexpr Index offset ()
const {
return offset_; }
73 Index index_, offset_;
83 template<
class GridPart,
class ... Mapper,
template<
class >
class Base >
84 class DofMapper< Traits< GridPart, Mapper ... >, Base >
85 :
public Base< Traits< GridPart, Mapper ... > >
87 typedef Base< Traits< GridPart, Mapper ... > > BaseType;
92 template<
class Functor,
int i >
95 FunctorWrapper ( Functor functor,
int localOffset,
int globalOffset )
96 : functor_( functor ),
97 localOffset_( localOffset ),
98 globalOffset_( globalOffset )
101 template<
class GlobalKey >
102 void operator() (
int localDof,
const GlobalKey &globalKey )
const
104 functor_( localDof + localOffset_, CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
107 template<
class GlobalKey >
108 void operator() (
const GlobalKey &globalKey )
const
110 functor_( CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
115 const int localOffset_;
116 const int globalOffset_;
121 static const int mapperTupleSize =
sizeof ... ( Mapper );
123 typedef std::array< typename BaseType::SizeType, mapperTupleSize + 1 > OffsetType;
126 typedef typename BaseType::ElementType ElementType;
127 typedef typename BaseType::SizeType SizeType;
128 typedef typename BaseType::Traits::GlobalKeyType GlobalKeyType;
130 typedef GridPart GridPartType;
132 DofMapper ( GridPartType &gridPart, Mapper & ... mapper )
133 : gridPart_( gridPart ),
134 mapperTuple_( mapper ... )
139 DofMapper ( GridPartType &gridPart, Mapper && ... mapper )
140 : gridPart_( gridPart ),
141 mapperTuple_(
std::move( mapper ) ... )
146 SizeType
size ()
const {
return size( std::index_sequence_for< Mapper ... >() ); }
148 bool contains (
const int codim )
const {
return contains( codim, std::index_sequence_for< Mapper ... >() ); }
150 bool fixedDataSize (
int codim )
const {
return fixedDataSize( codim, std::index_sequence_for< Mapper ... >() ); }
152 template<
class Functor >
153 void mapEach (
const ElementType &element, Functor f )
const
155 OffsetType localOffset;
156 localOffset[ 0 ] = 0;
160 FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
161 std::get< i >( mapperTuple_ ).mapEach( element, wrappedFunctor );
162 localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numDofs( element );
166 template<
class Entity,
class Functor >
167 void mapEachEntityDof (
const Entity &entity, Functor f )
const
169 OffsetType localOffset;
170 localOffset[ 0 ] = 0;
174 FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
175 std::get< i >( mapperTuple_ ).mapEachEntityDof( entity, wrappedFunctor );
176 localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numEntityDofs( entity );
180 [[deprecated(
"Use onSubEntity method with char vector instead")]]
181 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< bool > &indices )
const
183 std::vector< char > _idx;
184 onSubEntity(element, i, c, _idx);
185 indices.resize( _idx.size() );
186 for (std::size_t i=0; i<_idx.size();++i)
187 _idx[i] = indices[i] > 0;
197 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< char > &indices )
const
199 indices.resize( numDofs( element ) );
200 OffsetType localOffset;
201 localOffset[ 0 ] = 0;
206 std::vector< char > subIndices;
207 std::get< t >( mapperTuple_ ).onSubEntity( element, i,c, subIndices );
208 auto localSize = std::get< t >( mapperTuple_ ).numDofs( element );
209 assert( subIndices.size() == localSize );
210 assert( localOffset[ t ] + localSize <= indices.size() );
211 for (std::size_t d=0;d<subIndices.size();++d)
213 indices[ localOffset[t] + d ] = subIndices[d]==0? 0 : subIndices[d] + rangeOffset;
229 rangeOffset += std::get< t >( mapperTuple_ ).blockSize;
230 localOffset[ t + 1 ] = localOffset[ t ] + localSize;
241 int maxNumDofs ()
const {
return maxNumDofs( std::index_sequence_for< Mapper ... >() ); }
243 SizeType numDofs (
const ElementType &element )
const {
return numDofs( element, std::index_sequence_for< Mapper ... >() ); }
245 template<
class Entity >
246 SizeType numEntityDofs (
const Entity &entity )
const {
return numEntityDofs( entity, std::index_sequence_for< Mapper ... >() ); }
248 void map (
const ElementType &element, std::vector< SizeType > &indices )
const
250 indices.resize( numDofs( element ) );
251 mapEach( element, AssignFunctor< std::vector< SizeType > >( indices ) );
253 template<
class Entity >
254 void mapEntityDofs (
const Entity &entity, std::vector< SizeType > &indices )
const
256 indices.resize( numEntityDofs( entity ) );
257 mapEachEntityDof( entity, AssignFunctor< std::vector< SizeType > >( indices ) );
260 static constexpr bool consecutive () noexcept {
return false; }
262 SizeType numBlocks ()
const
264 DUNE_THROW( NotImplemented,
"Method numBlocks() called on non-adaptive block mapper" );
267 SizeType numberOfHoles (
int )
const
269 DUNE_THROW( NotImplemented,
"Method numberOfHoles() called on non-adaptive block mapper" );
272 GlobalKeyType oldIndex (
int hole,
int )
const
274 DUNE_THROW( NotImplemented,
"Method oldIndex() called on non-adaptive block mapper" );
277 GlobalKeyType newIndex (
int hole,
int )
const
279 DUNE_THROW( NotImplemented,
"Method newIndex() called on non-adaptive block mapper" );
282 SizeType oldOffSet (
int )
const
284 DUNE_THROW( NotImplemented,
"Method oldOffSet() called on non-adaptive block mapper" );
287 SizeType offSet (
int )
const
289 DUNE_THROW( NotImplemented,
"Method offSet() called on non-adaptive block mapper" );
296 [ & ](
auto i){ std::get< i >( mapperTuple_ ).update(); } );
303 SizeType offset (
int i )
const {
return globalOffset_[ i ]; }
306 SizeType subSize ()
const {
return std::get< i >( mapperTuple_ ).size(); }
309 template< std::size_t ... i >
310 SizeType
size ( std::index_sequence< i ... > )
const
312 return Std::sum( std::get< i >( mapperTuple_ ).
size() ... );
315 template< std::size_t ... i >
316 bool fixedDataSize (
const int codim, std::index_sequence< i ... > )
const
318 return Std::And( std::get< i >( mapperTuple_ ).fixedDataSize( codim ) ... );
321 template< std::size_t ... i >
322 bool contains (
const int codim, std::index_sequence< i ... > )
const
324 return Std::Or( std::get< i >( mapperTuple_ ).
contains( codim ) ... );
327 template< std::size_t ... i >
328 int maxNumDofs ( std::index_sequence< i ... > )
const
330 return Std::sum( std::get< i >( mapperTuple_ ).maxNumDofs() ... );
333 template< std::size_t ... i >
334 SizeType numDofs (
const ElementType &element, std::index_sequence< i ... > )
const
336 return Std::sum( std::get< i >( mapperTuple_ ).numDofs( element ) ... );
339 template<
class Entity, std::size_t ... i >
340 SizeType numEntityDofs (
const Entity &entity, std::index_sequence< i ... > )
const
342 return Std::sum( std::get< i >( mapperTuple_ ).numEntityDofs( entity ) ... );
345 void computeOffset ()
347 globalOffset_[ 0 ] = 0;
350 [ & ](
auto i ){ globalOffset_[ i + 1 ] = globalOffset_[ i ] + std::get< i >( mapperTuple_ ).size(); } );
353 GridPartType &gridPart_;
354 std::tuple< Mapper ... > mapperTuple_;
355 OffsetType globalOffset_;
364 class AdaptiveDofMapper;
366 template<
class GridPart,
class ... Mapper >
367 class AdaptiveDofMapper< Traits< GridPart, Mapper ... > >
368 :
public DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper >
373 typedef typename GridPart :: GridType GridType;
374 typedef AdaptationMethod< GridType > AdaptationMethodType;
376 typedef typename BaseType::OffsetType OffsetType;
378 using BaseType::mapperTupleSize;
379 using BaseType::mapperTuple_;
380 using BaseType::gridPart_;
381 using BaseType::globalOffset_;
384 typedef typename BaseType::ElementType ElementType;
385 typedef typename BaseType::SizeType SizeType;
386 typedef typename BaseType::GlobalKeyType GlobalKeyType;
387 typedef GridPart GridPartType;
389 AdaptiveDofMapper ( GridPartType &gridPart, Mapper & ... mapper )
390 : BaseType( gridPart, mapper ... ),
391 numBlocks_( computeNumBlocks() ),
392 isCallBackAdapt_( AdaptationMethodType( gridPart.grid() ).isCallBackAdaptation() ),
393 needsFullUpdate_(true)
395 oldGlobalOffset_ = globalOffset_;
399 AdaptiveDofMapper ( GridPartType &gridPart, Mapper && ... mapper )
400 : BaseType( gridPart,
std::move( mapper ) ... ),
401 numBlocks_( computeNumBlocks() ),
402 isCallBackAdapt_( AdaptationMethodType( gridPart.grid() ).isCallBackAdaptation() ),
403 needsFullUpdate_(true)
405 oldGlobalOffset_ = globalOffset_;
411 AdaptiveDofMapper (
const AdaptiveDofMapper & ) =
delete;
412 AdaptiveDofMapper ( AdaptiveDofMapper && ) =
delete;
414 static constexpr bool consecutive () noexcept {
return true; }
416 SizeType numBlocks ()
const {
return numBlocks( std::index_sequence_for< Mapper ... >() ); }
418 SizeType numberOfHoles (
const int block )
const
424 const int localBlock = computeBlock( i, block );
425 if( localBlock >= 0 )
427 nHoles = std::get< i >( this->mapperTuple_ ).numberOfHoles( localBlock );
434 GlobalKeyType oldIndex (
const int hole,
const int block )
const
440 const int localBlock = computeBlock( i, block );
441 if( localBlock >= 0 )
443 oIndex = std::get< i >( this->mapperTuple_ ).oldIndex( hole, localBlock ) + globalOffset_[ i ];
450 GlobalKeyType newIndex (
const int hole,
const int block )
const
456 const int localBlock = computeBlock( i, block );
457 if( localBlock >= 0 )
459 nIndex = std::get< i >( this->mapperTuple_ ).newIndex( hole, localBlock ) + globalOffset_[ i ];
466 SizeType oldOffSet (
int block )
const
468 SizeType oOffset = 0;
472 const int localBlock = computeBlock( i, block );
473 if( localBlock >= 0 )
475 oOffset = std::get< i >( this->mapperTuple_ ).oldOffSet( localBlock ) + oldGlobalOffset_[ i ];
482 SizeType offSet (
int block )
const
488 const int localBlock = computeBlock( i, block );
489 if( localBlock >= 0 )
491 offset = std::get< i >( this->mapperTuple_ ).offSet( localBlock ) + globalOffset_[ i ];
498 void resize () { update(); }
504 needsFullUpdate_ =
true;
508 void backup ()
const {}
510 void restore () { compress(); }
512 template<
class IOStream >
513 void read ( IOStream &in ) { compress(); }
515 template<
class IOStream >
516 void write ( IOStream &out )
const {}
518 template<
class Entity >
519 void insertEntity (
const Entity & )
521 if( needsFullUpdate_ )
534 template<
class Entity >
535 void removeEntity (
const Entity & ) {}
540 oldGlobalOffset_ = globalOffset_;
543 needsFullUpdate_ = isCallBackAdapt_ ;
550 int computeBlock(
const int i,
const unsigned int block )
const
552 if( block >= blocks_[ i ] && block < blocks_[ i + 1 ] )
553 return block - blocks_[ i ];
558 void printOffSet(
const OffsetType& offset,
const std::string& name )
const
560 for(
const auto& off : offset )
562 std::cout << name <<
" = " << off << std::endl;
566 template< std::size_t ... i >
567 SizeType numBlocks ( std::index_sequence< i ... > )
const
569 return Std::sum( std::get< i >( mapperTuple_ ).numBlocks() ... );
572 SizeType computeNumBlocks ()
578 [ & ](
auto i ){ blocks_[ i + 1 ] = blocks_[ i ] + std::get< i >( mapperTuple_ ).numBlocks(); } );
581 return blocks_.back();
585 OffsetType oldGlobalOffset_;
588 const SizeType numBlocks_;
589 const bool isCallBackAdapt_;
590 bool needsFullUpdate_;
598 template<
class GridPart,
class ... Mapper >
599 struct Implementation
601 typedef typename std::conditional<
602 Std::And( Capabilities::isAdaptiveDofMapper< Mapper >::v ... ),
603 AdaptiveDofMapper< Traits< GridPart, Mapper ... > >,
604 DofMapper< Traits< GridPart, Mapper ... > > >::type Type;
626 template<
class GridPart,
class ... Mapper >
628 :
public __TupleMapper::template Implementation< GridPart, Mapper ... >::Type
630 typedef typename __TupleMapper::template Implementation< GridPart,
Mapper ... >::Type BaseType;
633 TupleMapper ( GridPart &gridPart,
Mapper & ... mapper ) : BaseType( gridPart, mapper ... ) {}
634 TupleMapper ( GridPart &gridPart,
Mapper && ... mapper ) : BaseType( gridPart, std::move( mapper ) ... ) {}
640 namespace Capabilities
642 template<
class GridPart,
class ...
Mapper >
645 static const bool v = Std::And( isAdaptiveDofMapper< Mapper >::v ... );
648 template<
class GridPart,
class ...
Mapper >
649 struct isConsecutiveIndexSet< __TupleMapper::AdaptiveDofMapper< __TupleMapper::Traits< GridPart, Mapper ... > > >
651 static const bool v =
true;
661#pragma GCC diagnostic pop
Extended interface for adaptive DoF mappers.
Definition: dofmapper.hh:219
Interface for calculating the size of a function space for a grid on a specified level....
Definition: dofmapper.hh:43
mapper allocating one DoF per subentity of a given codimension
Definition: tuplemapper.hh:629
Mapper interface.
Definition: mapper.hh:110
void removeIndexSet(const IndexSetType &iset)
removed index set from dof manager's list of index sets
Definition: dofmanager.hh:1331
static ThisType & instance(const GridType &grid)
obtain a reference to the DofManager for a given grid
Definition: dofmanager.hh:1251
void addIndexSet(const IndexSetType &iset)
add index set to dof manager's list of index sets
Definition: dofmanager.hh:1296
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr std::bool_constant<((II==value)||...)> contains(std::integer_sequence< T, II... >, std::integral_constant< T, value >)
Checks whether or not a given sequence contains a value.
Definition: integersequence.hh:137