1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Variant of gather, scatter.
28 - construct null and read (>>) from Istream
29 - binary operator and assignment operator to combine values
32 - construct from Istream
33 - modify operator which modifies its lhs
35 \*---------------------------------------------------------------------------*/
39 #include "IOstreams.H"
40 #include "contiguous.H"
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
47 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
49 template <class T, class CombineOp>
50 void Pstream::combineGather
52 const List<Pstream::commsStruct>& comms,
57 if (Pstream::parRun())
59 // Get my communication order
60 const commsStruct& myComm = comms[Pstream::myProcNo()];
62 // Receive from my downstairs neighbours
63 forAll(myComm.below(), belowI)
65 label belowID = myComm.below()[belowI];
74 reinterpret_cast<char*>(&value),
80 Pout<< " received from "
81 << belowID << " data:" << value << endl;
88 IPstream fromBelow(Pstream::scheduled, belowID);
93 Pout<< " received from "
94 << belowID << " data:" << value << endl;
102 if (myComm.above() != -1)
106 Pout<< " sending to " << myComm.above()
107 << " data:" << Value << endl;
116 reinterpret_cast<const char*>(&Value),
122 OPstream toAbove(Pstream::scheduled, myComm.above());
130 template <class T, class CombineOp>
131 void Pstream::combineGather(T& Value, const CombineOp& cop)
133 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
135 combineGather(Pstream::linearCommunication(), Value, cop);
139 combineGather(Pstream::treeCommunication(), Value, cop);
145 void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
147 if (Pstream::parRun())
149 // Get my communication order
150 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
153 if (myComm.above() != -1)
161 reinterpret_cast<char*>(&Value),
167 IPstream fromAbove(Pstream::scheduled, myComm.above());
168 Value = T(fromAbove);
173 Pout<< " received from "
174 << myComm.above() << " data:" << Value << endl;
178 // Send to my downstairs neighbours
179 forAll(myComm.below(), belowI)
181 label belowID = myComm.below()[belowI];
185 Pout<< " sending to " << belowID << " data:" << Value << endl;
194 reinterpret_cast<const char*>(&Value),
200 OPstream toBelow(Pstream::scheduled, belowID);
209 void Pstream::combineScatter(T& Value)
211 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
213 combineScatter(Pstream::linearCommunication(), Value);
217 combineScatter(Pstream::treeCommunication(), Value);
222 // Same thing but for whole list at a time
223 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
226 template <class T, class CombineOp>
227 void Pstream::listCombineGather
229 const List<Pstream::commsStruct>& comms,
234 if (Pstream::parRun())
236 // Get my communication order
237 const commsStruct& myComm = comms[Pstream::myProcNo()];
239 // Receive from my downstairs neighbours
240 forAll(myComm.below(), belowI)
242 label belowID = myComm.below()[belowI];
246 List<T> receivedValues(Values.size());
252 reinterpret_cast<char*>(receivedValues.begin()),
253 receivedValues.byteSize()
258 Pout<< " received from "
259 << belowID << " data:" << receivedValues << endl;
264 cop(Values[i], receivedValues[i]);
269 IPstream fromBelow(Pstream::scheduled, belowID);
270 List<T> receivedValues(fromBelow);
274 Pout<< " received from "
275 << belowID << " data:" << receivedValues << endl;
280 cop(Values[i], receivedValues[i]);
286 if (myComm.above() != -1)
290 Pout<< " sending to " << myComm.above()
291 << " data:" << Values << endl;
300 reinterpret_cast<const char*>(Values.begin()),
306 OPstream toAbove(Pstream::scheduled, myComm.above());
314 template <class T, class CombineOp>
315 void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
317 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
319 listCombineGather(Pstream::linearCommunication(), Values, cop);
323 listCombineGather(Pstream::treeCommunication(), Values, cop);
329 void Pstream::listCombineScatter
331 const List<Pstream::commsStruct>& comms,
335 if (Pstream::parRun())
337 // Get my communication order
338 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
341 if (myComm.above() != -1)
349 reinterpret_cast<char*>(Values.begin()),
355 IPstream fromAbove(Pstream::scheduled, myComm.above());
361 Pout<< " received from "
362 << myComm.above() << " data:" << Values << endl;
366 // Send to my downstairs neighbours
367 forAll(myComm.below(), belowI)
369 label belowID = myComm.below()[belowI];
373 Pout<< " sending to " << belowID << " data:" << Values << endl;
382 reinterpret_cast<const char*>(Values.begin()),
388 OPstream toBelow(Pstream::scheduled, belowID);
397 void Pstream::listCombineScatter(List<T>& Values)
399 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
401 listCombineScatter(Pstream::linearCommunication(), Values);
405 listCombineScatter(Pstream::treeCommunication(), Values);
412 // Same thing but for sparse list (map)
413 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
416 template <class Container, class CombineOp>
417 void Pstream::mapCombineGather
419 const List<Pstream::commsStruct>& comms,
424 if (Pstream::parRun())
426 // Get my communication order
427 const commsStruct& myComm = comms[Pstream::myProcNo()];
429 // Receive from my downstairs neighbours
430 forAll(myComm.below(), belowI)
432 label belowID = myComm.below()[belowI];
434 IPstream fromBelow(Pstream::scheduled, belowID);
435 Container receivedValues(fromBelow);
439 Pout<< " received from "
440 << belowID << " data:" << receivedValues << endl;
445 typename Container::const_iterator slaveIter =
446 receivedValues.begin();
447 slaveIter != receivedValues.end();
451 typename Container::iterator
452 masterIter = Values.find(slaveIter.key());
454 if (masterIter != Values.end())
456 cop(masterIter(), slaveIter());
460 Values.insert(slaveIter.key(), slaveIter());
466 if (myComm.above() != -1)
470 Pout<< " sending to " << myComm.above()
471 << " data:" << Values << endl;
474 OPstream toAbove(Pstream::scheduled, myComm.above());
481 template <class Container, class CombineOp>
482 void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
484 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
486 mapCombineGather(Pstream::linearCommunication(), Values, cop);
490 mapCombineGather(Pstream::treeCommunication(), Values, cop);
495 template <class Container>
496 void Pstream::mapCombineScatter
498 const List<Pstream::commsStruct>& comms,
502 if (Pstream::parRun())
504 // Get my communication order
505 const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
508 if (myComm.above() != -1)
510 IPstream fromAbove(Pstream::scheduled, myComm.above());
515 Pout<< " received from "
516 << myComm.above() << " data:" << Values << endl;
520 // Send to my downstairs neighbours
521 forAll(myComm.below(), belowI)
523 label belowID = myComm.below()[belowI];
527 Pout<< " sending to " << belowID << " data:" << Values << endl;
530 OPstream toBelow(Pstream::scheduled, belowID);
537 template <class Container>
538 void Pstream::mapCombineScatter(Container& Values)
540 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
542 mapCombineScatter(Pstream::linearCommunication(), Values);
546 mapCombineScatter(Pstream::treeCommunication(), Values);
553 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
555 } // End namespace Foam
557 // ************************************************************************* //