PstreamGather.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2017 OpenFOAM Foundation
9 Copyright (C) 2019-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27Description
28 Gather data from all processors onto single processor according to some
29 communication schedule (usually linear-to-master or tree-to-master).
30 The gathered data will be a single value constructed from the values
31 on individual processors using a user-specified operator.
32
33\*---------------------------------------------------------------------------*/
34
35#include "OPstream.H"
36#include "IPstream.H"
37#include "contiguous.H"
38
39// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
40
41template<class T, class BinaryOp>
43(
44 const List<UPstream::commsStruct>& comms,
45 T& value,
46 const BinaryOp& bop,
47 const int tag,
48 const label comm
49)
50{
51 if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
52 {
53 // My communication order
54 const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
55
56 // Receive from my downstairs neighbours
57 for (const label belowID : myComm.below())
58 {
59 T received;
60
62 {
64 (
66 belowID,
67 reinterpret_cast<char*>(&received),
68 sizeof(T),
69 tag,
70 comm
71 );
72 }
73 else
74 {
75 IPstream fromBelow
76 (
78 belowID,
79 0,
80 tag,
81 comm
82 );
83 fromBelow >> received;
84 }
85
86 value = bop(value, received);
87 }
88
89 // Send up value
90 if (myComm.above() != -1)
91 {
93 {
95 (
97 myComm.above(),
98 reinterpret_cast<const char*>(&value),
99 sizeof(T),
100 tag,
101 comm
102 );
103 }
104 else
105 {
106 OPstream toAbove
107 (
109 myComm.above(),
110 0,
111 tag,
112 comm
113 );
114 toAbove << value;
115 }
116 }
117 }
118}
119
120
121template<class T>
123(
124 const List<UPstream::commsStruct>& comms,
125 T& value,
126 const int tag,
127 const label comm
128)
129{
130 #ifndef Foam_Pstream_scatter_nobroadcast
131 Pstream::broadcast(value, comm);
132 #else
133 if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
134 {
135 // My communication order
136 const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
137
138 // Receive from up
139 if (myComm.above() != -1)
140 {
142 {
144 (
146 myComm.above(),
147 reinterpret_cast<char*>(&value),
148 sizeof(T),
149 tag,
150 comm
151 );
152 }
153 else
154 {
155 IPstream fromAbove
156 (
158 myComm.above(),
159 0,
160 tag,
161 comm
162 );
163 fromAbove >> value;
164 }
165 }
166
167 // Send to my downstairs neighbours. Note reverse order (compared to
168 // receiving). This is to make sure to send to the critical path
169 // (only when using a tree schedule!) first.
170 forAllReverse(myComm.below(), belowI)
171 {
172 const label belowID = myComm.below()[belowI];
173
175 {
177 (
179 belowID,
180 reinterpret_cast<const char*>(&value),
181 sizeof(T),
182 tag,
183 comm
184 );
185 }
186 else
187 {
188 OPstream toBelow
189 (
191 belowID,
192 0,
193 tag,
194 comm
195 );
196 toBelow << value;
197 }
198 }
199 }
200 #endif
201}
202
203
204template<class T, class BinaryOp>
206(
207 T& value,
208 const BinaryOp& bop,
209 const int tag,
210 const label comm
211)
212{
213 Pstream::gather(UPstream::whichCommunication(comm), value, bop, tag, comm);
214}
215
216
217template<class T>
218void Foam::Pstream::scatter(T& value, const int tag, const label comm)
219{
220 #ifndef Foam_Pstream_scatter_nobroadcast
221 Pstream::broadcast(value, comm);
222 #else
223 scatter(UPstream::whichCommunication(comm), value, tag, comm);
224 #endif
225}
226
227
228// ************************************************************************* //
Input inter-processor communications stream.
Definition: IPstream.H:57
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
Output inter-processor communications stream.
Definition: OPstream.H:57
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
static void gather(const List< commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamGather.C:43
static void broadcast(Type &value, const label comm=UPstream::worldComm)
static void scatter(const List< commsStruct > &comms, T &value, const int tag, const label comm)
Broadcast data: Distribute without modification.
virtual bool read()
Re-read model coefficients if they have changed.
Structure for communicating between processors.
Definition: UPstream.H:81
const labelList & below() const noexcept
The procIDs of all processors directly below.
Definition: UPstream.H:134
label above() const noexcept
The procID of the processor directly above.
Definition: UPstream.H:128
static const List< commsStruct > & whichCommunication(const label communicator=worldComm)
Definition: UPstream.H:542
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
virtual bool write()
Write the output fields.
int myProcNo() const noexcept
Return processor number.
const volScalarField & T
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:346
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78