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 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
28 processor procID. Before calling every processor should insert
29 its value into 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 "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: " << 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 // ************************************************************************* //