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 Gather data from all processors onto single processor according to some
26 communication schedule (usually linear-to-master or tree-to-master).
27 The gathered data will be a list with element procID the data from processor
28 procID. Before calling every processor should insert its value into
29 Values[UPstream::myProcNo()].
30 Note: after gather every processor only knows its own data and that of the
31 processors below it. Only the 'master' of the communication schedule holds
32 a fully filled List. Use scatter to distribute the data.
34 \*---------------------------------------------------------------------------*/
38 #include "contiguous.H"
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
48 void Pstream::gatherList
50 const List<UPstream::commsStruct>& comms,
54 if (UPstream::parRun())
56 if (Values.size() != UPstream::nProcs())
60 "UPstream::gatherList(const List<UPstream::commsStruct>&"
62 ) << "Size of list:" << Values.size()
63 << " does not equal the number of processors:"
65 << Foam::abort(FatalError);
68 // Get my communication order
69 const commsStruct& myComm = comms[UPstream::myProcNo()];
71 // Receive from my downstairs neighbours
72 forAll(myComm.below(), belowI)
74 label belowID = myComm.below()[belowI];
75 const labelList& belowLeaves = comms[belowID].allBelow();
79 List<T> receivedValues(belowLeaves.size() + 1);
85 reinterpret_cast<char*>(receivedValues.begin()),
86 receivedValues.byteSize()
89 Values[belowID] = receivedValues[0];
91 forAll(belowLeaves, leafI)
93 Values[belowLeaves[leafI]] = receivedValues[leafI + 1];
98 IPstream fromBelow(UPstream::scheduled, belowID);
99 fromBelow >> Values[belowID];
103 Pout<< " received through "
104 << belowID << " data from:" << belowID
105 << " data:" << Values[belowID] << endl;
108 // Receive from all other processors below belowID
109 forAll(belowLeaves, leafI)
111 label leafID = belowLeaves[leafI];
112 fromBelow >> Values[leafID];
116 Pout<< " received through "
117 << belowID << " data from:" << leafID
118 << " data:" << Values[leafID] << endl;
124 // Send up from Values:
125 // - my own value first
126 // - all belowLeaves next
127 if (myComm.above() != -1)
129 const labelList& belowLeaves = myComm.allBelow();
133 Pout<< " sending to " << myComm.above()
134 << " data from me:" << UPstream::myProcNo()
135 << " data:" << Values[UPstream::myProcNo()] << endl;
140 List<T> sendingValues(belowLeaves.size() + 1);
141 sendingValues[0] = Values[UPstream::myProcNo()];
143 forAll(belowLeaves, leafI)
145 sendingValues[leafI + 1] = Values[belowLeaves[leafI]];
152 reinterpret_cast<const char*>(sendingValues.begin()),
153 sendingValues.byteSize()
158 OPstream toAbove(UPstream::scheduled, myComm.above());
159 toAbove << Values[UPstream::myProcNo()];
161 forAll(belowLeaves, leafI)
163 label leafID = belowLeaves[leafI];
167 Pout<< " sending to "
168 << myComm.above() << " data from:" << leafID
169 << " data:" << Values[leafID] << endl;
171 toAbove << Values[leafID];
180 void Pstream::gatherList(List<T>& Values)
182 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
184 gatherList(UPstream::linearCommunication(), Values);
188 gatherList(UPstream::treeCommunication(), Values);
194 void Pstream::scatterList
196 const List<UPstream::commsStruct>& comms,
200 if (UPstream::parRun())
202 if (Values.size() != UPstream::nProcs())
206 "UPstream::scatterList(const List<UPstream::commsStruct>&"
208 ) << "Size of list:" << Values.size()
209 << " does not equal the number of processors:"
210 << UPstream::nProcs()
211 << Foam::abort(FatalError);
214 // Get my communication order
215 const commsStruct& myComm = comms[UPstream::myProcNo()];
218 if (myComm.above() != -1)
220 const labelList& notBelowLeaves = myComm.allNotBelow();
224 List<T> receivedValues(notBelowLeaves.size());
230 reinterpret_cast<char*>(receivedValues.begin()),
231 receivedValues.byteSize()
234 forAll(notBelowLeaves, leafI)
236 Values[notBelowLeaves[leafI]] = receivedValues[leafI];
241 IPstream fromAbove(UPstream::scheduled, myComm.above());
243 forAll(notBelowLeaves, leafI)
245 label leafID = notBelowLeaves[leafI];
246 fromAbove >> Values[leafID];
250 Pout<< " received through "
251 << myComm.above() << " data for:" << leafID
252 << " data:" << Values[leafID] << endl;
258 // Send to my downstairs neighbours
259 forAll(myComm.below(), belowI)
261 label belowID = myComm.below()[belowI];
262 const labelList& notBelowLeaves = comms[belowID].allNotBelow();
266 List<T> sendingValues(notBelowLeaves.size());
268 forAll(notBelowLeaves, leafI)
270 sendingValues[leafI] = Values[notBelowLeaves[leafI]];
277 reinterpret_cast<const char*>(sendingValues.begin()),
278 sendingValues.byteSize()
283 OPstream toBelow(UPstream::scheduled, belowID);
285 // Send data destined for all other processors below belowID
286 forAll(notBelowLeaves, leafI)
288 label leafID = notBelowLeaves[leafI];
289 toBelow << Values[leafID];
293 Pout<< " sent through "
294 << belowID << " data for:" << leafID
295 << " data:" << Values[leafID] << endl;
305 void Pstream::scatterList(List<T>& Values)
307 if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
309 scatterList(UPstream::linearCommunication(), Values);
313 scatterList(UPstream::treeCommunication(), Values);
318 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
320 } // End namespace Foam
322 // ************************************************************************* //