dune-grid  2.2.1
common/defaultindexsets.hh
Go to the documentation of this file.
1 #ifndef DUNE_DEFAULTINDEXSETS_HH
2 #define DUNE_DEFAULTINDEXSETS_HH
3 
4 //- system includes
5 #include <vector>
6 #include <rpc/rpc.h>
7 
8 //- Dune includes
9 #include <dune/common/misc.hh>
10 // #include <dune/common/interfaces.hh>
11 #include <dune/grid/common/grid.hh>
12 #include <dune/grid/common/adaptcallback.hh> // for compatibility only
14 
21 namespace Dune {
22 
24 template <class GridImp>
26 {
28  template<int cd>
29  struct Codim
30  {
31  template<PartitionIteratorType pitype>
32  struct Partition
33  {
34  typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
35  };
36  };
37 };
38 
40 template <class GridImp>
42 {
44  template<int cd>
45  struct Codim
46  {
47  template<PartitionIteratorType pitype>
48  struct Partition
49  {
50  typedef typename GridImp::Traits::template Codim<cd>::
52  };
53  };
54 };
55 
56 
57 namespace DefaultIndexSetHelper
58 {
59 
60  template< class Grid, class Index >
62  {
63  static bool
65  const size_t index )
66  {
67  DUNE_THROW( NotImplemented, "DefaultIndexSetHelper::ContainsIndex not implemented for this grid." );
68  return true;
69  }
70  };
71 
72 } // namespace DefaultIndexSetHelper
73 
74 
79 template < class GridImp, class IteratorImp >
81  public IndexSet< GridImp, DefaultIndexSet <GridImp, IteratorImp>, unsigned int >
82 {
83  typedef GridImp GridType;
84  enum { dim = GridType :: dimension };
85 
86 public:
87  enum { ncodim = GridType::dimension + 1 };
88 
90  typedef unsigned int IndexType;
91 
93  typedef IteratorImp IteratorType ;
94 
95  struct Index
96  {
97  int index_;
98  Index() : index_( -1 ) {}
99  int index() const { return index_; }
100  void set( const int index ) { index_ = index; }
101  };
102 
104  typedef std::vector< PersistentContainerType* > PersistentContainerVectorType;
105 
106 private:
108 
109  template <class EntityType, int codim>
110  struct InsertEntity
111  {
112  template <class SizeVector>
113  static void insert(const EntityType & en,
115  SizeVector& sizes)
116  {
117  PersistentContainerType& codimContainer = *(indexContainer[ codim ]);
118  for( int i = 0; i < en.template count< codim >(); ++i )
119  {
120  Index& idx = codimContainer( en , i );
121  if( idx.index() < 0 )
122  {
123  idx.set( sizes[codim] );
124  ++ sizes[ codim ];
125  }
126  }
127  InsertEntity<EntityType,codim-1>::insert(en, indexContainer, sizes);
128  }
129  };
130 
131  template <class EntityType>
132  struct InsertEntity<EntityType,0>
133  {
134  template <class SizeVector>
135  static void insert(const EntityType & en,
137  SizeVector& sizes)
138  {
139  enum { codim = 0 };
140  PersistentContainerType& codimContainer = *(indexContainer[ codim ]);
141  Index& idx = codimContainer[ en ];
142  if( idx.index() < 0 )
143  {
144  idx.set( sizes[codim] );
145  ++ sizes[ codim ];
146  }
147  }
148  };
149 
150 public:
153  using IndexSet<GridType, DefaultIndexSet>::subIndex;
154 
157  DefaultIndexSet( const GridType & grid ,
158  const IteratorType& begin,
159  const IteratorType& end,
160  const int level = -1 )
161  : grid_(grid),
162  indexContainers_( ncodim, (PersistentContainerType *) 0),
163  size_( ncodim, -1 ),
164  level_(level)
165  {
166  for( int codim=0; codim < ncodim; ++codim )
167  indexContainers_[ codim ] = new PersistentContainerType( grid, codim );
168 
169  calcNewIndex (begin, end);
170  }
171 
174  {
175  for( int codim=0; codim < ncodim; ++codim )
176  delete indexContainers_[ codim ];
177  }
178 
179  const PersistentContainerType& indexContainer( const size_t codim ) const
180  {
181  assert( codim < indexContainers_.size() );
182  assert( indexContainers_[ codim ] );
183  return *( indexContainers_[ codim ] );
184  }
185 
186  PersistentContainerType& indexContainer( const size_t codim )
187  {
188  assert( codim < indexContainers_.size() );
189  assert( indexContainers_[ codim ] );
190  return *( indexContainers_[ codim ] );
191  }
192 
194  template<class EntityType>
195  IndexType index (const EntityType & en) const
196  {
197  enum { cd = EntityType :: codimension };
198  // this must not be true for vertices
199  // therefore only check other codims
200 #ifndef NDEBUG
201  const int codim = cd;
202  assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() ));
203  assert( indexContainer( codim )[ en ].index() >= 0 );
204 #endif
205  return indexContainer( cd )[ en ].index();
206  }
207 
209  template<int cd>
210  IndexType index (const typename GridImp::template Codim<cd>::Entity& en) const
211  {
212  // this must not be true for vertices
213  // therefore only check other codims
214 #ifndef NDEBUG
215  const int codim = cd;
216  //const bool isLeaf = (codim == 0) ? en.isLeaf() : true ;
217  assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() ));
218  assert( indexContainer( cd )[ en ].index() >= 0 );
219 #endif
220  return indexContainer( cd )[ en ].index();
221  }
222 
225  template< int cc >
226  IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e,
227  int i, unsigned int codim ) const
228  {
229  assert( (codim != 0) || (level_ < 0) || ( level_ == e.level() ) );
230  assert( indexContainer( codim )( e, i ).index() >= 0 );
231  return indexContainer( codim )( e, i ).index();
232  }
233 
235  template<class EntityType>
236  bool contains (const EntityType& en) const
237  {
238  enum { cd = EntityType :: codimension };
239  return (indexContainer( cd )[ en ].index() >= 0 );
240  }
241 
243  IndexType size ( int codim ) const
244  {
245  assert( codim >= 0 && codim <= GridType::dimension );
246  return size_[ codim ];
247  }
248 
251  IndexType size ( GeometryType type ) const
252  {
253  if( typeNotValid(type) ) return 0;
254  return size_[GridType::dimension-type.dim()];
255  }
256 
259  void calcNewIndex (const IteratorType& begin, const IteratorType& end )
260  {
261  // resize arrays to new size
262  // and set size to zero
263  for(int cd=0; cd<ncodim; ++cd)
264  {
265  indexContainer( cd ).clear();
266  size_[cd] = 0;
267  }
268 
269  // grid walk to setup index set
270  for(IteratorType it = begin; it != end; ++it)
271  {
272  assert( ( level_ < 0 ) ? it->isLeaf() : (it->level() == level_) );
273  insertEntity( *it, size_ );
274  }
275 
276  // remember the number of entity on level and cd = 0
277  for(int cd=0; cd<ncodim; ++cd)
278  {
279 #ifndef NDEBUG
280  const int gridSize = ( level_ < 0 ) ? grid_.size( cd ) : grid_.size( level_, cd);
281  const int mySize = size_[cd];
282  if( mySize > gridSize )
283  {
284  std::cout << mySize << " s | g " << gridSize << std::endl;
285  }
286  assert( mySize <= gridSize );
287 #endif
288  }
289  }
290 
292  const std::vector<GeometryType>& geomTypes (int codim) const
293  {
294  return grid_.geomTypes( codim );
295  }
296 
298  bool containsIndex ( const int cd , const int idx) const
299  {
301  return ContainsIndex::contains( indexContainer( cd ), idx );
302  }
303 
304 private:
305  // return whether set has this type stored or not
306  bool typeNotValid (const GeometryType & type) const
307  {
308  int codim = GridType :: dimension - type.dim();
309  const std::vector<GeometryType> & geomT = geomTypes(codim);
310  for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false;
311  return true;
312  }
313 
314  // calculate index for the codim
315  template <class EntityType, class SizeVector>
316  void insertEntity(EntityType & en, SizeVector& sizes)
317  {
318  InsertEntity<EntityType,dim>::insert( en, indexContainers_, sizes);
319  }
320 
321  // grid this index set belongs to
322  const GridType& grid_;
323 
325  PersistentContainerVectorType indexContainers_;
326 
327  // number of entitys of each level an codim
328  std::vector< int > size_;
329 
330  // the level for which this index set is created
331  const int level_;
332 
333 };
334 
335 
336 } // end namespace Dune
337 #endif