1#ifndef DUNE_SPGRID_PARTITIONPOOL_HH
2#define DUNE_SPGRID_PARTITIONPOOL_HH
4#include <dune/grid/common/gridenums.hh>
5#include <dune/grid/common/exceptions.hh>
7#include <dune/grid/spgrid/cachedpartitionlist.hh>
19 typedef SPPartitionPool< dim > This;
22 static const int dimension = dim;
24 typedef SPCachedPartitionList< dimension > PartitionList;
27 typedef typename PartitionList::Partition Partition;
28 typedef typename PartitionList::MultiIndex MultiIndex;
29 typedef typename PartitionList::Mesh Mesh;
31 SPPartitionPool (
const Mesh &localMesh,
const Mesh &globalMesh,
32 const MultiIndex &overlap,
const Topology &topology );
34 template< PartitionIteratorType pitype >
35 const PartitionList &get ()
const;
39 partitionType (
const MultiIndex &
id,
const unsigned int number )
const;
41 const Mesh &globalMesh ()
const {
return globalMesh_; }
42 const MultiIndex &overlap ()
const {
return overlap_; }
43 const Topology &topology ()
const {
return topology_; }
46 Partition makePartition (
const Mesh &localMesh,
const unsigned int number,
47 const unsigned int open )
const;
53 PartitionList interiorList_;
54 PartitionList interiorBorderList_;
55 PartitionList overlapList_;
56 PartitionList overlapFrontList_;
57 PartitionList allList_;
58 PartitionList ghostList_;
67 inline SPPartitionPool< dim >
68 ::SPPartitionPool (
const Mesh &localMesh,
const Mesh &globalMesh,
69 const MultiIndex &overlap,
const Topology &topology )
70 : globalMesh_( globalMesh ),
75 interiorList_ += makePartition( localMesh, 0, (1 << dimension) - 1 );
76 interiorBorderList_ += makePartition( localMesh, 0, 0 );
77 interiorList_.updateCache();
78 interiorBorderList_.updateCache();
81 const MultiIndex globalWidth = globalMesh.width();
82 Mesh overlapMesh = localMesh.grow( overlap );
83 const MultiIndex overlapWidth = overlapMesh.width();
85 int shift[ dimension ];
87 unsigned int openOverlap = 0;
90 for(
int i = 0; i < dimension; ++i )
93 for(
int i = 0; i < dimension; ++i )
95 openOverlap |= (overlap[ i ] > 0 ? (1 << i) : 0);
96 if( !topology.hasNeighbor( 0, 2*i ) )
99 if( overlapWidth[ i ] >= globalWidth[ i ] )
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 );
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 )
118 const unsigned int size = 1 << n;
119 for(
unsigned int d = 0; d < size; ++d )
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 )
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);
132 overlapList_ += open;
133 overlapFrontList_ += closed;
135 overlapList_.updateCache();
136 overlapFrontList_.updateCache();
139 allList_ = overlapFrontList_;
144 template< PartitionIteratorType pitype >
145 inline const typename SPPartitionPool< dim >::PartitionList &
146 SPPartitionPool< dim >::get ()
const
151 return interiorList_;
154 return interiorBorderList_;
160 return overlapFrontList_;
169 DUNE_THROW( GridError,
"No such PartitionIteratorType." );
175 template<
int codim >
177 SPPartitionPool< dim >
178 ::partitionType (
const MultiIndex &
id,
const unsigned int number )
const
180 assert( allList_.contains(
id, number ) );
181 if( interiorBorderList_.contains(
id, number ) )
183 else if( overlapFrontList_.contains(
id, number ) )
191 inline typename SPPartitionPool< dim >::Partition
192 SPPartitionPool< dim >
193 ::makePartition (
const Mesh &localMesh,
const unsigned int number,
194 const unsigned int open )
const
196 const MultiIndex &lbegin = localMesh.begin();
197 const MultiIndex &lend = localMesh.end();
198 const MultiIndex &gbegin = globalMesh().begin();
199 const MultiIndex &gend = globalMesh().end();
202 MultiIndex begin, end;
203 for(
int i = 0; i < dimension; ++i )
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 ] );
209 Partition partition( begin, end, globalMesh(), number );
212 for(
int i = 0; i < dimension; ++i )
214 if( !topology().hasNeighbor( 0, 2*i ) )
216 if( (lbegin[ i ] == gbegin[ i ]) && (lend[ i ] == gend[ i ]) )
217 partition.neighbor( 2*i ) = partition.neighbor( 2*i+1 ) = number;
topology of a Cartesian grid
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13