1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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.
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
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/>.
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<UPstream::commsStruct>& comms,
56 if (UPstream::parRun())
58 // Get my communication order
59 const commsStruct& myComm = comms[UPstream::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(UPstream::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(UPstream::scheduled, myComm.above());
129 template <class T, class CombineOp>
130 void Pstream::combineGather(T& Value, const CombineOp& cop)
132 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
134 combineGather(UPstream::linearCommunication(), Value, cop);
138 combineGather(UPstream::treeCommunication(), Value, cop);
144 void Pstream::combineScatter
146 const List<UPstream::commsStruct>& comms,
150 if (UPstream::parRun())
152 // Get my communication order
153 const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
156 if (myComm.above() != -1)
164 reinterpret_cast<char*>(&Value),
170 IPstream fromAbove(UPstream::scheduled, myComm.above());
171 Value = T(fromAbove);
176 Pout<< " received from "
177 << myComm.above() << " data:" << Value << endl;
181 // Send to my downstairs neighbours
182 forAll(myComm.below(), belowI)
184 label belowID = myComm.below()[belowI];
188 Pout<< " sending to " << belowID << " data:" << Value << endl;
197 reinterpret_cast<const char*>(&Value),
203 OPstream toBelow(UPstream::scheduled, belowID);
212 void Pstream::combineScatter(T& Value)
214 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
216 combineScatter(UPstream::linearCommunication(), Value);
220 combineScatter(UPstream::treeCommunication(), Value);
225 // Same thing but for whole list at a time
226 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229 template <class T, class CombineOp>
230 void Pstream::listCombineGather
232 const List<UPstream::commsStruct>& comms,
237 if (UPstream::parRun())
239 // Get my communication order
240 const commsStruct& myComm = comms[UPstream::myProcNo()];
242 // Receive from my downstairs neighbours
243 forAll(myComm.below(), belowI)
245 label belowID = myComm.below()[belowI];
249 List<T> receivedValues(Values.size());
255 reinterpret_cast<char*>(receivedValues.begin()),
256 receivedValues.byteSize()
261 Pout<< " received from "
262 << belowID << " data:" << receivedValues << endl;
267 cop(Values[i], receivedValues[i]);
272 IPstream fromBelow(UPstream::scheduled, belowID);
273 List<T> receivedValues(fromBelow);
277 Pout<< " received from "
278 << belowID << " data:" << receivedValues << endl;
283 cop(Values[i], receivedValues[i]);
289 if (myComm.above() != -1)
293 Pout<< " sending to " << myComm.above()
294 << " data:" << Values << endl;
303 reinterpret_cast<const char*>(Values.begin()),
309 OPstream toAbove(UPstream::scheduled, myComm.above());
317 template <class T, class CombineOp>
318 void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
320 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
322 listCombineGather(UPstream::linearCommunication(), Values, cop);
326 listCombineGather(UPstream::treeCommunication(), Values, cop);
332 void Pstream::listCombineScatter
334 const List<UPstream::commsStruct>& comms,
338 if (UPstream::parRun())
340 // Get my communication order
341 const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
344 if (myComm.above() != -1)
352 reinterpret_cast<char*>(Values.begin()),
358 IPstream fromAbove(UPstream::scheduled, myComm.above());
364 Pout<< " received from "
365 << myComm.above() << " data:" << Values << endl;
369 // Send to my downstairs neighbours
370 forAll(myComm.below(), belowI)
372 label belowID = myComm.below()[belowI];
376 Pout<< " sending to " << belowID << " data:" << Values << endl;
385 reinterpret_cast<const char*>(Values.begin()),
391 OPstream toBelow(UPstream::scheduled, belowID);
400 void Pstream::listCombineScatter(List<T>& Values)
402 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
404 listCombineScatter(UPstream::linearCommunication(), Values);
408 listCombineScatter(UPstream::treeCommunication(), Values);
415 // Same thing but for sparse list (map)
416 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
419 template <class Container, class CombineOp>
420 void Pstream::mapCombineGather
422 const List<UPstream::commsStruct>& comms,
427 if (UPstream::parRun())
429 // Get my communication order
430 const commsStruct& myComm = comms[UPstream::myProcNo()];
432 // Receive from my downstairs neighbours
433 forAll(myComm.below(), belowI)
435 label belowID = myComm.below()[belowI];
437 IPstream fromBelow(UPstream::scheduled, belowID);
438 Container receivedValues(fromBelow);
442 Pout<< " received from "
443 << belowID << " data:" << receivedValues << endl;
448 typename Container::const_iterator slaveIter =
449 receivedValues.begin();
450 slaveIter != receivedValues.end();
454 typename Container::iterator
455 masterIter = Values.find(slaveIter.key());
457 if (masterIter != Values.end())
459 cop(masterIter(), slaveIter());
463 Values.insert(slaveIter.key(), slaveIter());
469 if (myComm.above() != -1)
473 Pout<< " sending to " << myComm.above()
474 << " data:" << Values << endl;
477 OPstream toAbove(UPstream::scheduled, myComm.above());
484 template <class Container, class CombineOp>
485 void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
487 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
489 mapCombineGather(UPstream::linearCommunication(), Values, cop);
493 mapCombineGather(UPstream::treeCommunication(), Values, cop);
498 template <class Container>
499 void Pstream::mapCombineScatter
501 const List<UPstream::commsStruct>& comms,
505 if (UPstream::parRun())
507 // Get my communication order
508 const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
511 if (myComm.above() != -1)
513 IPstream fromAbove(UPstream::scheduled, myComm.above());
518 Pout<< " received from "
519 << myComm.above() << " data:" << Values << endl;
523 // Send to my downstairs neighbours
524 forAll(myComm.below(), belowI)
526 label belowID = myComm.below()[belowI];
530 Pout<< " sending to " << belowID << " data:" << Values << endl;
533 OPstream toBelow(UPstream::scheduled, belowID);
540 template <class Container>
541 void Pstream::mapCombineScatter(Container& Values)
543 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
545 mapCombineScatter(UPstream::linearCommunication(), Values);
549 mapCombineScatter(UPstream::treeCommunication(), Values);
554 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
556 } // End namespace Foam
558 // ************************************************************************* //