BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OpenFOAM / db / IOstreams / Pstreams / gatherScatter.C
blobf592e84af9e1e86af3108e8ad44e594ee8eea5a1
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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/>.
24 Description
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 single value constructed from the values
28     on individual processors using a user-specified operator.
30 \*---------------------------------------------------------------------------*/
32 #include "UOPstream.H"
33 #include "OPstream.H"
34 #include "UIPstream.H"
35 #include "IPstream.H"
36 #include "contiguous.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 namespace Foam
43 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
45 template <class T, class BinaryOp>
46 void Pstream::gather
48     const List<UPstream::commsStruct>& comms,
49     T& Value,
50     const BinaryOp& bop
53     if (UPstream::parRun())
54     {
55         // Get my communication order
56         const commsStruct& myComm = comms[UPstream::myProcNo()];
58         // Receive from my downstairs neighbours
59         forAll(myComm.below(), belowI)
60         {
61             T value;
63             if (contiguous<T>())
64             {
65                 UIPstream::read
66                 (
67                     UPstream::scheduled,
68                     myComm.below()[belowI],
69                     reinterpret_cast<char*>(&value),
70                     sizeof(T)
71                 );
72             }
73             else
74             {
75                 IPstream fromBelow(UPstream::scheduled, myComm.below()[belowI]);
76                 fromBelow >> value;
77             }
79             Value = bop(Value, value);
80         }
82         // Send up Value
83         if (myComm.above() != -1)
84         {
85             if (contiguous<T>())
86             {
87                 UOPstream::write
88                 (
89                     UPstream::scheduled,
90                     myComm.above(),
91                     reinterpret_cast<const char*>(&Value),
92                     sizeof(T)
93                 );
94             }
95             else
96             {
97                 OPstream toAbove(UPstream::scheduled, myComm.above());
98                 toAbove << Value;
99             }
100         }
101     }
105 template <class T, class BinaryOp>
106 void Pstream::gather(T& Value, const BinaryOp& bop)
108     if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
109     {
110         gather(UPstream::linearCommunication(), Value, bop);
111     }
112     else
113     {
114         gather(UPstream::treeCommunication(), Value, bop);
115     }
119 template <class T>
120 void Pstream::scatter(const List<UPstream::commsStruct>& comms, T& Value)
122     if (UPstream::parRun())
123     {
124         // Get my communication order
125         const commsStruct& myComm = comms[UPstream::myProcNo()];
127         // Reveive from up
128         if (myComm.above() != -1)
129         {
130             if (contiguous<T>())
131             {
132                 UIPstream::read
133                 (
134                     UPstream::scheduled,
135                     myComm.above(),
136                     reinterpret_cast<char*>(&Value),
137                     sizeof(T)
138                 );
139             }
140             else
141             {
142                 IPstream fromAbove(UPstream::scheduled, myComm.above());
143                 fromAbove >> Value;
144             }
145         }
147         // Send to my downstairs neighbours
148         forAll(myComm.below(), belowI)
149         {
150             if (contiguous<T>())
151             {
152                 UOPstream::write
153                 (
154                     UPstream::scheduled,
155                     myComm.below()[belowI],
156                     reinterpret_cast<const char*>(&Value),
157                     sizeof(T)
158                 );
159             }
160             else
161             {
162                 OPstream toBelow(UPstream::scheduled,myComm.below()[belowI]);
163                 toBelow << Value;
164             }
165         }
166     }
170 template <class T>
171 void Pstream::scatter(T& Value)
173     if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
174     {
175         scatter(UPstream::linearCommunication(), Value);
176     }
177     else
178     {
179         scatter(UPstream::treeCommunication(), Value);
180     }
184 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
186 } // End namespace Foam
188 // ************************************************************************* //