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 
00019 namespace Dune {
00020 
00034 class DefaultEmptyIndexSet
00035 {
00036   // dummy value 
00037   enum { myType = -1 };
00038 protected:  
00039   const bool adaptive_;
00040 public:  
00041   template <class IndexSetType, class EntityType,int enCodim, int codim>
00042   struct IndexWrapper 
00043   {
00044     static inline int index (const IndexSetType & set, const EntityType & en , int num )
00045     {
00046       return set.index(en);
00047     }
00048   };
00049 
00050   // if codim and enCodim are equal, then return index 
00051   template <class IndexSetType, class EntityType, int codim>
00052   struct IndexWrapper<IndexSetType,EntityType,codim,codim>
00053   {
00054     static inline int index (const IndexSetType & set, const EntityType & en , int num )
00055     {
00056       return set.index(en);
00057     }
00058   };
00059 
00060   // return number of vertex num
00061   template <class IndexSetType, class EntityType>
00062   struct IndexWrapper<IndexSetType,EntityType,0,3> 
00063   {
00064     static inline int index (const IndexSetType & set, const EntityType & en , int num )
00065     {
00066       return set.template subIndex<3> (en,num);
00067     }
00068   };
00069  
00070   // return number of vertex num for dim == 2 
00071   // return number of edge num for dim == 3
00072   template <class IndexSetType, class EntityType>
00073   struct IndexWrapper<IndexSetType,EntityType,0,2> 
00074   {
00075     static inline int index (const IndexSetType & set, const EntityType & en , int num )
00076     {
00077       return set.template subIndex<2> (en,num);
00078     }
00079   };
00080 
00081   // return number of vertex for dim == 1
00082   // return number of edge num for dim == 2 
00083   // return number of face num for dim == 3
00084   template <class IndexSetType, class EntityType>
00085   struct IndexWrapper<IndexSetType,EntityType,0,1> 
00086   {
00087     static inline int index (const IndexSetType & set, const EntityType & en , int num )
00088     {
00089       return set.template subIndex<1> (en,num);
00090     }
00091   };
00092 
00094   DefaultEmptyIndexSet (bool adaptive) : adaptive_(adaptive) {}
00095 
00098   bool compress () { 
00099     return false; 
00100   }
00101 
00104   bool adaptive () const { return adaptive_; }
00105   
00107   bool needsCompress () const { return false; }
00108 
00110   template <class EntityType> 
00111   void insertNewIndex( const EntityType & en ) {
00112     assert(adaptive_) ;
00113   }
00114 
00116   template <class EntityType> 
00117   void removeOldIndex( const EntityType & en ) {
00118     assert(adaptive_) ;
00119   }
00120 
00122   void resize () {}
00123 
00125   int additionalSizeEstimate () const { return 0; }
00126 
00127   static int type() { return myType; }
00128 
00130   int numberOfHoles ( int codim ) const { return 0; }
00131   
00133   int oldIndex (int hole, int codim ) const { return 0; }
00134   
00136   int newIndex (int hole, int codim ) const { return 0; }
00137   
00139   bool write_xdr(const std::basic_string<char> filename , int timestep) 
00140   {
00141     FILE  *file;
00142     XDR   xdrs;
00143     const char *path = "";
00144 
00145     std::basic_string<char> fnstr  = genFilename(path,filename, timestep);
00146     const char * fn = fnstr.c_str();
00147     file = fopen(fn, "wb");
00148     if (!file)
00149     {
00150         std::cerr << "\aERROR in DefaultGridIndexSet::write_xdr(..): could not open <"
00151                   << filename << ">!" << std::endl;
00152       return false;
00153     }
00154 
00155     xdrstdio_create(&xdrs, file, XDR_ENCODE);
00156     this->processXdr(&xdrs);
00157 
00158     xdr_destroy(&xdrs);
00159     fclose(file);
00160 
00161     return true;
00162   }
00163   
00165   bool read_xdr(const std::basic_string<char> filename , int timestep) 
00166   {
00167     FILE   *file;
00168     XDR     xdrs;
00169     const char *path = "";
00170 
00171     std::basic_string<char> fnstr = genFilename(path,filename, timestep);
00172     const char * fn  = fnstr.c_str();
00173     std::cout << "Reading <" << fn << "> \n";
00174     file = fopen(fn, "rb");
00175     if(!file)
00176     {
00177       std::cerr << "\aERROR in DefaultGridIndexSet::read_xdr(..): could not open <" 
00178                 << filename << ">!" << std::endl;
00179       return(false);
00180     }
00181 
00182     // read xdr 
00183     xdrstdio_create(&xdrs, file, XDR_DECODE);
00184     this->processXdr(&xdrs);
00185 
00186     xdr_destroy(&xdrs);
00187     fclose(file);
00188     return true;
00189   }
00190 
00191 protected: 
00192   // read/write from/to xdr stream 
00193   bool processXdr(XDR *xdrs)
00194   {
00195     int type = myType; 
00196     xdr_int ( xdrs, &type);
00197     if(type != myType)
00198     {
00199       std::cerr << "\nERROR: DefaultGridIndex: wrong type choosen! \n\n";
00200       assert(type == myType);
00201     }
00202     return true;
00203   }
00204 };
00205 
00208 template <class IndexSetImp> 
00209 class IndexSetWrapper : public DefaultEmptyIndexSet 
00210 {
00211 public:
00213   template<int cd>
00214   struct Codim
00215   {
00216     template<PartitionIteratorType pitype>
00217     struct Partition
00218     {
00219       typedef typename IndexSetImp::template Codim<cd>::
00220         template Partition<pitype>::Iterator  Iterator;
00221     };
00222   };
00223 
00225   IndexSetWrapper(const IndexSetImp & set, bool adaptive = false) 
00226     : DefaultEmptyIndexSet(adaptive)
00227     , set_(set) 
00228   {}
00229   
00231   IndexSetWrapper(const IndexSetWrapper<IndexSetImp> & s) 
00232     : DefaultEmptyIndexSet(s.adaptive_), set_(s.set_) {}
00233  
00235   int size ( GeometryType type ) const   
00236   {
00237     return set_.size(type);
00238   }
00239 
00241   int size ( int codim ) const   
00242   {
00243     return set_.size(codim);
00244   }
00245 
00247   template <class EntityType> 
00248   int index (const EntityType & en) const
00249   {
00250     return set_.index(en); 
00251   }
00252 
00254   template <int codim,class EntityType> 
00255   int subIndex (const EntityType & en, int num) const
00256   {
00257     return set_.template subIndex<codim> (en,num);
00258   }
00259 
00261   const std::vector< GeometryType > & geomTypes (int codim) const 
00262   {
00263     return set_.geomTypes(codim); 
00264   }
00265 
00267   template<class EntityType>
00268   bool contains (const EntityType& en) const
00269   {
00270     return set_.contains(en); 
00271   }
00272 
00274   template <int codim, class EntityType> 
00275   int index (const EntityType & en, int num) const
00276   {
00277     enum { enCodim = EntityType::codimension };
00278     return IndexWrapper<IndexSetImp,EntityType,enCodim,codim>::index(set_,en,num);
00279   }
00280 
00283   template<int cd, PartitionIteratorType pitype>
00284   typename Codim<cd>::template Partition<pitype>::Iterator begin () const
00285   { 
00286     return set_.template begin<cd,pitype> ();
00287   }
00288 
00291   template<int cd, PartitionIteratorType pitype>
00292   typename Codim<cd>::template Partition<pitype>::Iterator end () const
00293   { 
00294     return set_.template end<cd,pitype> ();
00295   }
00296 
00297 private: 
00298   const IndexSetImp & set_; 
00299 };
00300 
00302 template <class GridType>
00303 class DefaultGridIndexSetBase : public DefaultEmptyIndexSet
00304 {
00305   // dummy value 
00306   enum { myType = -1 };
00307 public:  
00308   enum { ncodim = GridType::dimension + 1 };
00309 
00311   DefaultGridIndexSetBase (const GridType & grid ) 
00312     // here false, because methods have to be overloaded
00313     : DefaultEmptyIndexSet(false) 
00314     , grid_ (grid) {}
00315 protected:
00316   // the corresponding grid 
00317   const GridType & grid_;
00318 };
00319 
00321 template <class GridType>
00322 class WrappedLevelIndexSet 
00323 : public IndexSetWrapper< typename GridType :: Traits:: LevelIndexSet > 
00324 {
00325   // my type, to be revised 
00326   enum { myType = 1 };
00327 
00328   typedef typename GridType :: Traits :: LevelIndexSet LevelIndexSetType;
00329   typedef WrappedLevelIndexSet < GridType >  ThisType;
00330 public:
00331   
00333   enum { ncodim = GridType::dimension + 1 };
00334 
00336   WrappedLevelIndexSet (const GridType & grid , const int level ) 
00337     : IndexSetWrapper<  LevelIndexSetType > (grid.levelIndexSet(level)) {}
00338  
00340   static int type() { return myType; }
00342   static ThisType & instance (const GridType & grid)
00343   { 
00344     static ThisType set(grid,grid.maxLevel());
00345     return set;
00346   }
00347 
00348 };
00349 
00351 template <class GridImp> 
00352 class HierarchicIndexSetSelector
00353 {
00354   
00355   // true if GridImp has HierarchicIndexSet 
00356   enum { hasHierarchicIndexSet = Conversion<GridImp,HasHierarchicIndexSet>::exists };
00357 
00358   template <class GridType, bool hasHSet> 
00359   struct HSetChooser
00360   {
00361     typedef typename GridType::Traits::LeafIndexSet IndexSetType;
00362     static const IndexSetType & hierarchicIndexSet(const GridType & grid)  
00363     { 
00364       return grid.leafIndexSet();
00365     }
00366   };
00367   
00368   template <class GridType> 
00369   struct HSetChooser<GridType,true>
00370   {
00371     typedef typename GridImp:: HierarchicIndexSet IndexSetType;
00372     static const IndexSetType & hierarchicIndexSet(const GridType & grid)  
00373     { 
00374       return grid.hierarchicIndexSet();
00375     }
00376   };
00377   
00378 public: 
00380   typedef typename HSetChooser<GridImp,hasHierarchicIndexSet>::IndexSetType HierarchicIndexSet; 
00381  
00383   static const HierarchicIndexSet & hierarchicIndexSet(const GridImp & grid) 
00384   { 
00385     return HSetChooser<GridImp,hasHierarchicIndexSet>::hierarchicIndexSet(grid);
00386   }
00387 
00389   static bool adaptive () { return hasHierarchicIndexSet; }
00390 };
00391 
00393 template <class GridType>
00394 class WrappedHierarchicIndexSet
00395 : public IndexSetWrapper< typename HierarchicIndexSetSelector<GridType> :: HierarchicIndexSet >
00396 {
00397   // my type, to be revised 
00398   enum { myType = 0 };
00399 
00401   typedef HierarchicIndexSetSelector<GridType> SelectorType;
00402   
00403   // my index set type 
00404   typedef typename SelectorType :: HierarchicIndexSet HSetType;
00405 
00406   typedef WrappedHierarchicIndexSet<GridType> ThisType;
00407 public:
00409   enum { ncodim = GridType::dimension + 1 };
00410 
00412   WrappedHierarchicIndexSet ( const GridType & grid , const int level =-1 ) 
00413     : IndexSetWrapper< HSetType > ( SelectorType :: hierarchicIndexSet(grid) 
00414                                   , SelectorType :: adaptive() ) {}
00415      
00417   static int type() { return myType; }
00418 
00420   static ThisType & instance (const GridType & grid)
00421   { 
00422     static ThisType set(grid);
00423     return set;
00424   }
00425 
00426 };
00427 
00429 template <class GridType>
00430 class WrappedLeafIndexSet
00431 :  public IndexSetWrapper<typename GridType :: Traits :: LeafIndexSet> 
00432 {
00433   // my type, to be revised 
00434   enum { myType = 5 };
00435 
00436   // my index set type 
00437   typedef typename GridType :: Traits :: LeafIndexSet IndexSetType;
00438   typedef WrappedLeafIndexSet<GridType> ThisType;
00439 public:
00441   enum { ncodim = GridType::dimension + 1 };
00443   WrappedLeafIndexSet ( const GridType & grid , const int level =-1 ) 
00444     : IndexSetWrapper < IndexSetType > (grid.leafIndexSet()) {}
00445 
00447   static int type() { return myType; }
00449   static ThisType & instance (const GridType & grid)
00450   { 
00451     static ThisType set(grid,grid.maxLevel());
00452     return set;
00453   }
00454 };
00455 
00456 //*********************************************************************
00462 //*********************************************************************
00463 
00464 template <class DefaultLevelIndexSetType, int codim>
00465 struct CheckLevelForCodim 
00466 {
00467   static void recursive(DefaultLevelIndexSetType & d)
00468   {
00469     d.template checkLevelIndexForCodim<codim> (); 
00470     CheckLevelForCodim<DefaultLevelIndexSetType,codim-1>::recursive(d);
00471   }
00472 };
00473 
00474 template <class DefaultLevelIndexSetType>
00475 struct CheckLevelForCodim<DefaultLevelIndexSetType,0>
00476 {
00477   static void recursive(DefaultLevelIndexSetType & d)
00478   {
00479     d.template checkLevelIndexForCodim<0> ();
00480   }
00481 };
00482 
00483 
00484 template <class GridImp>
00485 struct DefaultLevelIteratorTypes
00486 {
00488   template<int cd>
00489   struct Codim
00490   {
00491     template<PartitionIteratorType pitype>
00492     struct Partition
00493     {
00494       typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
00495     };
00496   };
00497 };
00498 
00503 template <class GridImp>
00504 class DefaultLevelIndexSet :
00505   public IndexSetDefaultImplementation< GridImp, 
00506                    DefaultLevelIndexSet <GridImp>,
00507                    DefaultLevelIteratorTypes<GridImp> > 
00508 
00509 {
00510   typedef GridImp GridType;
00511   enum { dim = GridType :: dimension };
00512 
00514   typedef std::vector<int> IndexArrayType;
00515   
00516 public:
00517   enum { ncodim = GridType::dimension + 1 };
00518 private:
00519   typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType;
00520 
00521   typedef DefaultLevelIndexSet<GridType> ThisType;
00522 
00523   template <class EntityType, int codim> 
00524   struct InsertEntity
00525   {
00526     template <class HierarchicIndexSet>
00527     static void insert(const EntityType & en, 
00528                        const HierarchicIndexSet & hset, 
00529                        IndexArrayType (&index)[ncodim], 
00530                        int (&num)[ncodim])
00531     {
00532       IndexArrayType & idx = index[codim];
00533       for(int i=0; i<en.template count<codim>(); ++i) 
00534       {
00535         const int id = hset.template subIndex<codim>(en,i);
00536         if( idx[id] < 0) 
00537         {
00538           idx[id] = num[codim];
00539           ++num[codim];
00540         }
00541       }
00542       InsertEntity<EntityType,codim-1>::insert(en,hset,index,num);
00543     }
00544   };
00545   
00546   template <class EntityType> 
00547   struct InsertEntity<EntityType,0>
00548   {
00549     template <class HierarchicIndexSet>
00550     static void insert(const EntityType & en, 
00551                        const HierarchicIndexSet & hset, 
00552                        IndexArrayType (&index)[ncodim], 
00553                        int (&num)[ncodim])
00554     {
00555       enum { codim = 0 };
00556       IndexArrayType & idx = index[codim];
00557       const int id = hset.index(en); 
00558       if( idx[id] < 0 ) 
00559       {
00560         idx[id] = num[codim];
00561         ++num[codim];
00562       }
00563     }
00564   };
00565   
00566 public:
00569   DefaultLevelIndexSet(const GridType & grid , int level ) :
00570     grid_(grid) , level_(level) , hIndexSet_ ( grid.hierarchicIndexSet() )
00571     , size_ ( ncodim )
00572   {
00573     calcNewIndex ();
00574   }
00575 
00577   template<class EntityType>
00578   int index (const EntityType & en) const 
00579   {
00580     enum { cd = EntityType :: codimension };
00581     // this must not be true for vertices 
00582     // therefore only check other codims 
00583 #ifndef NDEBUG 
00584     const int codim = cd;
00585     assert( (codim == dim) ? (1) : (level_ == en.level() )); 
00586     assert( levelIndex_[codim][ hIndexSet_.index(en) ] >= 0 );
00587 #endif
00588     return levelIndex_[cd][ hIndexSet_.index(en) ];
00589   }
00590  
00592   template<int cd>
00593   int index (const typename GridImp::template Codim<cd>::Entity& en) const 
00594   {
00595     // this must not be true for vertices 
00596     // therefore only check other codims 
00597 #ifndef NDEBUG 
00598     const int codim = cd;
00599     assert( (codim == dim) ? (1) : (level_ == en.level() )); 
00600     assert( levelIndex_[codim][ hIndexSet_.index(en) ] >= 0 );
00601 #endif
00602     return levelIndex_[cd][ hIndexSet_.index(en) ];
00603   }
00604  
00607   template <int cd>
00608   int subIndex (const typename GridType::template Codim<0>::Entity & en, int i) const
00609   {
00610     // this must not be true for vertices 
00611     // therefore only check other codims 
00612 #ifndef NDEBUG
00613     const int codim = cd;
00614     assert( (codim != 0) ? (1) : (level_ == en.level() )); 
00615     assert(levelIndex_[codim][ hIndexSet_.template subIndex<cd>(en,i) ] >= 0 );
00616 #endif
00617     return levelIndex_[cd][ hIndexSet_.template subIndex<cd>(en,i) ];
00618   }
00619 
00621   template<class EntityType>
00622   bool contains (const EntityType& en) const
00623   {
00624     enum { cd = EntityType :: codimension };
00625     return (levelIndex_[cd][ hIndexSet_.index(en) ] >= 0);
00626   }
00627 
00629   int size ( int codim ) const
00630   {
00631     assert( codim >= 0 && codim <= GridType::dimension );
00632     return size_[codim];
00633   }
00634 
00637   int size ( GeometryType type ) const
00638   {
00639     if( typeNotValid(type) ) return 0;
00640     return size_[GridType::dimension-type.dim()];
00641   }
00642 
00645   void calcNewIndex ()
00646   {
00647     // resize arrays to new size 
00648     for(int cd=0; cd<ncodim; ++cd) 
00649     {
00650       resizeVectors(levelIndex_[cd], hIndexSet_.size(cd));
00651     }
00652 
00653     // walk grid and store index 
00654     typedef typename DefaultLevelIteratorTypes<GridImp>:: template Codim<0>::
00655         template Partition<All_Partition> :: Iterator IteratorType;
00656 
00657     // we start with zero for all codims 
00658     int num[ncodim];
00659     for(int cd=0; cd<ncodim; ++cd) num[cd] = 0;
00660 
00661     IteratorType endit  = this->template end  < 0, All_Partition > ();
00662     for(IteratorType it = this->template begin< 0, All_Partition > (); 
00663         it != endit; ++it)
00664     {
00665       assert( it->level() == level_ );
00666       insertEntity(*it,num);
00667     }
00668 
00669     // remember the number of entity on level and cd = 0
00670     for(int cd=0; cd<ncodim; ++cd) 
00671     {
00672       size_[cd] = num[cd];
00673       assert( size_[cd] == grid_.size(level_,cd) );
00674     }
00675 
00676 #ifndef NDEBUG 
00677     CheckLevelForCodim<ThisType,dim>::recursive(*this);
00678 #endif
00679   }
00680 
00681   // calculate index for the codim 
00682   template <int cd>
00683   void checkLevelIndexForCodim ()
00684   {
00685     IndexArrayType & levIndex = levelIndex_[cd];
00686     // resize memory if necessary 
00687     // walk grid and store index 
00688     typedef typename DefaultLevelIteratorTypes<GridImp>:: template Codim<cd>::
00689       template Partition<All_Partition> :: Iterator LevelIterator;
00690 
00691     LevelIterator endit  = this->template end  < cd , All_Partition > ();
00692     for(LevelIterator it = this->template begin< cd , All_Partition > (); it != endit; ++it)
00693     { 
00694       int no = hIndexSet_.index(*it);
00695       assert( levIndex[no] >= 0 );
00696     }
00697   }
00698 
00700   const std::vector<GeometryType>& geomTypes (int codim) const
00701   {
00702     return grid_.geomTypes(codim);
00703   }
00704 
00707   template<int cd, PartitionIteratorType pitype>
00708   typename DefaultLevelIteratorTypes<GridImp>::template Codim<cd>::
00709     template Partition<pitype>::Iterator begin () const
00710   { 
00711     return this->grid_.template lbegin<cd,pitype> (level_);
00712   }
00713 
00716   template<int cd, PartitionIteratorType pitype>
00717   typename DefaultLevelIteratorTypes<GridImp>::template Codim<cd>::
00718     template Partition<pitype>::Iterator end () const
00719   { 
00720     return this->grid_.template lend<cd,pitype> (level_);
00721   }
00722 
00724   bool containsIndex (int cd , int idx) const
00725   {
00726     assert( cd >= 0 );
00727     assert( cd < ncodim );
00728     
00729     assert( idx >= 0);
00730     assert( idx < (int) levelIndex_[cd].size());
00731     return (levelIndex_[cd][ idx ] >= 0);
00732   }
00733 
00734 private:
00735   // return whether set has this type stored or not 
00736   bool typeNotValid (const GeometryType & type) const 
00737   {
00738     int codim = GridType :: dimension - type.dim();
00739     const std::vector<GeometryType> & geomT = geomTypes(codim); 
00740     for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false;
00741     return true;  
00742   }
00743   // calculate index for the codim 
00744   template <class EntityType>
00745   void insertEntity(EntityType & en, int (&num)[ncodim])
00746   {
00747     InsertEntity<EntityType,dim>::insert(en,hIndexSet_,levelIndex_,num);
00748   }
00749 
00750   // resize vectors of index set 
00751   void resizeVectors(IndexArrayType &a, int newNumberOfEntries)
00752   {
00753     if(newNumberOfEntries > 0)
00754     {
00755       a.resize(newNumberOfEntries);
00756     }
00757     for(size_t i=0; i<a.size(); i++) a[i] = -1;
00758   }
00759 
00760   // method prints indices of given codim, for debugging
00761   void print (int codim) const 
00762   {
00763     for(size_t i=0; i<levelIndex_[codim].size(); i++) 
00764     {
00765       std::cout << "levelind[" << i << "] = " << levelIndex_[codim][i] << "\n";
00766     }
00767   }
00768 
00769   // grid this level set belongs to 
00770   const GridType & grid_;
00771 
00772   // the level for which this index set is created 
00773   const int level_;
00774   
00775   // the grids HierarchicIndexSet
00776   const HierarchicIndexSetType & hIndexSet_;
00777 
00778   // number of entitys of each level an codim 
00779   IndexArrayType size_;
00780 
00781   //*********************************************************
00782   // Methods for mapping the hierarchic Index to index on Level
00783   IndexArrayType levelIndex_[ncodim];
00784   
00785 };
00786 
00787 
00789 template <class GridImp>
00790 struct DefaultLeafIteratorTypes
00791 {
00793   template<int cd>
00794   struct Codim
00795   {
00796     template<PartitionIteratorType pitype>
00797     struct Partition
00798     {
00799       typedef typename GridImp::Traits::template Codim<cd>::
00800         template Partition<pitype>::LeafIterator  Iterator;
00801     };
00802   };
00803 };
00804 
00805 
00807 template <class GridImp>
00808 class DefaultLeafIndexSet :
00809   public IndexSetDefaultImplementation< GridImp, 
00810                    DefaultLeafIndexSet <GridImp>,
00811                    DefaultLeafIteratorTypes<GridImp> > 
00812 
00813 {
00814   typedef GridImp GridType;
00815   enum { dim = GridType :: dimension };
00816 
00818   typedef std::vector<int> IndexArrayType;
00819 public:
00820   enum { ncodim = dim + 1 };
00821   typedef typename GridType :: HierarchicIndexSet HierarchicIndexSetType;
00822 
00823 private:
00824   typedef DefaultLeafIndexSet<GridType> ThisType;
00825 
00826   template <class EntityType, int codim> 
00827   struct InsertEntity
00828   {
00829     template <class HierarchicIndexSet>
00830     static void insert(const EntityType & en, 
00831                        const HierarchicIndexSet & hset, 
00832                        IndexArrayType (&index)[ncodim], 
00833                        int (&num)[ncodim])
00834     {
00835       IndexArrayType & idx = index[codim];
00836       for(int i=0; i<en.template count<codim>(); ++i) 
00837       {
00838         const int id = hset.template subIndex<codim>(en,i);
00839         if( idx[id] < 0) 
00840         {
00841           idx[id] = num[codim];
00842           ++num[codim];
00843         }
00844       }
00845       InsertEntity<EntityType,codim-1>::insert(en,hset,index,num);
00846     }
00847   };
00848   
00849   template <class EntityType> 
00850   struct InsertEntity<EntityType,0>
00851   {
00852     template <class HierarchicIndexSet>
00853     static void insert(const EntityType & en, 
00854                        const HierarchicIndexSet & hset, 
00855                        IndexArrayType (&index)[ncodim], 
00856                        int (&num)[ncodim])
00857     {
00858       enum { codim = 0 };
00859       IndexArrayType & idx = index[codim];
00860       const int id = hset.index(en); 
00861       if( idx[id] < 0 ) 
00862       {
00863         idx[id] = num[codim];
00864         ++num[codim];
00865       }
00866     }
00867   };
00868   
00869 public:
00872   DefaultLeafIndexSet(const GridType & grid) 
00873     : grid_(grid) 
00874     , hIndexSet_ ( grid.hierarchicIndexSet() )
00875     , size_ ( ncodim )
00876   {
00877     calcNewIndex ();
00878   }
00879 
00881   template<class EntityType>
00882   int index (const EntityType & en) const 
00883   {
00884     enum { cd = EntityType :: codimension };
00885     // this must not be true for vertices 
00886     // therefore only check other codims 
00887     assert( index_[cd][ hIndexSet_.index(en) ] >= 0 );
00888     return index_[cd][ hIndexSet_.index(en) ];
00889   }
00890  
00891   template<int cd>
00892   int index (const typename GridImp::template Codim<cd>::Entity& en) const 
00893   {
00894     // this must not be true for vertices 
00895     // therefore only check other codims 
00896     assert( index_[cd][ hIndexSet_.index(en) ] >= 0 );
00897     return index_[cd][ hIndexSet_.index(en) ];
00898   }
00899  
00902   template <int cd>
00903   int subIndex (const typename GridType::template Codim<0>::Entity & en, int i) const
00904   {
00905     // this must not be true for vertices 
00906     // therefore only check other codims 
00907     assert(index_[cd][ hIndexSet_.template subIndex<cd>(en,i) ] >= 0 );
00908     return index_[cd][ hIndexSet_.template subIndex<cd>(en,i) ];
00909   }
00910 
00912   template<class EntityType>
00913   bool contains (const EntityType& en) const
00914   {
00915     enum { cd = EntityType :: codimension };
00916     return (index_[cd][ hIndexSet_.index(en) ] >= 0 );
00917   }
00918 
00920   int size ( int codim ) const
00921   {
00922     assert( codim >= 0 && codim <= GridType::dimension );
00923     return size_[codim];
00924   }
00925 
00928   int size ( GeometryType type ) const
00929   {
00930     if( typeNotValid(type) ) return 0;
00931     return size_[GridType::dimension-type.dim()];
00932   }
00933 
00936   void calcNewIndex ()
00937   {
00938     // resize arrays to new size 
00939     for(int cd=0; cd<ncodim; ++cd) 
00940     {
00941       resizeVectors(index_[cd], hIndexSet_.size(cd));
00942     }
00943 
00944     // walk grid and store index 
00945     typedef typename DefaultLeafIteratorTypes<GridImp>:: template Codim<0>::
00946         template Partition<All_Partition> :: Iterator IteratorType;
00947 
00948     // we start with zero for all codims 
00949     int num[ncodim];
00950     for(int cd=0; cd<ncodim; ++cd) num[cd] = 0;
00951 
00952     int elems=0;
00953 
00954     IteratorType endit  = this->template end  < 0, All_Partition > ();
00955     for(IteratorType it = this->template begin< 0, All_Partition > (); 
00956         it != endit; ++it)
00957     {
00958       ++elems;
00959       insertEntity(*it,num);
00960     }
00961     
00962     // remember the number of entity on level and cd = 0
00963     for(int cd=0; cd<ncodim; ++cd) 
00964     {
00965       size_[cd] = num[cd];
00966       //if( size_[cd] != grid_.size(cd) ) 
00967       //  std::cout << size_[cd] << " calc | grid " << grid_.size(cd)  << "\n";
00968       //assert( size_[cd] == grid_.size(cd) );
00969     }
00970   }
00971 
00973   const std::vector<GeometryType>& geomTypes (int codim) const
00974   {
00975     return grid_.geomTypes(codim);
00976   }
00977 
00978 
00981   template<int cd, PartitionIteratorType pitype>
00982   typename DefaultLeafIteratorTypes<GridImp>::template Codim<cd>::
00983     template Partition<pitype>::Iterator begin () const
00984   { 
00985     return this->grid_.template leafbegin<cd,pitype> ();
00986   }
00987 
00990   template<int cd, PartitionIteratorType pitype>
00991   typename DefaultLeafIteratorTypes<GridImp>::template Codim<cd>::
00992     template Partition<pitype>::Iterator end () const
00993   { 
00994     return this->grid_.template leafend<cd,pitype> ();
00995   }
00996 
00997 private:
00998   // return whether set has this type stored or not 
00999   bool typeNotValid (const GeometryType & type) const 
01000   {
01001     int codim = GridType :: dimension - type.dim();
01002     const std::vector<GeometryType> & geomT = geomTypes(codim); 
01003     for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false;
01004     return true;  
01005   }
01006   // calculate index for the codim 
01007   template <class EntityType>
01008   void insertEntity(EntityType & en, int (&num)[ncodim])
01009   {
01010     InsertEntity<EntityType,dim>::insert(en,hIndexSet_,index_,num);
01011   }
01012 
01013   // resize vectors of index set 
01014   void resizeVectors(IndexArrayType &a, int newNumberOfEntries)
01015   {
01016     if( newNumberOfEntries > 0 )
01017     {
01018       a.resize(newNumberOfEntries);
01019     }
01020     for(size_t i=0; i<a.size(); ++i) a[i] = -1;
01021   }
01022 
01023   // method prints indices of given codim, for debugging
01024   void print (int codim) const 
01025   {
01026     for(size_t i=0; i<index_[codim].size(); i++) 
01027     {
01028       std::cout << "levelind[" << i << "] = " << index_[codim][i] << "\n";
01029     }
01030   }
01031 
01032   // grid this level set belongs to 
01033   const GridType & grid_;
01034 
01035   // the grids HierarchicIndexSet
01036   const HierarchicIndexSetType & hIndexSet_;
01037 
01038   // number of entitys of each level an codim 
01039   IndexArrayType size_;
01040 
01041   //*********************************************************
01042   // Methods for mapping the hierarchic Index to index on Level
01043   IndexArrayType index_[ncodim];
01044 };
01045 
01046 
01048 template <class A, class B >
01049 class CombinedAdaptProlongRestrict
01050 {
01052   const A & _a;
01053   const B & _b;
01054 public: 
01056   CombinedAdaptProlongRestrict ( const A & a, const B & b ) : _a ( a ) , _b ( b )
01057   {}
01058   
01060   template <class EntityType>
01061   void restrictLocal ( EntityType &father, EntityType &son, bool initialize ) const
01062   {
01063     _a.restrictLocal(father,son,initialize);
01064     _b.restrictLocal(father,son,initialize);
01065   }
01066 
01068   template <class EntityType>
01069   void prolongLocal ( EntityType &father, EntityType &son, bool initialize ) const
01070   {
01071     _a.prolongLocal(father,son,initialize);
01072     _b.prolongLocal(father,son,initialize);
01073   }
01074 };
01075 
01076 } // end namespace Dune 
01077 #endif

Generated on 9 Apr 2008 with Doxygen (ver 1.5.2) [logfile].