Dune Core Modules (2.8.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_GRID_COMMON_SIZECACHE_HH
4#define DUNE_GRID_COMMON_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
26namespace Dune {
27
29 template <class GridImp>
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:123
constexpr unsigned int dim() const
Return dimension of the type.
Definition: type.hh:369
constexpr unsigned int id() const
Return the topology id of the type.
Definition: type.hh:374
Grid view abstract base class.
Definition: gridview.hh:63
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:130
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:266
Dune namespace.
Definition: alignedallocator.hh:11
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.111.3 (Nov 21, 23:30, 2024)