1#ifndef DUNE_SPGRID_SUPERENTITYITERATOR_HH
2#define DUNE_SPGRID_SUPERENTITYITERATOR_HH
8#include <dune/grid/spgrid/direction.hh>
9#include <dune/grid/spgrid/entity.hh>
10#include <dune/grid/spgrid/referencecube.hh>
18 template<
class Gr
id >
19 class SPSuperEntityIterator
21 typedef SPSuperEntityIterator< Grid > This;
24 typedef typename std::remove_const< Grid >::type::Traits Traits;
26 static const int dimension = Traits::ReferenceCube::dimension;
27 static const int codimension = 0;
28 static const int mydimension = dimension - codimension;
30 typedef typename Traits::template Codim< codimension >::Entity Entity;
33 typedef SPEntity< codimension, dimension, Grid > EntityImpl;
36 typedef typename EntityImpl::EntityInfo EntityInfo;
37 typedef typename EntityImpl::GridLevel GridLevel;
43 typedef typename EntityInfo::MultiIndex MultiIndex;
50 unsigned int fBoundary;
53 struct SequenceProvider;
56 SPSuperEntityIterator () =
default;
58 template<
class SubInfo,
class BeginEnd >
59 SPSuperEntityIterator (
const SubInfo &subInfo,
const BeginEnd &be )
60 : entityInfo_( subInfo.gridLevel() ),
63 sequence_ = SequenceProvider::sequence( subInfo.direction().bits(), be );
65 MultiIndex &
id = entityInfo().id();
68 const typename GridLevel::Mesh &globalMesh = entityInfo().gridLevel().globalMesh();
69 for(
int i = 0; i < dimension; ++i )
71 const bool bndLow = (
id[ i ] == 2*globalMesh.begin()[ i ]);
72 const bool bndHigh = (
id[ i ] == 2*globalMesh.end()[ i ]);
73 fBoundary_ |= (int( bndLow ) | 2*int( bndHigh )) << (2*i);
77 entityInfo().update( subInfo.partitionNumber() );
80 SPSuperEntityIterator (
const This & ) =
default;
81 SPSuperEntityIterator ( This && ) =
default;
83 This &operator= (
const This & ) =
default;
84 This &operator= ( This && ) =
default;
86 Entity operator* ()
const {
return dereference(); }
91 Entity dereference ()
const {
return EntityImpl( entityInfo() ); }
93 bool equals (
const This &other )
const {
return entityInfo().equals( other.entityInfo() ); }
97 if( next( entityInfo().
id() ) )
98 entityInfo().update();
101 int index ()
const {
return index_; }
103 const EntityInfo &entityInfo ()
const {
return entityInfo_; }
104 EntityInfo &entityInfo () {
return entityInfo_; }
106 const GridLevel &gridLevel ()
const {
return entityInfo().gridLevel(); }
109 bool next ( MultiIndex &
id )
113 assert( sequence_ != 0 );
114 id += sequence_->idAdd;
115 index_ = sequence_->index;
116 skip = ((fBoundary_ & sequence_->fBoundary) != 0);
117 sequence_ = sequence_->next;
119 return (sequence_ != 0);
122 EntityInfo entityInfo_;
123 const Sequence *sequence_;
125 unsigned int fBoundary_;
133 template<
class Gr
id >
134 struct SPSuperEntityIterator< Grid >::SequenceProvider
136 static const unsigned int numDirections = 1 << dimension;
138 static const Sequence *
139 sequence (
const unsigned int direction,
const Begin &b )
141 assert( direction < numDirections );
142 return instance().begin_[ direction ];
145 static const Sequence *
146 sequence (
const unsigned int direction,
const End &e )
148 assert( direction < numDirections );
149 return instance().end_[ direction ];
154 ~SequenceProvider ();
156 static const SequenceProvider &instance ()
158 static SequenceProvider instance;
162 const Sequence *begin_[ numDirections ];
163 const Sequence *end_[ numDirections ];
168 template<
class Gr
id >
169 SPSuperEntityIterator< Grid >::SequenceProvider::SequenceProvider ()
171 SPReferenceCube< typename Grid::ctype, dimension > refCube;
173 for(
unsigned int dir = 0; dir < numDirections; ++dir )
175 const int codim = SPDirection< dimension >( dir ).codimension();
177 Sequence *head =
new Sequence;
179 Sequence *last = head;
181 for(
unsigned int d = 0; d < numDirections; ++d )
186 Sequence *next =
new Sequence;
188 for(
int i = 0; i < dimension; ++i )
190 const int dirbit = int( (dir >> i) & 1);
191 const int dbit = int( (d >> i) & 1 );
192 next->idAdd[ i ] = (1 - dirbit) * (2*dbit - 1);
193 next->fBoundary |= (1 - dirbit) * (1 << (2*i + dbit));
196 for(
int k = 0; k < refCube.count( codim ); ++k )
198 const MultiIndex &subId = refCube.subId( codim, k );
200 for(
int i = 0; i < dimension; ++i )
201 found &= (next->idAdd[ i ] == -subId[ i ]);
205 assert( next->index != -1 );
206 next->idAdd -= head->idAdd;
207 head->idAdd += next->idAdd;
212 begin_[ dir ] = head->next;
214 Sequence *end =
new Sequence;
218 for(
int i = 0; i < dimension; ++i )
219 end->idAdd[ i ] = 3 * (1 -
int( (dir >> i) & 1 ));
223 head->index = end->index;
224 head->fBoundary = end->fBoundary;
225 head->idAdd -= end->idAdd;
232 template<
class Gr
id >
233 SPSuperEntityIterator< Grid >::SequenceProvider::~SequenceProvider ()
235 for(
unsigned int dir = 0; dir < (1 << dimension); ++dir )
238 while( begin_[ dir ] != 0 )
240 const Sequence *tmp = begin_[ dir ];
241 begin_[ dir ] = begin_[ dir ]->next;
interface classes for superentity iterators
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:402
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:237
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
Dune namespace.
Definition: alignedallocator.hh:13