initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / db / IOstreams / Pstreams / gatherScatter.C
blob5239ed73eba5cf66c7760ccaf5cb389dd0351f5c
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
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 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
19     for more details.
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
25 Description
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 single value constructed from the values
29     on individual processors using a user-specified operator.
31 \*---------------------------------------------------------------------------*/
33 #include "OPstream.H"
34 #include "IPstream.H"
35 #include "contiguous.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 namespace Foam
42 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
44 template <class T, class BinaryOp>
45 void Pstream::gather
47     const List<Pstream::commsStruct>& comms,
48     T& Value,
49     const BinaryOp& bop
52     if (Pstream::parRun())
53     {
54         // Get my communication order
55         const commsStruct& myComm = comms[Pstream::myProcNo()];
57         // Receive from my downstairs neighbours
58         forAll(myComm.below(), belowI)
59         {
60             T value;
62             if (contiguous<T>())
63             {
64                 IPstream::read
65                 (
66                     Pstream::scheduled,
67                     myComm.below()[belowI],
68                     reinterpret_cast<char*>(&value),
69                     sizeof(T)
70                 );
71             }
72             else
73             {
74                 IPstream fromBelow(Pstream::scheduled, myComm.below()[belowI]);
75                 fromBelow >> value;
76             }
78             Value = bop(Value, value);
79         }
81         // Send up Value
82         if (myComm.above() != -1)
83         {
84             if (contiguous<T>())
85             {
86                 OPstream::write
87                 (
88                     Pstream::scheduled,
89                     myComm.above(),
90                     reinterpret_cast<const char*>(&Value),
91                     sizeof(T)
92                 );
93             }
94             else
95             {
96                 OPstream toAbove(Pstream::scheduled, myComm.above());
97                 toAbove << Value;
98             }
99         }
100     }
104 template <class T, class BinaryOp>
105 void Pstream::gather(T& Value, const BinaryOp& bop)
107     if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
108     {
109         gather(Pstream::linearCommunication(), Value, bop);
110     }
111     else
112     {
113         gather(Pstream::treeCommunication(), Value, bop);
114     }
118 template <class T>
119 void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
121     if (Pstream::parRun())
122     {
123         // Get my communication order
124         const commsStruct& myComm = comms[Pstream::myProcNo()];
126         // Reveive from up
127         if (myComm.above() != -1)
128         {
129             if (contiguous<T>())
130             {
131                 IPstream::read
132                 (
133                     Pstream::scheduled,
134                     myComm.above(),
135                     reinterpret_cast<char*>(&Value),
136                     sizeof(T)
137                 );
138             }
139             else
140             {
141                 IPstream fromAbove(Pstream::scheduled, myComm.above());
142                 fromAbove >> Value;
143             }
144         }
146         // Send to my downstairs neighbours
147         forAll(myComm.below(), belowI)
148         {
149             if (contiguous<T>())
150             {
151                 OPstream::write
152                 (
153                     Pstream::scheduled,
154                     myComm.below()[belowI],
155                     reinterpret_cast<const char*>(&Value),
156                     sizeof(T)
157                 );
158             }
159             else
160             {
161                 OPstream toBelow(Pstream::scheduled,myComm.below()[belowI]);
162                 toBelow << Value;
163             }
164         }
165     }
169 template <class T>
170 void Pstream::scatter(T& Value)
172     if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
173     {
174         scatter(Pstream::linearCommunication(), Value);
175     }
176     else
177     {
178         scatter(Pstream::treeCommunication(), Value);
179     }
183 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
185 } // End namespace Foam
187 // ************************************************************************* //