dune-grid  2.3beta2
defaultindexsets.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_DEFAULTINDEXSETS_HH
4 #define DUNE_DEFAULTINDEXSETS_HH
5 
6 //- system includes
7 #include <vector>
8 #include <rpc/rpc.h>
9 
10 //- Dune includes
11 #include <dune/common/forloop.hh>
12 
13 #include <dune/grid/common/grid.hh>
14 #include <dune/grid/common/adaptcallback.hh> // for compatibility only
16 
23 namespace Dune
24 {
25 
27  template <class GridImp>
29  {
31  template<int cd>
32  struct Codim
33  {
34  template<PartitionIteratorType pitype>
35  struct Partition
36  {
37  typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
38  };
39  };
40  };
41 
43  template <class GridImp>
45  {
47  template<int cd>
48  struct Codim
49  {
50  template<PartitionIteratorType pitype>
51  struct Partition
52  {
53  typedef typename GridImp::Traits::template Codim<cd>::
55  };
56  };
57  };
58 
59 
60 
65  template < class GridImp, class IteratorImp >
67  public IndexSet< GridImp, DefaultIndexSet <GridImp, IteratorImp>, unsigned int >
68  {
69  typedef GridImp GridType;
70  enum { dim = GridType :: dimension };
71 
72  public:
73  enum { ncodim = GridType::dimension + 1 };
74 
76  typedef unsigned int IndexType;
77 
78  private:
80  typedef IteratorImp IteratorType ;
81 
82  public:
83  struct Index
84  {
85  int index_;
86  Index() : index_( -1 ) {}
87  int index() const { return index_; }
88  void set( const int index ) { index_ = index; }
89  };
90 
92  typedef std::vector< PersistentContainerType* > PersistentContainerVectorType;
93 
94  private:
96 
97  template< int codim >
98  struct InsertEntity
99  {
100  static void apply ( const typename GridImp::template Codim< 0 >::Entity &entity,
102  std::vector< int > &sizes )
103  {
104  PersistentContainerType &codimContainer = *(indexContainer[ codim ]);
105  if( codim == 0 )
106  {
107  Index &idx = codimContainer[ entity ];
108  if( idx.index() < 0 )
109  idx.set( sizes[ codim ]++ );
110  }
111  else
112  {
113  for( int i = 0; i < entity.template count< codim >(); ++i )
114  {
115  Index &idx = codimContainer( entity, i );
116  if( idx.index() < 0 )
117  idx.set( sizes[ codim ]++ );
118  }
119  }
120  }
121  };
122 
123  template <class EntityType, int codim>
124  struct EntitySpec
125  {
127  const EntityType & e,
128  int i )
129  {
130  // if the codimension equals that of the entity simply return the index
131  if( codim == EntityType :: codimension )
132  return indexContainer[ e ].index();
133 
134  DUNE_THROW(NotImplemented,"subIndex for entities with codimension > 0 is not implemented");
135  return IndexType(-1);
136  }
137  };
138 
139  template <class EntityType>
140  struct EntitySpec<EntityType,0>
141  {
142  static IndexType subIndex( const PersistentContainerType& indexContainer,
143  const EntityType & e,
144  int i )
145  {
146  assert( indexContainer( e, i ).index() >= 0 );
147  return indexContainer( e, i ).index();
148  }
149  };
150 
151  public:
154  using IndexSet<GridType, DefaultIndexSet>::subIndex;
155 
158  DefaultIndexSet( const GridType & grid ,
159  const IteratorType& begin,
160  const IteratorType& end,
161  const int level = -1 )
162  : grid_(grid),
163  indexContainers_( ncodim, (PersistentContainerType *) 0),
164  size_( ncodim, -1 ),
165  level_(level)
166  {
167  for( int codim=0; codim < ncodim; ++codim )
168  indexContainers_[ codim ] = new PersistentContainerType( grid, codim );
169 
170  calcNewIndex (begin, end);
171  }
172 
175  {
176  for( int codim=0; codim < ncodim; ++codim )
177  delete indexContainers_[ codim ];
178  }
179 
180  const PersistentContainerType& indexContainer( const size_t codim ) const
181  {
182  assert( codim < indexContainers_.size() );
183  assert( indexContainers_[ codim ] );
184  return *( indexContainers_[ codim ] );
185  }
186 
188  {
189  assert( codim < indexContainers_.size() );
190  assert( indexContainers_[ codim ] );
191  return *( indexContainers_[ codim ] );
192  }
193 
195  template<class EntityType>
196  IndexType index (const EntityType & en) const
197  {
198  enum { cd = EntityType :: codimension };
199  // this must not be true for vertices
200  // therefore only check other codims
201 #ifndef NDEBUG
202  const int codim = cd;
203  assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() ));
204  assert( indexContainer( codim )[ en ].index() >= 0 );
205 #endif
206  return indexContainer( cd )[ en ].index();
207  }
208 
210  template<int cd>
211  IndexType index (const typename GridImp::template Codim<cd>::Entity& en) const
212  {
213  // this must not be true for vertices
214  // therefore only check other codims
215 #ifndef NDEBUG
216  const int codim = cd;
217  //const bool isLeaf = (codim == 0) ? en.isLeaf() : true ;
218  assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() ));
219  assert( indexContainer( cd )[ en ].index() >= 0 );
220 #endif
221  return indexContainer( cd )[ en ].index();
222  }
223 
226  template< int cc >
227  IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e,
228  int i, unsigned int codim ) const
229  {
230  assert( (codim != 0) || (level_ < 0) || ( level_ == e.level() ) );
231  typedef typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity Entity;
232  return EntitySpec< Entity, cc > :: subIndex( indexContainer( codim ), e, i );
233  }
234 
236  template<class EntityType>
237  bool contains (const EntityType& en) const
238  {
239  enum { cd = EntityType :: codimension };
240  return (indexContainer( cd )[ en ].index() >= 0 );
241  }
242 
244  IndexType size ( int codim ) const
245  {
246  assert( codim >= 0 && codim <= GridType::dimension );
247  return size_[ codim ];
248  }
249 
252  IndexType size ( GeometryType type ) const
253  {
254  if( typeNotValid(type) ) return 0;
255  return size_[GridType::dimension-type.dim()];
256  }
257 
260  void calcNewIndex ( const IteratorType &begin, const IteratorType &end )
261  {
262  // resize arrays to new size
263  // and set size to zero
264  for( int cd = 0; cd < ncodim; ++cd )
265  {
266  indexContainer( cd ).resize( Index() );
267  indexContainer( cd ).shrinkToFit();
268  indexContainer( cd ).fill( Index() );
269  size_[ cd ] = 0;
270  }
271 
272  // grid walk to setup index set
273  for( IteratorType it = begin; it != end; ++it )
274  {
275  assert( ( level_ < 0 ) ? it->isLeaf() : (it->level() == level_) );
276  ForLoop< InsertEntity, 0, dim >::apply( *it, indexContainers_, size_ );
277  }
278 
279  // remember the number of entity on level and cd = 0
280  for(int cd=0; cd<ncodim; ++cd)
281  {
282 #ifndef NDEBUG
283  const int gridSize = ( level_ < 0 ) ? grid_.size( cd ) : grid_.size( level_, cd);
284  const int mySize = size_[cd];
285  if( mySize > gridSize )
286  {
287  std::cout << "DefaultIndexSet[ " << level_ << " ]: " << mySize << " s | g " << gridSize << std::endl;
288  }
289  // this assertion currently fails for 3d conforming
290  // assert( ( grid_.conformingRefinement() && dim == 3 && level_ >= 0 ) ? true : (mySize <= gridSize) );
291 #endif
292  }
293  }
294 
296  const std::vector<GeometryType>& geomTypes (int codim) const
297  {
298  return grid_.geomTypes( codim );
299  }
300 
302  bool containsIndex ( const int cd, const int idx ) const
303  {
304  assert( (typename PersistentContainerType::Size)idx < indexContainer( cd ).size() );
305  return ((indexContainer( cd ).begin() + idx)->index() >= 0);
306  }
307 
308  private:
309  // return whether set has this type stored or not
310  bool typeNotValid (const GeometryType & type) const
311  {
312  int codim = GridType :: dimension - type.dim();
313  const std::vector<GeometryType> & geomT = geomTypes(codim);
314  for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false;
315  return true;
316  }
317 
318  // grid this index set belongs to
319  const GridType& grid_;
320 
322  PersistentContainerVectorType indexContainers_;
323 
324  // number of entitys of each level an codim
325  std::vector< int > size_;
326 
327  // the level for which this index set is created
328  const int level_;
329 
330  };
331 
332 
333 } // end namespace Dune
334 #endif // #ifndef DUNE_DEFAULTINDEXSETS_HH