FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

gatherScatter.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025     Gather data from all processors onto single processor according to some
00026     communication schedule (usually linear-to-master or tree-to-master).
00027     The gathered data will be a single value constructed from the values
00028     on individual processors using a user-specified operator.
00029 
00030 \*---------------------------------------------------------------------------*/
00031 
00032 #include "OPstream.H"
00033 #include "IPstream.H"
00034 #include <OpenFOAM/contiguous.H>
00035 
00036 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00037 
00038 namespace Foam
00039 {
00040 
00041 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00042 
00043 template <class T, class BinaryOp>
00044 void Pstream::gather
00045 (
00046     const List<Pstream::commsStruct>& comms,
00047     T& Value,
00048     const BinaryOp& bop
00049 )
00050 {
00051     if (Pstream::parRun())
00052     {
00053         // Get my communication order
00054         const commsStruct& myComm = comms[Pstream::myProcNo()];
00055 
00056         // Receive from my downstairs neighbours
00057         forAll(myComm.below(), belowI)
00058         {
00059             T value;
00060 
00061             if (contiguous<T>())
00062             {
00063                 IPstream::read
00064                 (
00065                     Pstream::scheduled,
00066                     myComm.below()[belowI],
00067                     reinterpret_cast<char*>(&value),
00068                     sizeof(T)
00069                 );
00070             }
00071             else
00072             {
00073                 IPstream fromBelow(Pstream::scheduled, myComm.below()[belowI]);
00074                 fromBelow >> value;
00075             }
00076 
00077             Value = bop(Value, value);
00078         }
00079 
00080         // Send up Value
00081         if (myComm.above() != -1)
00082         {
00083             if (contiguous<T>())
00084             {
00085                 OPstream::write
00086                 (
00087                     Pstream::scheduled,
00088                     myComm.above(),
00089                     reinterpret_cast<const char*>(&Value),
00090                     sizeof(T)
00091                 );
00092             }
00093             else
00094             {
00095                 OPstream toAbove(Pstream::scheduled, myComm.above());
00096                 toAbove << Value;
00097             }
00098         }
00099     }
00100 }
00101 
00102 
00103 template <class T, class BinaryOp>
00104 void Pstream::gather(T& Value, const BinaryOp& bop)
00105 {
00106     if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
00107     {
00108         gather(Pstream::linearCommunication(), Value, bop);
00109     }
00110     else
00111     {
00112         gather(Pstream::treeCommunication(), Value, bop);
00113     }
00114 }
00115 
00116 
00117 template <class T>
00118 void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
00119 {
00120     if (Pstream::parRun())
00121     {
00122         // Get my communication order
00123         const commsStruct& myComm = comms[Pstream::myProcNo()];
00124 
00125         // Reveive from up
00126         if (myComm.above() != -1)
00127         {
00128             if (contiguous<T>())
00129             {
00130                 IPstream::read
00131                 (
00132                     Pstream::scheduled,
00133                     myComm.above(),
00134                     reinterpret_cast<char*>(&Value),
00135                     sizeof(T)
00136                 );
00137             }
00138             else
00139             {
00140                 IPstream fromAbove(Pstream::scheduled, myComm.above());
00141                 fromAbove >> Value;
00142             }
00143         }
00144 
00145         // Send to my downstairs neighbours
00146         forAll(myComm.below(), belowI)
00147         {
00148             if (contiguous<T>())
00149             {
00150                 OPstream::write
00151                 (
00152                     Pstream::scheduled,
00153                     myComm.below()[belowI],
00154                     reinterpret_cast<const char*>(&Value),
00155                     sizeof(T)
00156                 );
00157             }
00158             else
00159             {
00160                 OPstream toBelow(Pstream::scheduled,myComm.below()[belowI]);
00161                 toBelow << Value;
00162             }
00163         }
00164     }
00165 }
00166 
00167 
00168 template <class T>
00169 void Pstream::scatter(T& Value)
00170 {
00171     if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
00172     {
00173         scatter(Pstream::linearCommunication(), Value);
00174     }
00175     else
00176     {
00177         scatter(Pstream::treeCommunication(), Value);
00178     }
00179 }
00180 
00181 
00182 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00183 
00184 } // End namespace Foam
00185 
00186 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines