1 #ifndef DUNE_FEM_NONBLOCKMAPPER_HH 2 #define DUNE_FEM_NONBLOCKMAPPER_HH 3 4 #include <vector> 5 6 #include <dune/fem/gridpart/common/indexset.hh> 7 #include <dune/fem/misc/functor.hh> 8 #include <dune/fem/space/mapper/dofmapper.hh> 9 10 namespace Dune 11 { 12 13 namespace Fem 14 { 15 16 // Internal Forward Declarations 17 // ----------------------------- 18 19 template< class BlockMapper, int blockSize > 20 class NonBlockMapper; 21 22 23 namespace __NonBlockMapper 24 { 25 26 // Traits 27 // ------ 28 29 template< class BlockMapper, int bS > 30 struct Traits 31 { 32 typedef NonBlockMapper< BlockMapper, bS > DofMapperType; 33 34 typedef BlockMapper BlockMapperType; 35 typedef typename BlockMapper::ElementType ElementType; 36 typedef typename BlockMapper::SizeType SizeType; 37 typedef typename BlockMapper::GlobalKeyType GlobalKeyType; 38 39 static const int blockSize = bS; 40 }; 41 42 43 // DofMapper 44 // --------- 45 46 template< class T, template< class > class Base = Dune::Fem::DofMapper > 47 class DofMapper 48 : public Base< T > 49 { 50 typedef Base< T > BaseType; 51 52 template< class, template< class > class > 53 friend class DofMapper; 54 55 public: 56 typedef typename BaseType::Traits Traits; 57 58 typedef typename Traits::BlockMapperType BlockMapperType; 59 static const int blockSize = Traits::blockSize; 60 61 typedef typename Traits::ElementType ElementType; 62 typedef typename Traits::SizeType SizeType; 63 typedef typename Traits::GlobalKeyType GlobalKeyType; 64 65 private: 66 template< class Functor > 67 struct BlockFunctor 68 { BlockFunctorDune::Fem::__NonBlockMapper::DofMapper::BlockFunctor69 explicit BlockFunctor ( Functor functor ) 70 : functor_( functor ) 71 {} 72 73 template< class GlobalKey > operator ()Dune::Fem::__NonBlockMapper::DofMapper::BlockFunctor74 void operator() ( int localBlock, const GlobalKey globalKey ) const 75 { 76 int localDof = blockSize*localBlock; 77 SizeType globalDof = blockSize*globalKey; 78 const int localEnd = localDof + blockSize; 79 while( localDof != localEnd ) 80 functor_( localDof++, globalDof++ ); 81 } 82 83 private: 84 Functor functor_; 85 }; 86 87 public: DofMapper(BlockMapperType & blockMapper)88 DofMapper ( BlockMapperType &blockMapper ) 89 : blockMapper_( blockMapper ) 90 {} 91 size() const92 SizeType size () const { return blockSize * blockMapper_.size(); } 93 contains(const int codim) const94 bool contains ( const int codim ) const { return blockMapper_.contains( codim ); } 95 fixedDataSize(int codim) const96 bool fixedDataSize ( int codim ) const { return blockMapper_.fixedDataSize( codim ); } 97 98 template< class Functor > mapEach(const ElementType & element,Functor f) const99 void mapEach ( const ElementType &element, Functor f ) const 100 { 101 blockMapper_.mapEach( element, BlockFunctor< Functor >( std::forward< Functor >( f ) ) ); 102 } 103 map(const ElementType & element,std::vector<GlobalKeyType> & indices) const104 void map ( const ElementType &element, std::vector< GlobalKeyType > &indices ) const 105 { 106 indices.resize( numDofs( element ) ); 107 mapEach( element, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } ); 108 } 109 onSubEntity(const ElementType & element,int i,int c,std::vector<bool> & indices) const110 void onSubEntity ( const ElementType &element, int i, int c, std::vector< bool > &indices ) const 111 { 112 const SizeType numDofs = blockMapper_.numDofs( element ); 113 blockMapper_.onSubEntity( element, i, c, indices ); 114 indices.resize( blockSize * numDofs ); 115 for( SizeType i = numDofs; i > 0; ) 116 { 117 for( int j = 0; j < blockSize; ++j ) 118 indices[ i*blockSize + j ] = indices[ i ]; 119 } 120 } 121 122 template< class Entity, class Functor > mapEachEntityDof(const Entity & entity,Functor f) const123 void mapEachEntityDof ( const Entity &entity, Functor f ) const 124 { 125 blockMapper_.mapEachEntityDof( entity, BlockFunctor< Functor >( std::forward< Functor >( f ) ) ); 126 } 127 128 template< class Entity > mapEntityDofs(const Entity & entity,std::vector<GlobalKeyType> & indices) const129 void mapEntityDofs ( const Entity &entity, std::vector< GlobalKeyType > &indices ) const 130 { 131 indices.resize( numEntityDofs( entity ) ); 132 mapEachEntityDof( entity, [ &indices ] ( int local, GlobalKeyType global ) { indices[ local ] = global; } ); 133 } 134 maxNumDofs() const135 int maxNumDofs () const { return blockSize * blockMapper_.maxNumDofs(); } 136 numDofs(const ElementType & element) const137 SizeType numDofs ( const ElementType &element ) const { return blockSize * blockMapper_.numDofs( element ); } 138 139 template< class Entity > numEntityDofs(const Entity & entity) const140 SizeType numEntityDofs ( const Entity &entity ) const { return blockSize * blockMapper_.numEntityDofs( entity ); } 141 consecutive()142 static constexpr bool consecutive () noexcept { return false; } 143 numBlocks() const144 SizeType numBlocks () const 145 { 146 DUNE_THROW( NotImplemented, "Method numBlocks() called on non-adaptive block mapper" ); 147 } 148 numberOfHoles(int) const149 SizeType numberOfHoles ( int ) const 150 { 151 DUNE_THROW( NotImplemented, "Method numberOfHoles() called on non-adaptive block mapper" ); 152 } 153 oldIndex(int hole,int) const154 GlobalKeyType oldIndex ( int hole, int ) const 155 { 156 DUNE_THROW( NotImplemented, "Method oldIndex() called on non-adaptive block mapper" ); 157 } 158 newIndex(int hole,int) const159 GlobalKeyType newIndex ( int hole, int ) const 160 { 161 DUNE_THROW( NotImplemented, "Method newIndex() called on non-adaptive block mapper" ); 162 } 163 oldOffSet(int) const164 SizeType oldOffSet ( int ) const 165 { 166 DUNE_THROW( NotImplemented, "Method oldOffSet() called on non-adaptive block mapper" ); 167 } 168 offSet(int) const169 SizeType offSet ( int ) const 170 { 171 DUNE_THROW( NotImplemented, "Method offSet() called on non-adaptive block mapper" ); 172 } 173 blockMapper() const174 const BlockMapperType &blockMapper () const { return blockMapper_; } 175 update()176 void update () { blockMapper_.update(); } 177 178 private: 179 BlockMapperType &blockMapper_; 180 }; 181 182 183 // AdaptiveDofMapper 184 // ----------------- 185 186 template< class T > 187 class AdaptiveDofMapper 188 : public DofMapper< T, Dune::Fem::AdaptiveDofMapper > 189 { 190 typedef DofMapper< T, Dune::Fem::AdaptiveDofMapper > BaseType; 191 192 template< class > 193 friend class AdaptiveDofMapper; 194 195 public: 196 typedef typename BaseType::Traits Traits; 197 198 typedef typename Traits::BlockMapperType BlockMapperType; 199 200 static const int blockSize = Traits::blockSize; 201 202 using BaseType::blockMapper; 203 204 typedef typename Traits::ElementType ElementType; 205 typedef typename Traits::SizeType SizeType; 206 typedef typename Traits::GlobalKeyType GlobalKeyType; 207 AdaptiveDofMapper(BlockMapperType & blockMapper)208 AdaptiveDofMapper ( BlockMapperType &blockMapper ) 209 : BaseType( blockMapper ) 210 {} 211 consecutive() const212 bool consecutive () const { return blockMapper().consecutive(); } 213 numBlocks() const214 SizeType numBlocks () const { return blockMapper().numBlocks(); } 215 numberOfHoles(const int block) const216 SizeType numberOfHoles ( const int block ) const { return blockSize * blockMapper().numberOfHoles( block ); } 217 oldIndex(const int hole,const int block) const218 GlobalKeyType oldIndex ( const int hole, const int block ) const 219 { 220 const int i = hole % blockSize; 221 const int blockHole = hole / blockSize; 222 return blockMapper().oldIndex( blockHole, block ) * blockSize + i; 223 } 224 newIndex(const int hole,const int block) const225 GlobalKeyType newIndex ( const int hole, const int block ) const 226 { 227 const int i = hole % blockSize; 228 const int blockHole = hole / blockSize; 229 return blockMapper().newIndex( blockHole, block ) * blockSize + i; 230 } 231 oldOffSet(const int block) const232 SizeType oldOffSet ( const int block ) const { return blockMapper().oldOffSet( block ) * blockSize; } 233 offSet(const int block) const234 SizeType offSet ( const int block ) const { return blockMapper().offSet( block ) * blockSize; } 235 }; 236 237 238 239 // Implementation 240 // -------------- 241 242 template< class BlockMapper, int blockSize, bool adaptive = Capabilities::isAdaptiveDofMapper< BlockMapper >::v > 243 class Implementation 244 { 245 typedef __NonBlockMapper::Traits< BlockMapper, blockSize > Traits; 246 247 public: 248 typedef typename std::conditional< adaptive, 249 AdaptiveDofMapper< Traits >, 250 DofMapper< Traits > >::type Type; 251 }; 252 253 } // namespace __NonBlockMapper 254 255 256 // NonBlockMapper 257 // -------------- 258 259 /**Flatten the index-space of a given BlockMapper. */ 260 template< class BlockMapper, int blockSize > 261 class NonBlockMapper 262 : public __NonBlockMapper::template Implementation< BlockMapper, blockSize >::Type 263 { 264 typedef typename __NonBlockMapper::template Implementation< BlockMapper, blockSize >::Type BaseType; 265 266 public: 267 NonBlockMapper(BlockMapper & blockMapper)268 NonBlockMapper ( BlockMapper &blockMapper ) 269 : BaseType( blockMapper ) 270 {} 271 }; 272 273 274 // NonBlockMapper for NonBlockMapper 275 // --------------------------------- 276 277 template< class BlockMapper, int innerBlockSize, int outerBlockSize > 278 class NonBlockMapper< NonBlockMapper< BlockMapper, innerBlockSize >, outerBlockSize > 279 : public NonBlockMapper< BlockMapper, innerBlockSize *outerBlockSize > 280 { 281 typedef NonBlockMapper< NonBlockMapper< BlockMapper, innerBlockSize >, outerBlockSize > ThisType; 282 typedef NonBlockMapper< BlockMapper, innerBlockSize *outerBlockSize > BaseType; 283 284 public: NonBlockMapper(const NonBlockMapper<BlockMapper,innerBlockSize> & blockMapper)285 explicit NonBlockMapper ( const NonBlockMapper< BlockMapper, innerBlockSize > &blockMapper ) 286 : BaseType( blockMapper.blockMapper_ ) 287 {} 288 }; 289 290 291 // Capabilities 292 // ------------ 293 294 namespace Capabilities 295 { 296 template< class BlockMapper, int blockSize > 297 struct isAdaptiveDofMapper< NonBlockMapper< BlockMapper, blockSize > > 298 { 299 static const bool v = isAdaptiveDofMapper< BlockMapper >::v; 300 }; 301 302 template< class BlockMapper, int blockSize > 303 struct isConsecutiveIndexSet< __NonBlockMapper::AdaptiveDofMapper< __NonBlockMapper::Traits< BlockMapper, blockSize > > > 304 { 305 static const bool v = isConsecutiveIndexSet< BlockMapper >::v; 306 }; 307 308 } // namespace Capabilities 309 310 } // namespace Fem 311 312 } // namespace Dune 313 314 #endif // #ifndef DUNE_FEM_NONBLOCKMAPPER_HH 315