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

Generated on Sun Nov 15 22:28:39 2009 for dune-grid by  doxygen 1.5.6