1 #ifndef DUNE_SIZECACHE_HH
2 #define DUNE_SIZECACHE_HH
8 #include <dune/common/forloop.hh>
9 #include <dune/common/exceptions.hh>
11 #include <dune/geometry/type.hh>
12 #include <dune/geometry/referenceelements.hh>
26 template <
class Gr
idImp>
31 enum { dim = GridImp::dimension };
34 enum { nCodim = GridImp::dimension+1 };
37 typedef GridImp GridType;
40 typedef typename GridType :: ctype ctype ;
43 mutable std::vector< int > levelSizes_[nCodim];
46 mutable std::vector< std::vector< int > > levelTypeSizes_[nCodim];
49 mutable int leafSizes_[nCodim];
52 mutable std::vector< int > leafTypeSizes_[nCodim];
55 const GridType & grid_;
58 template <
int codim,
bool gr
idHasCodim >
59 struct CountLevelEntitiesBase
61 template <
class SzCacheType >
62 static void apply(
const SzCacheType & sc,
int level,
int cd)
66 sc.template countLevelEntities<All_Partition,codim> (level);
71 template <
int codim >
72 struct CountLevelEntitiesBase< codim, false >
74 template <
class SzCacheType >
75 static void apply(
const SzCacheType & sc,
int level,
int cd)
79 sc.template countLevelEntitiesNoCodim<All_Partition,codim> (level);
84 template <
int codim >
85 struct CountLevelEntities
86 :
public CountLevelEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
91 template <
int codim,
bool gr
idHasCodim >
92 struct CountLeafEntitiesBase
94 template <
class SzCacheType>
95 static void apply(
const SzCacheType & sc,
int cd)
99 sc.template countLeafEntities<All_Partition,codim> ();
105 template <
int codim >
106 struct CountLeafEntitiesBase< codim, false >
108 template <
class SzCacheType>
109 static void apply(
const SzCacheType & sc,
int cd)
113 sc.template countLeafEntitiesNoCodim<All_Partition,codim> ();
118 template <
int codim >
119 struct CountLeafEntities
120 :
public CountLeafEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
126 return type.id() >> 1 ;
129 int sizeCodim(
const int codim )
const
131 const int mydim = GridType :: dimension - codim;
132 return ((1 << mydim) + 1) / 2;
147 for(
int codim=0; codim<nCodim; ++codim)
149 leafSizes_[ codim ] = -1;
150 leafTypeSizes_[ codim ].resize( sizeCodim( codim ), -1 );
153 const int numMxl = grid_.maxLevel()+1;
154 for(
int codim=0; codim<nCodim; ++codim)
156 std::vector<int> & vec = levelSizes_[codim];
158 levelTypeSizes_[codim].resize( numMxl );
159 for(
int level = 0; level<numMxl; ++level)
162 levelTypeSizes_[codim][level].resize( sizeCodim( codim ), -1 );
171 int size (
int level,
int codim)
const
173 assert( codim >= 0 );
174 assert( codim < nCodim );
175 assert( level >= 0 );
176 if( level >= (
int) levelSizes_[codim].
size() )
return 0;
178 if( levelSizes_[codim][level] < 0)
179 ForLoop< CountLevelEntities, 0, dim > :: apply( *
this, level, codim );
183 assert( levelSizes_[codim][level] >= 0 );
184 return levelSizes_[codim][level];
190 const int codim = GridType ::dimension - type.dim();
191 if( levelSizes_[codim][level] < 0)
192 ForLoop< CountLevelEntities, 0, dim > :: apply( *
this, level, codim );
194 assert( levelTypeSizes_[codim][level][gtIndex( type )] >= 0 );
195 return levelTypeSizes_[codim][level][gtIndex( type )];
204 assert( codim >= 0 );
205 assert( codim < nCodim );
206 if( leafSizes_[codim] < 0 )
207 ForLoop< CountLeafEntities, 0, dim > :: apply( *
this, codim );
209 assert( leafSizes_[codim] >= 0 );
210 return leafSizes_[codim];
216 const int codim = GridType :: dimension - type.dim();
217 if( leafSizes_[codim] < 0 )
218 ForLoop< CountLeafEntities, 0, dim > :: apply( *
this, codim );
220 assert( leafTypeSizes_[codim][ gtIndex( type )] >= 0 );
221 return leafTypeSizes_[codim][ gtIndex( type )];
225 template <PartitionIteratorType pitype,
int codim>
226 void countLevelEntities(
int level)
const
228 typedef typename GridType :: LevelGridView
GridView ;
229 typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
230 GridView gridView = grid_.levelView( level );
231 Iterator it = gridView.template begin<codim,pitype> ();
232 Iterator end = gridView.template end<codim,pitype> ();
233 levelSizes_[codim][level] = countElements(it,end, levelTypeSizes_[codim][level]);
236 template <PartitionIteratorType pitype,
int codim>
237 void countLeafEntities()
const
240 typedef typename GridType :: LeafGridView GridView ;
241 typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
242 GridView gridView = grid_.leafView();
243 Iterator it = gridView.template begin<codim,pitype> ();
244 Iterator end = gridView.template end<codim,pitype> ();
245 leafSizes_[codim] = countElements(it,end, leafTypeSizes_[codim] );
249 template <
class IteratorType>
250 int countElements(IteratorType & it,
const IteratorType & end, std::vector<int>& typeSizes)
const
253 const size_t types = typeSizes.size();
254 for(
size_t i=0; i<types; ++i) typeSizes[i] = 0;
255 for( ; it != end; ++it )
258 ++typeSizes[ gtIndex( type ) ];
263 for(
size_t i=0; i<types; ++i) sumtypes += typeSizes[i];
265 assert( overall == sumtypes );
269 template <PartitionIteratorType pitype,
int codim>
270 void countLevelEntitiesNoCodim(
int level)
const
272 typedef typename GridType :: LevelGridView GridView ;
273 typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
274 GridView gridView = grid_.levelView( level );
275 Iterator it = gridView.template begin< 0, pitype> ();
276 Iterator end = gridView.template end< 0, pitype> ();
277 levelSizes_[codim][level] = countElementsNoCodim< codim >(it,end, levelTypeSizes_[codim][level]);
280 template <PartitionIteratorType pitype,
int codim>
281 void countLeafEntitiesNoCodim()
const
284 typedef typename GridType :: LeafGridView GridView ;
285 typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
286 GridView gridView = grid_.leafView();
287 Iterator it = gridView.template begin< 0, pitype > ();
288 Iterator end = gridView.template end< 0, pitype > ();
289 leafSizes_[codim] = countElementsNoCodim< codim >(it,end, leafTypeSizes_[codim] );
293 template <
int codim,
class IteratorType >
294 int countElementsNoCodim(IteratorType & it,
const IteratorType & end, std::vector<int>& typeSizes)
const
296 typedef typename GridType :: LocalIdSet LocalIdSet ;
297 typedef typename LocalIdSet :: IdType IdType ;
299 typedef GenericReferenceElement< ctype, dim > ReferenceElementType;
300 typedef GenericReferenceElements< ctype, dim > ReferenceElementContainerType;
302 typedef std::set< IdType > CodimIdSetType ;
304 typedef typename IteratorType :: Entity
ElementType ;
307 const LocalIdSet& idSet = grid_.localIdSet();
309 const size_t types = typeSizes.size();
310 for(
size_t i=0; i<types; ++i) typeSizes[ i ] = 0;
312 std::vector< CodimIdSetType > typeCount( types );
315 for( ; it != end; ++it )
318 const ElementType& element = *it ;
320 const ReferenceElementType& refElem =
321 ReferenceElementContainerType :: general( element.type() );
324 const int count = element.template count< codim > ();
325 for(
int i=0; i< count; ++ i )
330 const IdType
id = idSet.subId( element, i, codim );
332 typeCount[ gtIndex( geomType ) ].insert(
id );
338 for(
size_t i=0; i<types; ++i)
340 typeSizes[ i ] = typeCount[ i ].size();
341 overall += typeSizes[ i ];
349 template <
class Gr
idImp>