AMDiS  0.1
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 
129 #if DUNE_VERSION_LT(DUNE_UGGRID,2,8)
130  template <int dim>
132  class UniqueBorderPartition<Dune::UGGrid<dim>>
133  : public Dune::CommDataHandleIF<UniqueBorderPartition<Dune::UGGrid<dim>>, int>
134  {
135  using Grid = Dune::UGGrid<dim>;
136  using IdSet = typename Grid::LocalIdSet;
137  using IdType = typename IdSet::IdType;
138 
139  public:
140  using EntitySet = std::set<IdType>;
141 
142  public:
145 
153  UniqueBorderPartition(int rank, Grid const& grid)
154  : myrank_(rank)
155  , idSet_(grid.localIdSet())
156  {}
157 
158  // Communicate all entities
159  bool contains(int /*dim*/, int codim) const { return true; }
160 
161  // see size()
162  bool fixedSize(int /*dim*/, int codim) const { return codim != 0; }
163 
164  // for codim=0 elements communicate data for all subEntities, otherwise communicate just the owner rank
165  template <class Entity>
166  std::size_t size(Entity const& e) const
167  {
168  if (Entity::codimension != 0)
169  return 1;
170 
171  std::size_t s = 0;
172  for (int codim = 1; codim <= Grid::dimension; ++codim)
173  s += e.subEntities(codim);
174  return s;
175  }
176 
177  template <class MessageBuffer, class Entity>
178  void gather(MessageBuffer& buff, Entity const& e) const
179  {
180  gatherImpl(buff, e, int_t<Entity::codimension>{});
181  }
182 
183  template <class MessageBuffer, class Entity>
184  void scatter(MessageBuffer& buff, Entity const& e, std::size_t n)
185  {
186  scatterImpl(buff, e, n, int_t<Entity::codimension>{});
187  }
188 
190  bool contains(IdType const& id) const
191  {
192  return entityToRank_[id] == myrank_;
193  }
194 
196  int numIterations() const
197  {
198  return Grid::dimension;
199  }
200 
201  private:
202  template <class MessageBuffer, class Entity, int cd>
203  void gatherImpl(MessageBuffer& buff, Entity const& e, int_t<cd>) const
204  {
205  int& rank = entityToRank_[idSet_.id(e)];
206  rank = std::max(rank, myrank_);
207  buff.write(rank);
208  }
209 
210  template <class MessageBuffer, class Entity>
211  void gatherImpl(MessageBuffer& buff, Entity const& e, int_t<0>) const
212  {
213  // maybe use global unique numbering (?)
214  for (int codim = 1; codim <= Grid::dimension; ++codim) {
215  for (int i = 0; i < int(e.subEntities(codim)); ++i) {
216  int& rank = entityToRank_[idSet_.subId(e, i, codim)];
217  rank = std::max(rank, myrank_);
218  buff.write(rank);
219  }
220  }
221  }
222 
223  template <class MessageBuffer, class Entity, int cd>
224  void scatterImpl(MessageBuffer& buff, Entity const& e, [[maybe_unused]] std::size_t n, int_t<cd>)
225  {
226  assert(n == 1);
227 
228  int rank = 0;
229  buff.read(rank);
230 
231  int& storedRank = entityToRank_[idSet_.id(e)];
232  storedRank = std::max(rank, storedRank);
233  }
234 
235  template <class MessageBuffer, class Entity>
236  void scatterImpl(MessageBuffer& buff, Entity const& e, std::size_t n, int_t<0>)
237  {
238  std::size_t j = 0;
239  for (int codim = 1; codim <= Grid::dimension; ++codim) {
240  for (int i = 0; i < int(e.subEntities(codim)); ++i, ++j) {
241  assert(j < n);
242  int rank = 0;
243  buff.read(rank);
244 
245  int& storedRank = entityToRank_[idSet_.subId(e, i, codim)];
246  storedRank = std::max(rank, storedRank);
247  }
248  }
249  }
250 
251  private:
252  int myrank_;
253  mutable std::map<IdType, int> entityToRank_;
254  IdSet const& idSet_;
255  };
256 #endif
257 
258 } // end namespace AMDiS
Definition: AdaptiveGrid.hpp:373
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
std::integral_constant< int, I > int_t
A wrapper for int type.
Definition: Index.hpp:15
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