dune-spgrid  2.7
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 
10 namespace 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 >
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 &
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 >
191  inline typename SPPartitionPool< dim >::Partition
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
MultiIndex width() const
Definition: mesh.hh:194
This intersect(const This &other) const
Definition: mesh.hh:157
This grow(int size) const
Definition: mesh.hh:135
const MultiIndex & end() const
Definition: mesh.hh:37
const MultiIndex & begin() const
Definition: mesh.hh:36
Definition: partition.hh:79
const unsigned int & neighbor(const int face) const
Definition: partition.hh:250
Definition: partitionpool.hh:18
PartitionList::Mesh Mesh
Definition: partitionpool.hh:29
PartitionList::Partition Partition
Definition: partitionpool.hh:27
const MultiIndex & overlap() const
Definition: partitionpool.hh:42
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 Mesh & globalMesh() const
Definition: partitionpool.hh:41
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