1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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 \*---------------------------------------------------------------------------*/
28 #include "processorPolyPatch.H"
29 #include "globalMeshData.H"
30 #include "PstreamCombineReduceOps.H"
31 #include "mapPolyMesh.H"
35 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
37 template<class ParticleType>
38 Foam::Cloud<ParticleType>::Cloud
40 const polyMesh& pMesh,
41 const IDLList<ParticleType>& particles
45 IDLList<ParticleType>(),
49 IDLList<ParticleType>::operator=(particles);
53 template<class ParticleType>
54 Foam::Cloud<ParticleType>::Cloud
56 const polyMesh& pMesh,
57 const word& cloudName,
58 const IDLList<ParticleType>& particles
61 cloud(pMesh, cloudName),
62 IDLList<ParticleType>(),
66 IDLList<ParticleType>::operator=(particles);
70 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
72 template<class ParticleType>
73 Foam::label Foam::Cloud<ParticleType>::getNewParticleID() const
75 label id = particleCount_++;
79 WarningIn("Cloud<ParticleType>::getNewParticleID() const")
80 << "Particle counter has overflowed. This might cause problems"
81 << " when reconstructing particle tracks." << endl;
87 template<class ParticleType>
88 void Foam::Cloud<ParticleType>::addParticle(ParticleType* pPtr)
94 template<class ParticleType>
95 void Foam::Cloud<ParticleType>::deleteParticle(ParticleType& p)
97 delete(this->remove(&p));
104 class combineNsTransPs
109 void operator()(labelListList& x, const labelListList& y) const
121 } // End namespace Foam
124 template<class ParticleType>
125 template<class TrackingData>
126 void Foam::Cloud<ParticleType>::move(TrackingData& td)
128 const globalMeshData& pData = polyMesh_.globalData();
129 const labelList& processorPatches = pData.processorPatches();
130 const labelList& processorPatchIndices = pData.processorPatchIndices();
131 const labelList& processorPatchNeighbours =
132 pData.processorPatchNeighbours();
134 // Initialise the setpFraction moved for the particles
135 forAllIter(typename Cloud<ParticleType>, *this, pIter)
137 pIter().stepFraction() = 0;
140 // Assume there will be particles to transfer
141 bool transfered = true;
143 // While there are particles to transfer
146 // List of lists of particles to be transfered for all the processor
148 List<IDLList<ParticleType> > transferList(processorPatches.size());
150 // Loop over all particles
151 forAllIter(typename Cloud<ParticleType>, *this, pIter)
153 ParticleType& p = pIter();
156 bool keepParticle = p.move(td);
158 // If the particle is to be kept
159 // (i.e. it hasn't passed through an inlet or outlet)
162 // If we are running in parallel and the particle is on a
164 if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces())
166 label patchi = pMesh().boundaryMesh().whichPatch(p.facei_);
167 label n = processorPatchIndices[patchi];
169 // ... and the face is on a processor patch
170 // prepare it for transfer
173 p.prepareForParallelTransfer(patchi, td);
174 transferList[n].append(this->remove(&p));
184 if (Pstream::parRun())
186 // List of the numbers of particles to be transfered across the
188 labelList nsTransPs(transferList.size());
190 forAll(transferList, i)
192 nsTransPs[i] = transferList[i].size();
195 // List of the numbers of particles to be transfered across the
196 // processor patches for all the processors
197 labelListList allNTrans(Pstream::nProcs());
198 allNTrans[Pstream::myProcNo()] = nsTransPs;
199 combineReduce(allNTrans, combineNsTransPs());
205 forAll(allNTrans[i], j)
220 forAll(transferList, i)
222 if (transferList[i].size())
224 OPstream particleStream
227 refCast<const processorPolyPatch>
229 pMesh().boundaryMesh()[processorPatches[i]]
233 particleStream << transferList[i];
237 forAll(processorPatches, i)
239 label patchi = processorPatches[i];
241 const processorPolyPatch& procPatch =
242 refCast<const processorPolyPatch>
243 (pMesh().boundaryMesh()[patchi]);
246 procPatch.neighbProcNo() - Pstream::masterNo();
248 label neighbProcPatchi = processorPatchNeighbours[patchi];
250 label nRecPs = allNTrans[neighbProci][neighbProcPatchi];
254 IPstream particleStream
257 procPatch.neighbProcNo()
259 IDLList<ParticleType> newParticles
262 typename ParticleType::iNew(*this)
267 typename Cloud<ParticleType>,
272 ParticleType& newp = newpIter();
273 newp.correctAfterParallelTransfer(patchi, td);
274 addParticle(newParticles.remove(&newp));
287 template<class ParticleType>
288 void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
292 Info<< "Cloud<ParticleType>::autoMap(const morphFieldMapper& map) "
293 "for lagrangian cloud " << cloud::name() << endl;
296 const labelList& reverseCellMap = mapper.reverseCellMap();
297 const labelList& reverseFaceMap = mapper.reverseFaceMap();
299 forAllIter(typename Cloud<ParticleType>, *this, pIter)
301 if (reverseCellMap[pIter().celli_] >= 0)
303 pIter().celli_ = reverseCellMap[pIter().celli_];
305 if (pIter().facei_ >= 0 && reverseFaceMap[pIter().facei_] >= 0)
307 pIter().facei_ = reverseFaceMap[pIter().facei_];
316 label trackStartCell = mapper.mergedCell(pIter().celli_);
318 if (trackStartCell < 0)
323 vector p = pIter().position();
324 const_cast<vector&>(pIter().position()) =
325 polyMesh_.cellCentres()[trackStartCell];
326 pIter().stepFraction() = 0;
333 template<class ParticleType>
334 void Foam::Cloud<ParticleType>::writePositions() const
338 this->db().time().path()/this->name() + "_positions.obj"
341 forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
343 const ParticleType& p = pIter();
344 pObj<< "v " << p.position().x() << " " << p.position().y() << " "
345 << p.position().z() << nl;
352 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
356 // ************************************************************************* //