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,
158  );
159 
160  if (io.typeHeaderOk<labelIOList>(true))
161  {
163  }
165  return nullptr;
166 }
167 
168 
169 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
170 
171 Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
172 :
174  primitiveMesh(),
175  points_
176  (
177  IOobject
178  (
179  "points",
180  time().findInstance(meshDir(), "points"),
181  meshSubDir,
182  *this,
183  IOobject::MUST_READ,
184  IOobject::NO_WRITE
185  )
186  ),
187  faces_
188  (
189  IOobject
190  (
191  "faces",
192  time().findInstance(meshDir(), "faces"),
193  meshSubDir,
194  *this,
195  IOobject::MUST_READ,
196  IOobject::NO_WRITE
197  )
198  ),
199  owner_
200  (
201  IOobject
202  (
203  "owner",
204  faces_.instance(),
205  meshSubDir,
206  *this,
207  IOobject::READ_IF_PRESENT,
208  IOobject::NO_WRITE
209  )
210  ),
211  neighbour_
212  (
213  IOobject
214  (
215  "neighbour",
216  faces_.instance(),
217  meshSubDir,
218  *this,
219  IOobject::READ_IF_PRESENT,
220  IOobject::NO_WRITE
221  )
222  ),
223  clearedPrimitives_(false),
224  boundary_
225  (
226  IOobject
227  (
228  "boundary",
229  time().findInstance // allow 'newer' boundary file
230  (
231  meshDir(),
232  "boundary",
233  IOobject::MUST_READ,
234  faces_.instance()
235  ),
236  meshSubDir,
237  *this,
238  IOobject::MUST_READ,
239  IOobject::NO_WRITE
240  ),
241  *this
242  ),
243  bounds_(points_),
244  comm_(UPstream::worldComm),
245  geometricD_(Zero),
246  solutionD_(Zero),
247  tetBasePtIsPtr_(readTetBasePtIs()),
248  cellTreePtr_(nullptr),
249  pointZones_
250  (
251  IOobject
252  (
253  "pointZones",
254  //time().findInstance
255  //(
256  // meshDir(),
257  // "pointZones",
258  // IOobject::READ_IF_PRESENT
259  //),
260  faces_.instance(),
261  meshSubDir,
262  *this,
263  IOobject::READ_IF_PRESENT,
264  IOobject::NO_WRITE
265  ),
266  *this
267  ),
268  faceZones_
269  (
270  IOobject
271  (
272  "faceZones",
273  //time().findInstance
274  //(
275  // meshDir(),
276  // "faceZones",
277  // IOobject::READ_IF_PRESENT
278  //),
279  faces_.instance(),
280  meshSubDir,
281  *this,
282  IOobject::READ_IF_PRESENT,
283  IOobject::NO_WRITE
284  ),
285  *this
286  ),
287  cellZones_
288  (
289  IOobject
290  (
291  "cellZones",
292  //time().findInstance
293  //(
294  // meshDir(),
295  // "cellZones",
296  // IOobject::READ_IF_PRESENT
297  //),
298  faces_.instance(),
299  meshSubDir,
300  *this,
301  IOobject::READ_IF_PRESENT,
302  IOobject::NO_WRITE
303  ),
304  *this
305  ),
306  globalMeshDataPtr_(nullptr),
307  moving_(false),
308  topoChanging_(false),
309  storeOldCellCentres_(false),
310  curMotionTimeIndex_(time().timeIndex()),
311  oldPointsPtr_(nullptr),
312  oldCellCentresPtr_(nullptr)
313 {
314  if (owner_.hasHeaderClass())
315  {
316  initMesh();
317  }
318  else
319  {
320  cellCompactIOList cLst
321  (
322  IOobject
323  (
324  "cells",
325  time().findInstance(meshDir(), "cells"),
326  meshSubDir,
327  *this,
330  )
331  );
332 
333  // Set the primitive mesh
334  initMesh(cLst);
335 
336  owner_.write();
337  neighbour_.write();
338  }
339 
340  if (returnReduceOr(boundary_.empty()))
341  {
343  << "Missing mesh boundary on one or more domains" << endl;
344 
345  // Warn if global empty mesh
346  if (returnReduceAnd(!nPoints()))
347  {
349  << "No points in mesh" << endl;
350  }
351  if (returnReduceAnd(!nCells()))
352  {
354  << "No cells in mesh" << endl;
355  }
356  }
357 
358  if (doInit)
359  {
360  polyMesh::init(false); // do not init lower levels
361  }
362 }
363 
364 
365 bool Foam::polyMesh::init(const bool doInit)
366 {
367  if (doInit)
368  {
369  primitiveMesh::init(doInit);
370  }
371 
372  // Calculate topology for the patches (processor-processor comms etc.)
373  boundary_.updateMesh();
374 
375  // Calculate the geometry for the patches (transformation tensors etc.)
376  boundary_.calcGeometry();
377 
378  // Initialise demand-driven data
379  calcDirections();
380 
381  return false;
382 }
383 
384 
385 Foam::polyMesh::polyMesh
386 (
387  const IOobject& io,
388  pointField&& points,
389  faceList&& faces,
390  labelList&& owner,
391  labelList&& neighbour,
392  const bool syncPar
393 )
394 :
396  primitiveMesh(),
397  points_
398  (
399  IOobject
400  (
401  "points",
402  instance(),
403  meshSubDir,
404  *this,
405  IOobject::NO_READ, //io.readOpt(),
406  io.writeOpt()
407  ),
408  std::move(points)
409  ),
410  faces_
411  (
412  IOobject
413  (
414  "faces",
415  instance(),
416  meshSubDir,
417  *this,
418  IOobject::NO_READ, //io.readOpt(),
419  io.writeOpt()
420  ),
421  std::move(faces)
422  ),
423  owner_
424  (
425  IOobject
426  (
427  "owner",
428  instance(),
429  meshSubDir,
430  *this,
431  IOobject::NO_READ, //io.readOpt(),
432  io.writeOpt()
433  ),
434  std::move(owner)
435  ),
436  neighbour_
437  (
438  IOobject
439  (
440  "neighbour",
441  instance(),
442  meshSubDir,
443  *this,
444  IOobject::NO_READ, //io.readOpt(),
445  io.writeOpt()
446  ),
447  std::move(neighbour)
448  ),
449  clearedPrimitives_(false),
450  boundary_
451  (
452  IOobject
453  (
454  "boundary",
455  instance(),
456  meshSubDir,
457  *this,
458  IOobject::NO_READ, // ignore since no alternative can be supplied
459  io.writeOpt()
460  ),
461  *this,
462  polyPatchList()
463  ),
464  bounds_(points_, syncPar),
465  comm_(UPstream::worldComm),
466  geometricD_(Zero),
467  solutionD_(Zero),
468  tetBasePtIsPtr_(nullptr),
469  cellTreePtr_(nullptr),
470  pointZones_
471  (
472  IOobject
473  (
474  "pointZones",
475  instance(),
476  meshSubDir,
477  *this,
478  IOobject::NO_READ, // ignore since no alternative can be supplied
479  IOobject::NO_WRITE
480  ),
481  *this,
482  PtrList<pointZone>()
483  ),
484  faceZones_
485  (
486  IOobject
487  (
488  "faceZones",
489  instance(),
490  meshSubDir,
491  *this,
492  IOobject::NO_READ,// ignore since no alternative can be supplied
493  IOobject::NO_WRITE
494  ),
495  *this,
496  PtrList<faceZone>()
497  ),
498  cellZones_
499  (
500  IOobject
501  (
502  "cellZones",
503  instance(),
504  meshSubDir,
505  *this,
506  IOobject::NO_READ, // ignore since no alternative can be supplied
507  IOobject::NO_WRITE
508  ),
509  *this,
510  PtrList<cellZone>()
511  ),
512  globalMeshDataPtr_(nullptr),
513  moving_(false),
514  topoChanging_(false),
515  storeOldCellCentres_(false),
516  curMotionTimeIndex_(time().timeIndex()),
517  oldPointsPtr_(nullptr),
518  oldCellCentresPtr_(nullptr)
519 {
520  // Check if the faces and cells are valid
521  forAll(faces_, facei)
522  {
523  const face& curFace = faces_[facei];
524 
525  if (min(curFace) < 0 || max(curFace) > points_.size())
526  {
528  << "Face " << facei << "contains vertex labels out of range: "
529  << curFace << " Max point index = " << points_.size()
530  << abort(FatalError);
531  }
532  }
534  // Set the primitive mesh
535  initMesh();
536 }
537 
538 
539 Foam::polyMesh::polyMesh
540 (
541  const IOobject& io,
542  pointField&& points,
543  faceList&& faces,
544  cellList&& cells,
545  const bool syncPar
546 )
547 :
549  primitiveMesh(),
550  points_
551  (
552  IOobject
553  (
554  "points",
555  instance(),
556  meshSubDir,
557  *this,
558  IOobject::NO_READ,
559  io.writeOpt()
560  ),
561  std::move(points)
562  ),
563  faces_
564  (
565  IOobject
566  (
567  "faces",
568  instance(),
569  meshSubDir,
570  *this,
571  IOobject::NO_READ,
572  io.writeOpt()
573  ),
574  std::move(faces)
575  ),
576  owner_
577  (
578  IOobject
579  (
580  "owner",
581  instance(),
582  meshSubDir,
583  *this,
584  IOobject::NO_READ,
585  io.writeOpt()
586  ),
587  0
588  ),
589  neighbour_
590  (
591  IOobject
592  (
593  "neighbour",
594  instance(),
595  meshSubDir,
596  *this,
597  IOobject::NO_READ,
598  io.writeOpt()
599  ),
600  0
601  ),
602  clearedPrimitives_(false),
603  boundary_
604  (
605  IOobject
606  (
607  "boundary",
608  instance(),
609  meshSubDir,
610  *this,
611  IOobject::NO_READ,
612  io.writeOpt()
613  ),
614  *this,
615  0
616  ),
617  bounds_(points_, syncPar),
618  comm_(UPstream::worldComm),
619  geometricD_(Zero),
620  solutionD_(Zero),
621  tetBasePtIsPtr_(nullptr),
622  cellTreePtr_(nullptr),
623  pointZones_
624  (
625  IOobject
626  (
627  "pointZones",
628  instance(),
629  meshSubDir,
630  *this,
631  IOobject::NO_READ,
632  IOobject::NO_WRITE
633  ),
634  *this,
635  0
636  ),
637  faceZones_
638  (
639  IOobject
640  (
641  "faceZones",
642  instance(),
643  meshSubDir,
644  *this,
645  IOobject::NO_READ,
646  IOobject::NO_WRITE
647  ),
648  *this,
649  0
650  ),
651  cellZones_
652  (
653  IOobject
654  (
655  "cellZones",
656  instance(),
657  meshSubDir,
658  *this,
659  IOobject::NO_READ,
660  IOobject::NO_WRITE
661  ),
662  *this,
663  0
664  ),
665  globalMeshDataPtr_(nullptr),
666  moving_(false),
667  topoChanging_(false),
668  storeOldCellCentres_(false),
669  curMotionTimeIndex_(time().timeIndex()),
670  oldPointsPtr_(nullptr),
671  oldCellCentresPtr_(nullptr)
672 {
673  // Check if faces are valid
674  forAll(faces_, facei)
675  {
676  const face& curFace = faces_[facei];
677 
678  if (min(curFace) < 0 || max(curFace) > points_.size())
679  {
681  << "Face " << facei << "contains vertex labels out of range: "
682  << curFace << " Max point index = " << points_.size()
683  << abort(FatalError);
684  }
685  }
686 
687  // Transfer in cell list
688  cellList cLst(std::move(cells));
689 
690  // Check if cells are valid
691  forAll(cLst, celli)
692  {
693  const cell& curCell = cLst[celli];
694 
695  if (min(curCell) < 0 || max(curCell) > faces_.size())
696  {
698  << "Cell " << celli << "contains face labels out of range: "
699  << curCell << " Max face index = " << faces_.size()
700  << abort(FatalError);
701  }
702  }
703 
704  // Set the primitive mesh
705  initMesh(cLst);
706 }
707 
708 
709 Foam::polyMesh::polyMesh(const IOobject& io, const zero, const bool syncPar)
710 :
711  polyMesh(io, pointField(), faceList(), labelList(), labelList(), syncPar)
712 {}
713 
714 
716 (
718  autoPtr<faceList>&& faces,
719  autoPtr<labelList>&& owner,
720  autoPtr<labelList>&& neighbour,
721  const labelUList& patchSizes,
722  const labelUList& patchStarts,
723  const bool validBoundary
724 )
725 {
726  // Clear addressing. Keep geometric props and updateable props for mapping.
727  clearAddressing(true);
728 
729  // Take over new primitive data.
730  // Optimized to avoid overwriting data at all
731  if (points)
732  {
733  points_.transfer(*points);
734  bounds_ = boundBox(points_, validBoundary);
735  }
736 
737  if (faces)
738  {
739  faces_.transfer(*faces);
740  }
741 
742  if (owner)
743  {
744  owner_.transfer(*owner);
745  }
746 
747  if (neighbour)
748  {
749  neighbour_.transfer(*neighbour);
750  }
751 
752 
753  // Reset patch sizes and starts
754  forAll(boundary_, patchi)
755  {
756  boundary_[patchi] = polyPatch
757  (
758  boundary_[patchi],
759  boundary_,
760  patchi,
761  patchSizes[patchi],
762  patchStarts[patchi]
763  );
764  }
765 
766 
767  // Flags the mesh files as being changed
768  setInstance(time().timeName());
769 
770  // Check if the faces and cells are valid
771  forAll(faces_, facei)
772  {
773  const face& curFace = faces_[facei];
774 
775  if (min(curFace) < 0 || max(curFace) > points_.size())
776  {
778  << "Face " << facei << " contains vertex labels out of range: "
779  << curFace << " Max point index = " << points_.size()
780  << abort(FatalError);
781  }
782  }
783 
784 
785  // Set the primitive mesh from the owner_, neighbour_.
786  // Works out from patch end where the active faces stop.
787  initMesh();
788 
789 
790  if (validBoundary)
791  {
792  // Note that we assume that all the patches stay the same and are
793  // correct etc. so we can already use the patches to do
794  // processor-processor comms.
795 
796  // Calculate topology for the patches (processor-processor comms etc.)
797  boundary_.updateMesh();
798 
799  // Calculate the geometry for the patches (transformation tensors etc.)
800  boundary_.calcGeometry();
801 
802  // Warn if global empty mesh
803  if (returnReduceAnd(!nPoints()) || returnReduceAnd(!nCells()))
804  {
806  << "No points or no cells in mesh" << endl;
807  }
808  }
809 }
810 
811 
812 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
813 
815 {
816  clearOut();
817  resetMotion();
818 }
819 
820 
821 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
822 
823 const Foam::word& Foam::polyMesh::regionName(const word& region)
824 {
825  return (region == polyMesh::defaultRegion ? word::null : region);
826 }
827 
828 
829 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
830 
832 {
833  if (objectRegistry::dbDir() == defaultRegion)
834  {
835  return parent().dbDir();
836  }
837 
838  return objectRegistry::dbDir();
839 }
840 
843 {
844  return dbDir()/meshSubDir;
845 }
846 
849 {
851 }
852 
855 {
856  return points_.instance();
857 }
858 
861 {
862  return faces_.instance();
863 }
864 
865 
867 {
868  if (geometricD_.x() == 0)
869  {
870  calcDirections();
871  }
872 
873  return geometricD_;
874 }
875 
877 Foam::label Foam::polyMesh::nGeometricD() const
878 {
879  return cmptSum(geometricD() + Vector<label>::one)/2;
880 }
881 
882 
884 {
885  if (solutionD_.x() == 0)
886  {
887  calcDirections();
888  }
889 
890  return solutionD_;
891 }
892 
894 Foam::label Foam::polyMesh::nSolutionD() const
895 {
896  return cmptSum(solutionD() + Vector<label>::one)/2;
897 }
898 
899 
901 {
902  if (!tetBasePtIsPtr_)
903  {
904  if (debug)
905  {
907  << "Forcing storage of base points."
908  << endl;
909  }
910 
911  tetBasePtIsPtr_.reset
912  (
913  new labelIOList
914  (
915  IOobject
916  (
917  "tetBasePtIs",
918  instance(),
919  meshSubDir,
920  *this,
923  ),
925  )
926  );
927  }
928 
929  return *tetBasePtIsPtr_;
930 }
931 
932 
935 {
936  if (!cellTreePtr_)
937  {
938  Random rndGen(261782);
939 
940  treeBoundBox overallBb(points());
941  overallBb.inflate(rndGen, 1e-4, ROOTVSMALL);
942 
943  cellTreePtr_.reset
944  (
945  new indexedOctree<treeDataCell>
946  (
947  treeDataCell
948  (
949  false, // not cache bb
950  *this,
951  CELL_TETS // use tet-decomposition for any inside test
952  ),
953  overallBb,
954  8, // maxLevel
955  10, // leafsize
956  5.0 // duplicity
957  )
958  );
959  }
960 
961  return *cellTreePtr_;
962 }
963 
964 
966 (
967  polyPatchList& plist,
968  const bool validBoundary
969 )
970 {
971  if (boundaryMesh().size())
972  {
974  << "boundary already exists"
975  << abort(FatalError);
976  }
977 
978  // Reset valid directions
979  geometricD_ = Zero;
980  solutionD_ = Zero;
981 
982  boundary_.transfer(plist);
983 
984  // parallelData depends on the processorPatch ordering so force
985  // recalculation. Problem: should really be done in removeBoundary but
986  // there is some info in parallelData which might be interesting inbetween
987  // removeBoundary and addPatches.
988  globalMeshDataPtr_.clear();
989 
990  if (validBoundary)
991  {
992  // Calculate topology for the patches (processor-processor comms etc.)
993  boundary_.updateMesh();
994 
995  // Calculate the geometry for the patches (transformation tensors etc.)
996  boundary_.calcGeometry();
998  boundary_.checkDefinition();
999  }
1000 }
1001 
1002 
1004 (
1005  PtrList<pointZone>&& pz,
1006  PtrList<faceZone>&& fz,
1007  PtrList<cellZone>&& cz
1008 )
1009 {
1010  if (pointZones_.size() || faceZones_.size() || cellZones_.size())
1011  {
1013  << "point, face or cell zone already exists"
1014  << abort(FatalError);
1015  }
1016 
1017  // Point zones - take ownership of the pointers
1018  if (pz.size())
1019  {
1020  pointZones_.clear();
1021  pointZones_.transfer(pz);
1022  pointZones_.writeOpt(IOobject::AUTO_WRITE);
1023  }
1024 
1025  // Face zones - take ownership of the pointers
1026  if (fz.size())
1027  {
1028  faceZones_.clear();
1029  faceZones_.transfer(fz);
1030  faceZones_.writeOpt(IOobject::AUTO_WRITE);
1031  }
1032 
1033  // Cell zones - take ownership of the pointers
1034  if (cz.size())
1035  {
1036  cellZones_.clear();
1037  cellZones_.transfer(cz);
1038  cellZones_.writeOpt(IOobject::AUTO_WRITE);
1039  }
1040 }
1041 
1042 
1044 (
1045  const List<polyPatch*>& p,
1046  const bool validBoundary
1047 )
1048 {
1049  // Acquire ownership of the pointers
1050  polyPatchList plist(const_cast<List<polyPatch*>&>(p));
1051 
1052  addPatches(plist, validBoundary);
1053 }
1054 
1055 
1057 (
1058  const List<pointZone*>& pz,
1059  const List<faceZone*>& fz,
1060  const List<cellZone*>& cz
1061 )
1062 {
1063  // Acquire ownership of the pointers
1064  addZones
1065  (
1067  PtrList<faceZone>(const_cast<List<faceZone*>&>(fz)),
1068  PtrList<cellZone>(const_cast<List<cellZone*>&>(cz))
1069  );
1070 }
1071 
1072 
1074 {
1075  if (clearedPrimitives_)
1076  {
1078  << "points deallocated"
1080  }
1081 
1082  return points_;
1083 }
1084 
1087 {
1088  return io.upToDate(points_);
1089 }
1090 
1093 {
1094  io.eventNo() = points_.eventNo()+1;
1095 }
1096 
1097 
1099 {
1100  if (clearedPrimitives_)
1101  {
1103  << "faces deallocated"
1105  }
1106 
1107  return faces_;
1108 }
1109 
1112 {
1113  return owner_;
1114 }
1115 
1118 {
1119  return neighbour_;
1120 }
1121 
1122 
1124 {
1125  if (!moving_)
1126  {
1127  return points_;
1128  }
1129 
1130  if (!oldPointsPtr_)
1131  {
1132  if (debug)
1133  {
1135  }
1136 
1137  oldPointsPtr_.reset(new pointField(points_));
1138  curMotionTimeIndex_ = time().timeIndex();
1139  }
1140 
1141  return *oldPointsPtr_;
1142 }
1143 
1144 
1146 {
1147  storeOldCellCentres_ = true;
1148 
1149  if (!moving_)
1150  {
1151  return cellCentres();
1152  }
1153 
1154  if (!oldCellCentresPtr_)
1155  {
1156  oldCellCentresPtr_.reset(new pointField(cellCentres()));
1157  }
1158 
1159  return *oldCellCentresPtr_;
1160 }
1161 
1162 
1163 void Foam::polyMesh::movePoints(const pointField& newPoints)
1164 {
1166  << "Moving points for time " << time().value()
1167  << " index " << time().timeIndex() << endl;
1168 
1169  if (newPoints.size() != points_.size())
1170  {
1172  << "Size of newPoints " << newPoints.size()
1173  << " does not correspond to current mesh points size "
1174  << points_.size()
1175  << exit(FatalError);
1176  }
1177 
1178 
1179  moving(true);
1180 
1181  // Pick up old points
1182  if (curMotionTimeIndex_ != time().timeIndex())
1183  {
1184  if (debug)
1185  {
1186  Info<< "tmp<scalarField> polyMesh::movePoints(const pointField&) : "
1187  << " Storing current points for time " << time().value()
1188  << " index " << time().timeIndex() << endl;
1189  }
1190 
1191  if (storeOldCellCentres_)
1192  {
1193  oldCellCentresPtr_.clear();
1194  oldCellCentresPtr_.reset(new pointField(cellCentres()));
1195  }
1196 
1197  // Mesh motion in the new time step
1198  oldPointsPtr_.clear();
1199  oldPointsPtr_.reset(new pointField(points_));
1200  curMotionTimeIndex_ = time().timeIndex();
1201  }
1202 
1203  points_ = newPoints;
1204 
1205  bool moveError = false;
1206  if (debug)
1207  {
1208  // Check mesh motion
1209  if (checkMeshMotion(points_, true))
1210  {
1211  moveError = true;
1212 
1214  << "Moving the mesh with given points will "
1215  << "invalidate the mesh." << nl
1216  << "Mesh motion should not be executed." << endl;
1217  }
1218  }
1219 
1220  points_.writeOpt(IOobject::AUTO_WRITE);
1221  points_.instance() = time().timeName();
1222  points_.eventNo() = getEvent();
1223 
1224  if (tetBasePtIsPtr_)
1225  {
1226  tetBasePtIsPtr_->writeOpt(IOobject::AUTO_WRITE);
1227  tetBasePtIsPtr_->instance() = time().timeName();
1228  tetBasePtIsPtr_->eventNo() = getEvent();
1229  }
1230 
1231  // Currently a no-op; earlier versions set meshPhi and call
1232  // primitiveMesh::clearGeom
1233  (void)primitiveMesh::movePoints(points_, oldPoints());
1234 
1235  // Update the mesh geometry (via fvGeometryScheme)
1236  // - updateGeom is virtual -> calls fvMesh::updateGeom (or higher)
1237  // - fvMesh::updateGeom defers to surfaceInterpolation::updateGeom(),
1238  // which defers to fvGeometryScheme::movePoints()
1239  // - set the mesh flux
1240  // - clear out/recalculate stale geometry
1241  updateGeom();
1242 
1243  // Adjust parallel shared points
1244  if (globalMeshDataPtr_)
1245  {
1246  globalMeshDataPtr_->movePoints(points_);
1247  }
1248 
1249  // Force recalculation of all geometric data with new points
1250 
1251  bounds_ = boundBox(points_);
1252  boundary_.movePoints(points_);
1253 
1254  pointZones_.movePoints(points_);
1255  faceZones_.movePoints(points_);
1256  cellZones_.movePoints(points_);
1257 
1258  // Reset cell tree - it gets built from mesh geometry so might have
1259  // wrong boxes. It is correct as long as none of the cells leaves
1260  // the boxes it is in which most likely is almost never the case except
1261  // for tiny displacements. An alternative is to check the displacements
1262  // to see if they are tiny - imagine a big windtunnel with a small rotating
1263  // object. In this case the processors without the rotating object wouldn't
1264  // have to clear any geometry. However your critical path still stays the
1265  // same so no time would be gained (unless the decomposition gets weighted).
1266  // Small benefit for lots of scope for problems so not done.
1267  cellTreePtr_.clear();
1268 
1269  // Reset valid directions (could change with rotation)
1270  geometricD_ = Zero;
1271  solutionD_ = Zero;
1272 
1273  // Note: tet-base decomposition does not get cleared. Ideally your face
1274  // decomposition should not change during mesh motion ...
1275 
1276 
1277  meshObject::movePoints<polyMesh>(*this);
1278  meshObject::movePoints<pointMesh>(*this);
1279 
1280  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1281 
1282 
1283  if (debug && moveError)
1284  {
1285  // Write mesh to ease debugging. Note we want to avoid calling
1286  // e.g. fvMesh::write since meshPhi not yet complete.
1287  polyMesh::write();
1288  }
1289 }
1290 
1291 
1292 void Foam::polyMesh::resetMotion() const
1294  curMotionTimeIndex_ = 0;
1295  oldPointsPtr_.clear();
1296  oldCellCentresPtr_.clear();
1297 }
1298 
1299 
1301 {
1302  if (!globalMeshDataPtr_)
1303  {
1304  if (debug)
1305  {
1306  Pout<< "polyMesh::globalData() const : "
1307  << "Constructing parallelData from processor topology"
1308  << endl;
1309  }
1310  // Construct globalMeshData using processorPatch information only.
1311  globalMeshDataPtr_.reset(new globalMeshData(*this));
1312  }
1313 
1314  return *globalMeshDataPtr_;
1315 }
1316 
1318 Foam::label Foam::polyMesh::comm() const noexcept
1319 {
1320  return comm_;
1321 }
1322 
1324 Foam::label& Foam::polyMesh::comm() noexcept
1325 {
1326  return comm_;
1327 }
1328 
1329 
1330 void Foam::polyMesh::removeFiles(const fileName& instanceDir) const
1331 {
1332  fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
1333 
1334  rm(meshFilesPath/"points");
1335  rm(meshFilesPath/"faces");
1336  rm(meshFilesPath/"owner");
1337  rm(meshFilesPath/"neighbour");
1338  rm(meshFilesPath/"cells");
1339  rm(meshFilesPath/"boundary");
1340  rm(meshFilesPath/"pointZones");
1341  rm(meshFilesPath/"faceZones");
1342  rm(meshFilesPath/"cellZones");
1343  rm(meshFilesPath/"meshModifiers");
1344  rm(meshFilesPath/"parallelData");
1345 
1346  // remove subdirectories
1347  if (isDir(meshFilesPath/"sets"))
1348  {
1349  rmDir(meshFilesPath/"sets");
1350  }
1351 }
1352 
1353 
1355 {
1356  removeFiles(instance());
1357 }
1358 
1359 
1361 (
1362  const point& p,
1363  label& celli,
1364  label& tetFacei,
1365  label& tetPti
1366 ) const
1367 {
1368  celli = -1;
1369  tetFacei = -1;
1370  tetPti = -1;
1371 
1372  const indexedOctree<treeDataCell>& tree = cellTree();
1373 
1374  // Find point inside cell
1375  celli = tree.findInside(p);
1376 
1377  if (celli != -1)
1378  {
1379  // Check the nearest cell to see if the point is inside.
1380  findTetFacePt(celli, p, tetFacei, tetPti);
1381  }
1382 }
1383 
1384 
1386 (
1387  const label celli,
1388  const point& p,
1389  label& tetFacei,
1390  label& tetPti
1391 ) const
1392 {
1393  const polyMesh& mesh = *this;
1394 
1396  tetFacei = tet.face();
1397  tetPti = tet.tetPt();
1398 }
1399 
1400 
1402 (
1403  const point& p,
1404  label celli,
1405  const cellDecomposition decompMode
1406 ) const
1407 {
1408  switch (decompMode)
1409  {
1410  case FACE_PLANES:
1411  {
1412  return primitiveMesh::pointInCell(p, celli);
1413  }
1414  break;
1415 
1416  case FACE_CENTRE_TRIS:
1417  {
1418  // only test that point is on inside of plane defined by cell face
1419  // triangles
1420  const cell& cFaces = cells()[celli];
1421 
1422  forAll(cFaces, cFacei)
1423  {
1424  label facei = cFaces[cFacei];
1425  const face& f = faces_[facei];
1426  const point& fc = faceCentres()[facei];
1427  bool isOwn = (owner_[facei] == celli);
1428 
1429  forAll(f, fp)
1430  {
1431  label pointi;
1432  label nextPointi;
1433 
1434  if (isOwn)
1435  {
1436  pointi = f[fp];
1437  nextPointi = f.nextLabel(fp);
1438  }
1439  else
1440  {
1441  pointi = f.nextLabel(fp);
1442  nextPointi = f[fp];
1443  }
1444 
1445  triPointRef faceTri
1446  (
1447  points()[pointi],
1448  points()[nextPointi],
1449  fc
1450  );
1451 
1452  vector proj = p - faceTri.centre();
1453 
1454  if ((faceTri.areaNormal() & proj) > 0)
1455  {
1456  return false;
1457  }
1458  }
1459  }
1460  return true;
1461  }
1462  break;
1463 
1464  case FACE_DIAG_TRIS:
1465  {
1466  // only test that point is on inside of plane defined by cell face
1467  // triangles
1468  const cell& cFaces = cells()[celli];
1469 
1470  forAll(cFaces, cFacei)
1471  {
1472  label facei = cFaces[cFacei];
1473  const face& f = faces_[facei];
1474 
1475  for (label tetPti = 1; tetPti < f.size() - 1; tetPti++)
1476  {
1477  // Get tetIndices of face triangle
1478  tetIndices faceTetIs(celli, facei, tetPti);
1479 
1480  triPointRef faceTri = faceTetIs.faceTri(*this);
1481 
1482  vector proj = p - faceTri.centre();
1483 
1484  if ((faceTri.areaNormal() & proj) > 0)
1485  {
1486  return false;
1487  }
1488  }
1489  }
1490 
1491  return true;
1492  }
1493  break;
1494 
1495  case CELL_TETS:
1496  {
1497  label tetFacei;
1498  label tetPti;
1499 
1500  findTetFacePt(celli, p, tetFacei, tetPti);
1501 
1502  return tetFacei != -1;
1503  }
1504  break;
1505  }
1506 
1507  return false;
1508 }
1509 
1510 
1511 Foam::label Foam::polyMesh::findCell
1512 (
1513  const point& p,
1514  const cellDecomposition decompMode
1515 ) const
1516 {
1517  if
1518  (
1519  Pstream::parRun()
1520  && (decompMode == FACE_DIAG_TRIS || decompMode == CELL_TETS)
1521  )
1522  {
1523  // Force construction of face-diagonal decomposition before testing
1524  // for zero cells.
1525  //
1526  // If parallel running a local domain might have zero cells so never
1527  // construct the face-diagonal decomposition which uses parallel
1528  // transfers.
1529  (void)tetBasePtIs();
1530  }
1531 
1532  if (nCells() == 0)
1533  {
1534  return -1;
1535  }
1536 
1537  if (decompMode == CELL_TETS)
1538  {
1539  // Advanced search method utilizing an octree
1540  // and tet-decomposition of the cells
1541 
1542  label celli;
1543  label tetFacei;
1544  label tetPti;
1545 
1546  findCellFacePt(p, celli, tetFacei, tetPti);
1547 
1548  return celli;
1549  }
1550  else
1551  {
1552  // Approximate search avoiding the construction of an octree
1553  // and cell decomposition
1554 
1555  if (Pstream::parRun() && decompMode == FACE_DIAG_TRIS)
1556  {
1557  // Force construction of face-diagonal decomposition before testing
1558  // for zero cells. If parallel running a local domain might have
1559  // zero cells so never construct the face-diagonal decomposition
1560  // (which uses parallel transfers)
1561  (void)tetBasePtIs();
1562  }
1563 
1564  // Find the nearest cell centre to this location
1565  label celli = findNearestCell(p);
1566 
1567  // If point is in the nearest cell return
1568  if (pointInCell(p, celli, decompMode))
1569  {
1570  return celli;
1571  }
1572  else
1573  {
1574  // Point is not in the nearest cell so search all cells
1575 
1576  for (label celli = 0; celli < nCells(); celli++)
1577  {
1578  if (pointInCell(p, celli, decompMode))
1579  {
1580  return celli;
1581  }
1582  }
1583 
1584  return -1;
1585  }
1586  }
1587 }
1588 
1589 
1590 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:584
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
Definition: polyMesh.C:358
uint8_t direction
Definition: direction.H:46
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.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual void movePoints(const pointField &)
Move points.
Definition: polyMesh.C:1156
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:853
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:1110
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:893
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:841
virtual void setUpToDatePoints(regIOobject &io) const
Set io to be up-to-date with points.
Definition: polyMesh.C:1085
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:75
void resetMotion() const
Reset motion.
Definition: polyMesh.C:1285
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:876
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:639
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:709
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:824
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:1395
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:870
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
bool hasHeaderClass() const noexcept
True if headerClassName() is non-empty (after reading)
Definition: IOobjectI.H:206
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1066
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
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:859
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:813
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:847
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
dynamicFvMesh & mesh
void removeFiles() const
Remove all files from mesh instance()
Definition: polyMesh.C:1347
const cellShapeList & cells
const pointField & points
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:1354
#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:997
virtual const pointField & oldPoints() const
Return old points (mesh motion)
Definition: polyMesh.C:1116
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1104
label comm() const noexcept
Return communicator used for parallel communication.
Definition: polyMesh.C:1311
static const word null
An empty word.
Definition: word.H:84
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1293
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:1091
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:1386
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
Definition: cellIOList.H:39
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:887
virtual bool upToDatePoints(const regIOobject &io) const
Return true if io is up-to-date with points.
Definition: polyMesh.C:1079
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:927
virtual const pointField & oldCellCentres() const
Return old cellCentres (mesh motion)
Definition: polyMesh.C:1138
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
IOobject(const IOobject &)=default
Copy construct.
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:835
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:1379
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:1505
virtual ~polyMesh()
Destructor.
Definition: polyMesh.C:807
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:69
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:58
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.
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
volScalarField & p
Registry of regIOobjects.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Definition: autoPtr.H:178
virtual bool write(const bool valid=true) const
Write using setting from DB.
void addPatches(polyPatchList &plist, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:959
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:166
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
List< cell > cellList
A List of cells.
Definition: cellListFwd.H:41
Inter-processor communications stream.
Definition: UPstream.H:54
IOList< label > labelIOList
Label container classes.
Definition: labelIOList.H:38
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:1357
#define InfoInFunction
Report an information message using Foam::Info.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157