AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
UniqueBorderPartition.hpp
1 #pragma once
2 
3 #include <cassert>
4 #include <set>
5 
6 #include <dune/common/unused.hh>
7 #include <dune/common/version.hh>
8 #include <dune/grid/common/datahandleif.hh>
9 
10 namespace Dune
11 {
12  // forward declaration
13  template <int dim> class UGGrid;
14 }
15 
16 namespace AMDiS
17 {
19 
27  template <class Grid>
29  : public Dune::CommDataHandleIF<UniqueBorderPartition<Grid>, int>
30  {
31  using IdSet = typename Grid::GlobalIdSet;
32  using IdType = typename IdSet::IdType;
33 
34  public:
35  using EntitySet = std::set<IdType>;
36 
37  public:
40 
48  UniqueBorderPartition(int rank, Grid const& grid)
49  : myrank_(rank)
50  , idSet_(grid.globalIdSet())
51  {}
52 
53  // Communicate all entities
54  bool contains(int /*dim*/, int /*codim*/) const { return true; }
55 
56  // communicate exactly one integer, the rank
57  bool fixedSize(int /*dim*/, int /*codim*/) const { return true; }
58 
59  // Always contains one int, the rank
60  template <class Entity>
61  std::size_t size(Entity const& e) const { return 1; }
62 
63  template <class MessageBuffer, class Entity>
64  void gather(MessageBuffer& buff, Entity const& e) const
65  {
66  buff.write(myrank_);
67  }
68 
69  template <class MessageBuffer, class Entity>
70  void scatter(MessageBuffer& buff, Entity const& e, std::size_t n)
71  {
72  scatterImpl(buff, e, n, int_t<Entity::codimension>{});
73  }
74 
76  bool contains(IdType const& id) const
77  {
78  return notOwner_.count(id) == 0;
79  }
80 
82  int numIterations() const
83  {
84  return 1;
85  }
86 
87  private:
88 
89  template <class MessageBuffer, class Entity, int cd>
90  void scatterImpl(MessageBuffer& buff, Entity const& e, [[maybe_unused]] std::size_t n, int_t<cd>)
91  {
92  assert(n == 1);
93 
94  int rank = 0;
95  buff.read(rank);
96 
97  // insert only border entities that are owned by other processors, i.e. rank > myrank
98  // Those entities are not owned by this rank.
99  if (rank > myrank_)
100  notOwner_.insert(idSet_.id(e));
101  }
102 
103  template <class MessageBuffer, class Entity>
104  void scatterImpl(MessageBuffer& buff, Entity const& e, [[maybe_unused]] std::size_t n, int_t<0>)
105  {
106  assert(n == 1);
107 
108  int rank = 0;
109  buff.read(rank);
110 
111  // insert only border entities that are owned by other processors, i.e. rank > myrank
112  // Those entities are not owned by this rank.
113  if (rank > myrank_) {
114  for (int codim = 1; codim <= Grid::dimension; ++codim) {
115  for (int i = 0; i < int(e.subEntities(codim)); ++i) {
116  notOwner_.insert(idSet_.subId(e, i, codim));
117  }
118  }
119  }
120  }
121 
122  private:
123  int myrank_;
124  EntitySet notOwner_;
125  IdSet const& idSet_;
126  };
127 
128 
130  template <int dim>
131  class UniqueBorderPartition<Dune::UGGrid<dim>>
132  : public Dune::CommDataHandleIF<UniqueBorderPartition<Dune::UGGrid<dim>>, int>
133  {
134  using Grid = Dune::UGGrid<dim>;
135  using IdSet = typename Grid::LocalIdSet;
136  using IdType = typename IdSet::IdType;
137 
138  public:
139  using EntitySet = std::set<IdType>;
140 
141  public:
144 
152  UniqueBorderPartition(int rank, Grid const& grid)
153  : myrank_(rank)
154  , idSet_(grid.localIdSet())
155  {}
156 
157  // Communicate all entities
158  bool contains(int /*dim*/, int codim) const { return true; }
159 
160  // see size()
161  bool fixedSize(int /*dim*/, int codim) const { return codim != 0; }
162 
163  // for codim=0 elements communicate data for all subEntities, otherwise communicate just the owner rank
164  template <class Entity>
165  std::size_t size(Entity const& e) const
166  {
167  if (Entity::codimension != 0)
168  return 1;
169 
170  std::size_t s = 0;
171  for (int codim = 1; codim <= Grid::dimension; ++codim)
172  s += e.subEntities(codim);
173  return s;
174  }
175 
176  template <class MessageBuffer, class Entity>
177  void gather(MessageBuffer& buff, Entity const& e) const
178  {
179  gatherImpl(buff, e, int_t<Entity::codimension>{});
180  }
181 
182  template <class MessageBuffer, class Entity>
183  void scatter(MessageBuffer& buff, Entity const& e, std::size_t n)
184  {
185  scatterImpl(buff, e, n, int_t<Entity::codimension>{});
186  }
187 
189  bool contains(IdType const& id) const
190  {
191  return entityToRank_[id] == myrank_;
192  }
193 
195  int numIterations() const
196  {
197  return Grid::dimension;
198  }
199 
200  private:
201  template <class MessageBuffer, class Entity, int cd>
202  void gatherImpl(MessageBuffer& buff, Entity const& e, int_t<cd>) const
203  {
204  int& rank = entityToRank_[idSet_.id(e)];
205  rank = std::max(rank, myrank_);
206  buff.write(rank);
207  }
208 
209  template <class MessageBuffer, class Entity>
210  void gatherImpl(MessageBuffer& buff, Entity const& e, int_t<0>) const
211  {
212  // maybe use global unique numbering (?)
213  for (int codim = 1; codim <= Grid::dimension; ++codim) {
214  for (int i = 0; i < int(e.subEntities(codim)); ++i) {
215  int& rank = entityToRank_[idSet_.subId(e, i, codim)];
216  rank = std::max(rank, myrank_);
217  buff.write(rank);
218  }
219  }
220  }
221 
222  template <class MessageBuffer, class Entity, int cd>
223  void scatterImpl(MessageBuffer& buff, Entity const& e, [[maybe_unused]] std::size_t n, int_t<cd>)
224  {
225  assert(n == 1);
226 
227  int rank = 0;
228  buff.read(rank);
229 
230  int& storedRank = entityToRank_[idSet_.id(e)];
231  storedRank = std::max(rank, storedRank);
232  }
233 
234  template <class MessageBuffer, class Entity>
235  void scatterImpl(MessageBuffer& buff, Entity const& e, std::size_t n, int_t<0>)
236  {
237  std::size_t j = 0;
238  for (int codim = 1; codim <= Grid::dimension; ++codim) {
239  for (int i = 0; i < int(e.subEntities(codim)); ++i, ++j) {
240  assert(j < n);
241  int rank = 0;
242  buff.read(rank);
243 
244  int& storedRank = entityToRank_[idSet_.subId(e, i, codim)];
245  storedRank = std::max(rank, storedRank);
246  }
247  }
248  }
249 
250  private:
251  int myrank_;
252  mutable std::map<IdType, int> entityToRank_;
253  IdSet const& idSet_;
254  };
255 
256 } // end namespace AMDiS
Definition: AdaptiveGrid.hpp:373
Definition: AdaptBase.hpp:6
int numIterations() const
Number of iterations to perform the communication in order to collect all neighboring entities...
Definition: UniqueBorderPartition.hpp:82
UniqueBorderPartition(int rank, Grid const &grid)
Construct a UniqueBorderPartition DataHandle to be used in a GridView communicator.
Definition: UniqueBorderPartition.hpp:48
bool contains(IdType const &id) const
Returns whether id is owned by this rank.
Definition: UniqueBorderPartition.hpp:76
Determine for each border entity which processor owns it.
Definition: UniqueBorderPartition.hpp:28