Dune Core Modules (2.9.0)

partitionpool.hh
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
7#include <dune/grid/spgrid/cachedpartitionlist.hh>
9
10namespace Dune
11{
12
13 // SPPartitionPool
14 // ---------------
15
16 template< int dim >
17 class SPPartitionPool
18 {
19 typedef SPPartitionPool< dim > This;
20
21 public:
22 static const int dimension = dim;
23
24 typedef SPCachedPartitionList< dimension > PartitionList;
25 typedef SPTopology< dimension > Topology;
26
27 typedef typename PartitionList::Partition Partition;
28 typedef typename PartitionList::MultiIndex MultiIndex;
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 >
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 {
121 MultiIndex s = MultiIndex::zero();
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 &
146 SPPartitionPool< dim >::get () const
147 {
148 switch( pitype )
149 {
151 return interiorList_;
152
154 return interiorBorderList_;
155
157 return overlapList_;
158
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
177 SPPartitionPool< dim >
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 >
191 inline typename SPPartitionPool< dim >::Partition
192 SPPartitionPool< 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
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
PartitionType
Attributes used in the generic overlap model.
Definition: gridenums.hh:30
@ All_Partition
all entities
Definition: gridenums.hh:141
@ OverlapFront_Partition
interior, border, overlap and front entities
Definition: gridenums.hh:140
@ Interior_Partition
only interior entities
Definition: gridenums.hh:137
@ InteriorBorder_Partition
interior and border entities
Definition: gridenums.hh:138
@ Overlap_Partition
interior, border, and overlap entities
Definition: gridenums.hh:139
@ Ghost_Partition
only ghost entities
Definition: gridenums.hh:142
@ FrontEntity
on boundary between overlap and ghost
Definition: gridenums.hh:34
@ InteriorEntity
all interior entities
Definition: gridenums.hh:31
@ GhostEntity
ghost entities
Definition: gridenums.hh:35
@ BorderEntity
on boundary between interior and overlap
Definition: gridenums.hh:32
@ OverlapEntity
all entities lying in the overlap zone
Definition: gridenums.hh:33
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)