polyMesh.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017, 2020 OpenFOAM Foundation
9  Copyright (C) 2016-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "polyMesh.H"
30 #include "Time.H"
31 #include "cellIOList.H"
32 #include "wedgePolyPatch.H"
33 #include "emptyPolyPatch.H"
34 #include "globalMeshData.H"
35 #include "processorPolyPatch.H"
37 #include "indexedOctree.H"
38 #include "treeDataCell.H"
39 #include "MeshObject.H"
40 #include "pointMesh.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46  defineTypeNameAndDebug(polyMesh, 0);
47 }
48 
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
55 void Foam::polyMesh::calcDirections() const
56 {
57  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
58  {
59  solutionD_[cmpt] = 1;
60  }
61 
62  // Knock out empty and wedge directions. Note:they will be present on all
63  // domains.
64 
65  bool hasEmptyPatches = false;
66  bool hasWedgePatches = false;
67 
68  vector emptyDirVec = Zero;
69  vector wedgeDirVec = Zero;
70 
71  forAll(boundaryMesh(), patchi)
72  {
73  const polyPatch& pp = boundaryMesh()[patchi];
74  if (isA<emptyPolyPatch>(pp))
75  {
76  // Force calculation of geometric properties, independent of
77  // size. This avoids parallel synchronisation problems.
78  const vectorField::subField fa(pp.faceAreas());
79 
80  if (pp.size())
81  {
82  hasEmptyPatches = true;
83  emptyDirVec += sum(cmptMag(fa));
84  }
85  }
86  else if (isA<wedgePolyPatch>(pp))
87  {
88  const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>(pp);
89 
90  // Force calculation of geometric properties, independent of
91  // size. This avoids parallel synchronisation problems.
92  (void)wpp.faceNormals();
93 
94  if (pp.size())
95  {
96  hasWedgePatches = true;
97  wedgeDirVec += cmptMag(wpp.centreNormal());
98  }
99  }
100  }
101 
102 
103  if (returnReduceOr(hasEmptyPatches))
104  {
105  reduce(emptyDirVec, sumOp<vector>());
106 
107  emptyDirVec.normalise();
108 
109  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
110  {
111  if (emptyDirVec[cmpt] > 1e-6)
112  {
113  solutionD_[cmpt] = -1;
114  }
115  else
116  {
117  solutionD_[cmpt] = 1;
118  }
119  }
120  }
121 
122 
123  // Knock out wedge directions
124 
125  geometricD_ = solutionD_;
126 
127  if (returnReduceOr(hasWedgePatches))
128  {
129  reduce(wedgeDirVec, sumOp<vector>());
130 
131  wedgeDirVec.normalise();
132 
133  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
134  {
135  if (wedgeDirVec[cmpt] > 1e-6)
136  {
137  geometricD_[cmpt] = -1;
138  }
139  else
140  {
141  geometricD_[cmpt] = 1;
142  }
143  }
144  }
145 }
146 
147 
148 Foam::autoPtr<Foam::labelIOList> Foam::polyMesh::readTetBasePtIs() const
149 {
150  IOobject io
151  (
152  "tetBasePtIs",
153  instance(),
154  meshSubDir,
155  *this,
159  );
160 
161  if (io.typeHeaderOk<labelIOList>(true))
162  {
164  }
166  return nullptr;
167 }
168 
169 
170 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
171 
172 Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
173 :
175  primitiveMesh(),
176  points_
177  (
178  IOobject
179  (
180  "points",
181  time().findInstance(meshDir(), "points"),
182  meshSubDir,
183  *this,
184  IOobject::MUST_READ,
185  IOobject::NO_WRITE
186  )
187  ),
188  faces_
189  (
190  IOobject
191  (
192  "faces",
193  time().findInstance(meshDir(), "faces"),
194  meshSubDir,
195  *this,
196  IOobject::MUST_READ,
197  IOobject::NO_WRITE
198  )
199  ),
200  owner_
201  (
202  IOobject
203  (
204  "owner",
205  faces_.instance(),
206  meshSubDir,
207  *this,
208  IOobject::READ_IF_PRESENT,
209  IOobject::NO_WRITE
210  )
211  ),
212  neighbour_
213  (
214  IOobject
215  (
216  "neighbour",
217  faces_.instance(),
218  meshSubDir,
219  *this,
220  IOobject::READ_IF_PRESENT,
221  IOobject::NO_WRITE
222  )
223  ),
224  clearedPrimitives_(false),
225  boundary_
226  (
227  IOobject
228  (
229  "boundary",
230  time().findInstance // allow 'newer' boundary file
231  (
232  meshDir(),
233  "boundary",
234  IOobject::MUST_READ,
235  faces_.instance()
236  ),
237  meshSubDir,
238  *this,
239  IOobject::MUST_READ,
240  IOobject::NO_WRITE
241  ),
242  *this
243  ),
244  bounds_(points_),
245  comm_(UPstream::worldComm),
246  geometricD_(Zero),
247  solutionD_(Zero),
248  tetBasePtIsPtr_(nullptr),
249  cellTreePtr_(nullptr),
250  pointZones_
251  (
252  IOobject
253  (
254  "pointZones",
255  //time().findInstance
256  //(
257  // meshDir(),
258  // "pointZones",
259  // IOobject::READ_IF_PRESENT
260  //),
261  faces_.instance(),
262  meshSubDir,
263  *this,
264  IOobject::READ_IF_PRESENT,
265  IOobject::NO_WRITE
266  ),
267  *this
268  ),
269  faceZones_
270  (
271  IOobject
272  (
273  "faceZones",
274  //time().findInstance
275  //(
276  // meshDir(),
277  // "faceZones",
278  // IOobject::READ_IF_PRESENT
279  //),
280  faces_.instance(),
281  meshSubDir,
282  *this,
283  IOobject::READ_IF_PRESENT,
284  IOobject::NO_WRITE
285  ),
286  *this
287  ),
288  cellZones_
289  (
290  IOobject
291  (
292  "cellZones",
293  //time().findInstance
294  //(
295  // meshDir(),
296  // "cellZones",
297  // IOobject::READ_IF_PRESENT
298  //),
299  faces_.instance(),
300  meshSubDir,
301  *this,
302  IOobject::READ_IF_PRESENT,
303  IOobject::NO_WRITE
304  ),
305  *this
306  ),
307  globalMeshDataPtr_(nullptr),
308  moving_(false),
309  topoChanging_(false),
310  storeOldCellCentres_(false),
311  curMotionTimeIndex_(time().timeIndex()),
312  oldPointsPtr_(nullptr),
313  oldCellCentresPtr_(nullptr)
314 {
315  if (owner_.hasHeaderClass())
316  {
317  initMesh();
318  }
319  else
320  {
321  cellCompactIOList cLst
322  (
323  IOobject
324  (
325  "cells",
326  time().findInstance(meshDir(), "cells"),
327  meshSubDir,
328  *this,
331  )
332  );
333 
334  // Set the primitive mesh
335  initMesh(cLst);
336 
337  owner_.write();
338  neighbour_.write();
339  }
340 
341  if (returnReduceOr(boundary_.empty()))
342  {
344  << "Missing mesh boundary on one or more domains" << endl;
345 
346  // Warn if global empty mesh
347  if (returnReduceAnd(!nPoints()))
348  {
350  << "No points in mesh" << endl;
351  }
352  if (returnReduceAnd(!nCells()))
353  {
355  << "No cells in mesh" << endl;
356  }
357  }
358 
359  if (doInit)
360  {
361  polyMesh::init(false); // do not init lower levels
362  }
363 }
364 
365 
366 bool Foam::polyMesh::init(const bool doInit)
367 {
368  if (doInit)
369  {
370  primitiveMesh::init(doInit);
371  }
372 
373  // Calculate topology for the patches (processor-processor comms etc.)
374  boundary_.updateMesh();
375 
376  // Calculate the geometry for the patches (transformation tensors etc.)
377  boundary_.calcGeometry();
378 
379  // Initialise demand-driven data
380  calcDirections();
381 
382  return false;
383 }
384 
385 
386 Foam::polyMesh::polyMesh
387 (
388  const IOobject& io,
389  pointField&& points,
390  faceList&& faces,
391  labelList&& owner,
392  labelList&& neighbour,
393  const bool syncPar
394 )
395 :
397  primitiveMesh(),
398  points_
399  (
400  IOobject
401  (
402  "points",
403  instance(),
404  meshSubDir,
405  *this,
406  IOobject::NO_READ, //io.readOpt(),
407  io.writeOpt()
408  ),
409  std::move(points)
410  ),
411  faces_
412  (
413  IOobject
414  (
415  "faces",
416  instance(),
417  meshSubDir,
418  *this,
419  IOobject::NO_READ, //io.readOpt(),
420  io.writeOpt()
421  ),
422  std::move(faces)
423  ),
424  owner_
425  (
426  IOobject
427  (
428  "owner",
429  instance(),
430  meshSubDir,
431  *this,
432  IOobject::NO_READ, //io.readOpt(),
433  io.writeOpt()
434  ),
435  std::move(owner)
436  ),
437  neighbour_
438  (
439  IOobject
440  (
441  "neighbour",
442  instance(),
443  meshSubDir,
444  *this,
445  IOobject::NO_READ, //io.readOpt(),
446  io.writeOpt()
447  ),
448  std::move(neighbour)
449  ),
450  clearedPrimitives_(false),
451  boundary_
452  (
453  IOobject
454  (
455  "boundary",
456  instance(),
457  meshSubDir,
458  *this,
459  IOobject::NO_READ, // ignore since no alternative can be supplied
460  io.writeOpt()
461  ),
462  *this,
463  polyPatchList()
464  ),
465  bounds_(points_, syncPar),
466  comm_(UPstream::worldComm),
467  geometricD_(Zero),
468  solutionD_(Zero),
469  tetBasePtIsPtr_(nullptr),
470  cellTreePtr_(nullptr),
471  pointZones_
472  (
473  IOobject
474  (
475  "pointZones",
476  instance(),
477  meshSubDir,
478  *this,
479  IOobject::NO_READ, // ignore since no alternative can be supplied
480  IOobject::NO_WRITE
481  ),
482  *this,
483  PtrList<pointZone>()
484  ),
485  faceZones_
486  (
487  IOobject
488  (
489  "faceZones",
490  instance(),
491  meshSubDir,
492  *this,
493  IOobject::NO_READ,// ignore since no alternative can be supplied
494  IOobject::NO_WRITE
495  ),
496  *this,
497  PtrList<faceZone>()
498  ),
499  cellZones_
500  (
501  IOobject
502  (
503  "cellZones",
504  instance(),
505  meshSubDir,
506  *this,
507  IOobject::NO_READ, // ignore since no alternative can be supplied
508  IOobject::NO_WRITE
509  ),
510  *this,
511  PtrList<cellZone>()
512  ),
513  globalMeshDataPtr_(nullptr),
514  moving_(false),
515  topoChanging_(false),
516  storeOldCellCentres_(false),
517  curMotionTimeIndex_(time().timeIndex()),
518  oldPointsPtr_(nullptr),
519  oldCellCentresPtr_(nullptr)
520 {
521  // Check if the faces and cells are valid
522  forAll(faces_, facei)
523  {
524  const face& curFace = faces_[facei];
525 
526  if (min(curFace) < 0 || max(curFace) > points_.size())
527  {
529  << "Face " << facei << "contains vertex labels out of range: "
530  << curFace << " Max point index = " << points_.size()
531  << abort(FatalError);
532  }
533  }
535  // Set the primitive mesh
536  initMesh();
537 }
538 
539 
540 Foam::polyMesh::polyMesh
541 (
542  const IOobject& io,
543  pointField&& points,
544  faceList&& faces,
545  cellList&& cells,
546  const bool syncPar
547 )
548 :
550  primitiveMesh(),
551  points_
552  (
553  IOobject
554  (
555  "points",
556  instance(),
557  meshSubDir,
558  *this,
559  IOobject::NO_READ,
560  io.writeOpt()
561  ),
562  std::move(points)
563  ),
564  faces_
565  (
566  IOobject
567  (
568  "faces",
569  instance(),
570  meshSubDir,
571  *this,
572  IOobject::NO_READ,
573  io.writeOpt()
574  ),
575  std::move(faces)
576  ),
577  owner_
578  (
579  IOobject
580  (
581  "owner",
582  instance(),
583  meshSubDir,
584  *this,
585  IOobject::NO_READ,
586  io.writeOpt()
587  ),
588  0
589  ),
590  neighbour_
591  (
592  IOobject
593  (
594  "neighbour",
595  instance(),
596  meshSubDir,
597  *this,
598  IOobject::NO_READ,
599  io.writeOpt()
600  ),
601  0
602  ),
603  clearedPrimitives_(false),
604  boundary_
605  (
606  IOobject
607  (
608  "boundary",
609  instance(),
610  meshSubDir,
611  *this,
612  IOobject::NO_READ,
613  io.writeOpt()
614  ),
615  *this,
616  0
617  ),
618  bounds_(points_, syncPar),
619  comm_(UPstream::worldComm),
620  geometricD_(Zero),
621  solutionD_(Zero),
622  tetBasePtIsPtr_(nullptr),
623  cellTreePtr_(nullptr),
624  pointZones_
625  (
626  IOobject
627  (
628  "pointZones",
629  instance(),
630  meshSubDir,
631  *this,
632  IOobject::NO_READ,
633  IOobject::NO_WRITE
634  ),
635  *this,
636  0
637  ),
638  faceZones_
639  (
640  IOobject
641  (
642  "faceZones",
643  instance(),
644  meshSubDir,
645  *this,
646  IOobject::NO_READ,
647  IOobject::NO_WRITE
648  ),
649  *this,
650  0
651  ),
652  cellZones_
653  (
654  IOobject
655  (
656  "cellZones",
657  instance(),
658  meshSubDir,
659  *this,
660  IOobject::NO_READ,
661  IOobject::NO_WRITE
662  ),
663  *this,
664  0
665  ),
666  globalMeshDataPtr_(nullptr),
667  moving_(false),
668  topoChanging_(false),
669  storeOldCellCentres_(false),
670  curMotionTimeIndex_(time().timeIndex()),
671  oldPointsPtr_(nullptr),
672  oldCellCentresPtr_(nullptr)
673 {
674  // Check if faces are valid
675  forAll(faces_, facei)
676  {
677  const face& curFace = faces_[facei];
678 
679  if (min(curFace) < 0 || max(curFace) > points_.size())
680  {
682  << "Face " << facei << "contains vertex labels out of range: "
683  << curFace << " Max point index = " << points_.size()
684  << abort(FatalError);
685  }
686  }
687 
688  // Transfer in cell list
689  cellList cLst(std::move(cells));
690 
691  // Check if cells are valid
692  forAll(cLst, celli)
693  {
694  const cell& curCell = cLst[celli];
695 
696  if (min(curCell) < 0 || max(curCell) > faces_.size())
697  {
699  << "Cell " << celli << "contains face labels out of range: "
700  << curCell << " Max face index = " << faces_.size()
701  << abort(FatalError);
702  }
703  }
704 
705  // Set the primitive mesh
706  initMesh(cLst);
707 }
708 
709 
710 Foam::polyMesh::polyMesh(const IOobject& io, const zero, const bool syncPar)
711 :
712  polyMesh(io, pointField(), faceList(), labelList(), labelList(), syncPar)
713 {}
714 
715 
717 (
719  autoPtr<faceList>&& faces,
720  autoPtr<labelList>&& owner,
721  autoPtr<labelList>&& neighbour,
722  const labelUList& patchSizes,
723  const labelUList& patchStarts,
724  const bool validBoundary
725 )
726 {
727  // Clear addressing. Keep geometric props and updateable props for mapping.
728  clearAddressing(true);
729 
730  // Take over new primitive data.
731  // Optimized to avoid overwriting data at all
732  if (points)
733  {
734  points_.transfer(*points);
735  bounds_ = boundBox(points_, validBoundary);
736  }
737 
738  if (faces)
739  {
740  faces_.transfer(*faces);
741  }
742 
743  if (owner)
744  {
745  owner_.transfer(*owner);
746  }
747 
748  if (neighbour)
749  {
750  neighbour_.transfer(*neighbour);
751  }
752 
753 
754  // Reset patch sizes and starts
755  forAll(boundary_, patchi)
756  {
757  boundary_[patchi] = polyPatch
758  (
759  boundary_[patchi],
760  boundary_,
761  patchi,
762  patchSizes[patchi],
763  patchStarts[patchi]
764  );
765  }
766 
767 
768  // Flags the mesh files as being changed
769  setInstance(time().timeName());
770 
771  // Check if the faces and cells are valid
772  forAll(faces_, facei)
773  {
774  const face& curFace = faces_[facei];
775 
776  if (min(curFace) < 0 || max(curFace) > points_.size())
777  {
779  << "Face " << facei << " contains vertex labels out of range: "
780  << curFace << " Max point index = " << points_.size()
781  << abort(FatalError);
782  }
783  }
784 
785 
786  // Set the primitive mesh from the owner_, neighbour_.
787  // Works out from patch end where the active faces stop.
788  initMesh();
789 
790 
791  if (validBoundary)
792  {
793  // Note that we assume that all the patches stay the same and are
794  // correct etc. so we can already use the patches to do
795  // processor-processor comms.
796 
797  // Calculate topology for the patches (processor-processor comms etc.)
798  boundary_.updateMesh();
799 
800  // Calculate the geometry for the patches (transformation tensors etc.)
801  boundary_.calcGeometry();
802 
803  // Warn if global empty mesh
804  if (returnReduceAnd(!nPoints()) || returnReduceAnd(!nCells()))
805  {
807  << "No points or no cells in mesh" << endl;
808  }
809  }
810 }
811 
812 
813 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
814 
816 {
817  clearOut();
818  resetMotion();
819 }
820 
821 
822 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
823 
824 const Foam::word& Foam::polyMesh::regionName(const word& region)
825 {
826  return (region == polyMesh::defaultRegion ? word::null : region);
827 }
828 
829 
830 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
831 
833 {
834  if (objectRegistry::dbDir() == defaultRegion)
835  {
836  return parent().dbDir();
837  }
838 
839  return objectRegistry::dbDir();
840 }
841 
844 {
845  return dbDir()/meshSubDir;
846 }
847 
850 {
852 }
853 
856 {
857  return points_.instance();
858 }
859 
862 {
863  return faces_.instance();
864 }
865 
866 
868 {
869  if (geometricD_.x() == 0)
870  {
871  calcDirections();
872  }
873 
874  return geometricD_;
875 }
876 
878 Foam::label Foam::polyMesh::nGeometricD() const
879 {
880  return cmptSum(geometricD() + Vector<label>::one)/2;
881 }
882 
883 
885 {
886  if (solutionD_.x() == 0)
887  {
888  calcDirections();
889  }
890 
891  return solutionD_;
892 }
893 
895 Foam::label Foam::polyMesh::nSolutionD() const
896 {
897  return cmptSum(solutionD() + Vector<label>::one)/2;
898 }
899 
900 
902 {
903  if (!tetBasePtIsPtr_)
904  {
905  if (debug)
906  {
908  << "Forcing storage of base points."
909  << endl;
910  }
911 
912  labelList basePts
913  (
915  );
916 
917  tetBasePtIsPtr_.reset
918  (
919  new labelIOList
920  (
921  IOobject
922  (
923  "tetBasePtIs",
924  instance(),
925  meshSubDir,
926  *this,
930  ),
931  std::move(basePts)
932  )
933  );
934  }
935 
936  return *tetBasePtIsPtr_;
937 }
938 
939 
942 {
943  if (!cellTreePtr_)
944  {
945  Random rndGen(261782);
946 
947  treeBoundBox overallBb(points());
948  overallBb.inflate(rndGen, 1e-4, ROOTVSMALL);
949 
950  cellTreePtr_.reset
951  (
952  new indexedOctree<treeDataCell>
953  (
954  treeDataCell
955  (
956  false, // not cache bb
957  *this,
958  CELL_TETS // use tet-decomposition for any inside test
959  ),
960  overallBb,
961  8, // maxLevel
962  10, // leafsize
963  5.0 // duplicity
964  )
965  );
966  }
967 
968  return *cellTreePtr_;
969 }
970 
971 
973 (
974  polyPatchList& plist,
975  const bool validBoundary
976 )
977 {
978  if (boundaryMesh().size())
979  {
981  << "boundary already exists"
982  << abort(FatalError);
983  }
984 
985  // Reset valid directions
986  geometricD_ = Zero;
987  solutionD_ = Zero;
988 
989  boundary_.transfer(plist);
990 
991  // parallelData depends on the processorPatch ordering so force
992  // recalculation. Problem: should really be done in removeBoundary but
993  // there is some info in parallelData which might be interesting inbetween
994  // removeBoundary and addPatches.
995  globalMeshDataPtr_.clear();
996 
997  if (validBoundary)
998  {
999  // Calculate topology for the patches (processor-processor comms etc.)
1000  boundary_.updateMesh();
1001 
1002  // Calculate the geometry for the patches (transformation tensors etc.)
1003  boundary_.calcGeometry();
1005  boundary_.checkDefinition();
1006  }
1007 }
1008 
1009 
1011 (
1012  PtrList<pointZone>&& pz,
1013  PtrList<faceZone>&& fz,
1014  PtrList<cellZone>&& cz
1015 )
1016 {
1017  if (pointZones_.size() || faceZones_.size() || cellZones_.size())
1018  {
1020  << "point, face or cell zone already exists"
1021  << abort(FatalError);
1022  }
1023 
1024  // Point zones - take ownership of the pointers
1025  if (pz.size())
1026  {
1027  pointZones_.clear();
1028  pointZones_.transfer(pz);
1029  pointZones_.writeOpt(IOobject::AUTO_WRITE);
1030  }
1031 
1032  // Face zones - take ownership of the pointers
1033  if (fz.size())
1034  {
1035  faceZones_.clear();
1036  faceZones_.transfer(fz);
1037  faceZones_.writeOpt(IOobject::AUTO_WRITE);
1038  }
1039 
1040  // Cell zones - take ownership of the pointers
1041  if (cz.size())
1042  {
1043  cellZones_.clear();
1044  cellZones_.transfer(cz);
1045  cellZones_.writeOpt(IOobject::AUTO_WRITE);
1046  }
1047 }
1048 
1049 
1051 (
1052  const List<polyPatch*>& p,
1053  const bool validBoundary
1054 )
1055 {
1056  // Acquire ownership of the pointers
1057  polyPatchList plist(const_cast<List<polyPatch*>&>(p));
1058 
1059  addPatches(plist, validBoundary);
1060 }
1061 
1062 
1064 (
1065  const List<pointZone*>& pz,
1066  const List<faceZone*>& fz,
1067  const List<cellZone*>& cz
1068 )
1069 {
1070  // Acquire ownership of the pointers
1071  addZones
1072  (
1074  PtrList<faceZone>(const_cast<List<faceZone*>&>(fz)),
1075  PtrList<cellZone>(const_cast<List<cellZone*>&>(cz))
1076  );
1077 }
1078 
1079 
1081 {
1082  if (clearedPrimitives_)
1083  {
1085  << "points deallocated"
1087  }
1088 
1089  return points_;
1090 }
1091 
1094 {
1095  return io.upToDate(points_);
1096 }
1097 
1100 {
1101  io.eventNo() = points_.eventNo()+1;
1102 }
1103 
1104 
1106 {
1107  if (clearedPrimitives_)
1108  {
1110  << "faces deallocated"
1112  }
1113 
1114  return faces_;
1115 }
1116 
1119 {
1120  return owner_;
1121 }
1122 
1125 {
1126  return neighbour_;
1127 }
1128 
1129 
1131 {
1132  if (!moving_)
1133  {
1134  return points_;
1135  }
1136 
1137  if (!oldPointsPtr_)
1138  {
1139  if (debug)
1140  {
1142  }
1143 
1144  oldPointsPtr_.reset(new pointField(points_));
1145  curMotionTimeIndex_ = time().timeIndex();
1146  }
1147 
1148  return *oldPointsPtr_;
1149 }
1150 
1151 
1153 {
1154  storeOldCellCentres_ = true;
1155 
1156  if (!moving_)
1157  {
1158  return cellCentres();
1159  }
1160 
1161  if (!oldCellCentresPtr_)
1162  {
1163  oldCellCentresPtr_.reset(new pointField(cellCentres()));
1164  }
1165 
1166  return *oldCellCentresPtr_;
1167 }
1168 
1169 
1170 void Foam::polyMesh::movePoints(const pointField& newPoints)
1171 {
1173  << "Moving points for time " << time().value()
1174  << " index " << time().timeIndex() << endl;
1175 
1176  if (newPoints.size() != points_.size())
1177  {
1179  << "Size of newPoints " << newPoints.size()
1180  << " does not correspond to current mesh points size "
1181  << points_.size()
1182  << exit(FatalError);
1183  }
1184 
1185 
1186  moving(true);
1187 
1188  // Pick up old points
1189  if (curMotionTimeIndex_ != time().timeIndex())
1190  {
1191  if (debug)
1192  {
1193  Info<< "tmp<scalarField> polyMesh::movePoints(const pointField&) : "
1194  << " Storing current points for time " << time().value()
1195  << " index " << time().timeIndex() << endl;
1196  }
1197 
1198  if (storeOldCellCentres_)
1199  {
1200  oldCellCentresPtr_.clear();
1201  oldCellCentresPtr_.reset(new pointField(cellCentres()));
1202  }
1203 
1204  // Mesh motion in the new time step
1205  oldPointsPtr_.clear();
1206  oldPointsPtr_.reset(new pointField(points_));
1207  curMotionTimeIndex_ = time().timeIndex();
1208  }
1209 
1210  points_ = newPoints;
1211 
1212  bool moveError = false;
1213  if (debug)
1214  {
1215  // Check mesh motion
1216  if (checkMeshMotion(points_, true))
1217  {
1218  moveError = true;
1219 
1221  << "Moving the mesh with given points will "
1222  << "invalidate the mesh." << nl
1223  << "Mesh motion should not be executed." << endl;
1224  }
1225  }
1226 
1227  points_.writeOpt(IOobject::AUTO_WRITE);
1228  points_.instance() = time().timeName();
1229  points_.eventNo() = getEvent();
1230 
1231  if (tetBasePtIsPtr_)
1232  {
1233  tetBasePtIsPtr_->writeOpt(IOobject::AUTO_WRITE);
1234  tetBasePtIsPtr_->instance() = time().timeName();
1235  tetBasePtIsPtr_->eventNo() = getEvent();
1236  }
1237 
1238  // Currently a no-op; earlier versions set meshPhi and call
1239  // primitiveMesh::clearGeom
1240  (void)primitiveMesh::movePoints(points_, oldPoints());
1241 
1242  // Update the mesh geometry (via fvGeometryScheme)
1243  // - updateGeom is virtual -> calls fvMesh::updateGeom (or higher)
1244  // - fvMesh::updateGeom defers to surfaceInterpolation::updateGeom(),
1245  // which defers to fvGeometryScheme::movePoints()
1246  // - set the mesh flux
1247  // - clear out/recalculate stale geometry
1248  updateGeom();
1249 
1250  // Adjust parallel shared points
1251  if (globalMeshDataPtr_)
1252  {
1253  globalMeshDataPtr_->movePoints(points_);
1254  }
1255 
1256  // Force recalculation of all geometric data with new points
1257 
1258  bounds_ = boundBox(points_);
1259  boundary_.movePoints(points_);
1260 
1261  pointZones_.movePoints(points_);
1262  faceZones_.movePoints(points_);
1263  cellZones_.movePoints(points_);
1264 
1265  // Reset cell tree - it gets built from mesh geometry so might have
1266  // wrong boxes. It is correct as long as none of the cells leaves
1267  // the boxes it is in which most likely is almost never the case except
1268  // for tiny displacements. An alternative is to check the displacements
1269  // to see if they are tiny - imagine a big windtunnel with a small rotating
1270  // object. In this case the processors without the rotating object wouldn't
1271  // have to clear any geometry. However your critical path still stays the
1272  // same so no time would be gained (unless the decomposition gets weighted).
1273  // Small benefit for lots of scope for problems so not done.
1274  cellTreePtr_.clear();
1275 
1276  // Reset valid directions (could change with rotation)
1277  geometricD_ = Zero;
1278  solutionD_ = Zero;
1279 
1280  // Note: tet-base decomposition does not get cleared. Ideally your face
1281  // decomposition should not change during mesh motion ...
1282 
1283 
1284  meshObject::movePoints<polyMesh>(*this);
1285  meshObject::movePoints<pointMesh>(*this);
1286 
1287  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1288 
1289 
1290  if (debug && moveError)
1291  {
1292  // Write mesh to ease debugging. Note we want to avoid calling
1293  // e.g. fvMesh::write since meshPhi not yet complete.
1294  polyMesh::write();
1295  }
1296 }
1297 
1298 
1299 void Foam::polyMesh::resetMotion() const
1301  curMotionTimeIndex_ = 0;
1302  oldPointsPtr_.clear();
1303  oldCellCentresPtr_.clear();
1304 }
1305 
1306 
1308 {
1309  if (!globalMeshDataPtr_)
1310  {
1311  if (debug)
1312  {
1313  Pout<< "polyMesh::globalData() const : "
1314  << "Constructing parallelData from processor topology"
1315  << endl;
1316  }
1317  // Construct globalMeshData using processorPatch information only.
1318  globalMeshDataPtr_.reset(new globalMeshData(*this));
1319  }
1320 
1321  return *globalMeshDataPtr_;
1322 }
1323 
1325 Foam::label Foam::polyMesh::comm() const noexcept
1326 {
1327  return comm_;
1328 }
1329 
1331 Foam::label& Foam::polyMesh::comm() noexcept
1332 {
1333  return comm_;
1334 }
1335 
1336 
1337 void Foam::polyMesh::removeFiles(const fileName& instanceDir) const
1338 {
1339  fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
1340 
1341  rm(meshFilesPath/"points");
1342  rm(meshFilesPath/"faces");
1343  rm(meshFilesPath/"owner");
1344  rm(meshFilesPath/"neighbour");
1345  rm(meshFilesPath/"cells");
1346  rm(meshFilesPath/"boundary");
1347  rm(meshFilesPath/"pointZones");
1348  rm(meshFilesPath/"faceZones");
1349  rm(meshFilesPath/"cellZones");
1350  rm(meshFilesPath/"meshModifiers");
1351  rm(meshFilesPath/"parallelData");
1352 
1353  // remove subdirectories
1354  if (isDir(meshFilesPath/"sets"))
1355  {
1356  rmDir(meshFilesPath/"sets");
1357  }
1358 }
1359 
1360 
1362 {
1363  removeFiles(instance());
1364 }
1365 
1366 
1368 (
1369  const point& p,
1370  label& celli,
1371  label& tetFacei,
1372  label& tetPti
1373 ) const
1374 {
1375  celli = -1;
1376  tetFacei = -1;
1377  tetPti = -1;
1378 
1379  const indexedOctree<treeDataCell>& tree = cellTree();
1380 
1381  // Find point inside cell
1382  celli = tree.findInside(p);
1383 
1384  if (celli != -1)
1385  {
1386  // Check the nearest cell to see if the point is inside.
1387  findTetFacePt(celli, p, tetFacei, tetPti);
1388  }
1389 }
1390 
1391 
1393 (
1394  const label celli,
1395  const point& p,
1396  label& tetFacei,
1397  label& tetPti
1398 ) const
1399 {
1400  const polyMesh& mesh = *this;
1401 
1403  tetFacei = tet.face();
1404  tetPti = tet.tetPt();
1405 }
1406 
1407 
1409 (
1410  const point& p,
1411  label celli,
1412  const cellDecomposition decompMode
1413 ) const
1414 {
1415  switch (decompMode)
1416  {
1417  case FACE_PLANES:
1418  {
1419  return primitiveMesh::pointInCell(p, celli);
1420  }
1421  break;
1422 
1423  case FACE_CENTRE_TRIS:
1424  {
1425  // only test that point is on inside of plane defined by cell face
1426  // triangles
1427  const cell& cFaces = cells()[celli];
1428 
1429  forAll(cFaces, cFacei)
1430  {
1431  label facei = cFaces[cFacei];
1432  const face& f = faces_[facei];
1433  const point& fc = faceCentres()[facei];
1434  bool isOwn = (owner_[facei] == celli);
1435 
1436  forAll(f, fp)
1437  {
1438  label pointi;
1439  label nextPointi;
1440 
1441  if (isOwn)
1442  {
1443  pointi = f[fp];
1444  nextPointi = f.nextLabel(fp);
1445  }
1446  else
1447  {
1448  pointi = f.nextLabel(fp);
1449  nextPointi = f[fp];
1450  }
1451 
1452  triPointRef faceTri
1453  (
1454  points()[pointi],
1455  points()[nextPointi],
1456  fc
1457  );
1458 
1459  vector proj = p - faceTri.centre();
1460 
1461  if ((faceTri.areaNormal() & proj) > 0)
1462  {
1463  return false;
1464  }
1465  }
1466  }
1467  return true;
1468  }
1469  break;
1470 
1471  case FACE_DIAG_TRIS:
1472  {
1473  // only test that point is on inside of plane defined by cell face
1474  // triangles
1475  const cell& cFaces = cells()[celli];
1476 
1477  forAll(cFaces, cFacei)
1478  {
1479  label facei = cFaces[cFacei];
1480  const face& f = faces_[facei];
1481 
1482  for (label tetPti = 1; tetPti < f.size() - 1; tetPti++)
1483  {
1484  // Get tetIndices of face triangle
1485  tetIndices faceTetIs(celli, facei, tetPti);
1486 
1487  triPointRef faceTri = faceTetIs.faceTri(*this);
1488 
1489  vector proj = p - faceTri.centre();
1490 
1491  if ((faceTri.areaNormal() & proj) > 0)
1492  {
1493  return false;
1494  }
1495  }
1496  }
1497 
1498  return true;
1499  }
1500  break;
1501 
1502  case CELL_TETS:
1503  {
1504  label tetFacei;
1505  label tetPti;
1506 
1507  findTetFacePt(celli, p, tetFacei, tetPti);
1508 
1509  return tetFacei != -1;
1510  }
1511  break;
1512  }
1513 
1514  return false;
1515 }
1516 
1517 
1518 Foam::label Foam::polyMesh::findCell
1519 (
1520  const point& p,
1521  const cellDecomposition decompMode
1522 ) const
1523 {
1524  if
1525  (
1526  Pstream::parRun()
1527  && (decompMode == FACE_DIAG_TRIS || decompMode == CELL_TETS)
1528  )
1529  {
1530  // Force construction of face-diagonal decomposition before testing
1531  // for zero cells.
1532  //
1533  // If parallel running a local domain might have zero cells so never
1534  // construct the face-diagonal decomposition which uses parallel
1535  // transfers.
1536  (void)tetBasePtIs();
1537  }
1538 
1539  if (nCells() == 0)
1540  {
1541  return -1;
1542  }
1543 
1544  if (decompMode == CELL_TETS)
1545  {
1546  // Advanced search method utilizing an octree
1547  // and tet-decomposition of the cells
1548 
1549  label celli;
1550  label tetFacei;
1551  label tetPti;
1552 
1553  findCellFacePt(p, celli, tetFacei, tetPti);
1554 
1555  return celli;
1556  }
1557  else
1558  {
1559  // Approximate search avoiding the construction of an octree
1560  // and cell decomposition
1561 
1562  if (Pstream::parRun() && decompMode == FACE_DIAG_TRIS)
1563  {
1564  // Force construction of face-diagonal decomposition before testing
1565  // for zero cells. If parallel running a local domain might have
1566  // zero cells so never construct the face-diagonal decomposition
1567  // (which uses parallel transfers)
1568  (void)tetBasePtIs();
1569  }
1570 
1571  // Find the nearest cell centre to this location
1572  label celli = findNearestCell(p);
1573 
1574  // If point is in the nearest cell return
1575  if (pointInCell(p, celli, decompMode))
1576  {
1577  return celli;
1578  }
1579  else
1580  {
1581  // Point is not in the nearest cell so search all cells
1582 
1583  for (label celli = 0; celli < nCells(); celli++)
1584  {
1585  if (pointInCell(p, celli, decompMode))
1586  {
1587  return celli;
1588  }
1589  }
1590 
1591  return -1;
1592  }
1593  }
1594 }
1595 
1596 
1597 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
Definition: polyMesh.C:359
uint8_t direction
Definition: direction.H:48
A class for handling file names.
Definition: fileName.H:71
static labelList findFaceBasePts(const polyMesh &mesh, scalar tol=minTetQuality, bool report=false)
Find a suitable base point for each face for decomposition into tets.
List< cell > cellList
List of cell.
Definition: cellListFwd.H:39
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual void movePoints(const pointField &)
Move points.
Definition: polyMesh.C:1163
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:854
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
Cmpt cmptSum(const SphericalTensor< Cmpt > &st)
Return the sum of components of a SphericalTensor.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1117
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:894
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:842
virtual void setUpToDatePoints(regIOobject &io) const
Set io to be up-to-date with points.
Definition: polyMesh.C:1092
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:162
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:75
void resetMotion() const
Reset motion.
Definition: polyMesh.C:1292
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:877
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
Random rndGen
Definition: createFields.H:23
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:402
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1004
void resetPrimitives(autoPtr< pointField > &&points, autoPtr< faceList > &&faces, autoPtr< labelList > &&owner, autoPtr< labelList > &&neighbour, const labelUList &patchSizes, const labelUList &patchStarts, const bool validBoundary=true)
Reset mesh primitive data. Assumes all patch info correct.
Definition: polyMesh.C:710
A bounding box defined in terms of min/max extrema points.
Definition: boundBox.H:63
const cellList & cells() const
bool pointInCell(const point &p, label celli) const
Return true if the point is in the cell.
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
Definition: polyMesh.C:825
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:169
Ignore writing from objectRegistry::writeObject()
bool pointInCell(const point &p, label celli, const cellDecomposition=CELL_TETS) const
Test if point p is in the celli.
Definition: polyMesh.C:1402
void movePoints(const pointField &p, const pointField &oldP)
Move points.
label nGeometricD() const
Return the number of valid geometric dimensions in the mesh.
Definition: polyMesh.C:871
bool hasHeaderClass() const noexcept
True if headerClassName() is non-empty (after reading)
Definition: IOobjectI.H:218
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1073
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
static tetIndices findTet(const polyMesh &mesh, label cI, const point &pt)
Find the tet decomposition of the cell containing the given point.
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
Definition: polyMesh.C:860
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:860
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
Definition: polyPatch.H:56
word timeName
Definition: getTimeIndex.H:3
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:848
IOList< label > labelIOList
IO for a List of label.
Definition: labelIOList.H:32
dynamicFvMesh & mesh
void removeFiles() const
Remove all files from mesh instance()
Definition: polyMesh.C:1354
const cellShapeList & cells
const pointField & points
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:584
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
const Time & time() const noexcept
Return time registry.
void findCellFacePt(const point &p, label &celli, label &tetFacei, label &tetPti) const
Find the cell, tetFacei and tetPti for point p.
Definition: polyMesh.C:1361
#define DebugInFunction
Report an information message using Foam::Info.
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:397
Tree tree(triangles.begin(), triangles.end())
void addZones(PtrList< pointZone > &&pz, PtrList< faceZone > &&fz, PtrList< cellZone > &&cz)
Add mesh zones.
Definition: polyMesh.C:1004
virtual const pointField & oldPoints() const
Return old points (mesh motion)
Definition: polyMesh.C:1123
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1111
label comm() const noexcept
Return communicator used for parallel communication.
Definition: polyMesh.C:1318
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
static const word null
An empty word.
Definition: word.H:84
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1300
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
Definition: tetIndices.H:78
Vector< scalar > vector
Definition: vector.H:57
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1098
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (uses typeFilePath to find file) and check its info.
bool rmDir(const fileName &directory, const bool silent=false, const bool emptyOnly=false)
Remove a directory and its contents recursively,.
Definition: POSIX.C:1433
Templated 3D Vector derived from VectorSpace adding construction from 3 components, element access using x(), y() and z() member functions and the inner-product (dot-product) and cross-product operators.
Definition: Vector.H:58
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
const direction noexcept
Definition: Scalar.H:258
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
CompactIOList< cell, label > cellCompactIOList
Compact IO for a List of cell.
Definition: cellIOList.H:35
labelList f(nPoints)
A subset of mesh cells.
Definition: cellZone.H:58
label nSolutionD() const
Return the number of valid solved-for dimensions in the mesh.
Definition: polyMesh.C:888
virtual bool upToDatePoints(const regIOobject &io) const
Return true if io is up-to-date with points.
Definition: polyMesh.C:1086
bool empty() const noexcept
True if the list is empty (ie, size() is zero)
Definition: UPtrListI.H:106
const indexedOctree< treeDataCell > & cellTree() const
Return the cell search tree.
Definition: polyMesh.C:934
virtual const pointField & oldCellCentres() const
Return old cellCentres (mesh motion)
Definition: polyMesh.C:1145
A subset of mesh points.
Definition: pointZone.H:61
vector point
Point is a vector.
Definition: point.H:37
#define WarningInFunction
Report a warning using Foam::Warning.
label nCells() const noexcept
Number of mesh cells.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:836
Nothing to be read.
Automatically write from objectRegistry::writeObject()
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
void findTetFacePt(const label celli, const point &p, label &tetFacei, label &tetPti) const
Find the tetFacei and tetPti for point p in celli.
Definition: polyMesh.C:1386
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangleFwd.H:39
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1512
virtual ~polyMesh()
Destructor.
Definition: polyMesh.C:808
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:65
messageStream Info
Information stream (stdout output on master, null elsewhere)
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
SubField< vector > subField
Declare type of subField.
Definition: Field.H:128
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
Reading is optional [identical to READ_IF_PRESENT].
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
A subset of mesh faces organised as a primitive patch.
Definition: faceZone.H:60
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
Registry of regIOobjects.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
void addPatches(polyPatchList &plist, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:966
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:171
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Inter-processor communications stream.
Definition: UPstream.H:62
Do not request registration (bool: false)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
label timeIndex
Definition: getTimeIndex.H:24
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:133