1#ifndef DUNE_FEM_CODIMINDEXSET_HH
2#define DUNE_FEM_CODIMINDEXSET_HH
7#include <dune/grid/utility/persistentcontainer.hh>
8#include <dune/grid/utility/persistentcontainervector.hh>
9#include <dune/grid/utility/persistentcontainerwrapper.hh>
10#include <dune/grid/utility/persistentcontainermap.hh>
12#include <dune/fem/io/streams/streams.hh>
13#include <dune/fem/storage/dynamicarray.hh>
14#include <dune/fem/space/common/commindexmap.hh>
28 template <
class Gr
idImp>
32 typedef GridImp GridType;
33 typedef CodimIndexSet < GridType > ThisType;
36 const GridType& grid_;
38 typedef unsigned char INDEXSTATE;
39 const INDEXSTATE stateUnused_ = 0;
40 const INDEXSTATE stateUsed_ = 1;
41 const INDEXSTATE stateNew_ = 2;
45 typedef typename Fem::CommunicationIndexMap::IndexType IndexType;
48 static IndexType invalidIndex() {
return IndexType(-1); }
52 typedef DynamicArray< IndexType > IndexArrayType;
59 IndexContainerType leafIndex_;
60 IndexStateArrayType indexState_;
63 IndexArrayType holes_;
67 IndexArrayType oldIdx_;
68 IndexArrayType newIdx_;
77 IndexType numberHoles_;
82 CodimIndexSet (
const GridType& grid,
84 const double memoryFactor = 1.1)
86 , leafIndex_( grid, codim, invalidIndex() )
95 setMemoryFactor(memoryFactor);
99 void setMemoryFactor(
const double memoryFactor)
101 indexState_.setMemoryFactor( memoryFactor );
102 holes_.setMemoryFactor(memoryFactor);
103 oldIdx_.setMemoryFactor(memoryFactor);
104 newIdx_.setMemoryFactor(memoryFactor);
108 void resize () { leafIndex_.resize( invalidIndex() ); }
111 void prepareCompress () {}
118 leafIndex_.fill( invalidIndex() );
120 indexState_.resize( 0 );
126 std::fill( indexState_.begin(), indexState_.end(), stateUnused_ );
131 std::set< IndexType > found ;
133 typedef typename IndexContainerType::Iterator Iterator;
134 bool consecutive =
true;
135 const Iterator end = leafIndex_.end();
136 for( Iterator it = leafIndex_.begin(); it != end; ++it )
138 if( *it != invalidIndex() )
140 if( found.find( *it ) != found.end() )
142 std::cout <<
"index " << *it <<
" exists twice " << std::endl;
144 assert( found.find( *it ) == found.end() );
150 consecutive &= (*it < IndexType( indexState_.size() ));
156 void checkConsecutive () { assert( consecutive() ); }
164 lastSize_ = indexState_.size();
171 const IndexType sizeOfVecs = indexState_.size();
172 holes_.resize( sizeOfVecs );
175 bool haveToCopy =
false;
178 IndexType actHole = 0;
179 for( IndexType index = 0; index < sizeOfVecs; ++index )
182 if( indexState_[ index ] == stateUnused_ )
183 holes_[ actHole++ ] = index;
187 const IndexType actSize = sizeOfVecs - actHole;
190 oldIdx_.resize(actHole);
191 newIdx_.resize(actHole);
197 const IndexType invIndex = invalidIndex();
201 typedef typename IndexContainerType::Iterator Iterator;
202 const Iterator end = leafIndex_.end();
203 for( Iterator it = leafIndex_.begin(); it != end; ++it )
205 IndexType& index = *it;
206 if( index == invIndex )
210 else if( indexState_[ index ] == stateUnused_ )
220 if( index >= actSize )
227 assert(actHole >= 0);
228 while ( holes_[actHole] >= actSize )
233 if( actHole == invIndex )
break;
236 assert(actHole >= 0);
242 if( indexState_[ index ] == stateUsed_ )
246 oldIdx_[holes] = index;
247 newIdx_[holes] = holes_[actHole];
251 index = holes_[actHole];
259 oldIdx_.resize(holes);
260 newIdx_.resize(holes);
265 for( IndexType hole = 0; hole < holes; ++hole )
266 indexState_[ newIdx_[ hole ] ] = stateNew_;
271 numberHoles_ = oldIdx_.size();
274 leafIndex_.resize( invalidIndex() );
277 indexState_.resize( actSize );
280 for( IndexType i=0; i<actSize; ++i )
281 assert( indexState_[ i ] == stateUsed_ ||
282 indexState_[ i ] == stateUnused_ ||
283 indexState_[ i ] == stateNew_ );
291 IndexType additionalSizeEstimate ()
const {
return indexState_.size(); }
294 IndexType
size ()
const {
return indexState_.size(); }
297 IndexType realSize ()
const
299 return leafIndex_.size();
304 template <
class EntityType>
305 IndexType index (
const EntityType& entity )
const
307 assert( myCodim_ == EntityType :: codimension );
308 assert( checkValidIndex( leafIndex_[ entity ] ) );
309 return leafIndex_[ entity ];
313 template <
class EntityType>
314 IndexType subIndex (
const EntityType& entity,
315 const int subNumber )
const
317 return subIndex( entity, subNumber,
318 std::integral_constant<bool, EntityType::codimension == 0 > () );
322 template <
class EntityType>
323 IndexType subIndex (
const EntityType& entity,
325 const std::integral_constant<bool,false> codim0 )
const
327 DUNE_THROW(NotImplemented,
"CodimIndexSet::subIndex: not implemented for entities with codim > 0" );
328 return IndexType( -1 );
332 template <
class EntityType>
333 IndexType subIndex (
const EntityType& entity,
335 const std::integral_constant<bool,true> codim0 )
const
337 assert( checkValidIndex( leafIndex_( entity, subNumber ) ) );
338 return leafIndex_( entity, subNumber );
342 template <
class EntityType>
343 bool exists (
const EntityType& entity )
const
345 assert( myCodim_ == EntityType :: codimension );
346 const IndexType &index = leafIndex_[ entity ];
348 if (index==invalidIndex())
return false;
349 assert( index < IndexType( indexState_.size() ) );
350 return (indexState_[ index ] != stateUnused_);
353 template <
class EntityType>
354 bool exists (
const EntityType& entity ,
355 const int subNumber )
const
357 assert( 0 == EntityType :: codimension );
358 const IndexType &index = leafIndex_( entity, subNumber );
360 if (index==invalidIndex())
return false;
361 assert( index < IndexType( indexState_.size() ) );
362 return (indexState_[ index ] != stateUnused_);
366 IndexType numberOfHoles ()
const
372 IndexType oldIndex ( IndexType elNum )
const
374 assert( numberHoles_ == IndexType(oldIdx_.size()) );
375 return oldIdx_[elNum];
379 IndexType newIndex ( IndexType elNum)
const
381 assert( numberHoles_ == IndexType(newIdx_.size()) );
382 return newIdx_[elNum];
386 template <
class EntityType>
387 void insert (
const EntityType& entity )
389 assert( myCodim_ == EntityType :: codimension );
390 insertIdx( leafIndex_[ entity ] );
394 template <
class EntityType>
395 void insertSubEntity (
const EntityType& entity,
398 assert( 0 == EntityType :: codimension );
399 insertIdx( leafIndex_( entity, subNumber ) );
403 template <
class EntityType>
404 void insertGhost (
const EntityType& entity )
406 assert( myCodim_ == EntityType :: codimension );
408 IndexType &leafIdx = leafIndex_[ entity ];
409 insertIdx( leafIdx );
413 if( leafIdx >= lastSize_ )
414 indexState_[ leafIdx ] = stateNew_;
418 template <
class EntityType>
419 void markForRemoval(
const EntityType& entity )
421 assert( myCodim_ == EntityType :: codimension );
422 const IndexType &index = leafIndex_[ entity ];
423 if( index != invalidIndex() )
424 indexState_[ index ] = stateUnused_;
428 template <
class EntityType>
429 bool validIndex (
const EntityType& entity )
const
431 assert( myCodim_ == EntityType :: codimension );
432 return (leafIndex_[ entity ] >= 0);
435 void print( std::ostream& out )
const
437 typedef typename IndexContainerType::ConstIterator Iterator;
438 const Iterator end = leafIndex_.end();
439 for( Iterator it = leafIndex_.begin(); it != end; ++it )
441 const IndexType &leafIdx = *it;
442 if( leafIdx < indexState_.size() )
444 out <<
"idx: " << leafIdx <<
" stat: " << indexState_[ leafIdx ] << std::endl;
451 bool checkValidIndex(
const IndexType& idx )
const
453 assert( idx != invalidIndex() );
454 assert( idx <
size() );
455 return (idx != invalidIndex() ) && ( idx <
size() );
459 void insertIdx ( IndexType &index )
461 if( index == invalidIndex() )
463 index = indexState_.size();
464 indexState_.resize( index+1 );
466 assert( index < IndexType( indexState_.size() ) );
467 indexState_[ index ] = stateUsed_;
472 template <
class StreamTraits>
473 bool write(OutStreamInterface< StreamTraits >& out)
const
479 const uint32_t indexSize = indexState_.size();
483 const uint64_t mysize = leafIndex_.size();
487 typedef typename IndexContainerType::ConstIterator ConstIterator;
488 const ConstIterator end = leafIndex_.end();
489 for( ConstIterator it = leafIndex_.begin(); it != end; ++it )
496 template <
class StreamTraits>
497 bool read(InStreamInterface< StreamTraits >& in)
504 indexState_.resize(
size );
505 std::fill( indexState_.begin(), indexState_.end(), stateUsed_ );
508 uint64_t storedSize = 0;
511 uint64_t leafsize = leafIndex_.size();
513 if( storedSize < leafsize )
515 DUNE_THROW(InvalidStateException,
"CodimIndexSet: size consistency check failed during restore!");
519 typedef typename IndexContainerType::Iterator Iterator;
520 const Iterator end = leafIndex_.end();
522 for( Iterator it = leafIndex_.begin(); it != end; ++it, ++count )
526 if( count < storedSize )
529 const uint64_t leftOver = storedSize - count ;
530 for( uint64_t i = 0; i < leftOver; ++i )
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
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