dune-grid
2.1.1
|
00001 #ifndef DUNE_DEFAULTINDEXSETS_HH 00002 #define DUNE_DEFAULTINDEXSETS_HH 00003 00004 //- system includes 00005 #include <vector> 00006 #include <rpc/rpc.h> 00007 00008 //- Dune includes 00009 #include <dune/common/misc.hh> 00010 // #include <dune/common/interfaces.hh> 00011 #include <dune/grid/common/grid.hh> 00012 #include <dune/grid/common/adaptcallback.hh> // for compatibility only 00013 00020 namespace Dune { 00021 00034 class DefaultEmptyIndexSet 00035 { 00036 // dummy value 00037 enum { myType = -1 }; 00038 00039 protected: 00040 const bool adaptive_; 00041 00042 public: 00044 DefaultEmptyIndexSet (bool adaptive) : adaptive_(adaptive) {} 00045 00048 bool compress () { 00049 return false; 00050 } 00051 00054 bool adaptive () const { return adaptive_; } 00055 00057 bool needsCompress () const { return false; } 00058 00060 template <class EntityType> 00061 void insertNewIndex( const EntityType & en ) { 00062 assert(adaptive_) ; 00063 } 00064 00066 template <class EntityType> 00067 void removeOldIndex( const EntityType & en ) { 00068 assert(adaptive_) ; 00069 } 00070 00072 void resize () {} 00073 00075 int additionalSizeEstimate () const { return 0; } 00076 00077 static int type() { return myType; } 00078 00080 int numberOfHoles ( int codim ) const { return 0; } 00081 00083 int oldIndex (int hole, int codim ) const { return 0; } 00084 00086 int newIndex (int hole, int codim ) const { return 0; } 00087 00089 bool write_xdr(const std::basic_string<char> filename , int timestep) 00090 { 00091 FILE *file; 00092 XDR xdrs; 00093 const char *path = ""; 00094 00095 std::basic_string<char> fnstr = genFilename(path,filename, timestep); 00096 const char * fn = fnstr.c_str(); 00097 file = fopen(fn, "wb"); 00098 if (!file) 00099 { 00100 std::cerr << "\aERROR in DefaultGridIndexSet::write_xdr(..): could not open <" 00101 << filename << ">!" << std::endl; 00102 return false; 00103 } 00104 00105 xdrstdio_create(&xdrs, file, XDR_ENCODE); 00106 this->processXdr(&xdrs); 00107 00108 xdr_destroy(&xdrs); 00109 fclose(file); 00110 00111 return true; 00112 } 00113 00115 bool read_xdr(const std::basic_string<char> filename , int timestep) 00116 { 00117 FILE *file; 00118 XDR xdrs; 00119 const char *path = ""; 00120 00121 std::basic_string<char> fnstr = genFilename(path,filename, timestep); 00122 const char * fn = fnstr.c_str(); 00123 std::cout << "Reading <" << fn << "> \n"; 00124 file = fopen(fn, "rb"); 00125 if(!file) 00126 { 00127 std::cerr << "\aERROR in DefaultGridIndexSet::read_xdr(..): could not open <" 00128 << filename << ">!" << std::endl; 00129 return(false); 00130 } 00131 00132 // read xdr 00133 xdrstdio_create(&xdrs, file, XDR_DECODE); 00134 this->processXdr(&xdrs); 00135 00136 xdr_destroy(&xdrs); 00137 fclose(file); 00138 return true; 00139 } 00140 00141 protected: 00142 // read/write from/to xdr stream 00143 bool processXdr(XDR *xdrs) 00144 { 00145 int type = myType; 00146 xdr_int ( xdrs, &type); 00147 if(type != myType) 00148 { 00149 std::cerr << "\nERROR: DefaultGridIndex: wrong type choosen! \n\n"; 00150 assert(type == myType); 00151 } 00152 return true; 00153 } 00154 }; 00156 template <class GridType> 00157 class DefaultGridIndexSetBase : public DefaultEmptyIndexSet 00158 { 00159 // dummy value 00160 enum { myType = -1 }; 00161 public: 00162 enum { ncodim = GridType::dimension + 1 }; 00163 00165 DefaultGridIndexSetBase (const GridType & grid ) 00166 // here false, because methods have to be overloaded 00167 : DefaultEmptyIndexSet(false) 00168 , grid_ (grid) {} 00169 protected: 00170 // the corresponding grid 00171 const GridType & grid_; 00172 }; 00173 //********************************************************************* 00179 //********************************************************************* 00180 00181 template <class DefaultLevelIndexSetType, int codim> 00182 struct CheckLevelForCodim 00183 { 00184 static void recursive(DefaultLevelIndexSetType & d) 00185 { 00186 d.template checkLevelIndexForCodim<codim> (); 00187 CheckLevelForCodim<DefaultLevelIndexSetType,codim-1>::recursive(d); 00188 } 00189 }; 00190 00191 template <class DefaultLevelIndexSetType> 00192 struct CheckLevelForCodim<DefaultLevelIndexSetType,0> 00193 { 00194 static void recursive(DefaultLevelIndexSetType & d) 00195 { 00196 d.template checkLevelIndexForCodim<0> (); 00197 } 00198 }; 00199 00200 00201 template <class GridImp> 00202 struct DefaultLevelIteratorTypes 00203 { 00205 template<int cd> 00206 struct Codim 00207 { 00208 template<PartitionIteratorType pitype> 00209 struct Partition 00210 { 00211 typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator; 00212 }; 00213 }; 00214 }; 00215 00220 template <class GridImp> 00221 class DefaultLevelIndexSet : 00222 public IndexSet< GridImp, DefaultLevelIndexSet <GridImp>, unsigned int > 00223 00224 { 00225 typedef GridImp GridType; 00226 enum { dim = GridType :: dimension }; 00227 00228 public: 00229 enum { ncodim = GridType::dimension + 1 }; 00230 00232 typedef unsigned int IndexType; 00233 00234 typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType; 00235 private: 00236 00238 typedef std::vector<int> IndexArrayType; 00239 00240 00241 typedef DefaultLevelIndexSet<GridType> ThisType; 00242 00243 template <class EntityType, int codim> 00244 struct InsertEntity 00245 { 00246 template <class HierarchicIndexSet> 00247 static void insert(const EntityType & en, 00248 const HierarchicIndexSet & hset, 00249 IndexArrayType (&index)[ncodim], 00250 int (&num)[ncodim]) 00251 { 00252 IndexArrayType & idx = index[codim]; 00253 for( int i = 0; i < en.template count< codim >(); ++i ) 00254 { 00255 const int id = hset.subIndex( en, i, codim ); 00256 if( idx[ id ] < 0 ) 00257 { 00258 idx[id] = num[codim]; 00259 ++num[codim]; 00260 } 00261 } 00262 InsertEntity<EntityType,codim-1>::insert(en,hset,index,num); 00263 } 00264 }; 00265 00266 template <class EntityType> 00267 struct InsertEntity<EntityType,0> 00268 { 00269 template <class HierarchicIndexSet> 00270 static void insert(const EntityType & en, 00271 const HierarchicIndexSet & hset, 00272 IndexArrayType (&index)[ncodim], 00273 int (&num)[ncodim]) 00274 { 00275 enum { codim = 0 }; 00276 IndexArrayType & idx = index[codim]; 00277 const int id = hset.index(en); 00278 if( idx[id] < 0 ) 00279 { 00280 idx[id] = num[codim]; 00281 ++num[codim]; 00282 } 00283 } 00284 }; 00285 00286 public: 00289 using IndexSet<GridType, DefaultLevelIndexSet>::subIndex; 00290 00293 DefaultLevelIndexSet(const GridType & grid , int level ) : 00294 grid_(grid) , level_(level) , hIndexSet_ ( grid.hierarchicIndexSet() ) 00295 , size_ ( ncodim ) 00296 { 00297 calcNewIndex (); 00298 } 00299 00301 template<class EntityType> 00302 IndexType index (const EntityType & en) const 00303 { 00304 enum { cd = EntityType :: codimension }; 00305 // this must not be true for vertices 00306 // therefore only check other codims 00307 #ifndef NDEBUG 00308 const int codim = cd; 00309 assert( (codim == dim) ? (1) : (level_ == en.level() )); 00310 assert( levelIndex_[codim][ hIndexSet_.index(en) ] >= 0 ); 00311 #endif 00312 return levelIndex_[cd][ hIndexSet_.index(en) ]; 00313 } 00314 00316 template<int cd> 00317 IndexType index (const typename GridImp::template Codim<cd>::Entity& en) const 00318 { 00319 // this must not be true for vertices 00320 // therefore only check other codims 00321 #ifndef NDEBUG 00322 const int codim = cd; 00323 assert( (codim == dim) ? (1) : (level_ == en.level() )); 00324 assert( levelIndex_[codim][ hIndexSet_.index(en) ] >= 0 ); 00325 #endif 00326 return levelIndex_[cd][ hIndexSet_.index(en) ]; 00327 } 00328 00331 template< int cc > 00332 IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e, 00333 int i, unsigned int codim ) const 00334 { 00335 const int hIndex = hIndexSet_.subIndex( e, i, codim ); 00336 assert( (codim != 0) || (level_ == e.level()) ); 00337 assert( levelIndex_[ codim ][ hIndex ] >= 0 ); 00338 return levelIndex_[ codim ][ hIndex ]; 00339 } 00340 00342 template<class EntityType> 00343 bool contains (const EntityType& en) const 00344 { 00345 enum { cd = EntityType :: codimension }; 00346 return (levelIndex_[cd][ hIndexSet_.index(en) ] >= 0); 00347 } 00348 00350 IndexType size ( int codim ) const 00351 { 00352 assert( codim >= 0 && codim <= GridType::dimension ); 00353 return size_[codim]; 00354 } 00355 00358 IndexType size ( GeometryType type ) const 00359 { 00360 if( typeNotValid(type) ) return 0; 00361 return size_[GridType::dimension-type.dim()]; 00362 } 00363 00366 void calcNewIndex () 00367 { 00368 // resize arrays to new size 00369 for(int cd=0; cd<ncodim; ++cd) 00370 { 00371 resizeVectors(levelIndex_[cd], hIndexSet_.size(cd)); 00372 } 00373 00374 // walk grid and store index 00375 typedef typename DefaultLevelIteratorTypes<GridImp>:: template Codim<0>:: 00376 template Partition<All_Partition> :: Iterator IteratorType; 00377 00378 // we start with zero for all codims 00379 int num[ncodim]; 00380 for(int cd=0; cd<ncodim; ++cd) num[cd] = 0; 00381 00382 IteratorType endit = this->template end < 0, All_Partition > (); 00383 for(IteratorType it = this->template begin< 0, All_Partition > (); 00384 it != endit; ++it) 00385 { 00386 assert( it->level() == level_ ); 00387 insertEntity(*it,num); 00388 } 00389 00390 // remember the number of entity on level and cd = 0 00391 for(int cd=0; cd<ncodim; ++cd) 00392 { 00393 size_[cd] = num[cd]; 00394 assert( size_[cd] == grid_.size(level_,cd) ); 00395 } 00396 00397 #ifndef NDEBUG 00398 CheckLevelForCodim<ThisType,dim>::recursive(*this); 00399 #endif 00400 } 00401 00402 // calculate index for the codim 00403 template <int cd> 00404 void checkLevelIndexForCodim () 00405 { 00406 IndexArrayType & levIndex = levelIndex_[cd]; 00407 // resize memory if necessary 00408 // walk grid and store index 00409 typedef typename DefaultLevelIteratorTypes<GridImp>:: template Codim<cd>:: 00410 template Partition<All_Partition> :: Iterator LevelIterator; 00411 00412 LevelIterator endit = this->template end < cd , All_Partition > (); 00413 for(LevelIterator it = this->template begin< cd , All_Partition > (); it != endit; ++it) 00414 { 00415 int no = hIndexSet_.index(*it); 00416 assert( levIndex[no] >= 0 ); 00417 } 00418 } 00419 00421 const std::vector<GeometryType>& geomTypes (int codim) const 00422 { 00423 return hIndexSet_.geomTypes( codim ); 00424 } 00425 00428 template<int cd, PartitionIteratorType pitype> 00429 typename DefaultLevelIteratorTypes<GridImp>::template Codim<cd>:: 00430 template Partition<pitype>::Iterator begin () const 00431 { 00432 return this->grid_.template lbegin<cd,pitype> (level_); 00433 } 00434 00437 template<int cd, PartitionIteratorType pitype> 00438 typename DefaultLevelIteratorTypes<GridImp>::template Codim<cd>:: 00439 template Partition<pitype>::Iterator end () const 00440 { 00441 return this->grid_.template lend<cd,pitype> (level_); 00442 } 00443 00445 bool containsIndex (int cd , int idx) const 00446 { 00447 assert( cd >= 0 ); 00448 assert( cd < ncodim ); 00449 00450 assert( idx >= 0); 00451 assert( idx < (int) levelIndex_[cd].size()); 00452 return (levelIndex_[cd][ idx ] >= 0); 00453 } 00454 00455 private: 00456 // return whether set has this type stored or not 00457 bool typeNotValid (const GeometryType & type) const 00458 { 00459 int codim = GridType :: dimension - type.dim(); 00460 const std::vector<GeometryType> & geomT = geomTypes(codim); 00461 for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false; 00462 return true; 00463 } 00464 // calculate index for the codim 00465 template <class EntityType> 00466 void insertEntity(EntityType & en, int (&num)[ncodim]) 00467 { 00468 InsertEntity<EntityType,dim>::insert(en,hIndexSet_,levelIndex_,num); 00469 } 00470 00471 // resize vectors of index set 00472 void resizeVectors(IndexArrayType &a, int newNumberOfEntries) 00473 { 00474 if(newNumberOfEntries > 0) 00475 { 00476 a.resize(newNumberOfEntries); 00477 } 00478 for(size_t i=0; i<a.size(); i++) a[i] = -1; 00479 } 00480 00481 // method prints indices of given codim, for debugging 00482 void print (int codim) const 00483 { 00484 for(size_t i=0; i<levelIndex_[codim].size(); i++) 00485 { 00486 std::cout << "levelind[" << i << "] = " << levelIndex_[codim][i] << "\n"; 00487 } 00488 } 00489 00490 // grid this level set belongs to 00491 const GridType & grid_; 00492 00493 // the level for which this index set is created 00494 const int level_; 00495 00496 // the grids HierarchicIndexSet 00497 const HierarchicIndexSetType & hIndexSet_; 00498 00499 // number of entitys of each level an codim 00500 IndexArrayType size_; 00501 00502 //********************************************************* 00503 // Methods for mapping the hierarchic Index to index on Level 00504 IndexArrayType levelIndex_[ncodim]; 00505 00506 }; 00507 00508 00510 template <class GridImp> 00511 struct DefaultLeafIteratorTypes 00512 { 00514 template<int cd> 00515 struct Codim 00516 { 00517 template<PartitionIteratorType pitype> 00518 struct Partition 00519 { 00520 typedef typename GridImp::Traits::template Codim<cd>:: 00521 template Partition<pitype>::LeafIterator Iterator; 00522 }; 00523 }; 00524 }; 00525 00526 00528 template <class GridImp> 00529 class DefaultLeafIndexSet : 00530 public IndexSet< GridImp, DefaultLeafIndexSet <GridImp>, unsigned int > 00531 00532 { 00533 typedef GridImp GridType; 00534 enum { dim = GridType :: dimension }; 00535 00536 public: 00537 enum { ncodim = dim + 1 }; 00538 typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType; 00539 00541 typedef unsigned int IndexType; 00542 private: 00544 typedef std::vector<int> IndexArrayType; 00545 00546 typedef DefaultLeafIndexSet<GridType> ThisType; 00547 00548 template <class EntityType, int codim> 00549 struct InsertEntity 00550 { 00551 template <class HierarchicIndexSet> 00552 static void insert(const EntityType & en, 00553 const HierarchicIndexSet & hset, 00554 IndexArrayType (&index)[ncodim], 00555 int (&num)[ncodim]) 00556 { 00557 IndexArrayType & idx = index[codim]; 00558 for( int i = 0; i < en.template count< codim >(); ++i ) 00559 { 00560 const int id = hset.subIndex( en, i, codim ); 00561 if( idx[ id ] < 0 ) 00562 { 00563 idx[id] = num[codim]; 00564 ++num[codim]; 00565 } 00566 } 00567 InsertEntity<EntityType,codim-1>::insert(en,hset,index,num); 00568 } 00569 }; 00570 00571 template <class EntityType> 00572 struct InsertEntity<EntityType,0> 00573 { 00574 template <class HierarchicIndexSet> 00575 static void insert(const EntityType & en, 00576 const HierarchicIndexSet & hset, 00577 IndexArrayType (&index)[ncodim], 00578 int (&num)[ncodim]) 00579 { 00580 enum { codim = 0 }; 00581 IndexArrayType & idx = index[codim]; 00582 const int id = hset.index(en); 00583 if( idx[id] < 0 ) 00584 { 00585 idx[id] = num[codim]; 00586 ++num[codim]; 00587 } 00588 } 00589 }; 00590 00591 public: 00594 using IndexSet<GridType, DefaultLeafIndexSet>::subIndex; 00595 00598 DefaultLeafIndexSet(const GridType & grid) 00599 : grid_(grid) 00600 , hIndexSet_ ( grid.hierarchicIndexSet() ) 00601 , size_ ( ncodim ) 00602 { 00603 calcNewIndex (); 00604 } 00605 00607 template<class EntityType> 00608 IndexType index (const EntityType & en) const 00609 { 00610 enum { cd = EntityType :: codimension }; 00611 // this must not be true for vertices 00612 // therefore only check other codims 00613 assert( index_[cd][ hIndexSet_.index(en) ] >= 0 ); 00614 return index_[cd][ hIndexSet_.index(en) ]; 00615 } 00616 00617 template<int cd> 00618 IndexType index (const typename GridImp::template Codim<cd>::Entity& en) const 00619 { 00620 // this must not be true for vertices 00621 // therefore only check other codims 00622 assert( index_[cd][ hIndexSet_.index(en) ] >= 0 ); 00623 return index_[cd][ hIndexSet_.index(en) ]; 00624 } 00625 00628 template< int cc > 00629 IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e, 00630 int i, unsigned int codim ) const 00631 { 00632 const int hIndex = hIndexSet_.subIndex( e, i, codim ); 00633 assert( index_[ codim ][ hIndex ] >= 0 ); 00634 return index_[ codim ][ hIndex ]; 00635 } 00636 00638 template<class EntityType> 00639 bool contains (const EntityType& en) const 00640 { 00641 enum { cd = EntityType :: codimension }; 00642 return (index_[cd][ hIndexSet_.index(en) ] >= 0 ); 00643 } 00644 00646 IndexType size ( int codim ) const 00647 { 00648 assert( codim >= 0 && codim <= GridType::dimension ); 00649 return size_[codim]; 00650 } 00651 00654 IndexType size ( GeometryType type ) const 00655 { 00656 if( typeNotValid(type) ) return 0; 00657 return size_[GridType::dimension-type.dim()]; 00658 } 00659 00662 void calcNewIndex () 00663 { 00664 // resize arrays to new size 00665 for(int cd=0; cd<ncodim; ++cd) 00666 { 00667 resizeVectors(index_[cd], hIndexSet_.size(cd)); 00668 } 00669 00670 // walk grid and store index 00671 typedef typename DefaultLeafIteratorTypes<GridImp>:: template Codim<0>:: 00672 template Partition<All_Partition> :: Iterator IteratorType; 00673 00674 // we start with zero for all codims 00675 int num[ncodim]; 00676 for(int cd=0; cd<ncodim; ++cd) num[cd] = 0; 00677 00678 int elems=0; 00679 00680 IteratorType endit = this->template end < 0, All_Partition > (); 00681 for(IteratorType it = this->template begin< 0, All_Partition > (); 00682 it != endit; ++it) 00683 { 00684 ++elems; 00685 insertEntity(*it,num); 00686 } 00687 00688 // remember the number of entity on level and cd = 0 00689 for(int cd=0; cd<ncodim; ++cd) 00690 { 00691 size_[cd] = num[cd]; 00692 //if( size_[cd] != grid_.size(cd) ) 00693 // std::cout << size_[cd] << " calc | grid " << grid_.size(cd) << "\n"; 00694 //assert( size_[cd] == grid_.size(cd) ); 00695 } 00696 } 00697 00699 const std::vector<GeometryType>& geomTypes (int codim) const 00700 { 00701 return hIndexSet_.geomTypes( codim ); 00702 } 00703 00704 00707 template<int cd, PartitionIteratorType pitype> 00708 typename DefaultLeafIteratorTypes<GridImp>::template Codim<cd>:: 00709 template Partition<pitype>::Iterator begin () const 00710 { 00711 return this->grid_.template leafbegin<cd,pitype> (); 00712 } 00713 00716 template<int cd, PartitionIteratorType pitype> 00717 typename DefaultLeafIteratorTypes<GridImp>::template Codim<cd>:: 00718 template Partition<pitype>::Iterator end () const 00719 { 00720 return this->grid_.template leafend<cd,pitype> (); 00721 } 00722 00723 private: 00724 // return whether set has this type stored or not 00725 bool typeNotValid (const GeometryType & type) const 00726 { 00727 int codim = GridType :: dimension - type.dim(); 00728 const std::vector<GeometryType> & geomT = geomTypes(codim); 00729 for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false; 00730 return true; 00731 } 00732 // calculate index for the codim 00733 template <class EntityType> 00734 void insertEntity(EntityType & en, int (&num)[ncodim]) 00735 { 00736 InsertEntity<EntityType,dim>::insert(en,hIndexSet_,index_,num); 00737 } 00738 00739 // resize vectors of index set 00740 void resizeVectors(IndexArrayType &a, int newNumberOfEntries) 00741 { 00742 if( newNumberOfEntries > 0 ) 00743 { 00744 a.resize(newNumberOfEntries); 00745 } 00746 for(size_t i=0; i<a.size(); ++i) a[i] = -1; 00747 } 00748 00749 // method prints indices of given codim, for debugging 00750 void print (int codim) const 00751 { 00752 for(size_t i=0; i<index_[codim].size(); i++) 00753 { 00754 std::cout << "levelind[" << i << "] = " << index_[codim][i] << "\n"; 00755 } 00756 } 00757 00758 // grid this level set belongs to 00759 const GridType & grid_; 00760 00761 // the grids HierarchicIndexSet 00762 const HierarchicIndexSetType & hIndexSet_; 00763 00764 // number of entitys of each level an codim 00765 IndexArrayType size_; 00766 00767 //********************************************************* 00768 // Methods for mapping the hierarchic Index to index on Level 00769 IndexArrayType index_[ncodim]; 00770 }; 00771 00772 } // end namespace Dune 00773 00774 #endif