FreeFOAM The Cross-Platform CFD Toolkit
Cloud.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
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.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "Cloud.H"
30 #include <OpenFOAM/mapPolyMesh.H>
31 #include <OpenFOAM/Time.H>
32 #include <OpenFOAM/OFstream.H>
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class ParticleType>
38 (
39  const polyMesh& pMesh,
40  const IDLList<ParticleType>& particles
41 )
42 :
43  cloud(pMesh),
45  polyMesh_(pMesh),
46  particleCount_(0)
47 {
49 }
50 
51 
52 template<class ParticleType>
54 (
55  const polyMesh& pMesh,
56  const word& cloudName,
57  const IDLList<ParticleType>& particles
58 )
59 :
60  cloud(pMesh, cloudName),
62  polyMesh_(pMesh),
63  particleCount_(0)
64 {
66 }
67 
68 
69 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
70 
71 template<class ParticleType>
73 {
74  label id = particleCount_++;
75 
76  if (id == labelMax)
77  {
78  WarningIn("Cloud<ParticleType>::getNewParticleID() const")
79  << "Particle counter has overflowed. This might cause problems"
80  << " when reconstructing particle tracks." << endl;
81  }
82  return id;
83 }
84 
85 
86 template<class ParticleType>
88 {
89  append(pPtr);
90 }
91 
92 
93 template<class ParticleType>
95 {
96  delete(this->remove(&p));
97 }
98 
99 
100 namespace Foam
101 {
102 
104 {
105 
106 public:
107 
108  void operator()(labelListList& x, const labelListList& y) const
109  {
110  forAll(y, i)
111  {
112  if (y[i].size())
113  {
114  x[i] = y[i];
115  }
116  }
117  }
118 };
119 
120 } // End namespace Foam
121 
122 
123 template<class ParticleType>
124 template<class TrackingData>
125 void Foam::Cloud<ParticleType>::move(TrackingData& td)
126 {
127  const globalMeshData& pData = polyMesh_.globalData();
128  const labelList& processorPatches = pData.processorPatches();
129  const labelList& processorPatchIndices = pData.processorPatchIndices();
130  const labelList& processorPatchNeighbours =
131  pData.processorPatchNeighbours();
132 
133  // Initialise the setpFraction moved for the particles
134  forAllIter(typename Cloud<ParticleType>, *this, pIter)
135  {
136  pIter().stepFraction() = 0;
137  }
138 
139  // Assume there will be particles to transfer
140  bool transfered = true;
141 
142  // While there are particles to transfer
143  while (transfered)
144  {
145  // List of lists of particles to be transfered for all the processor
146  // patches
147  List<IDLList<ParticleType> > transferList(processorPatches.size());
148 
149  // Loop over all particles
150  forAllIter(typename Cloud<ParticleType>, *this, pIter)
151  {
152  ParticleType& p = pIter();
153 
154  // Move the particle
155  bool keepParticle = p.move(td);
156 
157  // If the particle is to be kept
158  // (i.e. it hasn't passed through an inlet or outlet)
159  if (keepParticle)
160  {
161  // If we are running in parallel and the particle is on a
162  // boundary face
163  if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces())
164  {
165  label patchi = pMesh().boundaryMesh().whichPatch(p.facei_);
166  label n = processorPatchIndices[patchi];
167 
168  // ... and the face is on a processor patch
169  // prepare it for transfer
170  if (n != -1)
171  {
172  p.prepareForParallelTransfer(patchi, td);
173  transferList[n].append(this->remove(&p));
174  }
175  }
176  }
177  else
178  {
179  deleteParticle(p);
180  }
181  }
182 
183  if (Pstream::parRun())
184  {
185  // List of the numbers of particles to be transfered across the
186  // processor patches
187  labelList nsTransPs(transferList.size());
188 
189  forAll(transferList, i)
190  {
191  nsTransPs[i] = transferList[i].size();
192  }
193 
194  // List of the numbers of particles to be transfered across the
195  // processor patches for all the processors
196  labelListList allNTrans(Pstream::nProcs());
197  allNTrans[Pstream::myProcNo()] = nsTransPs;
198  combineReduce(allNTrans, combineNsTransPs());
199 
200  transfered = false;
201 
202  forAll(allNTrans, i)
203  {
204  forAll(allNTrans[i], j)
205  {
206  if (allNTrans[i][j])
207  {
208  transfered = true;
209  break;
210  }
211  }
212  }
213 
214  if (!transfered)
215  {
216  break;
217  }
218 
219  forAll(transferList, i)
220  {
221  if (transferList[i].size())
222  {
223  OPstream particleStream
224  (
225  Pstream::blocking,
226  refCast<const processorPolyPatch>
227  (
228  pMesh().boundaryMesh()[processorPatches[i]]
229  ).neighbProcNo()
230  );
231 
232  particleStream << transferList[i];
233  }
234  }
235 
236  forAll(processorPatches, i)
237  {
238  label patchi = processorPatches[i];
239 
240  const processorPolyPatch& procPatch =
241  refCast<const processorPolyPatch>
242  (pMesh().boundaryMesh()[patchi]);
243 
244  label neighbProci =
245  procPatch.neighbProcNo() - Pstream::masterNo();
246 
247  label neighbProcPatchi = processorPatchNeighbours[patchi];
248 
249  label nRecPs = allNTrans[neighbProci][neighbProcPatchi];
250 
251  if (nRecPs)
252  {
253  IPstream particleStream
254  (
255  Pstream::blocking,
256  procPatch.neighbProcNo()
257  );
258  IDLList<ParticleType> newParticles
259  (
260  particleStream,
261  typename ParticleType::iNew(*this)
262  );
263 
264  forAllIter
265  (
266  typename Cloud<ParticleType>,
267  newParticles,
268  newpIter
269  )
270  {
271  ParticleType& newp = newpIter();
272  newp.correctAfterParallelTransfer(patchi, td);
273  addParticle(newParticles.remove(&newp));
274  }
275  }
276  }
277  }
278  else
279  {
280  transfered = false;
281  }
282  }
283 }
284 
285 
286 template<class ParticleType>
288 {
289  if (cloud::debug)
290  {
291  Info<< "Cloud<ParticleType>::autoMap(const morphFieldMapper& map) "
292  "for lagrangian cloud " << cloud::name() << endl;
293  }
294 
295  const labelList& reverseCellMap = mapper.reverseCellMap();
296  const labelList& reverseFaceMap = mapper.reverseFaceMap();
297 
298  forAllIter(typename Cloud<ParticleType>, *this, pIter)
299  {
300  if (reverseCellMap[pIter().celli_] >= 0)
301  {
302  pIter().celli_ = reverseCellMap[pIter().celli_];
303 
304  if (pIter().facei_ >= 0 && reverseFaceMap[pIter().facei_] >= 0)
305  {
306  pIter().facei_ = reverseFaceMap[pIter().facei_];
307  }
308  else
309  {
310  pIter().facei_ = -1;
311  }
312  }
313  else
314  {
315  label trackStartCell = mapper.mergedCell(pIter().celli_);
316 
317  if (trackStartCell < 0)
318  {
319  trackStartCell = 0;
320  }
321 
322  vector p = pIter().position();
323  const_cast<vector&>(pIter().position()) =
324  polyMesh_.cellCentres()[trackStartCell];
325  pIter().stepFraction() = 0;
326  pIter().track(p);
327  }
328  }
329 }
330 
331 
332 template<class ParticleType>
334 {
335  OFstream pObj
336  (
337  this->db().time().path()/this->name() + "_positions.obj"
338  );
339 
340  forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
341  {
342  const ParticleType& p = pIter();
343  pObj<< "v " << p.position().x() << " " << p.position().y() << " "
344  << p.position().z() << nl;
345  }
346 
347  pObj.flush();
348 }
349 
350 
351 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
352 
353 #include "CloudIO.C"
354 
355 // ************************ vim: set sw=4 sts=4 et: ************************ //