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>
19#pragma GCC diagnostic push
21#pragma GCC diagnostic ignored "-Wattributes"
33 template<
class GridPart,
class ... Mapper >
39 namespace __TupleMapper
45 template<
class GridPart,
class ... Mapper >
48 static_assert( Std::are_all_same<
typename Mapper::ElementType ... >::value,
49 "TupleMapper needs common ElementType" );
51 typedef typename std::tuple_element< 0, std::tuple< Mapper ... > >::type FirstMapperType;
52 typedef typename FirstMapperType::ElementType ElementType;
53 typedef typename FirstMapperType::SizeType SizeType;
54 typedef typename FirstMapperType::GlobalKeyType GlobalKeyType;
56 typedef TupleMapper< GridPart, Mapper ... > DofMapperType;
62 template<
class Index,
class Int, Int i >
65 constexpr CombinedIndex ( Index index, Index offset ) : index_( index ), offset_( offset ) {}
67 static constexpr Int component () {
return i; }
69 constexpr operator Index ()
const {
return index_ + offset_; }
71 constexpr Index index ()
const {
return index_; }
73 constexpr Index offset ()
const {
return offset_; }
76 Index index_, offset_;
86 template<
class GridPart,
class ... Mapper,
template<
class >
class Base >
87 class DofMapper< Traits< GridPart, Mapper ... >, Base >
88 :
public Base< Traits< GridPart, Mapper ... > >
90 typedef Base< Traits< GridPart, Mapper ... > > BaseType;
95 template<
class Functor,
int i >
98 FunctorWrapper ( Functor functor,
int localOffset,
int globalOffset )
99 : functor_( functor ),
100 localOffset_( localOffset ),
101 globalOffset_( globalOffset )
104 template<
class GlobalKey >
105 void operator() (
int localDof,
const GlobalKey &globalKey )
const
107 functor_( localDof + localOffset_, CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
110 template<
class GlobalKey >
111 void operator() (
const GlobalKey &globalKey )
const
113 functor_( CombinedIndex< GlobalKey, int, i >( globalKey, globalOffset_ ) );
118 const int localOffset_;
119 const int globalOffset_;
124 static const int mapperTupleSize =
sizeof ... ( Mapper );
126 typedef std::array< typename BaseType::SizeType, mapperTupleSize + 1 > OffsetType;
129 typedef typename BaseType::ElementType ElementType;
130 typedef typename BaseType::SizeType SizeType;
131 typedef typename BaseType::Traits::GlobalKeyType GlobalKeyType;
133 typedef GridPart GridPartType;
135 DofMapper ( GridPartType &gridPart, Mapper & ... mapper )
136 : gridPart_( gridPart ),
137 mapperTuple_( mapper ... )
142 DofMapper ( GridPartType &gridPart, Mapper && ... mapper )
143 : gridPart_( gridPart ),
144 mapperTuple_(
std::move( mapper ) ... )
149 SizeType
size ()
const {
return size( std::index_sequence_for< Mapper ... >() ); }
151 bool contains (
const int codim )
const {
return contains( codim, std::index_sequence_for< Mapper ... >() ); }
153 bool fixedDataSize (
int codim )
const {
return fixedDataSize( codim, std::index_sequence_for< Mapper ... >() ); }
155 template<
class Functor >
156 void mapEach (
const ElementType &element, Functor f )
const
158 OffsetType localOffset;
159 localOffset[ 0 ] = 0;
163 FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
164 std::get< i >( mapperTuple_ ).mapEach( element, wrappedFunctor );
165 localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numDofs( element );
169 template<
class Entity,
class Functor >
170 void mapEachEntityDof (
const Entity &entity, Functor f )
const
172 OffsetType localOffset;
173 localOffset[ 0 ] = 0;
177 FunctorWrapper< Functor, i > wrappedFunctor( f, localOffset[ i ], globalOffset_[ i ] );
178 std::get< i >( mapperTuple_ ).mapEachEntityDof( entity, wrappedFunctor );
179 localOffset[ i + 1 ] = localOffset[ i ] + std::get< i >( mapperTuple_ ).numEntityDofs( entity );
183 [[deprecated(
"Use onSubEntity method with char vector instead")]]
184 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< bool > &indices )
const
186 std::vector< char > _idx;
187 onSubEntity(element, i, c, _idx);
188 indices.resize( _idx.size() );
189 for (std::size_t i=0; i<_idx.size();++i)
190 _idx[i] = indices[i] > 0;
200 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< char > &indices )
const
202 indices.resize( numDofs( element ) );
203 OffsetType localOffset;
204 localOffset[ 0 ] = 0;
209 std::vector< char > subIndices;
210 std::get< t >( mapperTuple_ ).onSubEntity( element, i,c, subIndices );
211 auto localSize = std::get< t >( mapperTuple_ ).numDofs( element );
212 assert( subIndices.size() == localSize );
213 assert( localOffset[ t ] + localSize <= indices.size() );
214 for (std::size_t d=0;d<subIndices.size();++d)
216 indices[ localOffset[t] + d ] = subIndices[d]==0? 0 : subIndices[d] + rangeOffset;
232 rangeOffset += std::get< t >( mapperTuple_ ).blockSize;
233 localOffset[ t + 1 ] = localOffset[ t ] + localSize;
244 int maxNumDofs ()
const {
return maxNumDofs( std::index_sequence_for< Mapper ... >() ); }
246 SizeType numDofs (
const ElementType &element )
const {
return numDofs( element, std::index_sequence_for< Mapper ... >() ); }
248 template<
class Entity >
249 SizeType numEntityDofs (
const Entity &entity )
const {
return numEntityDofs( entity, std::index_sequence_for< Mapper ... >() ); }
251 void map (
const ElementType &element, std::vector< SizeType > &indices )
const
253 indices.resize( numDofs( element ) );
254 mapEach( element, AssignFunctor< std::vector< SizeType > >( indices ) );
256 template<
class Entity >
257 void mapEntityDofs (
const Entity &entity, std::vector< SizeType > &indices )
const
259 indices.resize( numEntityDofs( entity ) );
260 mapEachEntityDof( entity, AssignFunctor< std::vector< SizeType > >( indices ) );
263 static constexpr bool consecutive () noexcept {
return false; }
265 SizeType numBlocks ()
const
267 DUNE_THROW( NotImplemented,
"Method numBlocks() called on non-adaptive block mapper" );
270 SizeType numberOfHoles (
int )
const
272 DUNE_THROW( NotImplemented,
"Method numberOfHoles() called on non-adaptive block mapper" );
275 GlobalKeyType oldIndex (
int hole,
int )
const
277 DUNE_THROW( NotImplemented,
"Method oldIndex() called on non-adaptive block mapper" );
280 GlobalKeyType newIndex (
int hole,
int )
const
282 DUNE_THROW( NotImplemented,
"Method newIndex() called on non-adaptive block mapper" );
285 SizeType oldOffSet (
int )
const
287 DUNE_THROW( NotImplemented,
"Method oldOffSet() called on non-adaptive block mapper" );
290 SizeType offSet (
int )
const
292 DUNE_THROW( NotImplemented,
"Method offSet() called on non-adaptive block mapper" );
299 [ & ](
auto i){ std::get< i >( mapperTuple_ ).update(); } );
306 SizeType offset (
int i )
const {
return globalOffset_[ i ]; }
309 SizeType subSize ()
const {
return std::get< i >( mapperTuple_ ).size(); }
312 template< std::size_t ... i >
313 SizeType
size ( std::index_sequence< i ... > )
const
315 return Std::sum( std::get< i >( mapperTuple_ ).
size() ... );
318 template< std::size_t ... i >
319 bool fixedDataSize (
const int codim, std::index_sequence< i ... > )
const
321 return Std::And( std::get< i >( mapperTuple_ ).fixedDataSize( codim ) ... );
324 template< std::size_t ... i >
325 bool contains (
const int codim, std::index_sequence< i ... > )
const
327 return Std::Or( std::get< i >( mapperTuple_ ).
contains( codim ) ... );
330 template< std::size_t ... i >
331 int maxNumDofs ( std::index_sequence< i ... > )
const
333 return Std::sum( std::get< i >( mapperTuple_ ).maxNumDofs() ... );
336 template< std::size_t ... i >
337 SizeType numDofs (
const ElementType &element, std::index_sequence< i ... > )
const
339 return Std::sum( std::get< i >( mapperTuple_ ).numDofs( element ) ... );
342 template<
class Entity, std::size_t ... i >
343 SizeType numEntityDofs (
const Entity &entity, std::index_sequence< i ... > )
const
345 return Std::sum( std::get< i >( mapperTuple_ ).numEntityDofs( entity ) ... );
348 void computeOffset ()
350 globalOffset_[ 0 ] = 0;
353 [ & ](
auto i ){ globalOffset_[ i + 1 ] = globalOffset_[ i ] + std::get< i >( mapperTuple_ ).size(); } );
356 GridPartType &gridPart_;
357 std::tuple< Mapper ... > mapperTuple_;
358 OffsetType globalOffset_;
367 class AdaptiveDofMapper;
369 template<
class GridPart,
class ... Mapper >
370 class AdaptiveDofMapper< Traits< GridPart, Mapper ... > >
371 :
public DofMapper< Traits< GridPart, Mapper ... >, Dune::Fem::AdaptiveDofMapper >
376 typedef typename GridPart :: GridType GridType;
377 typedef AdaptationMethod< GridType > AdaptationMethodType;
379 typedef typename BaseType::OffsetType OffsetType;
381 using BaseType::mapperTupleSize;
382 using BaseType::mapperTuple_;
383 using BaseType::gridPart_;
384 using BaseType::globalOffset_;
387 typedef typename BaseType::ElementType ElementType;
388 typedef typename BaseType::SizeType SizeType;
389 typedef typename BaseType::GlobalKeyType GlobalKeyType;
390 typedef GridPart GridPartType;
392 AdaptiveDofMapper ( GridPartType &gridPart, Mapper & ... mapper )
393 : BaseType( gridPart, mapper ... ),
394 numBlocks_( computeNumBlocks() ),
395 isCallBackAdapt_( AdaptationMethodType( gridPart.grid() ).isCallBackAdaptation() ),
396 needsFullUpdate_(true)
398 oldGlobalOffset_ = globalOffset_;
402 AdaptiveDofMapper ( GridPartType &gridPart, Mapper && ... mapper )
403 : BaseType( gridPart,
std::move( mapper ) ... ),
404 numBlocks_( computeNumBlocks() ),
405 isCallBackAdapt_( AdaptationMethodType( gridPart.grid() ).isCallBackAdaptation() ),
406 needsFullUpdate_(true)
408 oldGlobalOffset_ = globalOffset_;
414 AdaptiveDofMapper (
const AdaptiveDofMapper & ) =
delete;
415 AdaptiveDofMapper ( AdaptiveDofMapper && ) =
delete;
417 static constexpr bool consecutive () noexcept {
return true; }
419 SizeType numBlocks ()
const {
return numBlocks( std::index_sequence_for< Mapper ... >() ); }
421 SizeType numberOfHoles (
const int block )
const
427 const int localBlock = computeBlock( i, block );
428 if( localBlock >= 0 )
430 nHoles = std::get< i >( this->mapperTuple_ ).numberOfHoles( localBlock );
437 GlobalKeyType oldIndex (
const int hole,
const int block )
const
443 const int localBlock = computeBlock( i, block );
444 if( localBlock >= 0 )
446 oIndex = std::get< i >( this->mapperTuple_ ).oldIndex( hole, localBlock ) + globalOffset_[ i ];
453 GlobalKeyType newIndex (
const int hole,
const int block )
const
459 const int localBlock = computeBlock( i, block );
460 if( localBlock >= 0 )
462 nIndex = std::get< i >( this->mapperTuple_ ).newIndex( hole, localBlock ) + globalOffset_[ i ];
469 SizeType oldOffSet (
int block )
const
471 SizeType oOffset = 0;
475 const int localBlock = computeBlock( i, block );
476 if( localBlock >= 0 )
478 oOffset = std::get< i >( this->mapperTuple_ ).oldOffSet( localBlock ) + oldGlobalOffset_[ i ];
485 SizeType offSet (
int block )
const
491 const int localBlock = computeBlock( i, block );
492 if( localBlock >= 0 )
494 offset = std::get< i >( this->mapperTuple_ ).offSet( localBlock ) + globalOffset_[ i ];
501 void resize () { update(); }
507 needsFullUpdate_ =
true;
511 void backup ()
const {}
513 void restore () { compress(); }
515 template<
class IOStream >
516 void read ( IOStream &in ) { compress(); }
518 template<
class IOStream >
519 void write ( IOStream &out )
const {}
521 template<
class Entity >
522 void insertEntity (
const Entity & )
524 if( needsFullUpdate_ )
537 template<
class Entity >
538 void removeEntity (
const Entity & ) {}
543 oldGlobalOffset_ = globalOffset_;
546 needsFullUpdate_ = isCallBackAdapt_ ;
553 int computeBlock(
const int i,
const unsigned int block )
const
555 if( block >= blocks_[ i ] && block < blocks_[ i + 1 ] )
556 return block - blocks_[ i ];
561 void printOffSet(
const OffsetType& offset,
const std::string& name )
const
563 for(
const auto& off : offset )
565 std::cout << name <<
" = " << off << std::endl;
569 template< std::size_t ... i >
570 SizeType numBlocks ( std::index_sequence< i ... > )
const
572 return Std::sum( std::get< i >( mapperTuple_ ).numBlocks() ... );
575 SizeType computeNumBlocks ()
581 [ & ](
auto i ){ blocks_[ i + 1 ] = blocks_[ i ] + std::get< i >( mapperTuple_ ).numBlocks(); } );
584 return blocks_.back();
588 OffsetType oldGlobalOffset_;
591 const SizeType numBlocks_;
592 const bool isCallBackAdapt_;
593 bool needsFullUpdate_;
601 template<
class GridPart,
class ... Mapper >
602 struct Implementation
604 typedef typename std::conditional<
605 Std::And( Capabilities::isAdaptiveDofMapper< Mapper >::v ... ),
606 AdaptiveDofMapper< Traits< GridPart, Mapper ... > >,
607 DofMapper< Traits< GridPart, Mapper ... > > >::type Type;
629 template<
class GridPart,
class ... Mapper >
631 :
public __TupleMapper::template Implementation< GridPart, Mapper ... >::Type
633 typedef typename __TupleMapper::template Implementation< GridPart,
Mapper ... >::Type BaseType;
636 TupleMapper ( GridPart &gridPart,
Mapper & ... mapper ) : BaseType( gridPart, mapper ... ) {}
637 TupleMapper ( GridPart &gridPart,
Mapper && ... mapper ) : BaseType( gridPart, std::move( mapper ) ... ) {}
643 namespace Capabilities
645 template<
class GridPart,
class ...
Mapper >
648 static const bool v = Std::And( isAdaptiveDofMapper< Mapper >::v ... );
651 template<
class GridPart,
class ...
Mapper >
652 struct isConsecutiveIndexSet< __TupleMapper::AdaptiveDofMapper< __TupleMapper::Traits< GridPart, Mapper ... > > >
654 static const bool v =
true;
665#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:632
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,...)
Definition: exceptions.hh:314
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:257
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