dune-grid 2.12-git
Loading...
Searching...
No Matches
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
15
16#include <dune/geometry/type.hh>
18
21
28namespace Dune {
29
31 template <class GridImp>
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( codim < 0 )
195 return 0;
196 if( levelSizes_[codim][level] < 0)
197 Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLevelEntities< i >::apply( *this, level, codim ); } );
198
199 assert( levelTypeSizes_[codim][level][gtIndex( type )] >= 0 );
200 return levelTypeSizes_[codim][level][gtIndex( type )];
201 }
202
203 //********************************************************************
204 // leaf sizes
205 //********************************************************************
207 int size (int codim) const
208 {
209 assert( codim >= 0 );
210 assert( codim < nCodim );
211 if( leafSizes_[codim] < 0 )
212 Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLeafEntities< i >::apply( *this, codim ); } );
213
214 assert( leafSizes_[codim] >= 0 );
215 return leafSizes_[codim];
216 };
217
219 int size ( const GeometryType type ) const
220 {
221 int codim = GridType :: dimension - type.dim();
222 if( codim < 0 )
223 return 0;
224 if( leafSizes_[codim] < 0 )
225 Hybrid::forEach( std::make_index_sequence< dim+1 >{}, [ & ]( auto i ){ CountLeafEntities< i >::apply( *this, codim ); } );
226
227 assert( leafTypeSizes_[codim][ gtIndex( type )] >= 0 );
228 return leafTypeSizes_[codim][ gtIndex( type )];
229 }
230
231 private:
232 template <PartitionIteratorType pitype, int codim>
233 void countLevelEntities(int level) const
234 {
235 typedef typename GridType :: LevelGridView GridView ;
236 typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
237 GridView gridView = grid_.levelGridView( level );
238 Iterator it = gridView.template begin<codim,pitype> ();
239 Iterator end = gridView.template end<codim,pitype> ();
240 levelSizes_[codim][level] = countElements(it,end, levelTypeSizes_[codim][level]);
241 }
242
243 template <PartitionIteratorType pitype, int codim>
244 void countLeafEntities() const
245 {
246 // count All_Partition entities
247 typedef typename GridType :: LeafGridView GridView ;
248 typedef typename GridView :: template Codim< codim > :: template Partition<pitype> :: Iterator Iterator ;
249 GridView gridView = grid_.leafGridView();
250 Iterator it = gridView.template begin<codim,pitype> ();
251 Iterator end = gridView.template end<codim,pitype> ();
252 leafSizes_[codim] = countElements(it,end, leafTypeSizes_[codim] );
253 }
254
255 // counts entities with given type for given iterator
256 template <class IteratorType>
257 int countElements(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
258 {
259 int overall = 0;
260 const size_t types = typeSizes.size();
261 for(size_t i=0; i<types; ++i) typeSizes[i] = 0;
262 for( ; it != end; ++it )
263 {
264 const GeometryType type = it->type();
265 ++typeSizes[ gtIndex( type ) ];
266 ++overall;
267 }
268
269#ifndef NDEBUG
270 int sumtypes = 0;
271 for(size_t i=0; i<types; ++i)
272 sumtypes += typeSizes[i];
273
274 assert( overall == sumtypes );
275#endif
276
277 return overall;
278 }
279
280 template <PartitionIteratorType pitype, int codim>
281 void countLevelEntitiesNoCodim(int level) const
282 {
283 typedef typename GridType :: LevelGridView GridView ;
284 typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
285 GridView gridView = grid_.levelGridView( level );
286 Iterator it = gridView.template begin< 0, pitype> ();
287 Iterator end = gridView.template end< 0, pitype> ();
288 levelSizes_[codim][level] = countElementsNoCodim< codim >(it,end, levelTypeSizes_[codim][level]);
289 }
290
291 template <PartitionIteratorType pitype, int codim>
292 void countLeafEntitiesNoCodim() const
293 {
294 // count All_Partition entities
295 typedef typename GridType :: LeafGridView GridView ;
296 typedef typename GridView :: template Codim< 0 > :: template Partition<pitype> :: Iterator Iterator ;
297 GridView gridView = grid_.leafGridView();
298 Iterator it = gridView.template begin< 0, pitype > ();
299 Iterator end = gridView.template end< 0, pitype > ();
300 leafSizes_[codim] = countElementsNoCodim< codim >(it,end, leafTypeSizes_[codim] );
301 }
302
303 // counts entities with given type for given iterator
304 template < int codim, class IteratorType >
305 int countElementsNoCodim(IteratorType & it, const IteratorType & end, std::vector<int>& typeSizes) const
306 {
307 typedef typename GridType :: LocalIdSet LocalIdSet ;
308 typedef typename LocalIdSet :: IdType IdType ;
309
310 typedef ReferenceElements< ctype, dim > ReferenceElementContainerType;
311 typedef typename ReferenceElementContainerType::ReferenceElement ReferenceElementType;
312
313 typedef std::set< IdType > CodimIdSetType ;
314
315 typedef typename IteratorType :: Entity ElementType ;
316
317 // get id set
318 const LocalIdSet& idSet = grid_.localIdSet();
319
320 const size_t types = typeSizes.size();
321 for(size_t i=0; i<types; ++i) typeSizes[ i ] = 0;
322
323 std::vector< CodimIdSetType > typeCount( types );
324
325 // count all elements of codimension codim
326 for( ; it != end; ++it )
327 {
328 // get entity
329 const ElementType& element = *it ;
330 // get reference element
331 ReferenceElementType refElem =
332 ReferenceElementContainerType :: general( element.type() );
333
334 // count all sub entities of codimension codim
335 const int count = element.subEntities( codim );
336 for( int i=0; i< count; ++ i )
337 {
338 // get geometry type
339 const GeometryType geomType = refElem.type( i, codim );
340 // get id of sub entity
341 const IdType id = idSet.subId( element, i, codim );
342 // insert id into set
343 typeCount[ gtIndex( geomType ) ].insert( id );
344 }
345 }
346
347 // accumulate numbers
348 int overall = 0;
349 for(size_t i=0; i<types; ++i)
350 {
351 typeSizes[ i ] = typeCount[ i ].size();
352 overall += typeSizes[ i ];
353 }
354
355 return overall;
356 }
357 };
358
359} // end namespace Dune
360#endif
int size() const
iterator end()
constexpr void forEach(Range &&range, F &&f)
U_CHAR ElementType
Definition misc.hh:63
GeometryType
Type representing VTK's entity geometry types.
Definition common.hh:132
Include standard header files.
constexpr unsigned int dim() const
constexpr unsigned int id() const
Grid view abstract base class.
Definition common/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:207
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:219
void reset()
reset all cached sizes
Definition sizecache.hh:148
A set of traits classes to store static information about grid implementation.
T count(T... args)
T resize(T... args)
T size(T... args)