Dune Core Modules (unstable)

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