dune-spgrid  2.7
indexset.hh
Go to the documentation of this file.
1 #ifndef DUNE_SPGRID_INDEXSET_HH
2 #define DUNE_SPGRID_INDEXSET_HH
3 
4 #include <array>
5 #include <type_traits>
6 #include <vector>
7 
8 #include <dune/grid/common/indexidset.hh>
9 
12 
13 namespace Dune
14 {
15 
16  template< class Grid >
17  class SPIndexSet
18  : public IndexSet< Grid, SPIndexSet< Grid >, unsigned int, std::array< GeometryType, 1 > >
19  {
20  typedef SPIndexSet< Grid > This;
21  typedef IndexSet< Grid, This, unsigned int, std::array< GeometryType, 1 > > Base;
22 
23  typedef typename std::remove_const< Grid >::type::Traits Traits;
24 
25  public:
26  typedef typename Base::IndexType IndexType;
27  typedef typename Base::Types Types;
28 
29  static const int dimension = Traits::ReferenceCube::dimension;
30 
31  template< int codim >
32  struct Codim
33  {
35  typedef typename Traits::template Codim< codim >::Entity Entity;
36  };
37 
40 
41  private:
42  typedef typename GridLevel::MultiIndex MultiIndex;
43  typedef typename PartitionList::Partition Partition;
44 
45  public:
46  SPIndexSet () = default;
47  explicit SPIndexSet ( const GridLevel &gridLevel ) { update( gridLevel ); }
48 
49  void update ( const GridLevel &gridLevel );
50 
51  private:
52  IndexType index ( const MultiIndex &id, unsigned int number ) const;
53 
54  template< int cd >
55  IndexType subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, cd > ) const;
56  IndexType subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, 0 > ) const;
57  IndexType subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, dimension > ) const;
58 
59  public:
60  template< class Entity >
61  IndexType index ( const Entity &entity ) const;
62 
63  template< int codim >
64  IndexType index ( const typename Codim< codim >::Entity &entity ) const;
65 
66  template< class Entity >
67  IndexType subIndex ( const Entity &entity, int i, unsigned int codim ) const;
68 
69  template< int cd >
70  IndexType subIndex ( const typename Codim< cd >::Entity &entity, int i, unsigned int codim ) const;
71 
72  Types types ( int codim ) const { return {{ GeometryTypes::cube( dimension - codim ) }}; }
73 
74  IndexType size ( const GeometryType &type ) const;
75  IndexType size ( const int codim ) const;
76 
77  template< class Entity >
78  bool contains ( const Entity &entity ) const;
79 
80  template< int codim >
81  bool contains ( const typename Codim< codim >::Entity &entity ) const;
82 
83  const GridLevel &gridLevel () const { return *gridLevel_; }
84 
85  const PartitionList &partitions () const { assert( partitions_ ); return *partitions_; }
86 
87  private:
88  const GridLevel *gridLevel_ = nullptr;
89  const PartitionList *partitions_ = nullptr;
90  std::vector< std::array< IndexType, 1 << dimension > > offsets_;
91  IndexType size_[ dimension+1 ];
92  };
93 
94 
95 
96  // Implementation of SPIndexSet
97  // ----------------------------
98 
99  template< class Grid >
100  void SPIndexSet< Grid >::update ( const GridLevel &gridLevel )
101  {
102  gridLevel_ = &gridLevel;
103  partitions_ = &gridLevel.template partition< All_Partition >();
104 
105  for( int codim = 0; codim <= dimension; ++codim )
106  size_[ codim ] = 0;
107 
108  offsets_.resize( partitions().maxNumber() - partitions().minNumber() + 1 );
109  for( typename PartitionList::Iterator pit = partitions().begin(); pit; ++pit )
110  {
111  for( unsigned int dir = 0; dir < (1 << dimension); ++dir )
112  {
113  IndexType factor = 1;
114  unsigned int codim = dimension;
115  for( int j = 0; j < dimension; ++j )
116  {
117  const unsigned int d = (dir >> j) & 1;
118  const int w = pit->bound( 1, j, d ) - pit->bound( 0, j, d );
119  assert( w % 2 == 0 );
120  factor *= (w / 2 + 1);
121  codim -= d;
122  }
123  offsets_[ pit->number() - partitions().minNumber() ][ dir ] = size_[ codim ];
124  size_[ codim ] += factor;
125  }
126  }
127  }
128 
129 
130  template< class Grid >
131  inline typename SPIndexSet< Grid >::IndexType
132  SPIndexSet< Grid >::index ( const MultiIndex &id, unsigned int number ) const
133  {
134  const Partition &partition = partitions().partition( number );
135 
136  IndexType index = 0;
137  IndexType factor = 1;
138  unsigned int dir = 0;
139  for( int j = 0; j < dimension; ++j )
140  {
141  const unsigned int d = id[ j ] & 1;
142  dir |= (d << j);
143 
144  const int begin = partition.bound( 0, j, d );
145  const int end = partition.bound( 1, j, d );
146 
147  const IndexType idLocal = (id[ j ] - begin) >> 1;
148  const IndexType width = ((end - begin) >> 1) + 1;
149  assert( (idLocal >= 0) && (idLocal < width) );
150  index += idLocal * factor;
151 
152  factor *= width;
153  }
154  return offsets_[ number - partitions().minNumber() ][ dir ] + index;
155  }
156 
157 
158  template< class Grid >
159  template< int cd >
160  inline typename SPIndexSet< Grid >::IndexType
161  SPIndexSet< Grid >
162  ::subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, cd > ) const
163  {
164  const int mydim = dimension - cd;
165  const SPMultiIndex< mydim > refId = gridLevel().template referenceCube< cd >().subId( codim - cd, i );
166  MultiIndex subId( id );
167  for( int k = 0, l = 0; k < dimension; ++k )
168  {
169  if( (id[ k ] & 1) != 0 )
170  subId[ k ] += refId[ l++ ];
171  }
172  return index( subId, number );
173  }
174 
175  template< class Grid >
176  inline typename SPIndexSet< Grid >::IndexType
177  SPIndexSet< Grid >
178  ::subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, 0 > ) const
179  {
180  return index( id + gridLevel().referenceCube().subId( codim, i ), number );
181  }
182 
183  template< class Grid >
184  inline typename SPIndexSet< Grid >::IndexType
185  SPIndexSet< Grid >
186  ::subIndex ( const MultiIndex &id, int i, int codim, unsigned int number, std::integral_constant< int, dimension > ) const
187  {
188  assert( (codim == dimension) && (i == 0) );
189  return index( id, number );
190  }
191 
192 
193  template< class Grid >
194  template< class Entity >
195  inline typename SPIndexSet< Grid >::IndexType
196  SPIndexSet< Grid >::index ( const Entity &entity ) const
197  {
198  return index< Entity::codimension >( entity );
199  }
200 
201 
202  template< class Grid >
203  template< int codim >
204  inline typename SPIndexSet< Grid >::IndexType
205  SPIndexSet< Grid >::index ( const typename Codim< codim >::Entity &entity ) const
206  {
207  assert( contains( entity ) );
208  const typename Codim< codim >::EntityInfo &entityInfo
209  = entity.impl().entityInfo();
210  return index( entityInfo.id(), entityInfo.partitionNumber() );
211  }
212 
213 
214  template< class Grid >
215  template< class Entity >
216  inline typename SPIndexSet< Grid >::IndexType
217  SPIndexSet< Grid >::subIndex ( const Entity &entity, int i, unsigned int codim ) const
218  {
219  return subIndex< Entity::codimension >( entity, i, codim );
220  }
221 
222 
223  template< class Grid >
224  template< int cd >
225  inline typename SPIndexSet< Grid >::IndexType
227  ::subIndex ( const typename Codim< cd >::Entity &entity, int i, unsigned int codim ) const
228  {
229  assert( contains( entity ) );
230  const typename Codim< cd >::EntityInfo &entityInfo
231  = entity.impl().entityInfo();
232  // for the ghost approach, the partition number has to be corrected
233  return subIndex( entityInfo.id(), i, codim, entityInfo.partitionNumber(), std::integral_constant< int, cd >() );
234  }
235 
236 
237  template< class Grid >
238  inline typename SPIndexSet< Grid >::IndexType
239  SPIndexSet< Grid >::size ( const GeometryType &type ) const
240  {
241  return (type.isCube() ? size( dimension - type.dim() ) : 0);
242  }
243 
244 
245  template< class Grid >
246  inline typename SPIndexSet< Grid >::IndexType
247  SPIndexSet< Grid >::size ( const int codim ) const
248  {
249  assert( (codim >= 0) && (codim <= dimension) );
250  return size_[ codim ];
251  }
252 
253 
254  template< class Grid >
255  template< class Entity >
256  inline bool SPIndexSet< Grid >::contains ( const Entity &entity ) const
257  {
258  return contains< Entity::codimension >( entity );
259  }
260 
261 
262  template< class Grid >
263  template< int codim >
264  inline bool SPIndexSet< Grid >
265  ::contains ( const typename Codim< codim >::Entity &entity ) const
266  {
267  const typename Codim< codim >::EntityInfo &entityInfo
268  = entity.impl().entityInfo();
269  assert( partitions().contains( entityInfo.partitionNumber() ) );
270  return (&entityInfo.gridLevel() == &gridLevel());
271  }
272 
273 } // namespace Dune
274 
275 #endif // #ifndef DUNE_SPGRID_INDEXSET_HH
Definition: iostream.hh:7
Definition: entityinfo.hh:24
const GridLevel & gridLevel() const
Definition: entityinfo.hh:66
const MultiIndex & id() const
Definition: entityinfo.hh:68
unsigned int partitionNumber() const
Definition: entityinfo.hh:73
Definition: gridlevel.hh:35
PartitionPool::PartitionList PartitionList
Definition: gridlevel.hh:64
Definition: indexset.hh:19
Base::Types Types
Definition: indexset.hh:27
SPIndexSet()=default
static const int dimension
Definition: indexset.hh:29
bool contains(const Entity &entity) const
Definition: indexset.hh:256
Types types(int codim) const
Definition: indexset.hh:72
const PartitionList & partitions() const
Definition: indexset.hh:85
Base::IndexType IndexType
Definition: indexset.hh:26
SPGridLevel< typename std::remove_const< Grid >::type > GridLevel
Definition: indexset.hh:38
GridLevel::PartitionList PartitionList
Definition: indexset.hh:39
IndexType size(const GeometryType &type) const
Definition: indexset.hh:239
const GridLevel & gridLevel() const
Definition: indexset.hh:83
SPIndexSet(const GridLevel &gridLevel)
Definition: indexset.hh:47
void update(const GridLevel &gridLevel)
Definition: indexset.hh:100
Definition: indexset.hh:33
__SPGrid::EntityInfo< Grid, codim > EntityInfo
Definition: indexset.hh:34
Traits::template Codim< codim >::Entity Entity
Definition: indexset.hh:35
Definition: partition.hh:79
Definition: partitionlist.hh:124