FreeFOAM The Cross-Platform CFD Toolkit
combineGatherScatter.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 Description
25  Variant of gather, scatter.
26  Normal gather uses:
27  - construct null and read (>>) from Istream
28  - binary operator and assignment operator to combine values
29 
30  combineGather uses:
31  - construct from Istream
32  - modify operator which modifies its lhs
33 
34 \*---------------------------------------------------------------------------*/
35 
36 #include "OPstream.H"
37 #include "IPstream.H"
38 #include <OpenFOAM/IOstreams.H>
39 #include <OpenFOAM/contiguous.H>
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 template <class T, class CombineOp>
50 (
51  const List<Pstream::commsStruct>& comms,
52  T& Value,
53  const CombineOp& cop
54 )
55 {
56  if (Pstream::parRun())
57  {
58  // Get my communication order
59  const commsStruct& myComm = comms[Pstream::myProcNo()];
60 
61  // Receive from my downstairs neighbours
62  forAll(myComm.below(), belowI)
63  {
64  label belowID = myComm.below()[belowI];
65 
66  if (contiguous<T>())
67  {
68  T value;
70  (
72  belowID,
73  reinterpret_cast<char*>(&value),
74  sizeof(T)
75  );
76 
77  if (debug & 2)
78  {
79  Pout<< " received from "
80  << belowID << " data:" << value << endl;
81  }
82 
83  cop(Value, value);
84  }
85  else
86  {
87  IPstream fromBelow(Pstream::scheduled, belowID);
88  T value(fromBelow);
89 
90  if (debug & 2)
91  {
92  Pout<< " received from "
93  << belowID << " data:" << value << endl;
94  }
95 
96  cop(Value, value);
97  }
98  }
99 
100  // Send up Value
101  if (myComm.above() != -1)
102  {
103  if (debug & 2)
104  {
105  Pout<< " sending to " << myComm.above()
106  << " data:" << Value << endl;
107  }
108 
109  if (contiguous<T>())
110  {
112  (
114  myComm.above(),
115  reinterpret_cast<const char*>(&Value),
116  sizeof(T)
117  );
118  }
119  else
120  {
121  OPstream toAbove(Pstream::scheduled, myComm.above());
122  toAbove << Value;
123  }
124  }
125  }
126 }
127 
128 
129 template <class T, class CombineOp>
130 void Pstream::combineGather(T& Value, const CombineOp& cop)
131 {
133  {
135  }
136  else
137  {
139  }
140 }
141 
142 
143 template <class T>
145 {
146  if (Pstream::parRun())
147  {
148  // Get my communication order
149  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
150 
151  // Reveive from up
152  if (myComm.above() != -1)
153  {
154  if (contiguous<T>())
155  {
157  (
159  myComm.above(),
160  reinterpret_cast<char*>(&Value),
161  sizeof(T)
162  );
163  }
164  else
165  {
166  IPstream fromAbove(Pstream::scheduled, myComm.above());
167  Value = T(fromAbove);
168  }
169 
170  if (debug & 2)
171  {
172  Pout<< " received from "
173  << myComm.above() << " data:" << Value << endl;
174  }
175  }
176 
177  // Send to my downstairs neighbours
178  forAll(myComm.below(), belowI)
179  {
180  label belowID = myComm.below()[belowI];
181 
182  if (debug & 2)
183  {
184  Pout<< " sending to " << belowID << " data:" << Value << endl;
185  }
186 
187  if (contiguous<T>())
188  {
190  (
192  belowID,
193  reinterpret_cast<const char*>(&Value),
194  sizeof(T)
195  );
196  }
197  else
198  {
199  OPstream toBelow(Pstream::scheduled, belowID);
200  toBelow << Value;
201  }
202  }
203  }
204 }
205 
206 
207 template <class T>
209 {
211  {
213  }
214  else
215  {
217  }
218 }
219 
220 
221 // Same thing but for whole list at a time
222 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
223 
224 
225 template <class T, class CombineOp>
227 (
228  const List<Pstream::commsStruct>& comms,
229  List<T>& Values,
230  const CombineOp& cop
231 )
232 {
233  if (Pstream::parRun())
234  {
235  // Get my communication order
236  const commsStruct& myComm = comms[Pstream::myProcNo()];
237 
238  // Receive from my downstairs neighbours
239  forAll(myComm.below(), belowI)
240  {
241  label belowID = myComm.below()[belowI];
242 
243  if (contiguous<T>())
244  {
245  List<T> receivedValues(Values.size());
246 
248  (
250  belowID,
251  reinterpret_cast<char*>(receivedValues.begin()),
252  receivedValues.byteSize()
253  );
254 
255  if (debug & 2)
256  {
257  Pout<< " received from "
258  << belowID << " data:" << receivedValues << endl;
259  }
260 
261  forAll(Values, i)
262  {
263  cop(Values[i], receivedValues[i]);
264  }
265  }
266  else
267  {
268  IPstream fromBelow(Pstream::scheduled, belowID);
269  List<T> receivedValues(fromBelow);
270 
271  if (debug & 2)
272  {
273  Pout<< " received from "
274  << belowID << " data:" << receivedValues << endl;
275  }
276 
277  forAll(Values, i)
278  {
279  cop(Values[i], receivedValues[i]);
280  }
281  }
282  }
283 
284  // Send up Value
285  if (myComm.above() != -1)
286  {
287  if (debug & 2)
288  {
289  Pout<< " sending to " << myComm.above()
290  << " data:" << Values << endl;
291  }
292 
293  if (contiguous<T>())
294  {
296  (
298  myComm.above(),
299  reinterpret_cast<const char*>(Values.begin()),
300  Values.byteSize()
301  );
302  }
303  else
304  {
305  OPstream toAbove(Pstream::scheduled, myComm.above());
306  toAbove << Values;
307  }
308  }
309  }
310 }
311 
312 
313 template <class T, class CombineOp>
314 void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
315 {
317  {
319  }
320  else
321  {
323  }
324 }
325 
326 
327 template <class T>
329 (
330  const List<Pstream::commsStruct>& comms,
331  List<T>& Values
332 )
333 {
334  if (Pstream::parRun())
335  {
336  // Get my communication order
337  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
338 
339  // Reveive from up
340  if (myComm.above() != -1)
341  {
342  if (contiguous<T>())
343  {
345  (
347  myComm.above(),
348  reinterpret_cast<char*>(Values.begin()),
349  Values.byteSize()
350  );
351  }
352  else
353  {
354  IPstream fromAbove(Pstream::scheduled, myComm.above());
355  fromAbove >> Values;
356  }
357 
358  if (debug & 2)
359  {
360  Pout<< " received from "
361  << myComm.above() << " data:" << Values << endl;
362  }
363  }
364 
365  // Send to my downstairs neighbours
366  forAll(myComm.below(), belowI)
367  {
368  label belowID = myComm.below()[belowI];
369 
370  if (debug & 2)
371  {
372  Pout<< " sending to " << belowID << " data:" << Values << endl;
373  }
374 
375  if (contiguous<T>())
376  {
378  (
380  belowID,
381  reinterpret_cast<const char*>(Values.begin()),
382  Values.byteSize()
383  );
384  }
385  else
386  {
387  OPstream toBelow(Pstream::scheduled, belowID);
388  toBelow << Values;
389  }
390  }
391  }
392 }
393 
394 
395 template <class T>
397 {
399  {
401  }
402  else
403  {
405  }
406 }
407 
408 
409 
410 
411 // Same thing but for sparse list (map)
412 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413 
414 
415 template <class Container, class CombineOp>
417 (
418  const List<Pstream::commsStruct>& comms,
419  Container& Values,
420  const CombineOp& cop
421 )
422 {
423  if (Pstream::parRun())
424  {
425  // Get my communication order
426  const commsStruct& myComm = comms[Pstream::myProcNo()];
427 
428  // Receive from my downstairs neighbours
429  forAll(myComm.below(), belowI)
430  {
431  label belowID = myComm.below()[belowI];
432 
433  IPstream fromBelow(Pstream::scheduled, belowID);
434  Container receivedValues(fromBelow);
435 
436  if (debug & 2)
437  {
438  Pout<< " received from "
439  << belowID << " data:" << receivedValues << endl;
440  }
441 
442  for
443  (
444  typename Container::const_iterator slaveIter =
445  receivedValues.begin();
446  slaveIter != receivedValues.end();
447  ++slaveIter
448  )
449  {
450  typename Container::iterator
451  masterIter = Values.find(slaveIter.key());
452 
453  if (masterIter != Values.end())
454  {
455  cop(masterIter(), slaveIter());
456  }
457  else
458  {
459  Values.insert(slaveIter.key(), slaveIter());
460  }
461  }
462  }
463 
464  // Send up Value
465  if (myComm.above() != -1)
466  {
467  if (debug & 2)
468  {
469  Pout<< " sending to " << myComm.above()
470  << " data:" << Values << endl;
471  }
472 
473  OPstream toAbove(Pstream::scheduled, myComm.above());
474  toAbove << Values;
475  }
476  }
477 }
478 
479 
480 template <class Container, class CombineOp>
481 void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
482 {
484  {
486  }
487  else
488  {
490  }
491 }
492 
493 
494 template <class Container>
496 (
497  const List<Pstream::commsStruct>& comms,
498  Container& Values
499 )
500 {
501  if (Pstream::parRun())
502  {
503  // Get my communication order
504  const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
505 
506  // Reveive from up
507  if (myComm.above() != -1)
508  {
509  IPstream fromAbove(Pstream::scheduled, myComm.above());
510  fromAbove >> Values;
511 
512  if (debug & 2)
513  {
514  Pout<< " received from "
515  << myComm.above() << " data:" << Values << endl;
516  }
517  }
518 
519  // Send to my downstairs neighbours
520  forAll(myComm.below(), belowI)
521  {
522  label belowID = myComm.below()[belowI];
523 
524  if (debug & 2)
525  {
526  Pout<< " sending to " << belowID << " data:" << Values << endl;
527  }
528 
529  OPstream toBelow(Pstream::scheduled, belowID);
530  toBelow << Values;
531  }
532  }
533 }
534 
535 
536 template <class Container>
537 void Pstream::mapCombineScatter(Container& Values)
538 {
540  {
542  }
543  else
544  {
546  }
547 }
548 
549 
550 
551 
552 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
553 
554 } // End namespace Foam
555 
556 // ************************ vim: set sw=4 sts=4 et: ************************ //