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

processorLduInterfaceTemplates.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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "processorLduInterface.H"
00027 #include <OpenFOAM/IPstream.H>
00028 #include <OpenFOAM/OPstream.H>
00029 
00030 // * * * * * * * * * * * * * * * Member Functions * * *  * * * * * * * * * * //
00031 
00032 template<class Type>
00033 void Foam::processorLduInterface::send
00034 (
00035     const Pstream::commsTypes commsType,
00036     const UList<Type>& f
00037 ) const
00038 {
00039     if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
00040     {
00041         OPstream::write
00042         (
00043             commsType,
00044             neighbProcNo(),
00045             reinterpret_cast<const char*>(f.begin()),
00046             f.byteSize()
00047         );
00048     }
00049     else if (commsType == Pstream::nonBlocking)
00050     {
00051         resizeBuf(receiveBuf_, f.size()*sizeof(Type));
00052 
00053         IPstream::read
00054         (
00055             commsType,
00056             neighbProcNo(),
00057             receiveBuf_.begin(),
00058             receiveBuf_.size()
00059         );
00060 
00061         resizeBuf(sendBuf_, f.byteSize());
00062         memcpy(sendBuf_.begin(), f.begin(), f.byteSize());
00063 
00064         OPstream::write
00065         (
00066             commsType,
00067             neighbProcNo(),
00068             sendBuf_.begin(),
00069             f.byteSize()
00070         );
00071     }
00072     else
00073     {
00074         FatalErrorIn("processorLduInterface::send")
00075             << "Unsupported communications type " << commsType
00076             << exit(FatalError);
00077     }
00078 }
00079 
00080 
00081 template<class Type>
00082 void Foam::processorLduInterface::receive
00083 (
00084     const Pstream::commsTypes commsType,
00085     UList<Type>& f
00086 ) const
00087 {
00088     if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
00089     {
00090         IPstream::read
00091         (
00092             commsType,
00093             neighbProcNo(),
00094             reinterpret_cast<char*>(f.begin()),
00095             f.byteSize()
00096         );
00097     }
00098     else if (commsType == Pstream::nonBlocking)
00099     {
00100         memcpy(f.begin(), receiveBuf_.begin(), f.byteSize());
00101     }
00102     else
00103     {
00104         FatalErrorIn("processorLduInterface::receive")
00105             << "Unsupported communications type " << commsType
00106             << exit(FatalError);
00107     }
00108 }
00109 
00110 
00111 template<class Type>
00112 Foam::tmp<Foam::Field<Type> > Foam::processorLduInterface::receive
00113 (
00114     const Pstream::commsTypes commsType,
00115     const label size
00116 ) const
00117 {
00118     tmp<Field<Type> > tf(new Field<Type>(size));
00119     receive(commsType, tf());
00120     return tf;
00121 }
00122 
00123 
00124 template<class Type>
00125 void Foam::processorLduInterface::compressedSend
00126 (
00127     const Pstream::commsTypes commsType,
00128     const UList<Type>& f
00129 ) const
00130 {
00131     if (sizeof(scalar) != sizeof(float) && Pstream::floatTransfer && f.size())
00132     {
00133         static const label nCmpts = sizeof(Type)/sizeof(scalar);
00134         label nm1 = (f.size() - 1)*nCmpts;
00135         label nlast = sizeof(Type)/sizeof(float);
00136         label nFloats = nm1 + nlast;
00137         label nBytes = nFloats*sizeof(float);
00138 
00139         const scalar *sArray = reinterpret_cast<const scalar*>(f.begin());
00140         const scalar *slast = &sArray[nm1];
00141         resizeBuf(sendBuf_, nBytes);
00142         float *fArray = reinterpret_cast<float*>(sendBuf_.begin());
00143 
00144         for (register label i=0; i<nm1; i++)
00145         {
00146             fArray[i] = sArray[i] - slast[i%nCmpts];
00147         }
00148 
00149         reinterpret_cast<Type&>(fArray[nm1]) = f[f.size() - 1];
00150 
00151         if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
00152         {
00153             OPstream::write
00154             (
00155                 commsType,
00156                 neighbProcNo(),
00157                 sendBuf_.begin(),
00158                 nBytes
00159             );
00160         }
00161         else if (commsType == Pstream::nonBlocking)
00162         {
00163             resizeBuf(receiveBuf_, nBytes);
00164 
00165             IPstream::read
00166             (
00167                 commsType,
00168                 neighbProcNo(),
00169                 receiveBuf_.begin(),
00170                 receiveBuf_.size()
00171             );
00172 
00173             OPstream::write
00174             (
00175                 commsType,
00176                 neighbProcNo(),
00177                 sendBuf_.begin(),
00178                 nBytes
00179             );
00180         }
00181         else
00182         {
00183             FatalErrorIn("processorLduInterface::compressedSend")
00184                 << "Unsupported communications type " << commsType
00185                 << exit(FatalError);
00186         }
00187     }
00188     else
00189     {
00190         this->send(commsType, f);
00191     }
00192 }
00193 
00194 template<class Type>
00195 void Foam::processorLduInterface::compressedReceive
00196 (
00197     const Pstream::commsTypes commsType,
00198     UList<Type>& f
00199 ) const
00200 {
00201     if (sizeof(scalar) != sizeof(float) && Pstream::floatTransfer && f.size())
00202     {
00203         static const label nCmpts = sizeof(Type)/sizeof(scalar);
00204         label nm1 = (f.size() - 1)*nCmpts;
00205         label nlast = sizeof(Type)/sizeof(float);
00206         label nFloats = nm1 + nlast;
00207         label nBytes = nFloats*sizeof(float);
00208 
00209         if (commsType == Pstream::blocking || commsType == Pstream::scheduled)
00210         {
00211             resizeBuf(receiveBuf_, nBytes);
00212 
00213             IPstream::read
00214             (
00215                 commsType,
00216                 neighbProcNo(),
00217                 receiveBuf_.begin(),
00218                 nBytes
00219             );
00220         }
00221         else if (commsType != Pstream::nonBlocking)
00222         {
00223             FatalErrorIn("processorLduInterface::compressedReceive")
00224                 << "Unsupported communications type " << commsType
00225                 << exit(FatalError);
00226         }
00227 
00228         const float *fArray =
00229             reinterpret_cast<const float*>(receiveBuf_.begin());
00230         f[f.size() - 1] = reinterpret_cast<const Type&>(fArray[nm1]);
00231         scalar *sArray = reinterpret_cast<scalar*>(f.begin());
00232         const scalar *slast = &sArray[nm1];
00233 
00234         for (register label i=0; i<nm1; i++)
00235         {
00236             sArray[i] = fArray[i] + slast[i%nCmpts];
00237         }
00238     }
00239     else
00240     {
00241         this->receive<Type>(commsType, f);
00242     }
00243 }
00244 
00245 template<class Type>
00246 Foam::tmp<Foam::Field<Type> > Foam::processorLduInterface::compressedReceive
00247 (
00248     const Pstream::commsTypes commsType,
00249     const label size
00250 ) const
00251 {
00252     tmp<Field<Type> > tf(new Field<Type>(size));
00253     compressedReceive(commsType, tf());
00254     return tf;
00255 }
00256 
00257 
00258 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines