sizecache.hh

Go to the documentation of this file.
00001 #ifndef DUNE_SIZECACHE_HH
00002 #define DUNE_SIZECACHE_HH
00003 
00004 #include <cassert>
00005 #include <vector>
00006 
00007 #include <dune/common/geometrytype.hh>
00008 
00009 #include <dune/grid/common/gridenums.hh>
00010 
00017 namespace Dune {
00018 
00020 template <class GridImp> 
00021 class SingleTypeSizeCache 
00022 {
00023   typedef SingleTypeSizeCache<GridImp> ThisType;
00025   enum { dim    = GridImp::dimension   };
00026 
00028   enum { nCodim = GridImp::dimension+1 };
00029 
00030   typedef GridImp GridType;
00031     
00032   // stores all sizes of the levels 
00033   mutable std::vector<int> levelSizes_[nCodim]; 
00034   
00035   // stores all sizes of leafs 
00036   mutable int leafSizes_[nCodim]; 
00037 
00038   // stores all sizes of the levels 
00039   mutable std::vector<int> ghostLevelSizes_[nCodim]; 
00040   
00041   // stores all sizes of leafs 
00042   mutable int ghostLeafSizes_[nCodim]; 
00043 
00044   // the grid 
00045   const GridType & grid_;
00046 
00047   // true if this class counts simplices 
00048   const bool isSimplex_;
00049   // true if this class counts cubes 
00050   const bool isCube_;
00051 
00052   bool notWorry_; 
00053   
00054   // count elements of set by iterating the grid 
00055   template <class SzCacheType ,PartitionIteratorType pitype, int codim >
00056   struct CountLevelEntities
00057   {
00058     static inline int count (const SzCacheType & sc, int level, int cd)
00059     {   
00060       if( cd == codim )
00061       { 
00062         return sc.template countLevelEntities<pitype,codim> (level);
00063       }
00064       else
00065         return CountLevelEntities < SzCacheType, pitype, codim-1> :: count (sc,level,cd);
00066     }
00067   };
00068 
00069   // count elements of set by iterating the grid 
00070   template <class SzCacheType,PartitionIteratorType pitype>
00071   struct CountLevelEntities<SzCacheType,pitype,0>
00072   {
00073     static inline int count (const SzCacheType & sc, int level, int cd)
00074     {   
00075       enum { codim = 0 };
00076       assert( cd == codim );
00077       return sc.template countLevelEntities<pitype,codim> (level);
00078     }
00079   };
00080 
00081   
00082   // count elements of set by iterating the grid 
00083   template <class SzCacheType , PartitionIteratorType pitype, int codim >
00084   struct CountLeafEntities
00085   {
00086     static inline int count (const SzCacheType & sc, int cd)
00087     {   
00088       if( cd == codim )
00089       { 
00090         return sc.template countLeafEntities<pitype,codim> ();
00091       }
00092       else
00093         return CountLeafEntities < SzCacheType, pitype, codim-1> :: count (sc,cd);
00094     }
00095   };
00096 
00097   // count elements of set by iterating the grid 
00098   template <class SzCacheType,PartitionIteratorType pitype>
00099   struct CountLeafEntities<SzCacheType,pitype,0>
00100   {
00101     static inline int count (const SzCacheType & sc, int cd)
00102     {   
00103       enum { codim = 0 };
00104       assert( cd == codim );
00105       return sc.template countLeafEntities<pitype,codim> ();
00106     }
00107   };
00108 
00109   
00110     // private copy constructor 
00111     SingleTypeSizeCache (const SingleTypeSizeCache & );
00112 public:
00113     SingleTypeSizeCache (const GridType & grid, 
00114         const bool isSimplex , const bool isCube, bool notWorry = false )
00115       : grid_(grid) , isSimplex_(isSimplex) , isCube_(isCube), notWorry_ ( notWorry )
00116     {
00117       assert( isSimplex_ != isCube_ );
00118       for(int i=0; i<nCodim; i++) 
00119       {
00120         leafSizes_[i] = -1;
00121         ghostLeafSizes_[i] = -1;
00122       }
00123       
00124       int numMxl = grid_.maxLevel()+1;
00125       for(int i=0; i<nCodim; i++)
00126       {  
00127         std::vector<int> & vec = levelSizes_[i]; 
00128         vec.resize(numMxl);
00129         for(int level = 0; level<numMxl; level++) vec[level] = -1;
00130         
00131         std::vector<int> & ghVec = ghostLevelSizes_[i]; 
00132         ghVec.resize(numMxl);
00133         for(int level = 0; level<numMxl; level++) ghVec[level] = -1;
00134       }
00135     }
00136 
00137     //********************************************************************
00138     // level sizes 
00139     //********************************************************************
00144     int size (int level, int codim) const
00145     {
00146       assert( codim >= 0 );
00147       assert( codim < nCodim );
00148       assert( level >= 0 );
00149       if( level >= (int) levelSizes_[codim].size() ) return 0;
00150 
00151       if( levelSizes_[codim][level] < 0)
00152         levelSizes_[codim][level] = CountLevelEntities<ThisType,All_Partition,dim>::count(*this,level,codim);
00153       return levelSizes_[codim][level];
00154     }
00155     
00157     int size (int level, int codim, GeometryType type) const
00158     {
00159       // if isSimplex true, then this is a simplex counting one 
00160       if( (isSimplex_) && (isSimplex_ != type.isSimplex()) ) return 0;
00161       // if isCube true, then this is a cube counting one 
00162       if( (isCube_)    && (isCube_    != type.isCube()    ) ) return 0;
00163       return size(level,codim);
00164     }
00165    
00166     //********************************************************************
00167     // leaf sizes 
00168     //********************************************************************
00170     int size (int codim) const
00171     {
00172       assert( codim >= 0 );
00173       assert( codim < nCodim );
00174       if( leafSizes_[codim] < 0)
00175         leafSizes_[codim] = CountLeafEntities<ThisType,All_Partition,dim>::count(*this,codim);
00176       return leafSizes_[codim];
00177     }; 
00178     
00180     int size (int codim, GeometryType type) const
00181     {
00182       // if isSimplex true, then this is a simplex counting one 
00183       if( (isSimplex_) && (isSimplex_ != type.isSimplex()) ) return 0;
00184       // if isCube true, then this is a cube counting one 
00185       if( (isCube_)    && (isCube_    != type.isCube()   ) ) return 0;
00186       return size(codim);
00187     }
00188 
00190     int ghostSize (int codim) const { 
00191       if( ghostLeafSizes_[codim] < 0)
00192         ghostLeafSizes_[codim] = CountLeafEntities<ThisType,Ghost_Partition,dim>::count(*this,codim);
00193       return ghostLeafSizes_[codim];
00194     }
00195 
00197     int ghostSize (int level, int codim) const 
00198     { 
00199       // if level is larger than grid max level , return 0
00200       if( level >= (int) ghostLevelSizes_[codim].size() ) return 0;
00201 
00202       if( ghostLevelSizes_[codim][level] < 0)
00203         ghostLevelSizes_[codim][level] = CountLevelEntities<ThisType,Ghost_Partition,dim>::count(*this,level,codim);
00204       return ghostLevelSizes_[codim][level];
00205     }
00206 
00207 private:
00208     template <PartitionIteratorType pitype, int codim> 
00209     int countLevelEntities(int level) const 
00210     {
00211       typedef typename GridType::template Codim<codim> :: template Partition<pitype> :: LevelIterator LevelIterator;
00212       LevelIterator it  = grid_.template lbegin<codim,pitype> (level);
00213       LevelIterator end = grid_.template lend<codim,pitype>   (level);
00214 
00215       GeometryType type (((isSimplex_) ? GeometryType::simplex : GeometryType::cube ),dim-codim); 
00216       assert( ((dim-codim) > 1) ? (type.isCube() == isCube_) : 1);
00217       if( notWorry_ )  return countElements(it,end,type);
00218       return countElements(it,end);
00219     }
00220     
00221     template <PartitionIteratorType pitype, int codim> 
00222     int countLeafEntities() const 
00223     {
00224       // count All_Partition entities 
00225       typedef typename GridType::template Codim<codim> :: template Partition<pitype> :: LeafIterator LeafIterator;
00226       LeafIterator it  = grid_.template leafbegin<codim,pitype> ();
00227       LeafIterator end = grid_.template leafend<codim,pitype>   ();
00228       GeometryType type (((isSimplex_) ? GeometryType::simplex : GeometryType::cube ),dim-codim); 
00229       assert( ((dim-codim) > 1) ? (type.isCube() == isCube_) : 1);
00230       if( notWorry_ )  return countElements(it,end,type);
00231       return countElements(it,end);
00232     }
00233     
00234     // counts entities with given type for given iterator 
00235     template <class IteratorType> 
00236     int countElements(IteratorType & it, const IteratorType & end ,
00237         const GeometryType & type ) const 
00238     {
00239       int count = 0;
00240       if((type.isSimplex()) || (type.isCube()))
00241       {
00242         for( ; it != end; ++it )
00243         {
00244           if(it->type() == type) 
00245             ++ count ;
00246         }
00247       }
00248       return count;
00249     }
00250    
00251     // counts entities for given iterator 
00252     template <class IteratorType> 
00253     int countElements(IteratorType & it, const IteratorType & end) const 
00254     {
00255       int count = 0;
00256       for( ; it != end; ++it )
00257       {
00258         ++ count ;
00259       }
00260       return count;
00261     }
00262 };
00263   
00265 template <class GridImp> 
00266 class SizeCache 
00267 {
00268   typedef SizeCache<GridImp> ThisType;
00269   typedef GridImp GridType;
00270   
00271   SingleTypeSizeCache<GridType> simplexSize_;
00272   SingleTypeSizeCache<GridType>    cubeSize_;
00273   
00274 public:
00275     SizeCache (const GridType & grid) : simplexSize_(grid,true,false), cubeSize_(grid,false,true) 
00276     {
00277       // check that used grid only has simplex and/or cube as geomTypes 
00278       // to be revised 
00279       const std::vector<GeometryType> & geomTypes = grid.geomTypes(0);
00280       int found  = 0;
00281       int others = 0;
00282       for(unsigned int i=0; i<geomTypes.size(); i++)
00283       {
00284         if( (geomTypes[i].isSimplex()) || 
00285             (geomTypes[i].isCube()   )    )
00286           found++; 
00287         else 
00288           others++;
00289       }
00290       // only use with simplex or cube types
00291       // if others are found assert
00292       assert( !others );
00293 
00294       // assert that at least one of our tpyes is found 
00295       assert( found > 0 );
00296     }
00297 
00298     //********************************************************************
00299     // level sizes 
00300     //********************************************************************
00305     int size (int level, int codim) const
00306     {
00307       return (simplexSize_.size(level,codim) + cubeSize_(level,codim));
00308     }
00309     
00311     int size (int level, int codim, GeometryType type) const
00312     {
00313       if( type.isSimplex()) return simplexSize_.size(level,codim);
00314       if( type.isCube()   ) return cubeSize_(level,codim);
00315       return 0; 
00316     }
00317    
00318     //********************************************************************
00319     // leaf sizes 
00320     //********************************************************************
00322     int size (int codim) const
00323     {
00324       return (simplexSize_.size(codim) + cubeSize_(codim));
00325     }; 
00326     
00328     int size (int codim, GeometryType type) const
00329     {
00330       if( type.isSimplex() ) return simplexSize_.size(codim);
00331       if( type.isCube()    ) return cubeSize_(codim);
00332       return 0; 
00333     }
00334 
00336     int ghostSize (int codim) const
00337     {
00338       return simplexSize_.ghostSize(codim) + cubeSize_.ghostSize(codim);
00339     }
00340     
00342     int ghostSize (int level, int codim) const
00343     {
00344       return simplexSize_.ghostSize(level,codim) + cubeSize_.ghostSize(level,codim);
00345     }
00346 };
00347   
00348 
00349 } // end namespace Dune 
00350 #endif

Generated on Thu Apr 2 10:40:43 2009 for dune-grid by  doxygen 1.5.6