dune-grid  2.2.0
sizecache.hh
Go to the documentation of this file.
1 #ifndef DUNE_SIZECACHE_HH
2 #define DUNE_SIZECACHE_HH
3 
4 #include <cassert>
5 #include <vector>
6 #include <set>
7 
8 #include <dune/common/forloop.hh>
9 #include <dune/common/exceptions.hh>
10 
11 #include <dune/geometry/type.hh>
12 #include <dune/geometry/referenceelements.hh>
13 
16 
23 namespace Dune {
24 
26 template <class GridImp>
27 class SizeCache
28 {
31  enum { dim = GridImp::dimension };
32 
34  enum { nCodim = GridImp::dimension+1 };
35 
36  // type of grid
37  typedef GridImp GridType;
38 
39  // coordinate type
40  typedef typename GridType :: ctype ctype ;
41 
42  // stores all sizes of the levels
43  mutable std::vector< int > levelSizes_[nCodim];
44 
45  // stores all sizes of the levels
46  mutable std::vector< std::vector< int > > levelTypeSizes_[nCodim];
47 
48  // stores all sizes of leafs
49  mutable int leafSizes_[nCodim];
50 
51  // stores all sizes of leafs
52  mutable std::vector< int > leafTypeSizes_[nCodim];
53 
54  // the grid
55  const GridType & grid_;
56 
57  // count elements of set by iterating the grid
58  template < int codim, bool gridHasCodim >
59  struct CountLevelEntitiesBase
60  {
61  template < class SzCacheType >
62  static void apply(const SzCacheType & sc, int level, int cd)
63  {
64  if( cd == codim )
65  {
66  sc.template countLevelEntities<All_Partition,codim> (level);
67  }
68  }
69  };
70 
71  template < int codim >
72  struct CountLevelEntitiesBase< codim, false >
73  {
74  template < class SzCacheType >
75  static void apply(const SzCacheType & sc, int level, int cd)
76  {
77  if( cd == codim )
78  {
79  sc.template countLevelEntitiesNoCodim<All_Partition,codim> (level);
80  }
81  }
82  };
83 
84  template < int codim >
85  struct CountLevelEntities
86  : public CountLevelEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
87  {
88  };
89 
90  // count elements of set by iterating the grid
91  template < int codim, bool gridHasCodim >
92  struct CountLeafEntitiesBase
93  {
94  template <class SzCacheType>
95  static void apply(const SzCacheType & sc, int cd)
96  {
97  if( cd == codim )
98  {
99  sc.template countLeafEntities<All_Partition,codim> ();
100  }
101  }
102  };
103 
104  // count elements of set by iterating the grid
105  template < int codim >
106  struct CountLeafEntitiesBase< codim, false >
107  {
108  template <class SzCacheType>
109  static void apply(const SzCacheType & sc, int cd)
110  {
111  if( cd == codim )
112  {
113  sc.template countLeafEntitiesNoCodim<All_Partition,codim> ();
114  }
115  }
116  };
117 
118  template < int codim >
119  struct CountLeafEntities
120  : public CountLeafEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
121  {
122  };
123 
124  int gtIndex( const GeometryType& type ) const
125  {
126  return type.id() >> 1 ;
127  }
128 
129  int sizeCodim( const int codim ) const
130  {
131  const int mydim = GridType :: dimension - codim;
132  return ((1 << mydim) + 1) / 2;
133  }
134 
135  // private copy constructor
136  SizeCache (const SizeCache & );
137 public:
139  SizeCache (const GridType & grid) : grid_( grid )
140  {
141  reset();
142  }
143 
145  void reset()
146  {
147  for(int codim=0; codim<nCodim; ++codim)
148  {
149  leafSizes_[ codim ] = -1;
150  leafTypeSizes_[ codim ].resize( sizeCodim( codim ), -1 );
151  }
152 
153  const int numMxl = grid_.maxLevel()+1;
154  for(int codim=0; codim<nCodim; ++codim)
155  {
156  std::vector<int> & vec = levelSizes_[codim];
157  vec.resize(numMxl);
158  levelTypeSizes_[codim].resize( numMxl );
159  for(int level = 0; level<numMxl; ++level)
160  {
161  vec[level] = -1;
162  levelTypeSizes_[codim][level].resize( sizeCodim( codim ), -1 );
163  }
164  }
165  }
166 
167  //********************************************************************
168  // level sizes
169  //********************************************************************
171  int size (int level, int codim) const
172  {
173  assert( codim >= 0 );
174  assert( codim < nCodim );
175  assert( level >= 0 );
176  if( level >= (int) levelSizes_[codim].size() ) return 0;
177 
178  if( levelSizes_[codim][level] < 0)
179  ForLoop< CountLevelEntities, 0, dim > :: apply( *this, level, codim );
180 
181  // CountLevelEntities<ThisType,All_Partition,dim>::count(*this,level,codim);
182 
183  assert( levelSizes_[codim][level] >= 0 );
184  return levelSizes_[codim][level];
185  }
186 
188  int size (int level, GeometryType type) const
189  {
190  const int codim = GridType ::dimension - type.dim();
191  if( levelSizes_[codim][level] < 0)
192  ForLoop< CountLevelEntities, 0, dim > :: apply( *this, level, codim );
193 
194  assert( levelTypeSizes_[codim][level][gtIndex( type )] >= 0 );
195  return levelTypeSizes_[codim][level][gtIndex( type )];
196  }
197 
198  //********************************************************************
199  // leaf sizes
200  //********************************************************************
202  int size (int codim) const
203  {
204  assert( codim >= 0 );
205  assert( codim < nCodim );
206  if( leafSizes_[codim] < 0 )
207  ForLoop< CountLeafEntities, 0, dim > :: apply( *this, codim );
208 
209  assert( leafSizes_[codim] >= 0 );
210  return leafSizes_[codim];
211  };
212 
214  int size ( const GeometryType type ) const
215  {
216  const int codim = GridType :: dimension - type.dim();
217  if( leafSizes_[codim] < 0 )
218  ForLoop< CountLeafEntities, 0, dim > :: apply( *this, codim );
219 
220  assert( leafTypeSizes_[codim][ gtIndex( type )] >= 0 );
221  return leafTypeSizes_[codim][ gtIndex( type )];
222  }
223 
224 private:
225  template <PartitionIteratorType pitype, int codim>
226  void countLevelEntities(int level) const
227  {
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]);
234  }
235 
236  template <PartitionIteratorType pitype, int codim>
237  void countLeafEntities() const
238  {
239  // count All_Partition entities
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] );
246  }
247 
248  // counts entities with given type for given iterator
249  template <class IteratorType>
250  int countElements(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
251  {
252  int overall = 0;
253  const size_t types = typeSizes.size();
254  for(size_t i=0; i<types; ++i) typeSizes[i] = 0;
255  for( ; it != end; ++it )
256  {
257  const GeometryType type = it->type();
258  ++typeSizes[ gtIndex( type ) ];
259  ++overall;
260  }
261 
262  int sumtypes = 0;
263  for(size_t i=0; i<types; ++i) sumtypes += typeSizes[i];
264 
265  assert( overall == sumtypes );
266  return overall;
267  }
268 
269  template <PartitionIteratorType pitype, int codim>
270  void countLevelEntitiesNoCodim(int level) const
271  {
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]);
278  }
279 
280  template <PartitionIteratorType pitype, int codim>
281  void countLeafEntitiesNoCodim() const
282  {
283  // count All_Partition entities
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] );
290  }
291 
292  // counts entities with given type for given iterator
293  template < int codim, class IteratorType >
294  int countElementsNoCodim(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
295  {
296  typedef typename GridType :: LocalIdSet LocalIdSet ;
297  typedef typename LocalIdSet :: IdType IdType ;
298 
299  typedef GenericReferenceElement< ctype, dim > ReferenceElementType;
300  typedef GenericReferenceElements< ctype, dim > ReferenceElementContainerType;
301 
302  typedef std::set< IdType > CodimIdSetType ;
303 
304  typedef typename IteratorType :: Entity ElementType ;
305 
306  // get id set
307  const LocalIdSet& idSet = grid_.localIdSet();
308 
309  const size_t types = typeSizes.size();
310  for(size_t i=0; i<types; ++i) typeSizes[ i ] = 0;
311 
312  std::vector< CodimIdSetType > typeCount( types );
313 
314  // count all elements of codimension codim
315  for( ; it != end; ++it )
316  {
317  // get entity
318  const ElementType& element = *it ;
319  // get reference element
320  const ReferenceElementType& refElem =
321  ReferenceElementContainerType :: general( element.type() );
322 
323  // count all sub entities of codimension codim
324  const int count = element.template count< codim > ();
325  for( int i=0; i< count; ++ i )
326  {
327  // get geometry type
328  const GeometryType geomType = refElem.type( i, codim );
329  // get id of sub entity
330  const IdType id = idSet.subId( element, i, codim );
331  // insert id into set
332  typeCount[ gtIndex( geomType ) ].insert( id );
333  }
334  }
335 
336  // accumulate numbers
337  int overall = 0;
338  for(size_t i=0; i<types; ++i)
339  {
340  typeSizes[ i ] = typeCount[ i ].size();
341  overall += typeSizes[ i ];
342  }
343 
344  return overall;
345  }
346 };
347 
349 template <class GridImp>
350 struct SingleTypeSizeCache : public SizeCache< GridImp >
351 {
352  DUNE_DEPRECATED SingleTypeSizeCache( const GridImp& grid, bool isSimplex , bool isCube, bool notWorry = false ) : SizeCache< GridImp >( grid ) {}
353 };
354 
355 } // end namespace Dune
356 #endif