sizecache.hh

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

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