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

Cloud.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 "Cloud.H"
00027 #include <OpenFOAM/processorPolyPatch.H>
00028 #include <OpenFOAM/globalMeshData.H>
00029 #include <OpenFOAM/PstreamCombineReduceOps.H>
00030 #include <OpenFOAM/mapPolyMesh.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <OpenFOAM/OFstream.H>
00033 
00034 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00035 
00036 template<class ParticleType>
00037 Foam::Cloud<ParticleType>::Cloud
00038 (
00039     const polyMesh& pMesh,
00040     const IDLList<ParticleType>& particles
00041 )
00042 :
00043     cloud(pMesh),
00044     IDLList<ParticleType>(),
00045     polyMesh_(pMesh),
00046     particleCount_(0)
00047 {
00048     IDLList<ParticleType>::operator=(particles);
00049 }
00050 
00051 
00052 template<class ParticleType>
00053 Foam::Cloud<ParticleType>::Cloud
00054 (
00055     const polyMesh& pMesh,
00056     const word& cloudName,
00057     const IDLList<ParticleType>& particles
00058 )
00059 :
00060     cloud(pMesh, cloudName),
00061     IDLList<ParticleType>(),
00062     polyMesh_(pMesh),
00063     particleCount_(0)
00064 {
00065     IDLList<ParticleType>::operator=(particles);
00066 }
00067 
00068 
00069 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00070 
00071 template<class ParticleType>
00072 Foam::label Foam::Cloud<ParticleType>::getNewParticleID() const
00073 {
00074     label id = particleCount_++;
00075 
00076     if (id == labelMax)
00077     {
00078         WarningIn("Cloud<ParticleType>::getNewParticleID() const")
00079             << "Particle counter has overflowed. This might cause problems"
00080             << " when reconstructing particle tracks." << endl;
00081     }
00082     return id;
00083 }
00084 
00085 
00086 template<class ParticleType>
00087 void Foam::Cloud<ParticleType>::addParticle(ParticleType* pPtr)
00088 {
00089     this->append(pPtr);
00090 }
00091 
00092 
00093 template<class ParticleType>
00094 void Foam::Cloud<ParticleType>::deleteParticle(ParticleType& p)
00095 {
00096     delete(this->remove(&p));
00097 }
00098 
00099 
00100 namespace Foam
00101 {
00102 
00103 class combineNsTransPs
00104 {
00105 
00106 public:
00107 
00108     void operator()(labelListList& x, const labelListList& y) const
00109     {
00110         forAll(y, i)
00111         {
00112             if (y[i].size())
00113             {
00114                 x[i] = y[i];
00115             }
00116         }
00117     }
00118 };
00119 
00120 } // End namespace Foam
00121 
00122 
00123 template<class ParticleType>
00124 template<class TrackingData>
00125 void Foam::Cloud<ParticleType>::move(TrackingData& td)
00126 {
00127     const globalMeshData& pData = polyMesh_.globalData();
00128     const labelList& processorPatches = pData.processorPatches();
00129     const labelList& processorPatchIndices = pData.processorPatchIndices();
00130     const labelList& processorPatchNeighbours =
00131         pData.processorPatchNeighbours();
00132 
00133     // Initialise the setpFraction moved for the particles
00134     forAllIter(typename Cloud<ParticleType>, *this, pIter)
00135     {
00136         pIter().stepFraction() = 0;
00137     }
00138 
00139     // Assume there will be particles to transfer
00140     bool transfered = true;
00141 
00142     // While there are particles to transfer
00143     while (transfered)
00144     {
00145         // List of lists of particles to be transfered for all the processor
00146         // patches
00147         List<IDLList<ParticleType> > transferList(processorPatches.size());
00148 
00149         // Loop over all particles
00150         forAllIter(typename Cloud<ParticleType>, *this, pIter)
00151         {
00152             ParticleType& p = pIter();
00153 
00154             // Move the particle
00155             bool keepParticle = p.move(td);
00156 
00157             // If the particle is to be kept
00158             // (i.e. it hasn't passed through an inlet or outlet)
00159             if (keepParticle)
00160             {
00161                 // If we are running in parallel and the particle is on a
00162                 // boundary face
00163                 if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces())
00164                 {
00165                     label patchi = pMesh().boundaryMesh().whichPatch(p.facei_);
00166                     label n = processorPatchIndices[patchi];
00167 
00168                     // ... and the face is on a processor patch
00169                     // prepare it for transfer
00170                     if (n != -1)
00171                     {
00172                         p.prepareForParallelTransfer(patchi, td);
00173                         transferList[n].append(this->remove(&p));
00174                     }
00175                 }
00176             }
00177             else
00178             {
00179                 deleteParticle(p);
00180             }
00181         }
00182 
00183         if (Pstream::parRun())
00184         {
00185             // List of the numbers of particles to be transfered across the
00186             // processor patches
00187             labelList nsTransPs(transferList.size());
00188 
00189             forAll(transferList, i)
00190             {
00191                 nsTransPs[i] = transferList[i].size();
00192             }
00193 
00194             // List of the numbers of particles to be transfered across the
00195             // processor patches for all the processors
00196             labelListList allNTrans(Pstream::nProcs());
00197             allNTrans[Pstream::myProcNo()] = nsTransPs;
00198             combineReduce(allNTrans, combineNsTransPs());
00199 
00200             transfered = false;
00201 
00202             forAll(allNTrans, i)
00203             {
00204                 forAll(allNTrans[i], j)
00205                 {
00206                     if (allNTrans[i][j])
00207                     {
00208                         transfered = true;
00209                         break;
00210                     }
00211                 }
00212             }
00213 
00214             if (!transfered)
00215             {
00216                 break;
00217             }
00218 
00219             forAll(transferList, i)
00220             {
00221                 if (transferList[i].size())
00222                 {
00223                     OPstream particleStream
00224                     (
00225                         Pstream::blocking,
00226                         refCast<const processorPolyPatch>
00227                         (
00228                             pMesh().boundaryMesh()[processorPatches[i]]
00229                         ).neighbProcNo()
00230                     );
00231 
00232                     particleStream << transferList[i];
00233                 }
00234             }
00235 
00236             forAll(processorPatches, i)
00237             {
00238                 label patchi = processorPatches[i];
00239 
00240                 const processorPolyPatch& procPatch =
00241                     refCast<const processorPolyPatch>
00242                     (pMesh().boundaryMesh()[patchi]);
00243 
00244                 label neighbProci =
00245                     procPatch.neighbProcNo() - Pstream::masterNo();
00246 
00247                 label neighbProcPatchi = processorPatchNeighbours[patchi];
00248 
00249                 label nRecPs = allNTrans[neighbProci][neighbProcPatchi];
00250 
00251                 if (nRecPs)
00252                 {
00253                     IPstream particleStream
00254                     (
00255                         Pstream::blocking,
00256                         procPatch.neighbProcNo()
00257                     );
00258                     IDLList<ParticleType> newParticles
00259                     (
00260                         particleStream,
00261                         typename ParticleType::iNew(*this)
00262                     );
00263 
00264                     forAllIter
00265                     (
00266                         typename Cloud<ParticleType>,
00267                         newParticles,
00268                         newpIter
00269                     )
00270                     {
00271                         ParticleType& newp = newpIter();
00272                         newp.correctAfterParallelTransfer(patchi, td);
00273                         addParticle(newParticles.remove(&newp));
00274                     }
00275                 }
00276             }
00277         }
00278         else
00279         {
00280             transfered = false;
00281         }
00282     }
00283 }
00284 
00285 
00286 template<class ParticleType>
00287 void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
00288 {
00289     if (cloud::debug)
00290     {
00291         Info<< "Cloud<ParticleType>::autoMap(const morphFieldMapper& map) "
00292                "for lagrangian cloud " << cloud::name() << endl;
00293     }
00294 
00295     const labelList& reverseCellMap = mapper.reverseCellMap();
00296     const labelList& reverseFaceMap = mapper.reverseFaceMap();
00297 
00298     forAllIter(typename Cloud<ParticleType>, *this, pIter)
00299     {
00300         if (reverseCellMap[pIter().celli_] >= 0)
00301         {
00302             pIter().celli_ = reverseCellMap[pIter().celli_];
00303 
00304             if (pIter().facei_ >= 0 && reverseFaceMap[pIter().facei_] >= 0)
00305             {
00306                 pIter().facei_ = reverseFaceMap[pIter().facei_];
00307             }
00308             else
00309             {
00310                 pIter().facei_ = -1;
00311             }
00312         }
00313         else
00314         {
00315             label trackStartCell = mapper.mergedCell(pIter().celli_);
00316 
00317             if (trackStartCell < 0)
00318             {
00319                 trackStartCell = 0;
00320             }
00321 
00322             vector p = pIter().position();
00323             const_cast<vector&>(pIter().position()) =
00324                 polyMesh_.cellCentres()[trackStartCell];
00325             pIter().stepFraction() = 0;
00326             pIter().track(p);
00327         }
00328     }
00329 }
00330 
00331 
00332 template<class ParticleType>
00333 void Foam::Cloud<ParticleType>::writePositions() const
00334 {
00335     OFstream pObj
00336     (
00337         this->db().time().path()/this->name() + "_positions.obj"
00338     );
00339 
00340     forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
00341     {
00342         const ParticleType& p = pIter();
00343         pObj<< "v " << p.position().x() << " " << p.position().y() << " "
00344             << p.position().z() << nl;
00345     }
00346 
00347     pObj.flush();
00348 }
00349 
00350 
00351 // * * * * * * * * * * * * * * * *  IOStream operators * * * * * * * * * * * //
00352 
00353 #include "CloudIO.C"
00354 
00355 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines