dune-grid  2.1.1
common/defaultindexsets.hh
Go to the documentation of this file.
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