1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
25 Variant of gather, scatter.
27 - construct null and read (>>) from Istream
28 - binary operator and assignment operator to combine values
31 - construct from Istream
32 - modify operator which modifies its lhs
34 \*---------------------------------------------------------------------------*/
38 #include "IOstreams.H"
39 #include "contiguous.H"
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
48 template <class T, class CombineOp>
49 void Pstream::combineGather
51 const List<Pstream::commsStruct>& comms,
56 if (Pstream::parRun())
58 // Get my communication order
59 const commsStruct& myComm = comms[Pstream::myProcNo()];
61 // Receive from my downstairs neighbours
62 forAll(myComm.below(), belowI)
64 label belowID = myComm.below()[belowI];
73 reinterpret_cast<char*>(&value),
79 Pout<< " received from "
80 << belowID << " data:" << value << endl;
87 IPstream fromBelow(Pstream::scheduled, belowID);
92 Pout<< " received from "
93 << belowID << " data:" << value << endl;
101 if (myComm.above() != -1)
105 Pout<< " sending to " << myComm.above()
106 << " data:" << Value << endl;
115 reinterpret_cast<const char*>(&Value),
121 OPstream toAbove(Pstream::scheduled, myComm.above());
129 template <class T, class CombineOp>
130 void Pstream::combineGather(T& Value, const CombineOp& cop)
132 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
134 combineGather(Pstream::linearCommunication(), Value, cop);
138 combineGather(Pstream::treeCommunication(), Value, cop);
144 void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
146 if (Pstream::parRun())
148 // Get my communication order
149 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
152 if (myComm.above() != -1)
160 reinterpret_cast<char*>(&Value),
166 IPstream fromAbove(Pstream::scheduled, myComm.above());
167 Value = T(fromAbove);
172 Pout<< " received from "
173 << myComm.above() << " data:" << Value << endl;
177 // Send to my downstairs neighbours
178 forAll(myComm.below(), belowI)
180 label belowID = myComm.below()[belowI];
184 Pout<< " sending to " << belowID << " data:" << Value << endl;
193 reinterpret_cast<const char*>(&Value),
199 OPstream toBelow(Pstream::scheduled, belowID);
208 void Pstream::combineScatter(T& Value)
210 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
212 combineScatter(Pstream::linearCommunication(), Value);
216 combineScatter(Pstream::treeCommunication(), Value);
221 // Same thing but for whole list at a time
222 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225 template <class T, class CombineOp>
226 void Pstream::listCombineGather
228 const List<Pstream::commsStruct>& comms,
233 if (Pstream::parRun())
235 // Get my communication order
236 const commsStruct& myComm = comms[Pstream::myProcNo()];
238 // Receive from my downstairs neighbours
239 forAll(myComm.below(), belowI)
241 label belowID = myComm.below()[belowI];
245 List<T> receivedValues(Values.size());
251 reinterpret_cast<char*>(receivedValues.begin()),
252 receivedValues.byteSize()
257 Pout<< " received from "
258 << belowID << " data:" << receivedValues << endl;
263 cop(Values[i], receivedValues[i]);
268 IPstream fromBelow(Pstream::scheduled, belowID);
269 List<T> receivedValues(fromBelow);
273 Pout<< " received from "
274 << belowID << " data:" << receivedValues << endl;
279 cop(Values[i], receivedValues[i]);
285 if (myComm.above() != -1)
289 Pout<< " sending to " << myComm.above()
290 << " data:" << Values << endl;
299 reinterpret_cast<const char*>(Values.begin()),
305 OPstream toAbove(Pstream::scheduled, myComm.above());
313 template <class T, class CombineOp>
314 void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
316 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
318 listCombineGather(Pstream::linearCommunication(), Values, cop);
322 listCombineGather(Pstream::treeCommunication(), Values, cop);
328 void Pstream::listCombineScatter
330 const List<Pstream::commsStruct>& comms,
334 if (Pstream::parRun())
336 // Get my communication order
337 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
340 if (myComm.above() != -1)
348 reinterpret_cast<char*>(Values.begin()),
354 IPstream fromAbove(Pstream::scheduled, myComm.above());
360 Pout<< " received from "
361 << myComm.above() << " data:" << Values << endl;
365 // Send to my downstairs neighbours
366 forAll(myComm.below(), belowI)
368 label belowID = myComm.below()[belowI];
372 Pout<< " sending to " << belowID << " data:" << Values << endl;
381 reinterpret_cast<const char*>(Values.begin()),
387 OPstream toBelow(Pstream::scheduled, belowID);
396 void Pstream::listCombineScatter(List<T>& Values)
398 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
400 listCombineScatter(Pstream::linearCommunication(), Values);
404 listCombineScatter(Pstream::treeCommunication(), Values);
411 // Same thing but for sparse list (map)
412 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
415 template <class Container, class CombineOp>
416 void Pstream::mapCombineGather
418 const List<Pstream::commsStruct>& comms,
423 if (Pstream::parRun())
425 // Get my communication order
426 const commsStruct& myComm = comms[Pstream::myProcNo()];
428 // Receive from my downstairs neighbours
429 forAll(myComm.below(), belowI)
431 label belowID = myComm.below()[belowI];
433 IPstream fromBelow(Pstream::scheduled, belowID);
434 Container receivedValues(fromBelow);
438 Pout<< " received from "
439 << belowID << " data:" << receivedValues << endl;
444 typename Container::const_iterator slaveIter =
445 receivedValues.begin();
446 slaveIter != receivedValues.end();
450 typename Container::iterator
451 masterIter = Values.find(slaveIter.key());
453 if (masterIter != Values.end())
455 cop(masterIter(), slaveIter());
459 Values.insert(slaveIter.key(), slaveIter());
465 if (myComm.above() != -1)
469 Pout<< " sending to " << myComm.above()
470 << " data:" << Values << endl;
473 OPstream toAbove(Pstream::scheduled, myComm.above());
480 template <class Container, class CombineOp>
481 void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
483 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
485 mapCombineGather(Pstream::linearCommunication(), Values, cop);
489 mapCombineGather(Pstream::treeCommunication(), Values, cop);
494 template <class Container>
495 void Pstream::mapCombineScatter
497 const List<Pstream::commsStruct>& comms,
501 if (Pstream::parRun())
503 // Get my communication order
504 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
507 if (myComm.above() != -1)
509 IPstream fromAbove(Pstream::scheduled, myComm.above());
514 Pout<< " received from "
515 << myComm.above() << " data:" << Values << endl;
519 // Send to my downstairs neighbours
520 forAll(myComm.below(), belowI)
522 label belowID = myComm.below()[belowI];
526 Pout<< " sending to " << belowID << " data:" << Values << endl;
529 OPstream toBelow(Pstream::scheduled, belowID);
536 template <class Container>
537 void Pstream::mapCombineScatter(Container& Values)
539 if (Pstream::nProcs() < Pstream::nProcsSimpleSum())
541 mapCombineScatter(Pstream::linearCommunication(), Values);
545 mapCombineScatter(Pstream::treeCommunication(), Values);
550 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
552 } // End namespace Foam
554 // ************************************************************************* //