1#ifndef DUNE_FEM_DOFMAPPER_INDEXSETDOFMAPPER_HH
2#define DUNE_FEM_DOFMAPPER_INDEXSETDOFMAPPER_HH
9#include <dune/geometry/referenceelements.hh>
13#include <dune/fem/gridpart/common/gridpart.hh>
14#include <dune/fem/gridpart/common/indexset.hh>
15#include <dune/fem/misc/functor.hh>
16#include <dune/fem/space/common/dofmanager.hh>
17#include <dune/fem/space/mapper/code.hh>
18#include <dune/fem/space/mapper/exceptions.hh>
19#include <dune/fem/space/mapper/dofmapper.hh>
23#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wattributes"
37 template<
class Gr
idPart >
38 class DefaultLocalDofMapping
42 template<
class Iterator,
class Functor >
43 void operator() ( std::size_t index,
unsigned int numDofs, Iterator begin, Iterator end, Functor functor )
const
46 functor( *(begin++), index++ );
51 DefaultLocalDofMapping () {}
52 DefaultLocalDofMapping (
const GridPart & ) {}
54 Mapping operator() (
const typename GridPart::template Codim< 0 >::EntityType &element,
unsigned int subEntity,
unsigned int codim )
const {
return {}; }
59 namespace __IndexSetDofMapper
65 template<
class Gr
idPart,
class LocalDofMapping >
68 typedef DofMapperBase< GridPart, LocalDofMapping > ThisType;
71 typedef std::size_t SizeType;
82 SizeType offset, oldOffset;
85 enum CodimType { CodimEmpty, CodimFixedSize, CodimVariableSize };
86 static const int dimension = GridPart::dimension;
92 struct SubEntityFilter
94 SubEntityFilter(
const RefElementType &refElement,
int subEntity,
int codim)
95 : active_(dimension+1), size_(0)
97 for (
int c=0;c<=dimension;++c)
99 std::vector<bool> &a = active_[c];
100 a.resize( refElement.size( c ),
false );
101 if (c<codim)
continue;
102 if (c==codim) { a[subEntity]=
true; ++size_;
continue; }
103 for (
int i=0;i<refElement.size(subEntity, codim, c);++i)
105 a[refElement.subEntity(subEntity, codim, i, c)] =
true;
110 bool operator()(
int i,
int c)
const {
return active_[c][i]; }
112 std::vector< std::vector< bool > > active_;
116 template<
class Functor >
120 typedef SizeType GlobalKeyType;
122 typedef GridPart GridPartType;
123 typedef LocalDofMapping LocalDofMappingType;
124 typedef typename GridPart::GridType GridType;
126 typedef typename GridPartType::template Codim< 0 >::EntityType ElementType;
128 template<
class CodeFactory >
129 DofMapperBase (
const GridPartType &gridPart, LocalDofMappingType localDofMapping,
const CodeFactory &codeFactory );
152 template<
class Functor >
153 void mapEach (
const ElementType &element, Functor f )
const;
155 void map (
const ElementType &element, std::vector< GlobalKeyType > &indices )
const;
157 [[deprecated(
"Use onSubEntity method with char vector instead")]]
158 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< bool > &indices )
const
160 std::vector< char > _idx;
161 onSubEntity(element, i, c, _idx);
162 indices.resize( _idx.size() );
163 for (std::size_t i=0; i<_idx.size();++i)
164 _idx[i] = indices[i] > 0;
182 void onSubEntity(
const ElementType &element,
int i,
int c, std::vector< char > &indices )
const;
184 unsigned int maxNumDofs ()
const {
return maxNumDofs_; }
185 unsigned int numDofs (
const ElementType &element )
const {
return code( element ).numDofs(); }
188 template<
class Entity,
class Functor >
189 void mapEachEntityDof (
const Entity &entity, Functor f )
const;
191 template<
class Entity >
192 void mapEntityDofs (
const Entity &entity, std::vector< GlobalKeyType > &indices )
const;
194 template<
class Entity >
195 unsigned int numEntityDofs (
const Entity &entity )
const;
199 bool contains (
int codim )
const {
return (codimType_[ codim ] != CodimEmpty); }
201 bool fixedDataSize (
int codim )
const {
return (codimType_[ codim ] == CodimFixedSize); }
203 SizeType
size ()
const {
return size_; }
224 static constexpr bool consecutive () noexcept {
return false; }
226 SizeType numBlocks ()
const
228 DUNE_THROW( NotImplemented,
"Method numBlocks() called on non-adaptive block mapper" );
231 SizeType numberOfHoles (
int )
const
233 DUNE_THROW( NotImplemented,
"Method numberOfHoles() called on non-adaptive block mapper" );
236 GlobalKeyType oldIndex (
int hole,
int )
const
238 DUNE_THROW( NotImplemented,
"Method oldIndex() called on non-adaptive block mapper" );
241 GlobalKeyType newIndex (
int hole,
int )
const
243 DUNE_THROW( NotImplemented,
"Method newIndex() called on non-adaptive block mapper" );
246 SizeType oldOffSet (
int )
const
248 DUNE_THROW( NotImplemented,
"Method oldOffSet() called on non-adaptive block mapper" );
251 SizeType offSet (
int )
const
253 DUNE_THROW( NotImplemented,
"Method offSet() called on non-adaptive block mapper" );
256 template<
class Entity >
257 void insertEntity (
const Entity &entity )
259 DUNE_THROW( NotImplemented,
"Method insertEntity(entity) called on non-adaptive block mapper" );
261 template<
class Entity >
262 void removeEntity (
const Entity &entity )
264 DUNE_THROW( NotImplemented,
"Method removeEntity(entity) called on non-adaptive block mapper" );
267 void resize () { update(); }
268 bool compress () { update();
return true;}
269 void backup ()
const {}
271 template <
class StreamTraits>
272 void write( OutStreamInterface< StreamTraits >& out )
const {}
273 template <
class StreamTraits>
274 void read( InStreamInterface< StreamTraits >& in ) { update(); }
280 void requestCodimensions ();
283 typedef std::vector< GeometryType > BlockMapType;
285 const DofMapperCode &code (
const GeometryType &
gt )
const;
286 const DofMapperCode &code (
const ElementType &element )
const {
return code( element.type() ); }
288 template<
class Entity >
289 const SubEntityInfo &subEntityInfo (
const Entity &entity )
const;
291 const IndexSetType &indexSet ()
const {
return indexSet_; }
293 const IndexSetType &indexSet_;
294 LocalDofMapping localDofMapping_;
295 std::vector< DofMapperCode > code_;
296 unsigned int maxNumDofs_;
298 std::vector< SubEntityInfo > subEntityInfo_;
299 BlockMapType blockMap_;
300 CodimType codimType_[ dimension+1 ];
308 template<
class Gr
idPart,
class LocalDofMapping >
309 struct DofMapperBase< GridPart, LocalDofMapping >::BuildFunctor
311 explicit BuildFunctor ( std::vector< SubEntityInfo > &subEntityInfo )
312 : subEntityInfo_( subEntityInfo )
315 template<
class Iterator >
316 void operator() (
unsigned int gtIndex,
unsigned int subEntity, Iterator it, Iterator end )
318 SubEntityInfo &info = subEntityInfo_[ gtIndex ];
319 const unsigned int numDofs = end - it;
320 if( info.numDofs == 0 )
321 info.numDofs = numDofs;
322 else if( info.numDofs != numDofs )
323 DUNE_THROW( DofMapperError,
"Inconsistent number of DoFs on subEntity (codim = " << info.codim <<
")." );
327 std::vector< SubEntityInfo > &subEntityInfo_;
336 template<
class Gr
idPart,
class LocalDofMapping >
337 const int DofMapperBase< GridPart, LocalDofMapping >::dimension;
339 template<
class Gr
idPart,
class LocalDofMapping >
340 template<
class CodeFactory >
341 inline DofMapperBase< GridPart, LocalDofMapping >
342 ::DofMapperBase (
const GridPartType &gridPart, LocalDofMappingType localDofMapping,
const CodeFactory &codeFactory )
346 : indexSet_( gridPart.indexSet() ),
347 localDofMapping_(
std::move( localDofMapping ) ),
348 code_( LocalGeometryTypeIndex::
size( dimension ) ),
350 subEntityInfo_( GlobalGeometryTypeIndex::
size( dimension ) )
352 std::vector< GeometryType >
gt( GlobalGeometryTypeIndex::size( dimension ) );
354 const typename RefElementsType::Iterator end = RefElementsType::end();
355 for(
typename RefElementsType::Iterator it = RefElementsType::begin(); it != end; ++it )
357 const RefElementType refElement = *it;
359 for(
int codim = 0; codim <= dimension; ++codim )
361 for(
int i = 0; i < refElement.size( codim ); ++i )
363 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( refElement.type( i, codim ) );
364 gt[ gtIdx ] = refElement.type( i, codim );
365 subEntityInfo_[ gtIdx ].codim = codim;
369 DofMapperCode &code = code_[ LocalGeometryTypeIndex::index( refElement.type() ) ];
370 code = codeFactory( refElement );
371 maxNumDofs_ = std::max( code.numDofs(), maxNumDofs_ );
372 code( BuildFunctor( subEntityInfo_ ) );
375 for(
int codim = 0; codim <= dimension; ++codim )
376 codimType_[ codim ] = CodimEmpty;
378 unsigned int codimDofs[ dimension+1 ];
379 for(
unsigned int i = 0; i < subEntityInfo_.size(); ++i )
381 const SubEntityInfo &info = subEntityInfo_[ i ];
382 if( info.numDofs == 0 )
390 const auto & geomTypes = indexSet().types(info.codim);
392 if (hasSingleGeometryType && geomTypes[0] !=
gt[i])
397 if( codimType_[ info.codim ] == CodimEmpty )
398 codimType_[ info.codim ] = CodimFixedSize;
399 else if( codimDofs[ info.codim ] != info.numDofs )
400 codimType_[ info.codim ] = CodimVariableSize;
402 codimDofs[ info.codim ] = info.numDofs;
403 blockMap_.push_back(
gt[ i ] );
407 requestCodimensions ();
414 template<
class Gr
idPart,
class LocalDofMapping >
415 template<
class Functor >
416 inline void DofMapperBase< GridPart, LocalDofMapping >
417 ::mapEach (
const ElementType &element, Functor f )
const
419 const auto &idxSet = indexSet();
421 code( element )( [
this, &idxSet, &element, f ] (
unsigned int gtIndex,
unsigned int subEntity,
auto begin,
auto end ) {
422 const SubEntityInfo &info = subEntityInfo_[ gtIndex ];
423 const SizeType subIndex = idxSet.subIndex( element, subEntity, info.codim );
424 SizeType index = info.offset + SizeType( info.numDofs ) * subIndex;
425 localDofMapping_( element, subEntity, info.codim )( index, info.numDofs, begin, end, f );
430 template<
class Gr
idPart,
class LocalDofMapping >
431 inline void DofMapperBase< GridPart, LocalDofMapping >
432 ::map (
const ElementType &element, std::vector< SizeType > &indices )
const
434 indices.resize( numDofs( element ) );
435 mapEach( element, AssignFunctor< std::vector< SizeType > >( indices ) );
438 template<
class Gr
idPart,
class LocalDofMapping >
439 template<
class Entity,
class Functor >
440 inline void DofMapperBase< GridPart, LocalDofMapping >
441 ::mapEachEntityDof (
const Entity &entity, Functor f )
const
443 const SubEntityInfo &info = subEntityInfo( entity );
444 const unsigned int numDofs = info.numDofs;
445 SizeType index = info.offset + numDofs * SizeType( indexSet().index( entity ) );
446 for(
unsigned int i = 0; i < info.numDofs; ++i )
451 template<
class Gr
idPart,
class LocalDofMapping >
452 template<
class Entity >
453 inline void DofMapperBase< GridPart, LocalDofMapping >
454 ::mapEntityDofs (
const Entity &entity, std::vector< SizeType > &indices )
const
456 indices.resize( numEntityDofs( entity ) );
457 mapEachEntityDof( entity, AssignFunctor< std::vector< SizeType > >( indices ) );
460 template<
class Gr
idPart,
class LocalDofMapping >
461 inline void DofMapperBase< GridPart, LocalDofMapping >
462 ::onSubEntity(
const ElementType &element,
int i,
int c, std::vector< char > &indices )
const
464 const SubEntityFilter filter( RefElementsType::general( element.type() ), i, c );
465 indices.resize( numDofs( element ) );
466 code( element )( [
this, &indices, &filter ] (
unsigned int gtIndex,
unsigned int subEntity,
auto begin,
auto end ) {
467 const bool active = filter( subEntity, subEntityInfo_[ gtIndex ].codim );
468 while( begin != end )
469 indices[ *(begin++) ] = active? 1:0;
473 template<
class Gr
idPart,
class LocalDofMapping >
474 template<
class Entity >
476 DofMapperBase< GridPart, LocalDofMapping >
477 ::numEntityDofs (
const Entity &entity )
const
479 return subEntityInfo( entity ).numDofs;
483 template<
class Gr
idPart,
class LocalDofMapping >
484 inline void DofMapperBase< GridPart, LocalDofMapping >::requestCodimensions ()
487 if constexpr ( Capabilities::isDuneFemIndexSet< IndexSetType >::v )
490 std::vector< int > codimensions;
491 codimensions.reserve( dimension+1 );
493 for(
typename BlockMapType::const_iterator it = blockMap_.begin(); it != blockMap_.end(); ++it )
495 SubEntityInfo &info = subEntityInfo_[ GlobalGeometryTypeIndex::index( *it ) ];
496 codimensions.push_back( info.codim );
500 indexSet().requestCodimensions( codimensions );
504 template<
class Gr
idPart,
class LocalDofMapping >
505 inline void DofMapperBase< GridPart, LocalDofMapping >::update ()
508 for(
const auto& geomType : blockMap_ )
510 SubEntityInfo &info = subEntityInfo_[ GlobalGeometryTypeIndex::index( geomType ) ];
511 info.oldOffset = info.offset;
513 size_ += SizeType( info.numDofs ) * SizeType( indexSet().size( geomType ) );
518 template<
class Gr
idPart,
class LocalDofMapping >
519 inline const DofMapperCode &DofMapperBase< GridPart, LocalDofMapping >
520 ::code (
const GeometryType &
gt )
const
522 return code_[ LocalGeometryTypeIndex::index(
gt ) ];
526 template<
class Gr
idPart,
class LocalDofMapping >
527 template<
class Entity >
528 inline const typename DofMapperBase< GridPart, LocalDofMapping >::SubEntityInfo &
529 DofMapperBase< GridPart, LocalDofMapping >::subEntityInfo (
const Entity &entity )
const
531 return subEntityInfo_[ GlobalGeometryTypeIndex::index( entity.type() ) ];
539 template<
class Gr
idPart,
class LocalDofMapping >
541 :
public DofMapperBase< GridPart, LocalDofMapping >
543 typedef DofMapper< GridPart, LocalDofMapping > ThisType;
544 typedef DofMapperBase< GridPart, LocalDofMapping > BaseType;
547 typedef typename BaseType::SubEntityInfo SubEntityInfo;
548 typedef typename BaseType::GridPartType::GridType GridType;
549 typedef DofManager< GridType > DofManagerType;
552 typedef typename BaseType::GridPartType GridPartType;
553 typedef typename BaseType::LocalDofMappingType LocalDofMappingType;
554 typedef typename BaseType::SizeType SizeType;
556 template<
class CodeFactory >
557 DofMapper (
const GridPartType &gridPart, LocalDofMappingType localDofMapping,
const CodeFactory &codeFactory )
558 : BaseType( gridPart,
std::move( localDofMapping ), codeFactory ),
559 dofManager_( DofManagerType::instance( gridPart.grid() ) )
561 dofManager_.addIndexSet( *
this );
564 DofMapper (
const ThisType & ) =
delete;
568 dofManager_.removeIndexSet( *
this );
571 ThisType &operator= (
const ThisType & ) =
delete;
574 DofManagerType& dofManager_;
581 template<
class Gr
idPart,
class LocalDofMapping >
582 class AdaptiveDofMapper
583 :
public DofMapperBase< GridPart, LocalDofMapping >
585 typedef AdaptiveDofMapper< GridPart, LocalDofMapping > ThisType;
586 typedef DofMapperBase< GridPart, LocalDofMapping > BaseType;
589 typedef typename BaseType::SubEntityInfo SubEntityInfo;
590 typedef typename BaseType::GridPartType::GridType GridType;
591 typedef DofManager< GridType > DofManagerType;
594 typedef typename BaseType::GridPartType GridPartType;
595 typedef typename BaseType::LocalDofMappingType LocalDofMappingType;
596 typedef typename BaseType::SizeType SizeType;
598 template<
class CodeFactory >
599 AdaptiveDofMapper (
const GridPartType &gridPart, LocalDofMappingType localDofMapping,
const CodeFactory &codeFactory )
600 : BaseType( gridPart,
std::move( localDofMapping ), codeFactory ),
601 dofManager_( DofManagerType::instance( gridPart.grid() ) )
603 dofManager_.addIndexSet( *
this );
606 AdaptiveDofMapper (
const ThisType & ) =
delete;
608 ~AdaptiveDofMapper ()
610 dofManager_.removeIndexSet( *
this );
613 ThisType &operator= (
const ThisType & ) =
delete;
621 int numBlocks ()
const {
return blockMap_.size(); }
622 SizeType offSet (
int blk )
const;
623 SizeType oldOffSet (
int blk )
const;
625 SizeType numberOfHoles (
int blk )
const;
627 SizeType oldIndex ( SizeType hole,
int blk )
const;
628 SizeType newIndex ( SizeType hole,
int blk )
const;
632 bool consecutive ()
const {
return true; }
634 template<
class Entity >
635 void insertEntity (
const Entity &entity ) { BaseType::update(); }
637 template<
class Entity >
638 void removeEntity (
const Entity &entity ) {}
640 void resize () { BaseType::update(); }
642 bool compress () { BaseType::update();
return true; }
644 template <
class StreamTraits>
645 void write( OutStreamInterface< StreamTraits >& out )
const {}
647 template <
class StreamTraits>
648 void read( InStreamInterface< StreamTraits >& in )
653 void backup ()
const {}
657 using BaseType::indexSet;
659 using BaseType::blockMap_;
660 using BaseType::subEntityInfo_;
662 DofManagerType& dofManager_;
670 template<
class Gr
idPart,
class LocalDofMapping >
671 inline typename AdaptiveDofMapper< GridPart, LocalDofMapping >::SizeType
672 AdaptiveDofMapper< GridPart, LocalDofMapping >::offSet (
int blk )
const
674 assert( (blk >= 0) && (blk < numBlocks()) );
675 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( blockMap_[ blk ] );
676 return subEntityInfo_[ gtIdx ].offset;
680 template<
class Gr
idPart,
class LocalDofMapping >
681 inline typename AdaptiveDofMapper< GridPart, LocalDofMapping >::SizeType
682 AdaptiveDofMapper< GridPart, LocalDofMapping >::oldOffSet (
int blk )
const
684 assert( (blk >= 0) && (blk < numBlocks()) );
685 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( blockMap_[ blk ] );
686 return subEntityInfo_[ gtIdx ].oldOffset;
690 template<
class Gr
idPart,
class LocalDofMapping >
691 inline typename AdaptiveDofMapper< GridPart, LocalDofMapping >::SizeType
692 AdaptiveDofMapper< GridPart, LocalDofMapping >::numberOfHoles (
int blk )
const
694 assert( (blk >= 0) && (blk < numBlocks()) );
695 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( blockMap_[ blk ] );
696 const SubEntityInfo &info = subEntityInfo_[ gtIdx ];
697 return SizeType( info.numDofs ) * SizeType( indexSet().numberOfHoles( blockMap_[ blk ] ) );
701 template<
class Gr
idPart,
class LocalDofMapping >
702 inline typename AdaptiveDofMapper< GridPart, LocalDofMapping >::SizeType
703 AdaptiveDofMapper< GridPart, LocalDofMapping >::oldIndex ( SizeType hole,
int blk )
const
705 assert( (hole >= 0) && (hole < numberOfHoles( blk )) );
706 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( blockMap_[ blk ] );
707 const SubEntityInfo &info = subEntityInfo_[ gtIdx ];
708 const unsigned int numDofs = info.numDofs;
709 const SizeType index = indexSet().oldIndex( hole / numDofs, blockMap_[ blk ] );
710 return info.offset + numDofs * index + (hole % numDofs);
714 template<
class Gr
idPart,
class LocalDofMapping >
715 inline typename AdaptiveDofMapper< GridPart, LocalDofMapping >::SizeType
716 AdaptiveDofMapper< GridPart, LocalDofMapping >::newIndex ( SizeType hole,
int blk )
const
718 assert( (hole >= 0) && (hole < numberOfHoles( blk )) );
719 const unsigned int gtIdx = GlobalGeometryTypeIndex::index( blockMap_[ blk ] );
720 const SubEntityInfo &info = subEntityInfo_[ gtIdx ];
721 const unsigned int numDofs = info.numDofs;
722 const SizeType index = indexSet().newIndex( hole / numDofs, blockMap_[ blk ] );
723 return info.offset + numDofs * index + (hole % numDofs);
731 template< class GridPart, class LocalDofMapping, bool adaptive = Capabilities::isAdaptiveIndexSet< typename GridPart::IndexSetType >::v >
732 struct Implementation
734 typedef typename std::conditional< adaptive, AdaptiveDofMapper< GridPart, LocalDofMapping >, DofMapper< GridPart, LocalDofMapping > >::type Type;
744 template<
class Gr
idPart,
class LocalDofMapping = DefaultLocalDofMapping< Gr
idPart > >
745 class IndexSetDofMapper
746 :
public __IndexSetDofMapper::template Implementation< GridPart, LocalDofMapping >::Type
748 typedef typename __IndexSetDofMapper::template Implementation< GridPart, LocalDofMapping >::Type BaseType;
751 typedef typename BaseType::GridPartType GridPartType;
752 typedef typename BaseType::LocalDofMappingType LocalDofMappingType;
754 template<
class CodeFactory >
755 IndexSetDofMapper (
const GridPartType &gridPart, LocalDofMappingType localDofMapping,
const CodeFactory &codeFactory )
756 : BaseType( gridPart,
std::move( localDofMapping ), codeFactory )
759 template<
class CodeFactory >
760 IndexSetDofMapper (
const GridPartType &gridPart,
const CodeFactory &codeFactory )
761 : BaseType( gridPart, LocalDofMappingType( gridPart ), codeFactory )
769 namespace Capabilities
774 template<
class Gr
idPart,
class LocalDofMapping >
775 struct isAdaptiveDofMapper< IndexSetDofMapper< GridPart, LocalDofMapping > >
777 static const bool v = Capabilities::isAdaptiveIndexSet< typename GridPart::IndexSetType >::v;
784 template<
class Gr
idPart,
class LocalDofMapping >
785 struct isConsecutiveIndexSet< __IndexSetDofMapper::AdaptiveDofMapper< GridPart, LocalDofMapping > >
787 static const bool v =
true;
798#pragma GCC diagnostic pop
consecutive, persistent index set for the leaf level based on the grid's hierarchy index set
Definition: adaptiveleafindexset.hh:1351
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
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
Specialize with 'true' for if the codimension 0 entity of the grid has only one possible geometry typ...
Definition: capabilities.hh:27
Class providing access to the singletons of the reference elements.
Definition: referenceelements.hh:128
typename Container::ReferenceElement ReferenceElement
The reference element type.
Definition: referenceelements.hh:146
A unique label for each type of element that can occur in a grid.
Helper classes to provide indices for geometrytypes for use in a vector.