Dune Core Modules (2.6.0)

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 #include <utility>
10 
12 #include <dune/common/hybridutilities.hh>
13 
14 #include <dune/geometry/type.hh>
15 #include <dune/geometry/referenceelements.hh>
16 
17 #include <dune/grid/common/gridenums.hh>
19 
26 namespace Dune {
27 
29  template <class GridImp>
30  class SizeCache
31  {
34  enum { dim = GridImp::dimension };
35 
37  enum { nCodim = GridImp::dimension+1 };
38 
39  // type of grid
40  typedef GridImp GridType;
41 
42  // coordinate type
43  typedef typename GridType :: ctype ctype ;
44 
45  // stores all sizes of the levels
46  mutable std::vector< int > levelSizes_[nCodim];
47 
48  // stores all sizes of the levels
49  mutable std::vector< std::vector< int > > levelTypeSizes_[nCodim];
50 
51  // stores all sizes of leafs
52  mutable int leafSizes_[nCodim];
53 
54  // stores all sizes of leafs
55  mutable std::vector< int > leafTypeSizes_[nCodim];
56 
57  // the grid
58  const GridType & grid_;
59 
60  // count elements of set by iterating the grid
61  template < int codim, bool gridHasCodim >
62  struct CountLevelEntitiesBase
63  {
64  template < class SzCacheType >
65  static void apply(const SzCacheType & sc, int level, int cd)
66  {
67  if( cd == codim )
68  {
69  sc.template countLevelEntities<All_Partition,codim> (level);
70  }
71  }
72  };
73 
74  template < int codim >
75  struct CountLevelEntitiesBase< codim, false >
76  {
77  template < class SzCacheType >
78  static void apply(const SzCacheType & sc, int level, int cd)
79  {
80  if( cd == codim )
81  {
82  sc.template countLevelEntitiesNoCodim<All_Partition,codim> (level);
83  }
84  }
85  };
86 
87  template < int codim >
88  struct CountLevelEntities
89  : public CountLevelEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
90  {};
91 
92  // count elements of set by iterating the grid
93  template < int codim, bool gridHasCodim >
94  struct CountLeafEntitiesBase
95  {
96  template <class SzCacheType>
97  static void apply(const SzCacheType & sc, int cd)
98  {
99  if( cd == codim )
100  {
101  sc.template countLeafEntities<All_Partition,codim> ();
102  }
103  }
104  };
105 
106  // count elements of set by iterating the grid
107  template < int codim >
108  struct CountLeafEntitiesBase< codim, false >
109  {
110  template <class SzCacheType>
111  static void apply(const SzCacheType & sc, int cd)
112  {
113  if( cd == codim )
114  {
115  sc.template countLeafEntitiesNoCodim<All_Partition,codim> ();
116  }
117  }
118  };
119 
120  template < int codim >
121  struct CountLeafEntities
122  : public CountLeafEntitiesBase< codim, Capabilities :: hasEntity< GridType, codim > :: v >
123  {};
124 
125  int gtIndex( const GeometryType& type ) const
126  {
127  return type.id() >> 1 ;
128  }
129 
130  int sizeCodim( const int codim ) const
131  {
132  const int mydim = GridType :: dimension - codim;
133  return ((1 << mydim) + 1) / 2;
134  }
135 
136  // private copy constructor
137  SizeCache (const SizeCache & );
138  public:
140  SizeCache (const GridType & grid) : grid_( grid )
141  {
142  reset();
143  }
144 
146  void reset()
147  {
148  for(int codim=0; codim<nCodim; ++codim)
149  {
150  leafSizes_[ codim ] = -1;
151  leafTypeSizes_[ codim ].resize( sizeCodim( codim ), -1 );
152  }
153 
154  const int numMxl = grid_.maxLevel()+1;
155  for(int codim=0; codim<nCodim; ++codim)
156  {
157  std::vector<int> & vec = levelSizes_[codim];
158  vec.resize(numMxl);
159  levelTypeSizes_[codim].resize( numMxl );
160  for(int level = 0; level<numMxl; ++level)
161  {
162  vec[level] = -1;
163  levelTypeSizes_[codim][level].resize( sizeCodim( codim ), -1 );
164  }
165  }
166  }
167 
168  //********************************************************************
169  // level sizes
170  //********************************************************************
172  int size (int level, int codim) const
173  {
174  assert( codim >= 0 );
175  assert( codim < nCodim );
176  assert( level >= 0 );
177  if( level >= (int) levelSizes_[codim].size() ) return 0;
178 
179  if( levelSizes_[codim][level] < 0)
180  Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLevelEntities< i >::apply( *this, level, codim ); } );
181 
182  // CountLevelEntities<ThisType,All_Partition,dim>::count(*this,level,codim);
183 
184  assert( levelSizes_[codim][level] >= 0 );
185  return levelSizes_[codim][level];
186  }
187 
189  int size (int level, GeometryType type) const
190  {
191  int codim = GridType ::dimension - type.dim();
192  if( levelSizes_[codim][level] < 0)
193  Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLevelEntities< i >::apply( *this, level, codim ); } );
194 
195  assert( levelTypeSizes_[codim][level][gtIndex( type )] >= 0 );
196  return levelTypeSizes_[codim][level][gtIndex( type )];
197  }
198 
199  //********************************************************************
200  // leaf sizes
201  //********************************************************************
203  int size (int codim) const
204  {
205  assert( codim >= 0 );
206  assert( codim < nCodim );
207  if( leafSizes_[codim] < 0 )
208  Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLeafEntities< i >::apply( *this, codim ); } );
209 
210  assert( leafSizes_[codim] >= 0 );
211  return leafSizes_[codim];
212  };
213 
215  int size ( const GeometryType type ) const
216  {
217  int codim = GridType :: dimension - type.dim();
218  if( leafSizes_[codim] < 0 )
219  Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLeafEntities< i >::apply( *this, codim ); } );
220 
221  assert( leafTypeSizes_[codim][ gtIndex( type )] >= 0 );
222  return leafTypeSizes_[codim][ gtIndex( type )];
223  }
224 
225  private:
226  template <PartitionIteratorType pitype, int codim>
227  void countLevelEntities(int level) const
228  {
229  typedef typename GridType :: LevelGridView GridView ;
230  typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
231  GridView gridView = grid_.levelGridView( level );
232  Iterator it = gridView.template begin<codim,pitype> ();
233  Iterator end = gridView.template end<codim,pitype> ();
234  levelSizes_[codim][level] = countElements(it,end, levelTypeSizes_[codim][level]);
235  }
236 
237  template <PartitionIteratorType pitype, int codim>
238  void countLeafEntities() const
239  {
240  // count All_Partition entities
241  typedef typename GridType :: LeafGridView GridView ;
242  typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
243  GridView gridView = grid_.leafGridView();
244  Iterator it = gridView.template begin<codim,pitype> ();
245  Iterator end = gridView.template end<codim,pitype> ();
246  leafSizes_[codim] = countElements(it,end, leafTypeSizes_[codim] );
247  }
248 
249  // counts entities with given type for given iterator
250  template <class IteratorType>
251  int countElements(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
252  {
253  int overall = 0;
254  const size_t types = typeSizes.size();
255  for(size_t i=0; i<types; ++i) typeSizes[i] = 0;
256  for( ; it != end; ++it )
257  {
258  const GeometryType type = it->type();
259  ++typeSizes[ gtIndex( type ) ];
260  ++overall;
261  }
262 
263  int sumtypes = 0;
264  for(size_t i=0; i<types; ++i) sumtypes += typeSizes[i];
265 
266  assert( overall == sumtypes );
267  return overall;
268  }
269 
270  template <PartitionIteratorType pitype, int codim>
271  void countLevelEntitiesNoCodim(int level) const
272  {
273  typedef typename GridType :: LevelGridView GridView ;
274  typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
275  GridView gridView = grid_.levelGridView( level );
276  Iterator it = gridView.template begin< 0, pitype> ();
277  Iterator end = gridView.template end< 0, pitype> ();
278  levelSizes_[codim][level] = countElementsNoCodim< codim >(it,end, levelTypeSizes_[codim][level]);
279  }
280 
281  template <PartitionIteratorType pitype, int codim>
282  void countLeafEntitiesNoCodim() const
283  {
284  // count All_Partition entities
285  typedef typename GridType :: LeafGridView GridView ;
286  typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
287  GridView gridView = grid_.leafGridView();
288  Iterator it = gridView.template begin< 0, pitype > ();
289  Iterator end = gridView.template end< 0, pitype > ();
290  leafSizes_[codim] = countElementsNoCodim< codim >(it,end, leafTypeSizes_[codim] );
291  }
292 
293  // counts entities with given type for given iterator
294  template < int codim, class IteratorType >
295  int countElementsNoCodim(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
296  {
297  typedef typename GridType :: LocalIdSet LocalIdSet ;
298  typedef typename LocalIdSet :: IdType IdType ;
299 
300  typedef ReferenceElements< ctype, dim > ReferenceElementContainerType;
301  typedef typename ReferenceElementContainerType::ReferenceElement ReferenceElementType;
302 
303  typedef std::set< IdType > CodimIdSetType ;
304 
305  typedef typename IteratorType :: Entity ElementType ;
306 
307  // get id set
308  const LocalIdSet& idSet = grid_.localIdSet();
309 
310  const size_t types = typeSizes.size();
311  for(size_t i=0; i<types; ++i) typeSizes[ i ] = 0;
312 
313  std::vector< CodimIdSetType > typeCount( types );
314 
315  // count all elements of codimension codim
316  for( ; it != end; ++it )
317  {
318  // get entity
319  const ElementType& element = *it ;
320  // get reference element
321  ReferenceElementType refElem =
322  ReferenceElementContainerType :: general( element.type() );
323 
324  // count all sub entities of codimension codim
325  const int count = element.subEntities( codim );
326  for( int i=0; i< count; ++ i )
327  {
328  // get geometry type
329  const GeometryType geomType = refElem.type( i, codim );
330  // get id of sub entity
331  const IdType id = idSet.subId( element, i, codim );
332  // insert id into set
333  typeCount[ gtIndex( geomType ) ].insert( id );
334  }
335  }
336 
337  // accumulate numbers
338  int overall = 0;
339  for(size_t i=0; i<types; ++i)
340  {
341  typeSizes[ i ] = typeCount[ i ].size();
342  overall += typeSizes[ i ];
343  }
344 
345  return overall;
346  }
347  };
348 
349 } // end namespace Dune
350 #endif
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:277
constexpr unsigned int dim() const
Return dimension of the type.
Definition: type.hh:572
constexpr unsigned int id() const
Return the topology id of the type.
Definition: type.hh:577
Grid view abstract base class.
Definition: gridview.hh:60
organizes the caching of sizes for one grid and one GeometryType
Definition: sizecache.hh:31
int size(int level, GeometryType type) const
Return number of entities per level and geometry type in this process.
Definition: sizecache.hh:189
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:172
int size(int codim) const
Return number of leaf entities of a given codim in this process.
Definition: sizecache.hh:203
SizeCache(const GridType &grid)
constructor taking grid reference
Definition: sizecache.hh:140
int size(const GeometryType type) const
Return number of leaf entities per geometry type in this process.
Definition: sizecache.hh:215
void reset()
reset all cached sizes
Definition: sizecache.hh:146
A set of traits classes to store static information about grid implementation.
A few common exception classes.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:178
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:58
unspecified-type ReferenceElement
Returns the type of reference element for the argument types T...
Definition: referenceelements.hh:415
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:308
Dune namespace.
Definition: alignedallocator.hh:10
Static tag representing a codimension.
Definition: dimension.hh:22
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 5, 22:29, 2024)