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 Gather data from all processors onto single processor according to some
27 communication schedule (usually linear-to-master or tree-to-master).
28 The gathered data will be a list with element procID the data from processor
29 procID. Before calling every processor should insert its value into
30 Values[Pstream::myProcNo()].
31 Note: after gather every processor only knows its own data and that of the
32 processors below it. Only the 'master' of the communication schedule holds
33 a fully filled List. Use scatter to distribute the data.
35 \*---------------------------------------------------------------------------*/
39 #include <OpenFOAM/contiguous.H>
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
49 void Pstream::gatherList
51 const List<Pstream::commsStruct>& comms,
55 if (Pstream::parRun())
57 if (Values.size() != Pstream::nProcs())
61 "Pstream::gatherList(const List<Pstream::commsStruct>&"
63 ) << "Size of list:" << Values.size()
64 << " does not equal the number of processors:"
66 << Foam::abort(FatalError);
69 // Get my communication order
70 const commsStruct& myComm = comms[Pstream::myProcNo()];
72 // Receive from my downstairs neighbours
73 forAll(myComm.below(), belowI)
75 label belowID = myComm.below()[belowI];
76 const labelList& belowLeaves = comms[belowID].allBelow();
80 List<T> receivedValues(belowLeaves.size() + 1);
86 reinterpret_cast<char*>(receivedValues.begin()),
87 receivedValues.byteSize()
90 Values[belowID] = receivedValues[0];
92 forAll(belowLeaves, leafI)
94 Values[belowLeaves[leafI]] = receivedValues[leafI + 1];
99 IPstream fromBelow(Pstream::scheduled, belowID);
100 fromBelow >> Values[belowID];
104 Pout<< " received through "
105 << belowID << " data from:" << belowID
106 << " data:" << Values[belowID] << endl;
109 // Receive from all other processors below belowID
110 forAll(belowLeaves, leafI)
112 label leafID = belowLeaves[leafI];
113 fromBelow >> Values[leafID];
117 Pout<< " received through "
118 << belowID << " data from:" << leafID
119 << " data:" << Values[leafID] << endl;
125 // Send up from Values:
126 // - my own value first
127 // - all belowLeaves next
128 if (myComm.above() != -1)
130 const labelList& belowLeaves = myComm.allBelow();
134 Pout<< " sending to " << myComm.above()
135 << " data from me:" << Pstream::myProcNo()
136 << " data:" << Values[Pstream::myProcNo()] << endl;
141 List<T> sendingValues(belowLeaves.size() + 1);
142 sendingValues[0] = Values[Pstream::myProcNo()];
144 forAll(belowLeaves, leafI)
146 sendingValues[leafI + 1] = Values[belowLeaves[leafI]];
153 reinterpret_cast<const char*>(sendingValues.begin()),
154 sendingValues.byteSize()
159 OPstream toAbove(Pstream::scheduled, myComm.above());
160 toAbove << Values[Pstream::myProcNo()];
162 forAll(belowLeaves, leafI)
164 label leafID = belowLeaves[leafI];
168 Pout<< " sending to "
169 << myComm.above() << " data from:" << leafID
170 << " data:" << Values[leafID] << endl;
172 toAbove << Values[leafID];
181 void Pstream::gatherList(List<T>& Values)
183 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
185 gatherList(Pstream::linearCommunication(), Values);
189 gatherList(Pstream::treeCommunication(), Values);
195 void Pstream::scatterList
197 const List<Pstream::commsStruct>& comms,
201 if (Pstream::parRun())
203 if (Values.size() != Pstream::nProcs())
207 "Pstream::scatterList(const List<Pstream::commsStruct>&"
209 ) << "Size of list:" << Values.size()
210 << " does not equal the number of processors:"
212 << Foam::abort(FatalError);
215 // Get my communication order
216 const commsStruct& myComm = comms[Pstream::myProcNo()];
219 if (myComm.above() != -1)
221 const labelList& notBelowLeaves = myComm.allNotBelow();
225 List<T> receivedValues(notBelowLeaves.size());
231 reinterpret_cast<char*>(receivedValues.begin()),
232 receivedValues.byteSize()
235 forAll(notBelowLeaves, leafI)
237 Values[notBelowLeaves[leafI]] = receivedValues[leafI];
242 IPstream fromAbove(Pstream::scheduled, myComm.above());
244 forAll(notBelowLeaves, leafI)
246 label leafID = notBelowLeaves[leafI];
247 fromAbove >> Values[leafID];
251 Pout<< " received through "
252 << myComm.above() << " data for:" << leafID
253 << " data:" << Values[leafID] << endl;
259 // Send to my downstairs neighbours
260 forAll(myComm.below(), belowI)
262 label belowID = myComm.below()[belowI];
263 const labelList& notBelowLeaves = comms[belowID].allNotBelow();
267 List<T> sendingValues(notBelowLeaves.size());
269 forAll(notBelowLeaves, leafI)
271 sendingValues[leafI] = Values[notBelowLeaves[leafI]];
278 reinterpret_cast<const char*>(sendingValues.begin()),
279 sendingValues.byteSize()
284 OPstream toBelow(Pstream::scheduled, belowID);
286 // Send data destined for all other processors below belowID
287 forAll(notBelowLeaves, leafI)
289 label leafID = notBelowLeaves[leafI];
290 toBelow << Values[leafID];
294 Pout<< " sent through "
295 << belowID << " data for:" << leafID
296 << " data:" << Values[leafID] << endl;
306 void Pstream::scatterList(List<T>& Values)
308 if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
310 scatterList(Pstream::linearCommunication(), Values);
314 scatterList(Pstream::treeCommunication(), Values);
319 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
321 } // End namespace Foam
323 // ************************ vim: set sw=4 sts=4 et: ************************ //