Dune Core Modules (2.5.2)

sizecache.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_SIZECACHE_HH
4 #define DUNE_SIZECACHE_HH
5 
6 #include <cassert>
7 #include <vector>
8 #include <set>
9 
10 #include <dune/common/forloop.hh>
12 
13 #include <dune/geometry/type.hh>
14 #include <dune/geometry/referenceelements.hh>
15 
16 #include <dune/grid/common/gridenums.hh>
18 
25 namespace Dune {
26 
28  template <class GridImp>
29  class SizeCache
30  {
33  enum { dim = GridImp::dimension };
34 
36  enum { nCodim = GridImp::dimension+1 };
37 
38  // type of grid
39  typedef GridImp GridType;
40 
41  // coordinate type
42  typedef typename GridType :: ctype ctype ;
43 
44  // stores all sizes of the levels
45  mutable std::vector< int > levelSizes_[nCodim];
46 
47  // stores all sizes of the levels
48  mutable std::vector< std::vector< int > > levelTypeSizes_[nCodim];
49 
50  // stores all sizes of leafs
51  mutable int leafSizes_[nCodim];
52 
53  // stores all sizes of leafs
54  mutable std::vector< int > leafTypeSizes_[nCodim];
55 
56  // the grid
57  const GridType & grid_;
58 
59  // count elements of set by iterating the grid
60  template < int codim, bool gridHasCodim >
61  struct CountLevelEntitiesBase
62  {
63  template < class SzCacheType >
64  static void apply(const SzCacheType & sc, int level, int cd)
65  {
66  if( cd == codim )
67  {
68  sc.template countLevelEntities<All_Partition,codim> (level);
69  }
70  }
71  };
72 
73  template < int codim >
74  struct CountLevelEntitiesBase< codim, false >
75  {
76  template < class SzCacheType >
77  static void apply(const SzCacheType & sc, int level, int cd)
78  {
79  if( cd == codim )
80  {
81  sc.template countLevelEntitiesNoCodim<All_Partition,codim> (level);
82  }
83  }
84  };
85 
86  template < int codim >
87  struct CountLevelEntities
88  : public CountLevelEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
89  {};
90 
91  // count elements of set by iterating the grid
92  template < int codim, bool gridHasCodim >
93  struct CountLeafEntitiesBase
94  {
95  template <class SzCacheType>
96  static void apply(const SzCacheType & sc, int cd)
97  {
98  if( cd == codim )
99  {
100  sc.template countLeafEntities<All_Partition,codim> ();
101  }
102  }
103  };
104 
105  // count elements of set by iterating the grid
106  template < int codim >
107  struct CountLeafEntitiesBase< codim, false >
108  {
109  template <class SzCacheType>
110  static void apply(const SzCacheType & sc, int cd)
111  {
112  if( cd == codim )
113  {
114  sc.template countLeafEntitiesNoCodim<All_Partition,codim> ();
115  }
116  }
117  };
118 
119  template < int codim >
120  struct CountLeafEntities
121  : public CountLeafEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
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 )
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 )
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_.levelGridView( 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_.leafGridView();
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_.levelGridView( 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_.leafGridView();
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 ReferenceElement< ctype, dim > ReferenceElementType;
300  typedef ReferenceElements< 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.subEntities( 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 
348 } // end namespace Dune
349 #endif
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:268
unsigned int dim() const
Return dimension of the type.
Definition: type.hh:565
unsigned int id() const
Return the topology id the type.
Definition: type.hh:570
Grid view abstract base class.
Definition: gridview.hh:60
organizes the caching of sizes for one grid and one GeometryType
Definition: sizecache.hh:30
int size(int level, GeometryType type) const
Return number of entities per level and geometry type in this process.
Definition: sizecache.hh:188
int size(int level, int codim) const
Return number of grid entities of a given codim on a given level in this process.
Definition: sizecache.hh:171
int size(int codim) const
Return number of leaf entities of a given codim in this process.
Definition: sizecache.hh:202
SizeCache(const GridType &grid)
constructor taking grid reference
Definition: sizecache.hh:139
int size(const GeometryType type) const
Return number of leaf entities per geometry type in this process.
Definition: sizecache.hh:214
void reset()
reset all cached sizes
Definition: sizecache.hh:145
A set of traits classes to store static information about grid implementation.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:178
A few common exception classes.
A static for loop for template meta-programming.
Dune namespace.
Definition: alignment.hh:11
Static tag representing a codimension.
Definition: dimension.hh:22
A static loop using TMP.
Definition: forloop.hh:67
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)