dune-grid
2.1.1
|
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