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-2024 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 
40 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44 
45 template<class Type>
47 {
48  void operator()(IDLList<Type>& x, const IDLList<Type>& y) const
49  {
50  if (y.size())
51  {
52  forAllConstIter(typename IDLList<Type>, y, iter)
53  {
54  x.append(new Type(iter()));
55  }
56  }
57  }
58 };
59 
60 }
61 
62 
63 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
64 
65 template<class ParticleType>
67 (
68  const polyMesh& pMesh
69 )
70 {
71  const polyBoundaryMesh& pbm = pMesh.boundaryMesh();
72 
73  labelList result(pbm.size(), -1);
74 
75  if (Pstream::parRun())
76  {
77  forAll(pbm, patchi)
78  {
79  if (isA<processorPolyPatch>(pbm[patchi]))
80  {
81  const processorPolyPatch& ppp =
82  refCast<const processorPolyPatch>(pbm[patchi]);
83 
84  result[patchi] = ppp.neighbProcNo();
85  }
86  }
87  }
88 
89  return result;
90 }
91 
92 
93 template<class ParticleType>
95 (
96  const polyMesh& pMesh
97 )
98 {
99  const polyBoundaryMesh& pbm = pMesh.boundaryMesh();
100 
101  labelList result(pbm.size(), -1);
102 
103  if (Pstream::parRun())
104  {
105  PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
106 
107  forAll(pbm, patchi)
108  {
109  if (isA<processorPolyPatch>(pbm[patchi]))
110  {
111  const processorPolyPatch& ppp =
112  refCast<const processorPolyPatch>(pbm[patchi]);
113 
114  UOPstream(ppp.neighbProcNo(), pBufs)()
115  << ppp.index();
116  }
117  }
118 
119  pBufs.finishedSends();
120 
121  forAll(pbm, patchi)
122  {
123  if (isA<processorPolyPatch>(pbm[patchi]))
124  {
125  const processorPolyPatch& ppp =
126  refCast<const processorPolyPatch>(pbm[patchi]);
127 
128  UIPstream(ppp.neighbProcNo(), pBufs)()
129  >> result[patchi];
130  }
131  }
132  }
133 
134  return result;
135 }
136 
137 
138 template<class ParticleType>
140 (
141  const polyMesh& pMesh
142 )
143 {
144  const polyBoundaryMesh& pbm = pMesh.boundaryMesh();
145 
146  labelListList result(pbm.size(), labelList());
147 
148  forAll(pbm, patchi)
149  {
150  if (isA<nonConformalCyclicPolyPatch>(pbm[patchi]))
151  {
152  const nonConformalCyclicPolyPatch& nccPp =
153  refCast<const nonConformalCyclicPolyPatch>(pbm[patchi]);
154 
155  result[nccPp.origPatchIndex()].append(patchi);
156  }
157  }
158 
159  return result;
160 }
161 
162 
163 template<class ParticleType>
165 {
166  const polyBoundaryMesh& pbm = pMesh_.boundaryMesh();
167 
168  forAll(patchNonConformalCyclicPatches_, patchi)
169  {
170  forAll(patchNonConformalCyclicPatches_[patchi], i)
171  {
172  const label nccPatchi =
173  patchNonConformalCyclicPatches_[patchi][i];
174 
175  const nonConformalCyclicPolyPatch& nccPp =
176  refCast<const nonConformalCyclicPolyPatch>(pbm[nccPatchi]);
177 
178  if (nccPp.owner()) nccPp.rays();
179  }
180  }
181 }
182 
183 
184 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
185 
186 template<class ParticleType>
188 (
189  const polyMesh& pMesh,
190  const word& cloudName,
191  const IDLList<ParticleType>& particles
192 )
193 :
194  cloud(pMesh, cloudName),
195  IDLList<ParticleType>(),
196  pMesh_(pMesh),
197  patchNbrProc_(patchNbrProc(pMesh)),
198  patchNbrProcPatch_(patchNbrProcPatch(pMesh)),
199  patchNonConformalCyclicPatches_(patchNonConformalCyclicPatches(pMesh)),
200  globalPositionsPtr_(),
201  timeIndex_(-1)
202 {
203  // Ask for the tetBasePtIs and oldCellCentres to trigger all processors to
204  // build them, otherwise, if some processors have no particles then there
205  // is a comms mismatch.
206  pMesh_.tetBasePtIs();
207  pMesh_.oldCellCentres();
208 
209  if (particles.size())
210  {
212  }
213 }
214 
215 
216 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
217 
218 template<class ParticleType>
220 {
221  this->append(pPtr);
222 }
223 
224 
225 template<class ParticleType>
227 {
228  delete(this->remove(&p));
229 }
230 
231 
232 template<class ParticleType>
234 {
235  label lostCount = 0;
236 
237  forAllIter(typename Cloud<ParticleType>, *this, pIter)
238  {
239  if (pIter().cell() == -1)
240  {
241  deleteParticle(pIter());
242  lostCount ++;
243  }
244  }
245 
246  reduce(lostCount, sumOp<label>());
247  if (lostCount != 0)
248  {
250  << "Cloud " << this->name()
251  << " deleted " << lostCount << " lost particles" << endl;
252  }
253 }
254 
255 
256 template<class ParticleType>
258 {
259  // Reset particle count and particles only
260  // - not changing the cloud object registry or reference to the polyMesh
261  ParticleType::particleCount_ = 0;
263 }
264 
265 
266 template<class ParticleType>
268 {
269  forAllIter(typename Cloud<ParticleType>, *this, pIter)
270  {
271  pIter().reset(0);
272  }
273 
274  timeIndex_ = pMesh_.time().timeIndex();
275 }
276 
277 
278 template<class ParticleType>
279 template<class TrackCloudType>
281 (
282  TrackCloudType& cloud,
283  typename ParticleType::trackingData& td
284 )
285 {
286  // If the time has changed, modify the particles accordingly
287  if (timeIndex_ != pMesh_.time().timeIndex())
288  {
289  changeTimeStep();
290  }
291 
292  // Clear the global positions as these are about to change
293  globalPositionsPtr_.clear();
294 
295  // Ensure rays are available for non conformal transfers
296  storeRays();
297 
298  // Create transfer buffers
300 
301  // Create lists of particles and patch indices to transfer
303  List<DynamicList<label>> sendPatchIndices(Pstream::nProcs());
304 
305  optionalCpuLoad& cloudCpuTime
306  (
307  optionalCpuLoad::New(name() + ":cpuLoad", pMesh_, cloud.cpuLoad())
308  );
309 
310  // While there are particles to transfer
311  while (true)
312  {
313  // Clear the transfer lists
314  forAll(sendParticles, proci)
315  {
316  sendParticles[proci].clear();
317  sendPatchIndices[proci].clear();
318  }
319 
320  if (cloud.cpuLoad())
321  {
322  cloudCpuTime.resetCpuTime();
323  }
324 
325  // Loop over all particles
326  forAllIter(typename Cloud<ParticleType>, *this, pIter)
327  {
328  ParticleType& p = pIter();
329 
330  // Move the particle
331  const bool keepParticle = p.move(cloud, td);
332 
333  if (cloud.cpuLoad())
334  {
335  cloudCpuTime.cpuTimeIncrement(p.cell());
336  }
337 
338  // If the particle is to be kept
339  if (keepParticle)
340  {
341  if (td.sendToProc != -1)
342  {
343  #ifdef FULLDEBUG
344  if (!Pstream::parRun() || !p.onBoundaryFace(pMesh_))
345  {
347  << "Switch processor flag is true when no parallel "
348  << "transfer is possible. This is a bug."
349  << exit(FatalError);
350  }
351  #endif
352 
353  p.prepareForParallelTransfer(cloud, td);
354 
355  sendParticles[td.sendToProc].append(this->remove(&p));
356 
357  sendPatchIndices[td.sendToProc].append(td.sendToPatch);
358  }
359  }
360  else
361  {
362  deleteParticle(p);
363  }
364  }
365 
366  // If running in serial then everything has been moved, so finish
367  if (!Pstream::parRun())
368  {
369  break;
370  }
371 
372  // Clear transfer buffers
373  pBufs.clear();
374 
375  // Stream into send buffers
376  forAll(sendParticles, proci)
377  {
378  if (sendParticles[proci].size())
379  {
380  UOPstream particleStream(proci, pBufs);
381 
382  particleStream
383  << sendPatchIndices[proci]
384  << sendParticles[proci];
385  }
386  }
387 
388  // Start sending. Sets number of bytes transferred.
389  labelList receiveSizes(Pstream::nProcs());
390  pBufs.finishedSends(receiveSizes);
391 
392  // Determine if any particles were transferred. If not, then finish.
393  bool transferred = false;
394  forAll(receiveSizes, proci)
395  {
396  if (receiveSizes[proci])
397  {
398  transferred = true;
399  break;
400  }
401  }
402  reduce(transferred, orOp<bool>());
403  if (!transferred)
404  {
405  break;
406  }
407 
408  // Retrieve from receive buffers and add into the cloud
409  forAll(receiveSizes, proci)
410  {
411  if (receiveSizes[proci])
412  {
413  UIPstream particleStream(proci, pBufs);
414 
415  const labelList receivePatchIndices(particleStream);
416 
417  IDLList<ParticleType> newParticles(particleStream);
418 
419  label i = 0;
420 
421  forAllIter(typename Cloud<ParticleType>, newParticles, iter)
422  {
423  const label patchi = receivePatchIndices[i ++];
424 
425  ParticleType& p = iter();
426 
427  td.sendToPatch = patchi;
428 
429  p.correctAfterParallelTransfer(cloud, td);
430 
431  addParticle(newParticles.remove(&p));
432  }
433  }
434  }
435  }
436 
437  // Warn about any approximate locates
438  Pstream::listCombineGather(td.patchNLocateBoundaryHits, plusEqOp<label>());
439  if (Pstream::master())
440  {
441  forAll(td.patchNLocateBoundaryHits, patchi)
442  {
443  if (td.patchNLocateBoundaryHits[patchi] != 0)
444  {
446  << "Cloud " << name() << " did not accurately locate "
447  << td.patchNLocateBoundaryHits[patchi]
448  << " particles that transferred to patch "
449  << pMesh_.boundaryMesh()[patchi].name() << nl;
450  }
451  }
452  }
453 }
454 
455 
456 template<class ParticleType>
458 {
459  if (map.reverseCellMap().empty()) return;
460 
461  // Ask for the tetBasePtIs to trigger all processors to build
462  // them, otherwise, if some processors have no particles then
463  // there is a comms mismatch.
464  pMesh_.tetBasePtIs();
465  pMesh_.oldCellCentres();
466 
467  if (!globalPositionsPtr_.valid())
468  {
470  << "Global positions are not available. "
471  << "Cloud::storeGlobalPositions has not been called."
472  << exit(FatalError);
473  }
474 
475  const vectorField& positions = globalPositionsPtr_();
476 
477  label lostCount = 0;
478 
479  label particlei = 0;
480  forAllIter(typename Cloud<ParticleType>, *this, iter)
481  {
482  const point& pos = positions[particlei ++];
483 
484  const label celli = map.reverseCellMap()[iter().cell()];
485 
486  if (!iter().locate(pMesh_, pos, celli))
487  {
488  this->remove(iter);
489  lostCount ++;
490  }
491  }
492 
493  reduce(lostCount, sumOp<label>());
494  if (lostCount != 0)
495  {
497  << "Topology change of cloud " << this->name()
498  << " lost " << lostCount << " particles" << endl;
499  }
500 }
501 
502 
503 template<class ParticleType>
505 {
506  // Ask for the tetBasePtIs to trigger all processors to build
507  // them, otherwise, if some processors have no particles then
508  // there is a comms mismatch.
509  pMesh_.tetBasePtIs();
510  pMesh_.oldCellCentres();
511 
512  // Update cached mesh indexing
513  patchNbrProc_ = patchNbrProc(pMesh_);
514  patchNbrProcPatch_ = patchNbrProcPatch(pMesh_);
515  patchNonConformalCyclicPatches_ = patchNonConformalCyclicPatches(pMesh_);
516 
517  if (!globalPositionsPtr_.valid())
518  {
520  << "Global positions are not available. "
521  << "Cloud::storeGlobalPositions has not been called."
522  << exit(FatalError);
523  }
524 
525  const vectorField& positions = globalPositionsPtr_();
526 
527  label lostCount = 0;
528 
529  // Loop the particles. Map those that remain on this processor, and
530  // transfer others into send arrays.
531  List<DynamicList<label>> sendCellIndices(Pstream::nProcs());
532  List<DynamicList<point>> sendPositions(Pstream::nProcs());
534  {
535  label particlei = 0;
536  forAllIter(typename Cloud<ParticleType>, *this, iter)
537  {
538  const point& pos = positions[particlei ++];
539 
540  const remote tgtProcCell =
541  map.mapper().srcToTgtPoint(iter().cell(), pos);
542  const label proci = tgtProcCell.proci;
543  const label celli = tgtProcCell.elementi;
544 
545  if (tgtProcCell == remote())
546  {
547  this->remove(iter);
548  lostCount ++;
549  }
550  else if (proci == Pstream::myProcNo())
551  {
552  if (!iter().locate(pMesh_, pos, celli))
553  {
554  this->remove(iter);
555  lostCount ++;
556  }
557  }
558  else
559  {
560  sendCellIndices[proci].append(celli);
561  sendPositions[proci].append(pos);
562  sendParticles[proci].append(this->remove(iter));
563  }
564  }
565  }
566 
567  // If parallel then send and receive particles that move processes and map
568  // those sent to this process
569  if (Pstream::parRun())
570  {
571  // Create transfer buffers
573 
574  // Stream into send buffers
575  forAll(sendParticles, proci)
576  {
577  if (sendParticles[proci].size())
578  {
579  UOPstream particleStream(proci, pBufs);
580 
581  particleStream
582  << sendCellIndices[proci]
583  << sendPositions[proci]
584  << sendParticles[proci];
585  }
586  }
587 
588  // Finish sending
589  labelList receiveSizes(Pstream::nProcs());
590  pBufs.finishedSends(receiveSizes);
591 
592  // Retrieve from receive buffers and map into the new mesh
593  forAll(sendParticles, proci)
594  {
595  if (receiveSizes[proci])
596  {
597  UIPstream particleStream(proci, pBufs);
598 
599  const labelList receiveCellIndices(particleStream);
600  const List<point> receivePositions(particleStream);
601  IDLList<ParticleType> receiveParticles(particleStream);
602 
603  label particlei = 0;
604  forAllIter(typename Cloud<ParticleType>, receiveParticles, iter)
605  {
606  const label celli = receiveCellIndices[particlei];
607  const vector& pos = receivePositions[particlei ++];
608 
609  if (iter().locate(pMesh_, pos, celli))
610  {
611  this->append(receiveParticles.remove(iter));
612  }
613  else
614  {
615  receiveParticles.remove(iter);
616  lostCount ++;
617  }
618  }
619  }
620  }
621  }
622 
623  reduce(lostCount, sumOp<label>());
624  if (lostCount != 0)
625  {
627  << "Mesh-to-mesh mapping of cloud " << this->name()
628  << " lost " << lostCount << " particles" << endl;
629  }
630 }
631 
632 
633 template<class ParticleType>
635 {
636  // Ask for the tetBasePtIs to trigger all processors to build
637  // them, otherwise, if some processors have no particles then
638  // there is a comms mismatch.
639  pMesh_.tetBasePtIs();
640  pMesh_.oldCellCentres();
641 
642  // Update cached mesh indexing
643  patchNbrProc_ = patchNbrProc(pMesh_);
644  patchNbrProcPatch_ = patchNbrProcPatch(pMesh_);
645  patchNonConformalCyclicPatches_ = patchNonConformalCyclicPatches(pMesh_);
646 
647  if (!globalPositionsPtr_.valid())
648  {
650  << "Global positions are not available. "
651  << "Cloud::storeGlobalPositions has not been called."
652  << exit(FatalError);
653  }
654 
655  const vectorField& positions = globalPositionsPtr_();
656 
657  // Distribute the global positions
658  List<List<point>> cellParticlePositions(map.nOldCells());
659  {
660  labelList cellParticleis(map.nOldCells(), 0);
661  forAllIter(typename Cloud<ParticleType>, *this, iter)
662  {
663  cellParticleis[iter().cell()] ++;
664  }
665  forAll(cellParticlePositions, celli)
666  {
667  cellParticlePositions[celli].resize(cellParticleis[celli]);
668  }
669 
670  label particlei = 0;
671  cellParticleis = 0;
672  forAllIter(typename Cloud<ParticleType>, *this, iter)
673  {
674  const label celli = iter().cell();
675  label& cellParticlei = cellParticleis[celli];
676 
677  cellParticlePositions[celli][cellParticlei ++] =
678  positions[particlei ++];
679  }
680  }
682  (
684  List<labelPair>(),
685  pMesh_.nCells(),
686  map.cellMap().subMap(),
687  false,
688  map.cellMap().constructMap(),
689  false,
690  cellParticlePositions,
692  flipOp(),
693  List<point>()
694  );
695 
696  // Distribute the particles
697  List<IDLList<ParticleType>> cellParticles(map.nOldCells());
698  forAllIter(typename Cloud<ParticleType>, *this, iter)
699  {
700  cellParticles[iter().cell()].append(this->remove(iter));
701  }
703  (
705  List<labelPair>(),
706  pMesh_.nCells(),
707  map.cellMap().subMap(),
708  false,
709  map.cellMap().constructMap(),
710  false,
711  cellParticles,
713  flipOp(),
715  );
716 
717  label lostCount = 0;
718 
719  // Locate the particles within the new mesh
720  forAll(cellParticles, celli)
721  {
722  label cellParticlei = 0;
723  forAllIter(typename IDLList<ParticleType>, cellParticles[celli], iter)
724  {
725  const point& pos = cellParticlePositions[celli][cellParticlei++];
726 
727  if (iter().locate(pMesh_, pos, celli))
728  {
729  this->append(cellParticles[celli].remove(iter));
730  }
731  else
732  {
733  cellParticles[celli].remove(iter);
734  lostCount ++;
735  }
736  }
737  }
738 
739  reduce(lostCount, sumOp<label>());
740  if (lostCount != 0)
741  {
743  << "Distribution of cloud " << this->name()
744  << " lost " << lostCount << " particles" << endl;
745  }
746 }
747 
748 
749 template<class ParticleType>
751 {
752  OFstream pObj
753  (
754  this->db().time().path()/this->name() + "_positions.obj"
755  );
756 
757  forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
758  {
759  const point pos = pIter().position(pMesh_);
760 
761  pObj<< "v " << pos.x() << " " << pos.y() << " " << pos.z() << nl;
762  }
763 
764  pObj.flush();
765 }
766 
767 
768 template<class ParticleType>
770 {
771  // Store the global positions for later use by mapping functions. It would
772  // be preferable not to need this. If the objects passed to had a copy of
773  // the old mesh then the global positions could be recovered within the
774  // mapping functions, and this pre-processing would not be necessary.
775 
776  globalPositionsPtr_.reset(new vectorField(this->size()));
777 
778  vectorField& positions = globalPositionsPtr_();
779 
780  label particlei = 0;
781  forAllConstIter(typename Cloud<ParticleType>, *this, iter)
782  {
783  positions[particlei++] = iter().position(pMesh_);
784  }
785 }
786 
787 
788 // * * * * * * * * * * * * * * * * IOStream operators * * * * * * * * * * * //
789 
790 #include "CloudIO.C"
791 
792 // ************************************************************************* //
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:434
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
Base cloud calls templated on particle type.
Definition: Cloud.H:74
void changeTimeStep()
Change the particles' state from the end of the previous time.
Definition: Cloud.C:267
void deleteParticle(ParticleType &)
Remove particle from cloud and delete.
Definition: Cloud.C:226
void writePositions() const
Write positions to <cloudName>_positions.obj file.
Definition: Cloud.C:750
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:457
virtual void distribute(const polyDistributionMap &)
Redistribute or update using the given distribution map.
Definition: Cloud.C:634
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:233
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: Cloud.C:504
void cloudReset(const Cloud< ParticleType > &c)
Reset the particles.
Definition: Cloud.C:257
Cloud(const polyMesh &mesh, const word &cloudName, const IDLList< ParticleType > &particles)
Construct from mesh and a list of particles.
Definition: Cloud.C:188
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:769
void addParticle(ParticleType *pPtr)
Transfer particle to cloud.
Definition: Cloud.C:219
void move(TrackCloudType &cloud, typename ParticleType::trackingData &td)
Move the particles.
Definition: Cloud.C:281
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:86
virtual void flush()
Flush stream.
Definition: OSstream.C:223
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
A cloud is a collection of lagrangian particles.
Definition: cloud.H:55
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
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...
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:80
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:1023
virtual const pointField & oldCellCentres() const
Return old cell centres for mesh motion.
Definition: polyMesh.C:1369
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:62
#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.
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:257
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
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.
error FatalError
static const char nl
Definition: Ostream.H:266
volScalarField & p
void operator()(IDLList< Type > &x, const IDLList< Type > &y) const
Definition: Cloud.C:48
List operator to append one list onto another.
Definition: ListOps.H:304
const word cloudName(propsDict.lookup("cloudName"))