1#ifndef DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
2#define DUNE_FEM_GENERICPADAPTIVEDOFMAPPER_HH
8#include <dune/grid/utility/persistentcontainer.hh>
10#include <dune/fem/common/forloop.hh>
11#include <dune/fem/misc/capabilities.hh>
12#include <dune/fem/misc/metaprogramming.hh>
13#include <dune/fem/misc/functor.hh>
14#include <dune/fem/space/common/dofmanager.hh>
15#include <dune/fem/space/mapper/localkey.hh>
16#include <dune/fem/space/lagrange/lagrangepoints.hh>
17#include <dune/fem/space/mapper/dofmapper.hh>
18#include <dune/fem/space/mapper/codimensionmapper.hh>
29 template<
class TraitsImp >
30 class GenericAdaptiveDofMapper
31 :
public AdaptiveDofMapper< TraitsImp >
33 typedef GenericAdaptiveDofMapper< TraitsImp > ThisType;
37 typedef TraitsImp Traits;
38 typedef std::size_t SizeType;
41 static const bool discontinuousMapper = Traits :: discontinuousMapper ;
44 using BaseType::asImp;
48 typedef typename Traits::GridPartType GridPartType;
51 typedef typename Traits::ElementType ElementType;
54 typedef typename GridPartType::GridType GridType;
60 typedef typename Traits :: GlobalKeyType GlobalKeyType ;
63 typedef typename GridType::ctype FieldType;
66 static const int dimension = GridType::dimension;
69 static const int highestDimension = ( discontinuousMapper ) ? 0 : dimension ;
72 static const int polynomialOrder = Traits::polynomialOrder;
78 typedef typename Traits :: CompiledLocalKeyVectorType CompiledLocalKeyVectorType;
81 typedef typename CompiledLocalKeyVectorType :: value_type :: value_type CompiledLocalKeyType;
84 typedef DofManager< GridType > DofManagerType;
86 enum { minOrder = 1, maxOrder = polynomialOrder, numOrders = maxOrder - minOrder + 1 };
88 struct EntityDofStorage
90 typedef std::vector< int > DofVectorType;
91 std::vector< DofVectorType > dofs_;
94 char used_[ numOrders ];
97 dofs_( numOrders, DofVectorType() ),
101 for(
int i=0; i<numOrders; ++i )
105 void assign(
const EntityDofStorage& other )
107 assert( dofs_.size() == other.dofs_.size() );
111 for(
int k=0; k<numOrders; ++k )
113 used_[ k ] = other.used_[ k ];
114 DofVectorType& dofs = dofs_[ k ];
115 const DofVectorType& otherDofs = other.dofs_[ k ];
116 const int dofSize = otherDofs.size();
117 dofs.resize( dofSize );
118 for(
int d = 0; d<dofSize; ++d )
119 dofs[ d ] = otherDofs[ d ];
123 EntityDofStorage(
const EntityDofStorage& other )
129 EntityDofStorage& operator= (
const EntityDofStorage& other )
135 bool exists(
const int codim,
const int polOrd )
const
137 const int entry = determineVectorEntry( codim, polOrd );
138 return dofs_[ entry ].size() > 0 ;
142 bool use(
const int codim,
const int polOrd )
144 const int entry = determineVectorEntry( codim, polOrd ) ;
146 return ( used_[ entry ] == 1 );
149 void insert(
const GeometryType type,
152 const int numDofs,
const int startDof )
154 use( codim, polOrd );
155 assert( ! exists ( codim, polOrd ) );
158 DofVectorType& dofs = dofs_[ determineVectorEntry( codim, polOrd ) ];
160 dofs.resize( numDofs );
161 for(
int i=0, dof=startDof ; i<numDofs; ++i, ++dof )
166 int determineVectorEntry(
const int codim,
const int polOrd )
const
168 assert( codim >= 0 );
169 assert( codim <= highestDimension );
173 return (codim < dimension) ? (polOrd-minOrder) : 0;
178 void remove(
const int codim,
const int polOrd )
180 const int entry = determineVectorEntry( codim, polOrd );
181 if( used_[ entry ] > 0 )
187 for(
int k=0; k<numOrders; ++k )
191 int dof (
const int codim,
const int polOrd,
const size_t dofNumber )
const
193 const unsigned int entry = determineVectorEntry( codim, polOrd );
194 assert( entry < dofs_.size() );
196 assert( dofNumber < dofs_[ entry ].
size() );
197 return dofs_[ entry ][ dofNumber ];
200 int entityDof (
int dofNumber )
const
202 for(
int k = 0; k<numOrders; ++k )
204 const int dofSize = dofs_[ k ].size();
205 if( dofNumber < dofSize )
206 return dofs_[ k ][ dofNumber ];
208 dofNumber -= dofSize;
216 int entityDofs ()
const
219 for(
int k = 0; k<numOrders; ++k )
221 dofSize += dofs_[ k ].size();
226 template <
class VectorType>
227 void detectUnusedDofs( VectorType& isHole,
230 for(
int k=0; k<numOrders; ++k )
232 DofVectorType& dofs = dofs_[ k ];
233 const int dofSize = dofs.size();
239 for(
int d = 0; d<dofSize; ++d )
241 const int dof = dofs[ d ] ;
244 assert( dof < (
int)isHole.size() );
245 isHole[ dof ] = false ;
257 void printDofs()
const
259 for(
int k = 0; k<numOrders; ++k )
261 const DofVectorType& dofs = dofs_[ k ];
262 const int dofSize = dofs.size();
263 for(
int d = 0; d<dofSize; ++d )
264 std::cout << dofs[ d ] <<
" dofs " << std::endl;
268 template <
class VectorType>
269 bool removeHoles( VectorType& oldIdx, VectorType& newIdx,
270 VectorType& holesVec,
int& currentHole,
271 const int usedSize,
int& holes )
273 bool haveToCopy = false ;
274 for(
int k=0; k<numOrders; ++k )
276 DofVectorType& dofs = dofs_[ k ];
277 const int dofSize = dofs.size();
278 for(
int dof = 0; dof<dofSize; ++dof )
280 assert( used_[ k ] );
282 int& currDof = dofs[ dof ] ;
285 if( currDof >= usedSize )
292 assert(currentHole >= 0);
293 assert( holesVec[currentHole] < usedSize );
296 oldIdx[ holes ] = currDof;
297 currDof = holesVec[ currentHole ];
298 newIdx[ holes ] = currDof ;
311 typedef EntityDofStorage EntityDofStorageType;
313 struct PolynomialOrderStorage
318 signed char active_ ;
322 PolynomialOrderStorage(
const int k ) : k_( k ), active_( -
std::abs(k_) ) {}
323 int order ()
const {
return k_; }
324 void suggest (
const int k )
327 active_ = std::abs( k );
329 active_ = -std::abs( k );
331 void set (
const int k ) { k_ = k; active_ = std::abs( k ) ; }
332 void activate() { active_ = std::abs( active_ ); }
333 bool active ()
const {
return active_ > 0; }
334 bool deactivate (
int& k )
345 int suggested ()
const {
return std::abs( active_ ); }
346 void update() { set( suggested() ); }
349 typedef PolynomialOrderStorage PolynomialOrderStorageType;
351 typedef PersistentContainer< GridType, EntityDofStorageType > DofContainerType ;
355 template <
int codim,
bool dg>
358 static int numDofs(
const ElementType& entity,
359 const CompiledLocalKeyType& clk,
360 const int subEntity )
362 return clk.numDofs( codim, subEntity );
367 struct NumDofs<codim, true>
369 static int numDofs(
const ElementType& entity,
370 const CompiledLocalKeyType& clk,
371 const int subEntity )
380 template <
int codim >
381 struct InsertSubEntities
383 static void insertDofs(
const ElementType& entity,
384 const CompiledLocalKeyType& clk,
387 unsigned int& globalSize,
388 unsigned int& notAlreadyCounted,
389 EntityDofStorage& entityDofs )
391 const int numDofs = NumDofs<codim, discontinuousMapper>::numDofs( entity, clk, subEntity );
396 bool notCountedYet = false ;
397 if( ! entityDofs.exists( codim, polOrd ) )
399 entityDofs.insert( entity.type(), codim, polOrd, numDofs, globalSize );
400 globalSize += numDofs;
401 notCountedYet = true ;
406 notCountedYet = entityDofs.use( codim, polOrd );
412 notAlreadyCounted += numDofs;
417 static void apply(
const ElementType& entity,
418 const CompiledLocalKeyType& clk,
420 unsigned int& globalSize,
421 unsigned int& notAlreadyCounted,
422 std::vector< DofContainerType* > dofContainers )
424 DofContainerType &dofContainer = *dofContainers[ codim ];
427 insertDofs( entity, clk, polOrd, 0, globalSize,
428 notAlreadyCounted, dofContainer[ entity ] );
432 const int count = entity.subEntities( codim );
433 for(
int i=0; i<count; ++i )
435 insertDofs( entity, clk, polOrd, i, globalSize,
436 notAlreadyCounted, dofContainer( entity, i ) );
442 template <
int codim >
443 struct RemoveSubEntities
445 static void apply(
const ElementType& entity,
447 std::vector< DofContainerType* > dofContainers )
449 DofContainerType &dofContainer = *dofContainers[ codim ];
450 const int count = entity.subEntities( codim );
451 for(
int i=0; i<count; ++i )
453 EntityDofStorage& entityDofs = dofContainer( entity, i );
454 entityDofs.remove( codim, polOrd );
461 GenericAdaptiveDofMapper (
const GridPartType &gridPart,
463 CompiledLocalKeyVectorType &compiledLocalKeyVector )
464 : gridPart_( gridPart ),
465 dm_( DofManagerType :: instance(gridPart.grid()) ),
466 compiledLocalKeys_( compiledLocalKeyVector ),
467 order_( ( order >= minOrder && order <= maxOrder ) ? order : maxOrder ),
468 entityPolynomOrder_( gridPart.grid(), 0, PolynomialOrderStorageType( order_ ) ),
469 dofContainer_( dimension+1, nullptr ),
475 sequence_( dm_.sequence() )
477 for(
int codim = 0; codim <= highestDimension; ++codim )
478 dofContainer_[ codim ] =
new DofContainerType( gridPart.grid(), codim );
480 for(
size_t i=0; i<compiledLocalKeys_.size(); ++i )
482 maxNumDofs_ =
std :: max( maxNumDofs_, compiledLocalKeys_[ i ].maxSize() );
487 dm_.addIndexSet( asImp() );
491 GenericAdaptiveDofMapper (
const GenericAdaptiveDofMapper& other,
493 CompiledLocalKeyVectorType &compiledLocalKeyVector )
494 : gridPart_( other.gridPart_ ),
496 compiledLocalKeys_( compiledLocalKeyVector ),
497 order_( ( order >= minOrder && order <= maxOrder ) ? order : maxOrder ),
498 entityPolynomOrder_( other.entityPolynomOrder_ ),
499 dofContainer_( dimension+1, nullptr ),
500 numberOfHoles_( other.numberOfHoles_ ),
501 oldIndex_( other.oldIndex_ ),
502 newIndex_( other.newIndex_ ),
503 size_( other.size_ ),
504 maxNumDofs_( other.maxNumDofs_ ),
505 sequence_( other.sequence_ )
507 for(
int codim = 0; codim <= highestDimension; ++codim )
508 dofContainer_[ codim ] =
new DofContainerType( *(other.dofContainer_[ codim ]) );
510 dm_.addIndexSet( asImp() );
513 int polynomOrder(
const ElementType& entity )
const
515 return entityPolynomOrder_[ entity ].order();
518 int suggestedOrder(
const ElementType& entity )
const
520 return entityPolynomOrder_[ entity ].suggestedOrder();
523 void suggestPolynomOrder(
const ElementType& entity,
const int polOrd )
526 if( polOrd < minOrder || polOrd > order_ )
529 entityPolynomOrder_[ entity ].suggest( polOrd );
532 DofContainerType &dofContainer (
const std::size_t codim )
const
534 assert( codim < dofContainer_.size() );
535 assert( dofContainer_[ codim ] );
536 return *(dofContainer_[ codim ]);
539 const CompiledLocalKeyType&
540 compiledLocalKey(
const int polOrd,
const GeometryType type )
const
543 return compiledLocalKeys_[ polOrd ][ type ];
547 virtual ~GenericAdaptiveDofMapper ()
549 dm_.removeIndexSet( asImp() );
558 template<
class Functor >
559 void mapEach (
const ElementType &element, Functor f )
const
561 const int n = numDofs( element );
562 for(
int i = 0; i < n; ++i )
563 f( i, mapToGlobal( element, i ) );
567 int mapToGlobal (
const ElementType &entity,
const int localDof )
const
569 if( discontinuousMapper )
572 const int polOrd = polynomOrder( entity );
575 return dofContainer( 0 )[ entity ].dof( 0, polOrd, localDof );
580 const int polOrd = polynomOrder( entity );
582 const CompiledLocalKeyType& compLocalKey = compiledLocalKey( polOrd, entity.type() );
584 const Fem::LocalKey &dofInfo = compLocalKey.localKey( localDof );
586 const unsigned int codim = dofInfo.codim();
587 const unsigned int subEntity = dofInfo.subEntity();
589 unsigned int index = dofInfo.index() ;
592 if( dimension == 2 && codim == 1 )
594 auto refElem = referenceElement< FieldType, dimension >( entity.type() );
597 const int vxSize = refElem.size( subEntity, codim, dimension );
599 assert( vxSize == 2 );
601 const int vx[ 2 ] = { refElem.subEntity ( subEntity, codim, 0, dimension ),
602 refElem.subEntity ( subEntity, codim, 1, dimension ) };
605 if( gridPart_.grid().localIdSet().subId( entity, vx[ 0 ], dimension ) >
606 gridPart_.grid().localIdSet().subId( entity, vx[ 1 ], dimension ) )
608 const unsigned int numDofsSubEntity = compLocalKey.numDofs( codim, subEntity );
609 index = numDofsSubEntity - index - 1;
613 assert( index < compLocalKey.numDofs( codim, subEntity ) );
614 return dofContainer( codim )( entity, subEntity ).dof( codim, polOrd, index );
619 template<
class Entity,
class Functor >
620 void mapEachEntityDof (
const Entity &entity, Functor f )
const
622 const int n = numEntityDofs( entity );
623 for(
int i = 0; i < n; ++i )
627 [[deprecated(
"Use onSubEntity method with char vector instead")]]
628 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< bool > &indices )
const
630 std::vector< char > _idx;
631 onSubEntity(element, i, c, _idx);
632 indices.resize( _idx.size() );
633 for (std::size_t i=0; i<_idx.size();++i)
634 _idx[i] = indices[i] > 0;
644 void onSubEntity (
const ElementType &element,
int i,
int c, std::vector< char > &indices )
const
646 indices.resize( numDofs(element) );
647 if( discontinuousMapper )
650 std::fill(indices.begin(),indices.end(),1);
652 std::fill(indices.begin(),indices.end(),0);
656 DUNE_THROW( NotImplemented,
"Method onSubEntity(...) not yet implemented for continuous mappers" );
660 void map (
const ElementType &element, std::vector< SizeType > &indices )
const
662 indices.resize( numDofs( element ) );
663 mapEach( element, AssignFunctor< std::vector< SizeType > >( indices ) );
666 template<
class Entity >
667 void mapEntityDofs (
const Entity &entity, std::vector< SizeType > &indices )
const
669 indices.resize( numEntityDofs( entity ) );
670 mapEachEntityDof( entity, AssignFunctor< std::vector< SizeType > >( indices ) );
674 int maxNumDofs ()
const
680 int numDofs (
const ElementType &entity )
const
682 const int polOrd = polynomOrder( entity );
683 return compiledLocalKey( polOrd, entity.type() ).size();
687 template<
class Entity >
688 int numEntityDofs (
const Entity &entity )
const
690 if( discontinuousMapper )
693 return dofContainer( 0 )[ entity ].entityDofs();
708 return (discontinuousMapper) ? (codim == 0) :
true;
712 bool fixedDataSize (
int codim )
const
718 int oldIndex (
const int hole,
const int block )
const
720 assert( oldIndex_[ hole ] >= 0 );
721 return oldIndex_[ hole ];
725 int newIndex (
const int hole,
const int block )
const
727 assert( newIndex_[ hole ] >= 0 );
728 return newIndex_[ hole ];
732 int numberOfHoles (
const int block )
const
734 return numberOfHoles_;
739 int numBlocks ()
const
746 int oldOffSet (
const int block )
const
753 int offSet (
const int block )
const
759 bool consecutive ()
const
765 void resizeContainers()
767 entityPolynomOrder_.resize( PolynomialOrderStorageType( order_ ) );
768 entityPolynomOrder_.shrinkToFit();
769 for(
int codim = 0; codim <= highestDimension; ++codim )
771 dofContainer( codim ).resize();
772 dofContainer( codim ).shrinkToFit();
776 void insertEntity (
const ElementType &entity )
779 insertEntityDofs( entity );
783 unsigned int insertEntityDofs(
const ElementType &entity )
785 PolynomialOrderStorageType& polyStorage = entityPolynomOrder_[ entity ];
786 if( ! polyStorage.active() )
788 unsigned int notAlreadyCounted = 0;
790 const int polOrd = polyStorage.order();
792 const CompiledLocalKeyType& clk = compiledLocalKey( polOrd, entity.type() );
797 polyStorage.activate();
800 Fem::ForLoop< InsertSubEntities, 0, highestDimension>::
801 apply( entity, clk, polOrd, size_, notAlreadyCounted, dofContainer_ );
804 return notAlreadyCounted ;
810 void removeEntity (
const ElementType &entity )
814 if( entityPolynomOrder_[ entity ].deactivate( polOrd ) )
816 Fem::ForLoop< RemoveSubEntities, 0, highestDimension>::
817 apply( entity, polOrd, dofContainer_ );
831 for(
auto& pol : entityPolynomOrder_ )
840 unsigned int insertFather(
const ElementType &entity )
842 if( entity.hasFather() )
845 ElementType dad = entity.father();
848 unsigned int usedSize = insertEntityDofs( dad );
850 usedSize += insertFather( dad );
858 bool considerHierarchy ()
const
865 size_t insertAllUsed()
873 const bool considerHierarchyOfElements = considerHierarchy();
876 const auto end = gridPart_.template end<0, pitype>();
877 for(
auto it = gridPart_.template begin<0, pitype>();
880 const ElementType &element = *it;
881 if( considerHierarchyOfElements )
884 usedSize += insertFather( element );
888 usedSize += insertEntityDofs( element );
897 void printDofs()
const
900 typedef typename GridPartType :: template
Codim< 0 > :: IteratorType IteratorType;
901 const IteratorType end = gridPart_.template end<0>();
902 for( IteratorType it = gridPart_.template begin<0>();
905 printEntityDofs( *it );
909 void printEntityDofs(
const ElementType& entity )
const
911 std::cout <<
"Print entity " << gridPart_.grid().localIdSet().id( entity ) <<
" with " << std::endl;
912 for(
int i = 0; i<numDofs( entity ); ++i )
914 std::cout <<
"en[ " << i <<
" ] = " << mapToGlobal( entity, i ) << std::endl;
923 typedef typename PolyOrderContainerType :: Iterator Iterator;
924 const Iterator endit = entityPolynomOrder_.end();
925 for( Iterator it = entityPolynomOrder_.begin(); it != endit; ++it )
927 PolynomialOrderStorageType& p = *it;
929 p.deactivate( pOrd );
933 for(
int codim = 0; codim <= highestDimension; ++codim )
935 DofContainerType& codimContainer = dofContainer( codim );
936 typedef typename DofContainerType :: Iterator Iterator;
937 const Iterator endit = codimContainer.end();
938 for( Iterator it = codimContainer.begin(); it != endit; ++it )
948 if( sequence_ == dm_.sequence() )
959 const size_t usedSize = insertAllUsed();
968 bool haveToCopy =
false;
970 std::vector<int> validHoles;
974 std::vector< bool > holeMarker( size_,
true );
977 for(
int codim = 0; codim <= highestDimension; ++codim )
979 DofContainerType& codimContainer = dofContainer( codim );
980 typedef typename DofContainerType :: Iterator Iterator;
981 const Iterator endit = codimContainer.end();
982 for( Iterator it = codimContainer.begin(); it != endit; ++it )
984 EntityDofStorageType& dof = *it;
986 dof.detectUnusedDofs( holeMarker, usedSize );
991 validHoles.reserve( usedSize );
992 validHoles.resize( 0 );
995 for(
size_t i=0; i<usedSize; ++i )
998 if( holeMarker[ i ] )
1001 validHoles.push_back( i );
1006 if( validHoles.size() > 0 )
1009 int currentHole = validHoles.size();
1012 oldIndex_.resize( currentHole, -1) ;
1013 newIndex_.resize( currentHole, -1) ;
1015 for(
int codim = 0; codim <= highestDimension; ++codim )
1017 DofContainerType& codimContainer = dofContainer( codim );
1018 typedef typename DofContainerType :: Iterator Iterator;
1019 const Iterator endit = codimContainer.end();
1020 for( Iterator it = codimContainer.begin(); it != endit; ++it )
1023 EntityDofStorageType& dof = *it;
1027 haveToCopy |= dof.removeHoles( oldIndex_, newIndex_,
1028 validHoles, currentHole,
1029 usedSize, numberOfHoles_ );
1040 sequence_ = dm_.sequence();
1045 void backup ()
const
1051 template<
class InStream >
1052 void read ( InStream &in )
1055 template<
class OutStream >
1056 void write ( OutStream &out )
1059 GenericAdaptiveDofMapper (
const ThisType& ) =
delete;
1060 ThisType& operator=(
const ThisType& ) =
delete;
1064 const GridPartType& gridPart_;
1066 DofManagerType& dm_;
1068 CompiledLocalKeyVectorType &compiledLocalKeys_;
1073 PolyOrderContainerType entityPolynomOrder_;
1075 mutable std::vector< DofContainerType* > dofContainer_;
1077 int numberOfHoles_ ;
1078 std::vector< int > oldIndex_ ;
1079 std::vector< int > newIndex_ ;
1081 mutable unsigned int size_;
1082 unsigned int maxNumDofs_;
1087 namespace Capabilities
1092 template<
class Traits >
1093 struct isConsecutiveIndexSet< GenericAdaptiveDofMapper< Traits > >
1095 static const bool v =
true;
1098 template<
class Traits >
1099 struct isAdaptiveDofMapper< GenericAdaptiveDofMapper< Traits > >
1101 static const bool v =
true;
static constexpr int codimension
Know your own codimension.
Definition: entity.hh:106
consecutive, persistent index set for the leaf level based on the grid's hierarchy index set
Definition: adaptiveleafindexset.hh:1351
A few common exception classes.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
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
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
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
static int refineStepsForHalf()
number of globalRefine steps needed to refuce h by 0.5
A unique label for each type of element that can occur in a grid.