dune-grid-glue  2.9
gridgluecommunicate.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-dune-grid-glue-exception
5 #ifndef DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
6 #define DUNE_GRIDGLUE_ADAPTER_GRIDGLUECOMMUNICATE_HH
7 
13 #include <type_traits>
14 
15 #include <dune/common/bartonnackmanifcheck.hh>
16 #include <dune/common/parallel/communicator.hh>
17 #include <dune/grid/common/datahandleif.hh>
18 #include <dune/grid/common/gridenums.hh>
19 
20 
21 namespace Dune {
22  namespace GridGlue {
23 
24  typedef std::pair<int, int> RankPair;
25  struct GlobalId : public std::pair<RankPair, unsigned int>
26  {
31  this->first.first = 0;
32  this->first.second = 0;
33  this->second = 0;
34  }
38  GlobalId(int i) {
39  this->first.first = i;
40  this->first.second = i;
41  this->second = 0;
42  }
48  GlobalId(int i, int j, unsigned int n) {
49  this->first.first = std::min(i,j);
50  this->first.second = std::max(i,j);
51  this->second = n;
52  }
53  };
54 
55  inline std::ostream& operator<<(std::ostream& os, const GlobalId & id)
56  {
57  os << "("
58  << id.first.first << "," << id.first.second << ","
59  << id.second << ")";
60  return os;
61  }
62 
75  template <class DataHandleImp, class DataTypeImp>
77  {
78  public:
80  typedef DataTypeImp DataType;
81 
82  protected:
83  // one should not create an explicit instance of this inteface object
85 
86  public:
87 
91  template<class RISType>
92  size_t size (RISType& i) const
93  {
94  CHECK_INTERFACE_IMPLEMENTATION((asImp().size(i)));
95  return asImp().size(i);
96  }
97 
103  template<class MessageBufferImp, class EntityType, class RISType>
104  void gather (MessageBufferImp& buff, const EntityType& e, const RISType & i) const
105  {
106  MessageBufferIF<MessageBufferImp> buffIF(buff);
107  CHECK_AND_CALL_INTERFACE_IMPLEMENTATION((asImp().gather(buffIF,e,i)));
108  }
109 
117  template<class MessageBufferImp, class EntityType, class RISType>
118  void scatter (MessageBufferImp& buff, const EntityType& e, const RISType & i, size_t n)
119  {
120  MessageBufferIF<MessageBufferImp> buffIF(buff);
121  CHECK_AND_CALL_INTERFACE_IMPLEMENTATION((asImp().scatter(buffIF,e,i,n)));
122  }
123 
124  private:
126  DataHandleImp& asImp () {
127  return static_cast<DataHandleImp &> (*this);
128  }
130  const DataHandleImp& asImp () const
131  {
132  return static_cast<const DataHandleImp &>(*this);
133  }
134  }; // end class CommDataHandleIF
135 
140  template<typename DT>
142  public:
143  typedef DT value_type;
144 
145  // Constructor
147  {
148  a=p;
149  i=0;
150  j=0;
151  }
152 
153  // write data to message buffer, acts like a stream !
154  template<class Y>
155  void write (const Y& data)
156  {
157  static_assert(std::is_same<DT,Y>::value, "DataType mismatch");
158  a[i++] = data;
159  }
160 
161  // read data from message buffer, acts like a stream !
162  template<class Y>
163  void read (Y& data) const
164  {
165  static_assert(std::is_same<DT,Y>::value, "DataType mismatch");
166  data = a[j++];
167  }
168 
169  size_t counter() const { return i; }
170 
171  void clear()
172  {
173  i = 0;
174  j = 0;
175  }
176 
177  // we need access to these variables in an assertion
178 #ifdef NDEBUG
179  private:
180 #endif
181  DT *a;
182  size_t i;
183  mutable size_t j;
184  };
185 
192  template<int dir>
194  {
195  public:
196  template<class CommInfo>
197  static const typename CommInfo::DataType& gather(const CommInfo& commInfo, size_t i, size_t j = 0)
198  {
199  // get Intersection
200  typedef typename CommInfo::GridGlue::Intersection Intersection;
201  Intersection ris(commInfo.gridglue->getIntersection(i));
202 
203  // fill buffer if we have a new intersection
204  if (j == 0)
205  {
206  commInfo.mbuffer.clear();
207  if (dir == Dune::ForwardCommunication)
208  {
209  // read from grid0
210  if(ris.self())
211  commInfo.data->gather(commInfo.mbuffer, ris.inside(), ris);
212  }
213  else // (dir == Dune::BackwardCommunication)
214  {
215  // read from grid1
216  if(ris.neighbor())
217  commInfo.data->gather(commInfo.mbuffer, ris.outside(), ris.flip());
218  }
219  }
220 
221  // return the j'th value in the buffer
222  assert(j < commInfo.mbuffer.i);
223  return commInfo.buffer[j];
224  }
225 
226  template<class CommInfo>
227  static void scatter(CommInfo& commInfo, const typename CommInfo::DataType& v, std::size_t i, std::size_t j = 0)
228  {
229  // extract GridGlue objects...
230  typedef typename CommInfo::GridGlue::Intersection Intersection;
231  Intersection ris(commInfo.gridglue->getIntersection(i));
232 
233  // get size if we have a new intersection
234  if (j == 0)
235  {
236  commInfo.mbuffer.clear();
237  commInfo.currentsize = commInfo.data->size(ris);
238  }
239 
240  // write entry to buffer
241  commInfo.buffer[j] = v;
242 
243  // write back the buffer if we are at the end of this intersection
244  if (j == commInfo.currentsize-1)
245  {
246  if (dir == Dune::ForwardCommunication)
247  {
248  // write to grid1
249  if(ris.neighbor())
250  commInfo.data->scatter(commInfo.mbuffer, ris.outside(), ris.flip(), commInfo.currentsize);
251  }
252  else // (dir == Dune::BackwardCommunication)
253  {
254  // write to grid0
255  if(ris.self())
256  commInfo.data->scatter(commInfo.mbuffer, ris.inside(), ris, commInfo.currentsize);
257  }
258  assert(commInfo.mbuffer.j <= commInfo.currentsize);
259  }
260  }
261  };
262 
265 
270  template <typename GG, class DataHandleImp, class DataTypeImp>
271  struct CommInfo
272  {
273  typedef DataTypeImp value_type;
274  typedef GG GridGlue;
275  typedef DataTypeImp DataType;
276 
277  CommInfo() : buffer(100), mbuffer(&buffer[0])
278  {}
279 
280  // tunnel information to the policy and the operators
283 
284  // state variables
285  std::vector<DataType> buffer;
286  mutable ::Dune::GridGlue::StreamingMessageBuffer<DataType> mbuffer;
287  size_t currentsize;
288  Dune::CommunicationDirection dir;
289  };
290 
291  } // end namespace GridGlue
292 
293 #if HAVE_MPI
298  template<typename GG, class DataHandleImp, class DataTypeImp>
299  struct CommPolicy< ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> >
300  {
304  typedef ::Dune::GridGlue::CommInfo<GG, DataHandleImp, DataTypeImp> Type;
305 
309  typedef DataTypeImp IndexedType;
310 
314  // typedef SizeOne IndexedTypeFlag;
315  typedef VariableSize IndexedTypeFlag;
316 
320  static size_t getSize(const Type& commInfo, size_t i)
321  {
322  // get Intersection
323  typedef typename Type::GridGlue::Intersection Intersection;
324  Intersection ris(commInfo.gridglue->getIntersection(i));
325 
326  // ask data handle for size
327  return commInfo.data->size(ris);
328  }
329  };
330 #endif
331 
332 } // end namespace Dune
333 #endif
Definition: gridglue.hh:37
std::ostream & operator<<(std::ostream &os, const GlobalId &id)
Definition: gridgluecommunicate.hh:55
CommunicationOperator< Dune::BackwardCommunication > BackwardOperator
Definition: gridgluecommunicate.hh:264
CommunicationOperator< Dune::ForwardCommunication > ForwardOperator
Definition: gridgluecommunicate.hh:263
std::pair< int, int > RankPair
Definition: gridgluecommunicate.hh:24
The intersection of two entities of the two patches of a GridGlue.
Definition: intersection.hh:261
Intersection< P0, P1, O, I > flip() const
Return a copy of the intersection with inside and outside switched.
Definition: intersection.hh:483
bool self() const
For parallel computations: Return true if inside() entity exists locally.
Definition: intersection.hh:393
InsideEntity inside(unsigned int parentId=0) const
Return element on the inside of this intersection.
Definition: intersection.hh:319
size_t neighbor(unsigned int g=0) const
Return number of embeddings into local grid0 (grid1) entities.
Definition: intersection.hh:399
OutsideEntity outside(unsigned int parentId=0) const
Return element on the outside of this intersection.
Definition: intersection.hh:328
Definition: gridgluecommunicate.hh:26
GlobalId(int i)
Definition: gridgluecommunicate.hh:38
GlobalId()
Definition: gridgluecommunicate.hh:30
GlobalId(int i, int j, unsigned int n)
Definition: gridgluecommunicate.hh:48
describes the features of a data handle for communication in parallel runs using the GridGlue::commun...
Definition: gridgluecommunicate.hh:77
size_t size(RISType &i) const
Definition: gridgluecommunicate.hh:92
void scatter(MessageBufferImp &buff, const EntityType &e, const RISType &i, size_t n)
Definition: gridgluecommunicate.hh:118
void gather(MessageBufferImp &buff, const EntityType &e, const RISType &i) const
pack data from user to message buffer
Definition: gridgluecommunicate.hh:104
DataTypeImp DataType
data type of data to communicate
Definition: gridgluecommunicate.hh:80
CommDataHandle()
Definition: gridgluecommunicate.hh:84
Definition: gridgluecommunicate.hh:141
size_t j
Definition: gridgluecommunicate.hh:183
StreamingMessageBuffer(DT *p)
Definition: gridgluecommunicate.hh:146
DT * a
Definition: gridgluecommunicate.hh:181
size_t counter() const
Definition: gridgluecommunicate.hh:169
void write(const Y &data)
Definition: gridgluecommunicate.hh:155
void read(Y &data) const
Definition: gridgluecommunicate.hh:163
DT value_type
Definition: gridgluecommunicate.hh:143
size_t i
Definition: gridgluecommunicate.hh:182
void clear()
Definition: gridgluecommunicate.hh:171
forward gather scatter to user defined CommInfo class
Definition: gridgluecommunicate.hh:194
static void scatter(CommInfo &commInfo, const typename CommInfo::DataType &v, std::size_t i, std::size_t j=0)
Definition: gridgluecommunicate.hh:227
static const CommInfo::DataType & gather(const CommInfo &commInfo, size_t i, size_t j=0)
Definition: gridgluecommunicate.hh:197
collects all GridGlue data requried for communication
Definition: gridgluecommunicate.hh:272
Dune::CommunicationDirection dir
Definition: gridgluecommunicate.hh:288
DataTypeImp value_type
Definition: gridgluecommunicate.hh:273
DataTypeImp DataType
Definition: gridgluecommunicate.hh:275
::Dune::GridGlue::CommDataHandle< DataHandleImp, DataTypeImp > * data
Definition: gridgluecommunicate.hh:282
GG GridGlue
Definition: gridgluecommunicate.hh:274
size_t currentsize
Definition: gridgluecommunicate.hh:287
CommInfo()
Definition: gridgluecommunicate.hh:277
mutable ::Dune::GridGlue::StreamingMessageBuffer< DataType > mbuffer
Definition: gridgluecommunicate.hh:286
const GridGlue * gridglue
Definition: gridgluecommunicate.hh:281
std::vector< DataType > buffer
Definition: gridgluecommunicate.hh:285
static size_t getSize(const Type &commInfo, size_t i)
Get the number of objects at an intersection.
Definition: gridgluecommunicate.hh:320
DataTypeImp IndexedType
The datatype that should be communicated.
Definition: gridgluecommunicate.hh:309
::Dune::GridGlue::CommInfo< GG, DataHandleImp, DataTypeImp > Type
The type of the GridGlueCommInfo.
Definition: gridgluecommunicate.hh:304
VariableSize IndexedTypeFlag
Each intersection can communicate a different number of objects.
Definition: gridgluecommunicate.hh:315