dune-spgrid 2.8.0
Loading...
Searching...
No Matches
partitionpool.hh
Go to the documentation of this file.
1#ifndef DUNE_SPGRID_PARTITIONPOOL_HH
2#define DUNE_SPGRID_PARTITIONPOOL_HH
3
4#include <dune/grid/common/gridenums.hh>
5#include <dune/grid/common/exceptions.hh>
6
9
10namespace Dune
11{
12
13 // SPPartitionPool
14 // ---------------
15
16 template< int dim >
18 {
20
21 public:
22 static const int dimension = dim;
23
26
29 typedef typename PartitionList::Mesh Mesh;
30
31 SPPartitionPool ( const Mesh &localMesh, const Mesh &globalMesh,
32 const MultiIndex &overlap, const Topology &topology );
33
34 template< PartitionIteratorType pitype >
35 const PartitionList &get () const;
36
37 template< int codim >
38 PartitionType
39 partitionType ( const MultiIndex &id, const unsigned int number ) const;
40
41 const Mesh &globalMesh () const { return globalMesh_; }
42 const MultiIndex &overlap () const { return overlap_; }
43 const Topology &topology () const { return topology_; }
44
45 private:
46 Partition makePartition ( const Mesh &localMesh, const unsigned int number,
47 const unsigned int open ) const;
48
49 Mesh globalMesh_;
50 MultiIndex overlap_;
51 Topology topology_;
52
53 PartitionList interiorList_;
54 PartitionList interiorBorderList_;
55 PartitionList overlapList_;
56 PartitionList overlapFrontList_;
57 PartitionList allList_;
58 PartitionList ghostList_;
59 };
60
61
62
63 // Implementation of SPPartitionPool
64 // ---------------------------------
65
66 template< int dim >
67 inline SPPartitionPool< dim >
68 ::SPPartitionPool ( const Mesh &localMesh, const Mesh &globalMesh,
69 const MultiIndex &overlap, const Topology &topology )
70 : globalMesh_( globalMesh ),
71 overlap_( overlap ),
72 topology_( topology )
73 {
74 // generate Interior and InteriorBorder
75 interiorList_ += makePartition( localMesh, 0, (1 << dimension) - 1 );
76 interiorBorderList_ += makePartition( localMesh, 0, 0 );
77 interiorList_.updateCache();
78 interiorBorderList_.updateCache();
79
80 // detect which directions have to be split in the overlap partition
81 const MultiIndex globalWidth = globalMesh.width();
82 Mesh overlapMesh = localMesh.grow( overlap );
83 const MultiIndex overlapWidth = overlapMesh.width();
84 int n = 0;
85 int shift[ dimension ];
86 int dir[ dimension ];
87 unsigned int openOverlap = 0;
88
89 // initialize shift
90 for( int i = 0; i < dimension; ++i )
91 shift[ i ] = 0;
92
93 for( int i = 0; i < dimension; ++i )
94 {
95 openOverlap |= (overlap[ i ] > 0 ? (1 << i) : 0);
96 if( !topology.hasNeighbor( 0, 2*i ) )
97 continue;
98
99 if( overlapWidth[ i ] >= globalWidth[ i ] )
100 {
101 MultiIndex begin = overlapMesh.begin();
102 MultiIndex end = overlapMesh.end();
103 begin[ i ] = globalMesh.begin()[ i ];
104 end[ i ] = globalMesh.end()[ i ];
105 overlapMesh = Mesh( begin, end );
106 continue;
107 }
108
109 if( overlapMesh.begin()[ i ] < globalMesh.begin()[ i ] )
110 shift[ n ] += globalWidth[ i ];
111 if( overlapMesh.end()[ i ] > globalMesh.end()[ i ] )
112 shift[ n ] -= globalWidth[ i ];
113 if( shift[ n ] != 0 )
114 dir[ n++ ] = i;
115 }
116
117 // generate Overlap and OverlapFront
118 const unsigned int size = 1 << n;
119 for( unsigned int d = 0; d < size; ++d )
120 {
122 for( int i = 0; i < n; ++i )
123 s[ dir[ i ] ] = ((d >> i)&1)*shift[ i ];
124 Partition open = makePartition( globalMesh.intersect( overlapMesh + s ), d, openOverlap );
125 Partition closed = makePartition( globalMesh.intersect( overlapMesh + s ), d, 0 );
126 for( int i = 0; i < n; ++i )
127 {
128 const int j = (shift[ i ] < 0) ^ ((d >> i)&1);
129 open.neighbor( 2*dir[ i ] + j ) = d ^ (1 << i);
130 closed.neighbor( 2*dir[ i ] + j ) = d ^ (1 << i);
131 }
132 overlapList_ += open;
133 overlapFrontList_ += closed;
134 }
135 overlapList_.updateCache();
136 overlapFrontList_.updateCache();
137
138 // generate All
139 allList_ = overlapFrontList_;
140 }
141
142
143 template< int dim >
144 template< PartitionIteratorType pitype >
145 inline const typename SPPartitionPool< dim >::PartitionList &
147 {
148 switch( pitype )
149 {
150 case Interior_Partition:
151 return interiorList_;
152
153 case InteriorBorder_Partition:
154 return interiorBorderList_;
155
156 case Overlap_Partition:
157 return overlapList_;
158
159 case OverlapFront_Partition:
160 return overlapFrontList_;
161
162 case All_Partition:
163 return allList_;
164
165 case Ghost_Partition:
166 return ghostList_;
167
168 default:
169 DUNE_THROW( GridError, "No such PartitionIteratorType." );
170 }
171 }
172
173
174 template< int dim >
175 template< int codim >
176 inline PartitionType
178 ::partitionType ( const MultiIndex &id, const unsigned int number ) const
179 {
180 assert( allList_.contains( id, number ) );
181 if( interiorBorderList_.contains( id, number ) )
182 return ((codim == 0) || interiorList_.contains( id, number )) ? InteriorEntity : BorderEntity;
183 else if( overlapFrontList_.contains( id, number ) )
184 return ((codim == 0) || overlapList_.contains( id, number )) ? OverlapEntity : FrontEntity;
185 else
186 return GhostEntity;
187 }
188
189
190 template< int dim >
193 ::makePartition ( const Mesh &localMesh, const unsigned int number,
194 const unsigned int open ) const
195 {
196 const MultiIndex &lbegin = localMesh.begin();
197 const MultiIndex &lend = localMesh.end();
198 const MultiIndex &gbegin = globalMesh().begin();
199 const MultiIndex &gend = globalMesh().end();
200
201 // create partition
202 MultiIndex begin, end;
203 for( int i = 0; i < dimension; ++i )
204 {
205 const int o = ((open >> i) & 1);
206 begin[ i ] = 2*lbegin[ i ] + o*int( lbegin[ i ] != gbegin[ i ] );
207 end[ i ] = 2*lend[ i ] - o*int( lend[ i ] != gend[ i ] );
208 }
209 Partition partition( begin, end, globalMesh(), number );
210
211 // deal with self-neighborship (periodicity)
212 for( int i = 0; i < dimension; ++i )
213 {
214 if( !topology().hasNeighbor( 0, 2*i ) )
215 continue;
216 if( (lbegin[ i ] == gbegin[ i ]) && (lend[ i ] == gend[ i ]) )
217 partition.neighbor( 2*i ) = partition.neighbor( 2*i+1 ) = number;
218 }
219
220 return partition;
221 }
222
223} // namespace Dune
224
225#endif // #ifndef DUNE_SPGRID_PARTITIONPOOL_HH
topology of a Cartesian grid
Definition: iostream.hh:7
void updateCache()
Definition: cachedpartitionlist.hh:116
MultiIndex width() const
Definition: mesh.hh:194
This intersect(const This &other) const
Definition: mesh.hh:157
const MultiIndex & begin() const
Definition: mesh.hh:36
This grow(int size) const
Definition: mesh.hh:135
const MultiIndex & end() const
Definition: mesh.hh:37
static This zero()
obtain the zero multiindex
Definition: multiindex.hh:196
Definition: partition.hh:79
const unsigned int & neighbor(const int face) const
Definition: partition.hh:250
Definition: partitionpool.hh:18
const Mesh & globalMesh() const
Definition: partitionpool.hh:41
PartitionList::Mesh Mesh
Definition: partitionpool.hh:29
PartitionList::Partition Partition
Definition: partitionpool.hh:27
const PartitionList & get() const
Definition: partitionpool.hh:146
PartitionList::MultiIndex MultiIndex
Definition: partitionpool.hh:28
static const int dimension
Definition: partitionpool.hh:22
SPCachedPartitionList< dimension > PartitionList
Definition: partitionpool.hh:24
const MultiIndex & overlap() const
Definition: partitionpool.hh:42
PartitionType partitionType(const MultiIndex &id, const unsigned int number) const
Definition: partitionpool.hh:178
SPPartitionPool(const Mesh &localMesh, const Mesh &globalMesh, const MultiIndex &overlap, const Topology &topology)
Definition: partitionpool.hh:68
SPTopology< dimension > Topology
Definition: partitionpool.hh:25
const Topology & topology() const
Definition: partitionpool.hh:43
bool hasNeighbor(const unsigned int node, const int face) const
check whether a node has a neighbor over a face
Definition: topology.hh:154