dune-fem 2.12-git
Loading...
Searching...
No Matches
codimindexset.hh
Go to the documentation of this file.
1#ifndef DUNE_FEM_CODIMINDEXSET_HH
2#define DUNE_FEM_CODIMINDEXSET_HH
3
4#include <algorithm>
5#include <set>
6
7#include <dune/grid/utility/persistentcontainer.hh>
11
15
16namespace Dune
17{
18
19 namespace Fem
20 {
21
22 //***********************************************************************
23 //
24 // Index Set for one codimension
25 // --CodimIndexSet
26 //
27 //***********************************************************************
28 template <class GridImp>
30 {
31 protected:
32 typedef GridImp GridType;
33 typedef CodimIndexSet < GridType > ThisType;
34
35 // reference to grid
37
38 typedef unsigned char INDEXSTATE;
39 const INDEXSTATE stateUnused_ = 0; // unused indices
40 const INDEXSTATE stateUsed_ = 1; // used indices
41 const INDEXSTATE stateNew_ = 2; // new indices
42
43 public:
44 // type of exported index (local to one core)
46
47 // indices in this status have not been initialized
48 static IndexType invalidIndex() { return IndexType(-1); }
49
50 protected:
51 // array type for indices
54
55 // use the imporved PersistentContainer
57
58 // the mapping of the global to leaf index
61
62 // stack for holes
64
65 // Array that only remeber the occuring
66 // holes (for compress of data)
69
70 // last size of set before compress (needed in parallel runs)
72
73 // codim for which index is provided
74 const int myCodim_;
75
76 // actual number of holes
78
79 public:
80
82 CodimIndexSet (const GridType& grid,
83 const int codim,
84 const double memoryFactor = 1.1)
85 : grid_( grid )
86 , leafIndex_( grid, codim, invalidIndex() )
87 , indexState_( 0 )
88 , holes_(0)
89 , oldIdx_(0)
90 , newIdx_(0)
91 , lastSize_ (0)
92 , myCodim_( codim )
93 , numberHoles_(0)
94 {
95 setMemoryFactor(memoryFactor);
96 }
97
99 void setMemoryFactor(const double memoryFactor)
100 {
101 indexState_.setMemoryFactor( memoryFactor );
102 holes_.setMemoryFactor(memoryFactor);
103 oldIdx_.setMemoryFactor(memoryFactor);
104 newIdx_.setMemoryFactor(memoryFactor);
105 }
106
109
112
113 public:
115 void clear()
116 {
117 // set all values to invalidIndex
119 // free all indices
120 indexState_.resize( 0 );
121 }
122
128
130 {
132 // Something's wrong here: This method _must_ always return true
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 )
137 {
138 if( *it != invalidIndex() )
139 {
140 if( found.find( *it ) != found.end() )
141 {
142 std::cout << "index " << *it << " exists twice " << std::endl;
143 }
144 assert( found.find( *it ) == found.end() );
145 found.insert( *it );
146 //consecutive &= (*it < IndexType( indexState_.size() ));
147 }
148 //else
149 // consecutive = false;
150 consecutive &= (*it < IndexType( indexState_.size() ));
151 }
152 return consecutive;
153 }
154
156 void checkConsecutive () { assert( consecutive() ); }
157
160 {
161 // set number of holes to zero
162 numberHoles_ = 0;
163 // remember actual size
165 }
166
169 bool compress ()
170 {
171 const IndexType sizeOfVecs = indexState_.size();
172 holes_.resize( sizeOfVecs );
173
174 // true if a least one dof must be copied
175 bool haveToCopy = false;
176
177 // mark holes
178 IndexType actHole = 0;
179 for( IndexType index = 0; index < sizeOfVecs; ++index )
180 {
181 // create vector with all holes
182 if( indexState_[ index ] == stateUnused_ )
183 holes_[ actHole++ ] = index;
184 }
185
186 // the new size is the actual size minus the holes
187 const IndexType actSize = sizeOfVecs - actHole;
188
189 // resize hole storing vectors
190 oldIdx_.resize(actHole);
191 newIdx_.resize(actHole);
192
193 // only compress if number of holes > 0
194 if(actHole > 0)
195 {
196 // for int this is -1 or a large number for unsigned types
197 const IndexType invIndex = invalidIndex();
198
199 // close holes
200 IndexType holes = 0; // number of real holes
201 typedef typename IndexContainerType::Iterator Iterator;
202 const Iterator end = leafIndex_.end();
203 for( Iterator it = leafIndex_.begin(); it != end; ++it )
204 {
205 IndexType& index = *it;
206 if( index == invIndex )
207 {
208 continue ;
209 }
210 else if( indexState_[ index ] == stateUnused_ )
211 {
212 index = invIndex;
213 continue ;
214 }
215
216 // a index that is used but larger then actual size
217 // has to move to a hole
218 // if used index lies behind size, then index has to move
219 // to one of the holes
220 if( index >= actSize )
221 {
222 //std::cout << "Check index " << index << std::endl;
223 // serach next hole that is smaler than actual size
224 --actHole;
225 // if actHole < 0 then error, because we have index larger then
226 // actual size
227 assert(actHole >= 0);
228 while ( holes_[actHole] >= actSize )
229 {
230 assert(actHole > 0);
231 --actHole;
232
233 if( actHole == invIndex ) break;
234 }
235
236 assert(actHole >= 0);
237
238#if HAVE_MPI
239 // only for none-ghost elements hole storage is applied
240 // this is because ghost indices might have in introduced
241 // after the resize was done.
242 if( indexState_[ index ] == stateUsed_ )
243#endif
244 {
245 // remember old and new index
246 oldIdx_[holes] = index;
247 newIdx_[holes] = holes_[actHole];
248 ++holes;
249 }
250
251 index = holes_[actHole];
252
253 // means that dof manager has to copy the mem
254 haveToCopy = true;
255 }
256 }
257
258 // this call only sets the size of the vectors
259 oldIdx_.resize(holes);
260 newIdx_.resize(holes);
261
262 // mark holes as new
263 // note: This needs to be done after reassignment, so that their
264 // original entry will still see them as stateUnused_.
265 for( IndexType hole = 0; hole < holes; ++hole )
266 indexState_[ newIdx_[ hole ] ] = stateNew_;
267
268 } // end if actHole > 0
269
270 // store number of actual holes
272
273 // adjust size of container to correct value
275
276 // resize vector of index states
277 indexState_.resize( actSize );
278
279#ifndef NDEBUG
280 for( IndexType i=0; i<actSize; ++i )
281 assert( indexState_[ i ] == stateUsed_ ||
282 indexState_[ i ] == stateUnused_ ||
283 indexState_[ i ] == stateNew_ );
284
286#endif
287 return haveToCopy;
288 }
289
292
294 IndexType size () const { return indexState_.size(); }
295
298 {
299 return leafIndex_.size();
300 }
301
303 //- --index
304 template <class EntityType>
305 IndexType index ( const EntityType& entity ) const
306 {
307 assert( myCodim_ == EntityType :: codimension );
308 assert( checkValidIndex( leafIndex_[ entity ] ) );
309 return leafIndex_[ entity ];
310 }
311
313 template <class EntityType>
314 IndexType subIndex ( const EntityType& entity,
315 const int subNumber ) const
316 {
317 return subIndex( entity, subNumber,
319 }
320
322 template <class EntityType>
323 IndexType subIndex ( const EntityType& entity,
324 const int subNumber,
325 const std::integral_constant<bool,false> codim0 ) const
326 {
327 DUNE_THROW(NotImplemented,"CodimIndexSet::subIndex: not implemented for entities with codim > 0" );
328 return IndexType( -1 );
329 }
330
332 template <class EntityType>
333 IndexType subIndex ( const EntityType& entity,
334 const int subNumber,
335 const std::integral_constant<bool,true> codim0 ) const
336 {
337 assert( checkValidIndex( leafIndex_( entity, subNumber ) ) );
338 return leafIndex_( entity, subNumber );
339 }
340
342 template <class EntityType>
343 bool exists ( const EntityType& entity ) const
344 {
345 assert( myCodim_ == EntityType :: codimension );
346 const IndexType &index = leafIndex_[ entity ];
347 // if index is invalid (-1) it does not exist
348 if (index==invalidIndex()) return false;
349 assert( index < IndexType( indexState_.size() ) );
350 return (indexState_[ index ] != stateUnused_);
351 }
352
353 template <class EntityType>
354 bool exists ( const EntityType& entity ,
355 const int subNumber ) const
356 {
357 assert( 0 == EntityType :: codimension );
358 const IndexType &index = leafIndex_( entity, subNumber );
359 // if index is invalid (-1) it does not exist
360 if (index==invalidIndex()) return false;
361 assert( index < IndexType( indexState_.size() ) );
362 return (indexState_[ index ] != stateUnused_);
363 }
364
367 {
368 return numberHoles_;
369 }
370
373 {
374 assert( numberHoles_ == IndexType(oldIdx_.size()) );
375 return oldIdx_[elNum];
376 }
377
380 {
381 assert( numberHoles_ == IndexType(newIdx_.size()) );
382 return newIdx_[elNum];
383 }
384
385 // insert element and create index for element number
386 template <class EntityType>
387 void insert (const EntityType& entity )
388 {
389 assert( myCodim_ == EntityType :: codimension );
390 insertIdx( leafIndex_[ entity ] );
391 }
392
393 // insert element and create index for element number
394 template <class EntityType>
395 void insertSubEntity (const EntityType& entity,
396 const int subNumber)
397 {
398 assert( 0 == EntityType :: codimension );
399 insertIdx( leafIndex_( entity, subNumber ) );
400 }
401
402 // insert element as ghost and create index for element number
403 template <class EntityType>
404 void insertGhost (const EntityType& entity )
405 {
406 assert( myCodim_ == EntityType :: codimension );
407 // insert index
408 IndexType &leafIdx = leafIndex_[ entity ];
409 insertIdx( leafIdx );
410
411 // if index is also larger than lastSize
412 // mark as new to skip old-new index lists
413 if( leafIdx >= lastSize_ )
414 indexState_[ leafIdx ] = stateNew_;
415 }
416
417 // insert element and create index for element number
418 template <class EntityType>
419 void markForRemoval( const EntityType& entity )
420 {
421 assert( myCodim_ == EntityType :: codimension );
422 const IndexType &index = leafIndex_[ entity ];
423 if( index != invalidIndex() )
425 }
426
427 // insert element as ghost and create index for element number
428 template <class EntityType>
429 bool validIndex (const EntityType& entity ) const
430 {
431 assert( myCodim_ == EntityType :: codimension );
432 return (leafIndex_[ entity ] >= 0);
433 }
434
435 void print( std::ostream& out ) const
436 {
437 typedef typename IndexContainerType::ConstIterator Iterator;
438 const Iterator end = leafIndex_.end();
439 for( Iterator it = leafIndex_.begin(); it != end; ++it )
440 {
441 const IndexType &leafIdx = *it;
442 if( leafIdx < indexState_.size() )
443 {
444 out << "idx: " << leafIdx << " stat: " << indexState_[ leafIdx ] << std::endl;
445 }
446 }
447 }
448
449 protected:
450 // return true if the index idx is valid
451 bool checkValidIndex( const IndexType& idx ) const
452 {
453 assert( idx != invalidIndex() );
454 assert( idx < size() );
455 return (idx != invalidIndex() ) && ( idx < size() );
456 }
457
458 // insert element and create index for element number
460 {
461 if( index == invalidIndex() )
462 {
465 }
466 assert( index < IndexType( indexState_.size() ) );
468 }
469
470 public:
471 // write to stream
472 template <class StreamTraits>
474 {
475 // store current index set size
476 // don't write something like out << indexState_.size()
477 // since on read you then don't know exactly what
478 // type has been written, it must be the same types
479 const uint32_t indexSize = indexState_.size();
480 out << indexSize;
481
482 // for consistency checking, write size as 64bit integer
483 const uint64_t mysize = leafIndex_.size();
484 out << mysize ;
485
486 // backup indices
487 typedef typename IndexContainerType::ConstIterator ConstIterator;
488 const ConstIterator end = leafIndex_.end();
489 for( ConstIterator it = leafIndex_.begin(); it != end; ++it )
490 out << *it;
491
492 return true;
493 }
494
495 // read from stream
496 template <class StreamTraits>
498 {
499 // read current index set size
500 uint32_t size = 0;
501 in >> size;
502
503 // mark all indices used
506
507 // for consistency checking
508 uint64_t storedSize = 0;
509 in >> storedSize ;
510
511 uint64_t leafsize = leafIndex_.size();
512 // the stored size can be larger (visualization of parallel grids in serial)
513 if( storedSize < leafsize )
514 {
515 DUNE_THROW(InvalidStateException,"CodimIndexSet: size consistency check failed during restore!");
516 }
517
518 // restore indices
519 typedef typename IndexContainerType::Iterator Iterator;
520 const Iterator end = leafIndex_.end();
521 uint64_t count = 0 ;
522 for( Iterator it = leafIndex_.begin(); it != end; ++it, ++count )
523 in >> *it;
524
525 // also read indices that were stored but are not needed on read
526 if( count < storedSize )
527 {
528 IndexType value ;
529 const uint64_t leftOver = storedSize - count ;
530 for( uint64_t i = 0; i < leftOver; ++i )
531 in >> value ;
532 }
533
534 return true;
535 }
536
537 }; // end of CodimIndexSet
538
539 } // namespace Fem
540
541} // namespace Dune
542
543#endif // #ifndef DUNE_FEM_CODIMINDEXSET_HH
iterator end()
std::ptrdiff_t index() const
#define DUNE_THROW(E,...)
constexpr Iterator end()
constexpr Iterator begin()
void fill(const Value &value)
IteratorWrapper< const Value, typename Map::const_iterator > ConstIterator
void resize(const Value &value=Value())
ConstIterator begin() const
ConstIterator end() const
IteratorWrapper< Value, typename Map::iterator > Iterator
Definition codimindexset.hh:30
DynamicArray< INDEXSTATE > IndexStateArrayType
Definition codimindexset.hh:53
void setMemoryFactor(const double memoryFactor)
set memory overestimation factor
Definition codimindexset.hh:99
bool exists(const EntityType &entity, const int subNumber) const
Definition codimindexset.hh:354
IndexType additionalSizeEstimate() const
return how much extra memory is needed for restriction
Definition codimindexset.hh:291
DynamicArray< IndexType > IndexArrayType
Definition codimindexset.hh:52
IndexType subIndex(const EntityType &entity, const int subNumber, const std::integral_constant< bool, false > codim0) const
return leaf index for given entity
Definition codimindexset.hh:323
void insert(const EntityType &entity)
Definition codimindexset.hh:387
void markForRemoval(const EntityType &entity)
Definition codimindexset.hh:419
IndexType numberOfHoles() const
return number of holes
Definition codimindexset.hh:366
void insertGhost(const EntityType &entity)
Definition codimindexset.hh:404
IndexType newIndex(IndexType elNum) const
return new index, for dof manager only returns index
Definition codimindexset.hh:379
bool read(InStreamInterface< StreamTraits > &in)
Definition codimindexset.hh:497
const int myCodim_
Definition codimindexset.hh:74
bool write(OutStreamInterface< StreamTraits > &out) const
Definition codimindexset.hh:473
void insertSubEntity(const EntityType &entity, const int subNumber)
Definition codimindexset.hh:395
IndexType size() const
return size of grid entities per level and codim
Definition codimindexset.hh:294
void resetUsed()
set all entries to unused
Definition codimindexset.hh:124
IndexArrayType holes_
Definition codimindexset.hh:63
CodimIndexSet< GridType > ThisType
Definition codimindexset.hh:33
IndexStateArrayType indexState_
Definition codimindexset.hh:60
GridImp GridType
Definition codimindexset.hh:32
CodimIndexSet(const GridType &grid, const int codim, const double memoryFactor=1.1)
Constructor taking memory factor (default = 1.1)
Definition codimindexset.hh:82
IndexType subIndex(const EntityType &entity, const int subNumber, const std::integral_constant< bool, true > codim0) const
return leaf index for given entity
Definition codimindexset.hh:333
bool compress()
Definition codimindexset.hh:169
bool exists(const EntityType &entity) const
return state of index for given hierarchic number
Definition codimindexset.hh:343
IndexArrayType newIdx_
Definition codimindexset.hh:68
bool checkValidIndex(const IndexType &idx) const
Definition codimindexset.hh:451
void insertIdx(IndexType &index)
Definition codimindexset.hh:459
IndexType numberHoles_
Definition codimindexset.hh:77
bool consecutive()
Definition codimindexset.hh:129
IndexArrayType oldIdx_
Definition codimindexset.hh:67
void print(std::ostream &out) const
Definition codimindexset.hh:435
IndexContainerType leafIndex_
Definition codimindexset.hh:59
IndexType realSize() const
return size of grid entities per level and codim
Definition codimindexset.hh:297
void prepareCompress()
prepare for setup (nothing to do here)
Definition codimindexset.hh:111
const INDEXSTATE stateUsed_
Definition codimindexset.hh:40
IndexType subIndex(const EntityType &entity, const int subNumber) const
return leaf index for given entity
Definition codimindexset.hh:314
const GridType & grid_
Definition codimindexset.hh:36
void clear()
clear set
Definition codimindexset.hh:115
void resize()
reallocate the vectors
Definition codimindexset.hh:108
void checkConsecutive()
set all entries to unused
Definition codimindexset.hh:156
void clearHoles()
clear holes, i.e. set number of holes to zero
Definition codimindexset.hh:159
const INDEXSTATE stateUnused_
Definition codimindexset.hh:39
bool validIndex(const EntityType &entity) const
Definition codimindexset.hh:429
PersistentContainer< GridType, IndexType > IndexContainerType
Definition codimindexset.hh:56
IndexType index(const EntityType &entity) const
return leaf index for given entity
Definition codimindexset.hh:305
const INDEXSTATE stateNew_
Definition codimindexset.hh:41
IndexType lastSize_
Definition codimindexset.hh:71
static IndexType invalidIndex()
Definition codimindexset.hh:48
Fem::CommunicationIndexMap::IndexType IndexType
Definition codimindexset.hh:45
IndexType oldIndex(IndexType elNum) const
return old index, for dof manager only
Definition codimindexset.hh:372
unsigned char INDEXSTATE
Definition codimindexset.hh:38
abstract interface for an output stream
Definition streams.hh:48
abstract interface for an input stream
Definition streams.hh:190
int IndexType
Definition commindexmap.hh:21
size_type size() const
return size of array
Definition dynamicarray.hh:170
An implementation of DenseVector which uses a C-array of dynamic size as storage.
Definition dynamicarray.hh:244
void setMemoryFactor(double memFactor)
set memory factor
Definition dynamicarray.hh:296
void resize(size_type nsize)
Definition dynamicarray.hh:334
T end(T... args)
T endl(T... args)
T fill(T... args)
T find(T... args)
T insert(T... args)