Cloud.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
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"
27 #include "processorPolyPatch.H"
28 #include "globalMeshData.H"
29 #include "meshToMesh.H"
31 #include "polyTopoChangeMap.H"
32 #include "polyMeshMap.H"
33 #include "polyDistributionMap.H"
34 #include "Time.H"
35 #include "OFstream.H"
36 #include "wallPolyPatch.H"
38 #include "cpuLoad.H"
39 #include "meshSearch.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 template<class Type>
48 {
49  void operator()(IDLList<Type>& x, const IDLList<Type>& y) const
50  {
51  if (y.size())
52  {
53  forAllConstIter(typename IDLList<Type>, y, iter)
54  {
55  x.append(new Type(iter()));
56  }
57  }
58  }
59 };
60 
61 }
62 
63 
64 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
65 
66 template<class ParticleType>
68 (
69  const polyMesh& pMesh
70 )
71 {
72  const polyBoundaryMesh& pbm = pMesh.boundary();
73 
74  labelList result(pbm.size(), -1);
75 
76  if (Pstream::parRun())
77  {
78  forAll(pbm, patchi)
79  {
80  if (isA<processorPolyPatch>(pbm[patchi]))
81  {
82  const processorPolyPatch& ppp =
83  refCast<const processorPolyPatch>(pbm[patchi]);
84 
85  result[patchi] = ppp.neighbProcNo();
86  }
87  }
88  }
89 
90  return result;
91 }
92 
93 
94 template<class ParticleType>
96 (
97  const polyMesh& pMesh
98 )
99 {
100  const polyBoundaryMesh& pbm = pMesh.boundary();
101 
102  labelList result(pbm.size(), -1);
103 
104  if (Pstream::parRun())
105  {
106  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
107 
108  forAll(pbm, patchi)
109  {
110  if (isA<processorPolyPatch>(pbm[patchi]))
111  {
112  const processorPolyPatch& ppp =
113  refCast<const processorPolyPatch>(pbm[patchi]);
114 
115  UOPstream(ppp.neighbProcNo(), pBufs)()
116  << ppp.index();
117  }
118  }
119 
120  pBufs.finishedSends();
121 
122  forAll(pbm, patchi)
123  {
124  if (isA<processorPolyPatch>(pbm[patchi]))
125  {
126  const processorPolyPatch& ppp =
127  refCast<const processorPolyPatch>(pbm[patchi]);
128 
129  UIPstream(ppp.neighbProcNo(), pBufs)()
130  >> result[patchi];
131  }
132  }
133  }
134 
135  return result;
136 }
137 
138 
139 template<class ParticleType>
142 (
143  const polyMesh& pMesh
144 )
145 {
146  const polyBoundaryMesh& pbm = pMesh.boundary();
147 
148  labelListList result(pbm.size(), labelList());
149 
150  forAll(pbm, patchi)
151  {
152  if (isA<nonConformalCyclicPolyPatch>(pbm[patchi]))
153  {
154  const nonConformalCyclicPolyPatch& nccPp =
155  refCast<const nonConformalCyclicPolyPatch>(pbm[patchi]);
156 
157  result[nccPp.origPatchIndex()].append(patchi);
158  }
159  }
160 
161  return result;
162 }
163 
164 
165 template<class ParticleType>
167 {
168  const polyBoundaryMesh& pbm = pMesh_.boundary();
169 
170  forAll(patchNonConformalCyclicPatches_, patchi)
171  {
172  forAll(patchNonConformalCyclicPatches_[patchi], i)
173  {
174  const label nccPatchi =
175  patchNonConformalCyclicPatches_[patchi][i];
176 
177  const nonConformalCyclicPolyPatch& nccPp =
178  refCast<const nonConformalCyclicPolyPatch>(pbm[nccPatchi]);
179 
180  if (nccPp.owner()) nccPp.rays();
181  }
182  }
183 }
184 
185 
186 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
187 
188 template<class ParticleType>
190 (
191  const polyMesh& pMesh,
192  const word& cloudName,
193  const IDLList<ParticleType>& particles
194 )
195 :
196  cloud(pMesh, cloudName),
197  IDLList<ParticleType>(),
198  pMesh_(pMesh),
199  patchNbrProc_(patchNbrProc(pMesh)),
200  patchNbrProcPatch_(patchNbrProcPatch(pMesh)),
201  patchNonConformalCyclicPatches_(patchNonConformalCyclicPatches(pMesh)),
202  globalPositionsPtr_(),
203  timeIndex_(-1)
204 {
205  // Request the tet base points so that they are built on all processors.
206  // Constructing tet base points requires communication, so we can't leave
207  // it until the tracking requests them as those calls are not synchronised.
208  // Some processors might not be doing any tracking at all.
209  pMesh_.tetBasePtIs();
210 
211  // Mark the need to store the old-time cell-centres if the mesh is moving
212  if (!ParticleType::instantaneous)
213  {
214  pMesh_.oldCellCentres();
215  }
216 
217  if (particles.size())
218  {
220  }
221 }
222 
223 
224 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
225 
226 template<class ParticleType>
228 {
229  this->append(pPtr);
230 }
231 
232 
233 template<class ParticleType>
235 {
236  delete(this->remove(&p));
237 }
238 
239 
240 template<class ParticleType>
242 {
243  label lostCount = 0;
244 
245  forAllIter(typename Cloud<ParticleType>, *this, pIter)
246  {
247  if (pIter().cell() == -1)
248  {
249  deleteParticle(pIter());
250  lostCount ++;
251  }
252  }
253 
254  reduce(lostCount, sumOp<label>());
255  if (lostCount != 0)
256  {
258  << "Cloud " << this->name()
259  << " deleted " << lostCount << " lost particles" << endl;
260  }
261 }
262 
263 
264 template<class ParticleType>
266 (
267  const Cloud<ParticleType>& c
268 )
269 {
270  // Reset particle count and particles only
271  // - not changing the cloud object registry or reference to the polyMesh
272  ParticleType::particleCount = 0;
274 }
275 
276 
277 template<class ParticleType>
279 {
280  forAllIter(typename Cloud<ParticleType>, *this, pIter)
281  {
282  pIter().reset(0);
283  }
284 
285  timeIndex_ = pMesh_.time().timeIndex();
286 }
287 
288 
289 template<class ParticleType>
290 template<class TrackCloudType>
292 (
293  TrackCloudType& cloud,
294  typename ParticleType::trackingData& td
295 )
296 {
297  // If the time has changed, modify the particles accordingly
298  if (!ParticleType::instantaneous && timeIndex_ != pMesh_.time().timeIndex())
299  {
300  changeTimeStep();
301  }
302 
303  // Clear the global positions as these are about to change
304  globalPositionsPtr_.clear();
305 
306  // Ensure rays are available for non conformal transfers
307  storeRays();
308 
309  // Create transfer buffers
311 
312  // Create lists of particles and patch indices to transfer
314  List<DynamicList<label>> sendPatchIndices(Pstream::nProcs());
315 
316  optionalCpuLoad& cloudCpuTime
317  (
318  optionalCpuLoad::New(name() + ":cpuLoad", pMesh_, cloud.cpuLoad())
319  );
320 
321  // While there are particles to transfer
322  while (true)
323  {
324  // Clear the transfer lists
325  forAll(sendParticles, proci)
326  {
327  sendParticles[proci].clear();
328  sendPatchIndices[proci].clear();
329  }
330 
331  if (cloud.cpuLoad())
332  {
333  cloudCpuTime.resetCpuTime();
334  }
335 
336  // Loop over all particles
337  forAllIter(typename Cloud<ParticleType>, *this, pIter)
338  {
339  ParticleType& p = pIter();
340 
341  // Move the particle
342  const bool keepParticle = p.move(cloud, td);
343 
344  if (cloud.cpuLoad())
345  {
346  cloudCpuTime.cpuTimeIncrement(p.cell());
347  }
348 
349  // If the particle is to be kept
350  if (keepParticle)
351  {
352  if (td.sendToProc != -1)
353  {
354  #ifdef FULLDEBUG
355  if (!Pstream::parRun() || !p.onBoundaryFace(pMesh_))
356  {
358  << "Switch processor flag is true when no parallel "
359  << "transfer is possible. This is a bug."
360  << exit(FatalError);
361  }
362  #endif
363 
364  p.prepareForParallelTransfer(cloud, td);
365 
366  sendParticles[td.sendToProc].append(this->remove(&p));
367 
368  sendPatchIndices[td.sendToProc].append(td.sendToPatch);
369  }
370  }
371  else
372  {
373  deleteParticle(p);
374  }
375  }
376 
377  // If running in serial then everything has been moved, so finish
378  if (!Pstream::parRun())
379  {
380  break;
381  }
382 
383  // Clear transfer buffers
384  pBufs.clear();
385 
386  // Stream into send buffers
387  forAll(sendParticles, proci)
388  {
389  if (sendParticles[proci].size())
390  {
391  UOPstream particleStream(proci, pBufs);
392 
393  particleStream
394  << sendPatchIndices[proci]
395  << sendParticles[proci];
396  }
397  }
398 
399  // Start sending. Sets number of bytes transferred.
400  labelList receiveSizes(Pstream::nProcs());
401  pBufs.finishedSends(receiveSizes);
402 
403  // Determine if any particles were transferred. If not, then finish.
404  bool transferred = false;
405  forAll(receiveSizes, proci)
406  {
407  if (receiveSizes[proci])
408  {
409  transferred = true;
410  break;
411  }
412  }
413  reduce(transferred, orOp<bool>());
414  if (!transferred)
415  {
416  break;
417  }
418 
419  // Retrieve from receive buffers and add into the cloud
420  forAll(receiveSizes, proci)
421  {
422  if (receiveSizes[proci])
423  {
424  UIPstream particleStream(proci, pBufs);
425 
426  const labelList receivePatchIndices(particleStream);
427 
428  IDLList<ParticleType> newParticles(particleStream);
429 
430  label i = 0;
431 
432  forAllIter(typename Cloud<ParticleType>, newParticles, iter)
433  {
434  const label patchi = receivePatchIndices[i ++];
435 
436  ParticleType& p = iter();
437 
438  td.sendToPatch = patchi;
439 
440  p.correctAfterParallelTransfer(cloud, td);
441 
442  addParticle(newParticles.remove(&p));
443  }
444  }
445  }
446  }
447 
448  // Warn about any approximate locates
449  Pstream::listCombineGather(td.patchNLocateBoundaryHits, plusEqOp<label>());
450  if (Pstream::master())
451  {
452  forAll(td.patchNLocateBoundaryHits, patchi)
453  {
454  if (td.patchNLocateBoundaryHits[patchi] != 0)
455  {
457  << "Cloud " << name() << " did not accurately locate "
458  << td.patchNLocateBoundaryHits[patchi]
459  << " particles that transferred to patch "
460  << pMesh_.boundary()[patchi].name() << nl;
461  }
462  }
463  }
464 }
465 
466 
467 template<class ParticleType>
469 (
470  const polyTopoChangeMap& map
471 )
472 {
473  if (map.reverseCellMap().empty()) return;
474 
475  // See comments in the constructor
476  pMesh_.tetBasePtIs();
477  pMesh_.oldCellCentres();
478 
479  if (!globalPositionsPtr_.valid())
480  {
482  << "Global positions are not available. "
483  << "Cloud::storeGlobalPositions has not been called."
484  << exit(FatalError);
485  }
486 
487  const vectorField& positions = globalPositionsPtr_();
488 
489  const meshSearch& searchEngine = meshSearch::New(pMesh_);
490 
491  label lostCount = 0;
492 
493  label particlei = 0;
494  forAllIter(typename Cloud<ParticleType>, *this, iter)
495  {
496  const point& pos = positions[particlei ++];
497 
498  const label celli = map.reverseCellMap()[iter().cell()];
499 
500  if (!iter().locate(searchEngine, pos, celli))
501  {
502  this->remove(iter);
503  lostCount ++;
504  }
505  }
506 
507  reduce(lostCount, sumOp<label>());
508  if (lostCount != 0)
509  {
511  << "Topology change of cloud " << this->name()
512  << " lost " << lostCount << " particles" << endl;
513  }
514 }
515 
516 
517 template<class ParticleType>
519 {
520  // See comments in the constructor
521  pMesh_.tetBasePtIs();
522  pMesh_.oldCellCentres();
523 
524  // Update cached mesh indexing
525  patchNbrProc_ = patchNbrProc(pMesh_);
526  patchNbrProcPatch_ = patchNbrProcPatch(pMesh_);
527  patchNonConformalCyclicPatches_ = patchNonConformalCyclicPatches(pMesh_);
528 
529  if (!globalPositionsPtr_.valid())
530  {
532  << "Global positions are not available. "
533  << "Cloud::storeGlobalPositions has not been called."
534  << exit(FatalError);
535  }
536 
537  const vectorField& positions = globalPositionsPtr_();
538 
539  const meshSearch& searchEngine = meshSearch::New(pMesh_);
540 
541  label lostCount = 0;
542 
543  // Loop the particles. Map those that remain on this processor, and
544  // transfer others into send arrays.
545  List<DynamicList<label>> sendCellIndices(Pstream::nProcs());
546  List<DynamicList<point>> sendPositions(Pstream::nProcs());
548  {
549  label particlei = 0;
550  forAllIter(typename Cloud<ParticleType>, *this, iter)
551  {
552  const point& pos = positions[particlei ++];
553 
554  const remote tgtProcCell =
555  map.mapper().srcToTgtPoint(iter().cell(), pos);
556  const label proci = tgtProcCell.proci;
557  const label celli = tgtProcCell.elementi;
558 
559  if (tgtProcCell == remote())
560  {
561  this->remove(iter);
562  lostCount ++;
563  }
564  else if (proci == Pstream::myProcNo())
565  {
566  if (!iter().locate(searchEngine, pos, celli))
567  {
568  this->remove(iter);
569  lostCount ++;
570  }
571  }
572  else
573  {
574  sendCellIndices[proci].append(celli);
575  sendPositions[proci].append(pos);
576  sendParticles[proci].append(this->remove(iter));
577  }
578  }
579  }
580 
581  // If parallel then send and receive particles that move processes and map
582  // those sent to this process
583  if (Pstream::parRun())
584  {
585  // Create transfer buffers
587 
588  // Stream into send buffers
589  forAll(sendParticles, proci)
590  {
591  if (sendParticles[proci].size())
592  {
593  UOPstream particleStream(proci, pBufs);
594 
595  particleStream
596  << sendCellIndices[proci]
597  << sendPositions[proci]
598  << sendParticles[proci];
599  }
600  }
601 
602  // Finish sending
603  labelList receiveSizes(Pstream::nProcs());
604  pBufs.finishedSends(receiveSizes);
605 
606  // Retrieve from receive buffers and map into the new mesh
607  forAll(sendParticles, proci)
608  {
609  if (receiveSizes[proci])
610  {
611  UIPstream particleStream(proci, pBufs);
612 
613  const labelList receiveCellIndices(particleStream);
614  const List<point> receivePositions(particleStream);
615  IDLList<ParticleType> receiveParticles(particleStream);
616 
617  label particlei = 0;
618  forAllIter(typename Cloud<ParticleType>, receiveParticles, iter)
619  {
620  const label celli = receiveCellIndices[particlei];
621  const vector& pos = receivePositions[particlei ++];
622 
623  if (iter().locate(searchEngine, pos, celli))
624  {
625  this->append(receiveParticles.remove(iter));
626  }
627  else
628  {
629  receiveParticles.remove(iter);
630  lostCount ++;
631  }
632  }
633  }
634  }
635  }
636 
637  reduce(lostCount, sumOp<label>());
638  if (lostCount != 0)
639  {
641  << "Mesh-to-mesh mapping of cloud " << this->name()
642  << " lost " << lostCount << " particles" << endl;
643  }
644 }
645 
646 
647 template<class ParticleType>
649 (
650  const polyDistributionMap& map
651 )
652 {
653  // See comments in the constructor
654  pMesh_.tetBasePtIs();
655  pMesh_.oldCellCentres();
656 
657  // Update cached mesh indexing
658  patchNbrProc_ = patchNbrProc(pMesh_);
659  patchNbrProcPatch_ = patchNbrProcPatch(pMesh_);
660  patchNonConformalCyclicPatches_ = patchNonConformalCyclicPatches(pMesh_);
661 
662  if (!globalPositionsPtr_.valid())
663  {
665  << "Global positions are not available. "
666  << "Cloud::storeGlobalPositions has not been called."
667  << exit(FatalError);
668  }
669 
670  const meshSearch& searchEngine = meshSearch::New(pMesh_);
671 
672  const vectorField& positions = globalPositionsPtr_();
673 
674  // Distribute the global positions
675  List<List<point>> cellParticlePositions(map.nOldCells());
676  {
677  labelList cellParticleis(map.nOldCells(), 0);
678  forAllIter(typename Cloud<ParticleType>, *this, iter)
679  {
680  cellParticleis[iter().cell()] ++;
681  }
682  forAll(cellParticlePositions, celli)
683  {
684  cellParticlePositions[celli].resize(cellParticleis[celli]);
685  }
686 
687  label particlei = 0;
688  cellParticleis = 0;
689  forAllIter(typename Cloud<ParticleType>, *this, iter)
690  {
691  const label celli = iter().cell();
692  label& cellParticlei = cellParticleis[celli];
693 
694  cellParticlePositions[celli][cellParticlei ++] =
695  positions[particlei ++];
696  }
697  }
699  (
701  List<labelPair>(),
702  pMesh_.nCells(),
703  map.cellMap().subMap(),
704  false,
705  map.cellMap().constructMap(),
706  false,
707  cellParticlePositions,
709  flipOp(),
710  List<point>()
711  );
712 
713  // Distribute the particles
714  List<IDLList<ParticleType>> cellParticles(map.nOldCells());
715  forAllIter(typename Cloud<ParticleType>, *this, iter)
716  {
717  cellParticles[iter().cell()].append(this->remove(iter));
718  }
720  (
722  List<labelPair>(),
723  pMesh_.nCells(),
724  map.cellMap().subMap(),
725  false,
726  map.cellMap().constructMap(),
727  false,
728  cellParticles,
730  flipOp(),
732  );
733 
734  label lostCount = 0;
735 
736  // Locate the particles within the new mesh
737  forAll(cellParticles, celli)
738  {
739  label cellParticlei = 0;
740  forAllIter(typename IDLList<ParticleType>, cellParticles[celli], iter)
741  {
742  const point& pos = cellParticlePositions[celli][cellParticlei++];
743 
744  if (iter().locate(searchEngine, pos, celli))
745  {
746  this->append(cellParticles[celli].remove(iter));
747  }
748  else
749  {
750  cellParticles[celli].remove(iter);
751  lostCount ++;
752  }
753  }
754  }
755 
756  reduce(lostCount, sumOp<label>());
757  if (lostCount != 0)
758  {
760  << "Distribution of cloud " << this->name()
761  << " lost " << lostCount << " particles" << endl;
762  }
763 }
764 
765 
766 template<class ParticleType>
768 {
769  OFstream pObj
770  (
771  this->time().path()/this->name() + "_positions.obj"
772  );
773 
774  forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
775  {
776  const point pos = pIter().position(pMesh_);
777 
778  pObj<< "v " << pos.x() << " " << pos.y() << " " << pos.z() << nl;
779  }
780 
781  pObj.flush();
782 }
783 
784 
785 template<class ParticleType>
787 {
788  // Store the global positions for later use by mapping functions. It would
789  // be preferable not to need this. If the objects passed to had a copy of
790  // the old mesh then the global positions could be recovered within the
791  // mapping functions, and this pre-processing would not be necessary.
792 
793  globalPositionsPtr_.reset(new vectorField(this->size()));
794 
795  vectorField& positions = globalPositionsPtr_();
796 
797  label particlei = 0;
798  forAllConstIter(typename Cloud<ParticleType>, *this, iter)
799  {
800  positions[particlei++] = iter().position(pMesh_);
801  }
802 }
803 
804 
805 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
806 
807 #include "CloudIO.C"
808 
809 // ************************************************************************* //
scalar y
Combination-Reduction operation for a parallel run. The information from all nodes is collected on th...
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:474
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Base cloud calls templated on particle type.
Template class for intrusive linked lists.
Definition: ILList.H:67
void operator=(const ILList< LListBase, T > &)
Assignment operator.
Definition: ILList.C:144
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void resize(const label)
Alias for setSize(const label)
Definition: ListI.H:138
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
Output to file stream.
Definition: OFstream.H:87
virtual void flush()
Flush stream.
Definition: OSstream.C:231
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
void clear()
Clear storage and reset.
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
T * remove(T *p)
Remove and return element.
Definition: UILList.H:142
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:57
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:325
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:58
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:411
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:60
Base class for clouds. Provides a basic evolution algorithm, models, and a database for caching deriv...
Definition: cloud.H:61
const labelListList & constructMap() const
From subsetted data to new reconstructed data.
const labelListList & subMap() const
From subsetted data back to original data.
static void distribute(const Pstream::commsTypes commsType, const List< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &, const negateOp &negOp, const int tag=UPstream::msgType())
Distribute data. Note:schedule only used for.
Class containing functor to negate primitives. Dummy for all other types.
Definition: flipOp.H:51
void changeTimeStep()
Change the particles' state from the end of the previous time.
Definition: Cloud.C:278
void deleteParticle(ParticleType &)
Remove particle from cloud and delete.
Definition: Cloud.C:234
void writePositions() const
Write positions to <cloudName>_positions.obj file.
Definition: Cloud.C:767
const labelListList & patchNonConformalCyclicPatches() const
Return map from patch index to connected non-conformal cyclics.
Definition: Cloud.H:185
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
Definition: Cloud.C:469
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
Definition: Cloud.C:649
const labelList & patchNbrProcPatch() const
Map from patch index to the corresponding patch index on the.
Definition: Cloud.H:179
void deleteLostParticles()
Remove lost particles from cloud and delete.
Definition: Cloud.C:241
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: Cloud.C:518
void cloudReset(const Cloud< ParticleType > &c)
Reset the particles.
Definition: Cloud.C:266
Cloud(const polyMesh &mesh, const word &cloudName, const IDLList< ParticleType > &particles)
Construct from mesh and a list of particles.
Definition: Cloud.C:190
const labelList & patchNbrProc() const
Map from patch index to the neighbouring processor index.
Definition: Cloud.H:172
void storeGlobalPositions() const
Call this before a topology change. Stores the particles global.
Definition: Cloud.C:786
void addParticle(ParticleType *pPtr)
Transfer particle to cloud.
Definition: Cloud.C:227
void move(TrackCloudType &cloud, typename ParticleType::trackingData &td)
Move the particles.
Definition: Cloud.C:292
Mesh object that implements searches within the local cells and faces.
Definition: meshSearch.H:59
static const meshSearch & New(const polyMesh &mesh, const pointInCellShapes=pointInCellShapes::tets)
Lookup or construct from mesh and cell decomposition option.
Definition: meshSearch.C:61
remote srcToTgtPoint(const label srcCelli, const point &p) const
Find the target processor and cell associated with a point in a.
Definition: meshToMesh.C:249
Non-conformal cyclic poly patch. As nonConformalCoupledPolyPatch, but the neighbouring patch is local...
virtual bool owner() const
Inherit the cyclic owner method.
const patchToPatches::rays & rays() const
Access the rays engine.
label origPatchIndex() const
Original patchID.
virtual void resetCpuTime()
Reset the CPU time (dummy)
Definition: cpuLoad.H:101
virtual void cpuTimeIncrement(const label celli)
Cache the CPU time increment for celli (dummy)
Definition: cpuLoad.H:105
static optionalCpuLoad & New(const word &name, const polyMesh &mesh, const bool loadBalancing)
Construct from polyMesh if loadBalancing is true.
Definition: cpuLoad.C:63
Foam::polyBoundaryMesh.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
label nOldCells() const
Number of cells in mesh before distribution.
const distributionMap & cellMap() const
Cell distribute map.
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
const meshToMesh & mapper() const
Return meshToMesh mapper.
Definition: polyMeshMap.H:81
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:1064
virtual const pointField & oldCellCentres() const
Return old cell centres for mesh motion.
Definition: polyMesh.C:1351
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelList & reverseCellMap() const
Reverse cell map.
Struct for keeping processor, element (cell, face, point) index.
Definition: remote.H:57
label elementi
Element index.
Definition: remote.H:70
label proci
Processor index.
Definition: remote.H:67
A class for handling words, derived from string.
Definition: word.H:63
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
label patchi
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionedScalar c
Speed of light in a vacuum.
const dimensionSet time
bool locate(const polyMesh &mesh, const point &position, barycentric &coordinates, label &celli, label &facei, label &faceTrii, const scalar stepFraction, const string &debugPrefix=NullObjectRef< string >())
Initialise the location at the given position. Returns whether or not a.
Definition: tracking.C:1592
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
dimensionedScalar pos(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Field< vector > vectorField
Specialisation of Field<T> for vector.
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
error FatalError
static const char nl
Definition: Ostream.H:297
volScalarField & p
void operator()(IDLList< Type > &x, const IDLList< Type > &y) const
Definition: Cloud.C:49
List operator to append one list onto another.
Definition: ListOps.H:313
const word cloudName(propsDict.lookup("cloudName"))