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 | Copyright (C) 2011-2015 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 "polyMesh.H"
27 #include "Time.H"
28 #include "cellIOList.H"
29 #include "wedgePolyPatch.H"
30 #include "emptyPolyPatch.H"
31 #include "globalMeshData.H"
32 #include "processorPolyPatch.H"
34 #include "indexedOctree.H"
35 #include "treeDataCell.H"
36 #include "MeshObject.H"
37 #include "pointMesh.H"
38 
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 
41 namespace Foam
42 {
43  defineTypeNameAndDebug(polyMesh, 0);
44 
45  word polyMesh::defaultRegion = "region0";
46  word polyMesh::meshSubDir = "polyMesh";
47 }
48 
49 
50 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 
52 void Foam::polyMesh::calcDirections() const
53 {
54  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
55  {
56  solutionD_[cmpt] = 1;
57  }
58 
59  // Knock out empty and wedge directions. Note:they will be present on all
60  // domains.
61 
62  label nEmptyPatches = 0;
63  label nWedgePatches = 0;
64 
65  vector emptyDirVec = vector::zero;
66  vector wedgeDirVec = vector::zero;
67 
68  forAll(boundaryMesh(), patchi)
69  {
70  if (boundaryMesh()[patchi].size())
71  {
72  if (isA<emptyPolyPatch>(boundaryMesh()[patchi]))
73  {
74  nEmptyPatches++;
75  emptyDirVec += sum(cmptMag(boundaryMesh()[patchi].faceAreas()));
76  }
77  else if (isA<wedgePolyPatch>(boundaryMesh()[patchi]))
78  {
79  const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>
80  (
81  boundaryMesh()[patchi]
82  );
83 
84  nWedgePatches++;
85  wedgeDirVec += cmptMag(wpp.centreNormal());
86  }
87  }
88  }
89 
90  reduce(nEmptyPatches, maxOp<label>());
91  reduce(nWedgePatches, maxOp<label>());
92 
93  if (nEmptyPatches)
94  {
95  reduce(emptyDirVec, sumOp<vector>());
96 
97  emptyDirVec /= mag(emptyDirVec);
98 
99  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
100  {
101  if (emptyDirVec[cmpt] > 1e-6)
102  {
103  solutionD_[cmpt] = -1;
104  }
105  else
106  {
107  solutionD_[cmpt] = 1;
108  }
109  }
110  }
111 
112 
113  // Knock out wedge directions
114 
115  geometricD_ = solutionD_;
116 
117  if (nWedgePatches)
118  {
119  reduce(wedgeDirVec, sumOp<vector>());
120 
121  wedgeDirVec /= mag(wedgeDirVec);
122 
123  for (direction cmpt=0; cmpt<vector::nComponents; cmpt++)
124  {
125  if (wedgeDirVec[cmpt] > 1e-6)
126  {
127  geometricD_[cmpt] = -1;
128  }
129  else
130  {
131  geometricD_[cmpt] = 1;
132  }
133  }
134  }
135 }
136 
137 
138 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
139 
140 Foam::polyMesh::polyMesh(const IOobject& io)
141 :
142  objectRegistry(io),
143  primitiveMesh(),
144  points_
145  (
146  IOobject
147  (
148  "points",
149  time().findInstance(meshDir(), "points"),
150  meshSubDir,
151  *this,
152  IOobject::MUST_READ,
153  IOobject::NO_WRITE
154  )
155  ),
156  faces_
157  (
158  IOobject
159  (
160  "faces",
161  time().findInstance(meshDir(), "faces"),
162  meshSubDir,
163  *this,
164  IOobject::MUST_READ,
165  IOobject::NO_WRITE
166  )
167  ),
168  owner_
169  (
170  IOobject
171  (
172  "owner",
173  faces_.instance(),
174  meshSubDir,
175  *this,
176  IOobject::READ_IF_PRESENT,
177  IOobject::NO_WRITE
178  )
179  ),
180  neighbour_
181  (
182  IOobject
183  (
184  "neighbour",
185  faces_.instance(),
186  meshSubDir,
187  *this,
188  IOobject::READ_IF_PRESENT,
189  IOobject::NO_WRITE
190  )
191  ),
192  clearedPrimitives_(false),
193  boundary_
194  (
195  IOobject
196  (
197  "boundary",
198  time().findInstance(meshDir(), "boundary"),
199  meshSubDir,
200  *this,
201  IOobject::MUST_READ,
202  IOobject::NO_WRITE
203  ),
204  *this
205  ),
206  bounds_(points_),
207  comm_(UPstream::worldComm),
208  geometricD_(Vector<label>::zero),
209  solutionD_(Vector<label>::zero),
210  tetBasePtIsPtr_(NULL),
211  cellTreePtr_(NULL),
212  pointZones_
213  (
214  IOobject
215  (
216  "pointZones",
217  time().findInstance
218  (
219  meshDir(),
220  "pointZones",
221  IOobject::READ_IF_PRESENT
222  ),
223  meshSubDir,
224  *this,
225  IOobject::READ_IF_PRESENT,
226  IOobject::NO_WRITE
227  ),
228  *this
229  ),
230  faceZones_
231  (
232  IOobject
233  (
234  "faceZones",
235  time().findInstance
236  (
237  meshDir(),
238  "faceZones",
239  IOobject::READ_IF_PRESENT
240  ),
241  meshSubDir,
242  *this,
243  IOobject::READ_IF_PRESENT,
244  IOobject::NO_WRITE
245  ),
246  *this
247  ),
248  cellZones_
249  (
250  IOobject
251  (
252  "cellZones",
253  time().findInstance
254  (
255  meshDir(),
256  "cellZones",
257  IOobject::READ_IF_PRESENT
258  ),
259  meshSubDir,
260  *this,
261  IOobject::READ_IF_PRESENT,
262  IOobject::NO_WRITE
263  ),
264  *this
265  ),
266  globalMeshDataPtr_(NULL),
267  moving_(false),
268  topoChanging_(false),
269  curMotionTimeIndex_(time().timeIndex()),
270  oldPointsPtr_(NULL)
271 {
272  if (exists(owner_.objectPath()))
273  {
274  initMesh();
275  }
276  else
277  {
278  cellCompactIOList cLst
279  (
280  IOobject
281  (
282  "cells",
283  time().findInstance(meshDir(), "cells"),
284  meshSubDir,
285  *this,
288  )
289  );
290 
291  // Set the primitive mesh
292  initMesh(cLst);
293 
294  owner_.write();
295  neighbour_.write();
296  }
297 
298  // Calculate topology for the patches (processor-processor comms etc.)
299  boundary_.updateMesh();
300 
301  // Calculate the geometry for the patches (transformation tensors etc.)
302  boundary_.calcGeometry();
303 
304  // Warn if global empty mesh
305  if (returnReduce(nPoints(), sumOp<label>()) == 0)
306  {
307  WarningIn("polyMesh(const IOobject&)")
308  << "no points in mesh" << endl;
309  }
310  if (returnReduce(nCells(), sumOp<label>()) == 0)
311  {
312  WarningIn("polyMesh(const IOobject&)")
313  << "no cells in mesh" << endl;
314  }
315 
316  // Initialise demand-driven data
317  calcDirections();
318 }
319 
320 
321 Foam::polyMesh::polyMesh
322 (
323  const IOobject& io,
324  const Xfer<pointField>& points,
325  const Xfer<faceList>& faces,
326  const Xfer<labelList>& owner,
327  const Xfer<labelList>& neighbour,
328  const bool syncPar
329 )
330 :
331  objectRegistry(io),
332  primitiveMesh(),
333  points_
334  (
335  IOobject
336  (
337  "points",
338  instance(),
339  meshSubDir,
340  *this,
341  io.readOpt(),
343  ),
344  points
345  ),
346  faces_
347  (
348  IOobject
349  (
350  "faces",
351  instance(),
352  meshSubDir,
353  *this,
354  io.readOpt(),
356  ),
357  faces
358  ),
359  owner_
360  (
361  IOobject
362  (
363  "owner",
364  instance(),
365  meshSubDir,
366  *this,
367  io.readOpt(),
369  ),
370  owner
371  ),
372  neighbour_
373  (
374  IOobject
375  (
376  "neighbour",
377  instance(),
378  meshSubDir,
379  *this,
380  io.readOpt(),
382  ),
383  neighbour
384  ),
385  clearedPrimitives_(false),
386  boundary_
387  (
388  IOobject
389  (
390  "boundary",
391  instance(),
392  meshSubDir,
393  *this,
394  io.readOpt(),
396  ),
397  *this,
398  polyPatchList()
399  ),
400  bounds_(points_, syncPar),
401  comm_(UPstream::worldComm),
402  geometricD_(Vector<label>::zero),
403  solutionD_(Vector<label>::zero),
404  tetBasePtIsPtr_(NULL),
405  cellTreePtr_(NULL),
406  pointZones_
407  (
408  IOobject
409  (
410  "pointZones",
411  instance(),
412  meshSubDir,
413  *this,
414  io.readOpt(),
416  ),
417  *this,
419  ),
420  faceZones_
421  (
422  IOobject
423  (
424  "faceZones",
425  instance(),
426  meshSubDir,
427  *this,
428  io.readOpt(),
430  ),
431  *this,
433  ),
434  cellZones_
435  (
436  IOobject
437  (
438  "cellZones",
439  instance(),
440  meshSubDir,
441  *this,
442  io.readOpt(),
444  ),
445  *this,
447  ),
448  globalMeshDataPtr_(NULL),
449  moving_(false),
450  topoChanging_(false),
451  curMotionTimeIndex_(time().timeIndex()),
452  oldPointsPtr_(NULL)
453 {
454  // Check if the faces and cells are valid
455  forAll(faces_, facei)
456  {
457  const face& curFace = faces_[facei];
458 
459  if (min(curFace) < 0 || max(curFace) > points_.size())
460  {
462  (
463  "polyMesh::polyMesh\n"
464  "(\n"
465  " const IOobject& io,\n"
466  " const pointField& points,\n"
467  " const faceList& faces,\n"
468  " const cellList& cells\n"
469  ")\n"
470  ) << "Face " << facei << "contains vertex labels out of range: "
471  << curFace << " Max point index = " << points_.size()
472  << abort(FatalError);
473  }
474  }
475 
476  // Set the primitive mesh
477  initMesh();
478 }
479 
480 
481 Foam::polyMesh::polyMesh
482 (
483  const IOobject& io,
484  const Xfer<pointField>& points,
485  const Xfer<faceList>& faces,
486  const Xfer<cellList>& cells,
487  const bool syncPar
488 )
489 :
490  objectRegistry(io),
491  primitiveMesh(),
492  points_
493  (
494  IOobject
495  (
496  "points",
497  instance(),
498  meshSubDir,
499  *this,
502  ),
503  points
504  ),
505  faces_
506  (
507  IOobject
508  (
509  "faces",
510  instance(),
511  meshSubDir,
512  *this,
515  ),
516  faces
517  ),
518  owner_
519  (
520  IOobject
521  (
522  "owner",
523  instance(),
524  meshSubDir,
525  *this,
528  ),
529  0
530  ),
531  neighbour_
532  (
533  IOobject
534  (
535  "neighbour",
536  instance(),
537  meshSubDir,
538  *this,
541  ),
542  0
543  ),
544  clearedPrimitives_(false),
545  boundary_
546  (
547  IOobject
548  (
549  "boundary",
550  instance(),
551  meshSubDir,
552  *this,
555  ),
556  *this,
557  0
558  ),
559  bounds_(points_, syncPar),
560  comm_(UPstream::worldComm),
561  geometricD_(Vector<label>::zero),
562  solutionD_(Vector<label>::zero),
563  tetBasePtIsPtr_(NULL),
564  cellTreePtr_(NULL),
565  pointZones_
566  (
567  IOobject
568  (
569  "pointZones",
570  instance(),
571  meshSubDir,
572  *this,
575  ),
576  *this,
577  0
578  ),
579  faceZones_
580  (
581  IOobject
582  (
583  "faceZones",
584  instance(),
585  meshSubDir,
586  *this,
589  ),
590  *this,
591  0
592  ),
593  cellZones_
594  (
595  IOobject
596  (
597  "cellZones",
598  instance(),
599  meshSubDir,
600  *this,
603  ),
604  *this,
605  0
606  ),
607  globalMeshDataPtr_(NULL),
608  moving_(false),
609  topoChanging_(false),
610  curMotionTimeIndex_(time().timeIndex()),
611  oldPointsPtr_(NULL)
612 {
613  // Check if faces are valid
614  forAll(faces_, facei)
615  {
616  const face& curFace = faces_[facei];
617 
618  if (min(curFace) < 0 || max(curFace) > points_.size())
619  {
621  (
622  "polyMesh::polyMesh\n"
623  "(\n"
624  " const IOobject&,\n"
625  " const Xfer<pointField>&,\n"
626  " const Xfer<faceList>&,\n"
627  " const Xfer<cellList>&\n"
628  ")\n"
629  ) << "Face " << facei << "contains vertex labels out of range: "
630  << curFace << " Max point index = " << points_.size()
631  << abort(FatalError);
632  }
633  }
634 
635  // transfer in cell list
636  cellList cLst(cells);
637 
638  // Check if cells are valid
639  forAll(cLst, celli)
640  {
641  const cell& curCell = cLst[celli];
642 
643  if (min(curCell) < 0 || max(curCell) > faces_.size())
644  {
646  (
647  "polyMesh::polyMesh\n"
648  "(\n"
649  " const IOobject&,\n"
650  " const Xfer<pointField>&,\n"
651  " const Xfer<faceList>&,\n"
652  " const Xfer<cellList>&\n"
653  ")\n"
654  ) << "Cell " << celli << "contains face labels out of range: "
655  << curCell << " Max face index = " << faces_.size()
656  << abort(FatalError);
657  }
658  }
659 
660  // Set the primitive mesh
661  initMesh(cLst);
662 }
663 
664 
666 (
667  const Xfer<pointField>& points,
668  const Xfer<faceList>& faces,
669  const Xfer<labelList>& owner,
670  const Xfer<labelList>& neighbour,
671  const labelList& patchSizes,
672  const labelList& patchStarts,
673  const bool validBoundary
674 )
675 {
676  // Clear addressing. Keep geometric props and updateable props for mapping.
677  clearAddressing(true);
678 
679  // Take over new primitive data.
680  // Optimized to avoid overwriting data at all
681  if (notNull(points))
682  {
683  points_.transfer(points());
684  bounds_ = boundBox(points_, validBoundary);
685  }
686 
687  if (notNull(faces))
688  {
689  faces_.transfer(faces());
690  }
691 
692  if (notNull(owner))
693  {
694  owner_.transfer(owner());
695  }
696 
697  if (notNull(neighbour))
698  {
699  neighbour_.transfer(neighbour());
700  }
701 
702 
703  // Reset patch sizes and starts
704  forAll(boundary_, patchI)
705  {
706  boundary_[patchI] = polyPatch
707  (
708  boundary_[patchI],
709  boundary_,
710  patchI,
711  patchSizes[patchI],
712  patchStarts[patchI]
713  );
714  }
715 
716 
717  // Flags the mesh files as being changed
719 
720  // Check if the faces and cells are valid
721  forAll(faces_, facei)
722  {
723  const face& curFace = faces_[facei];
724 
725  if (min(curFace) < 0 || max(curFace) > points_.size())
726  {
728  (
729  "polyMesh::polyMesh::resetPrimitives\n"
730  "(\n"
731  " const Xfer<pointField>&,\n"
732  " const Xfer<faceList>&,\n"
733  " const Xfer<labelList>& owner,\n"
734  " const Xfer<labelList>& neighbour,\n"
735  " const labelList& patchSizes,\n"
736  " const labelList& patchStarts\n"
737  " const bool validBoundary\n"
738  ")\n"
739  ) << "Face " << facei << " contains vertex labels out of range: "
740  << curFace << " Max point index = " << points_.size()
741  << abort(FatalError);
742  }
743  }
744 
745 
746  // Set the primitive mesh from the owner_, neighbour_.
747  // Works out from patch end where the active faces stop.
748  initMesh();
749 
750 
751  if (validBoundary)
752  {
753  // Note that we assume that all the patches stay the same and are
754  // correct etc. so we can already use the patches to do
755  // processor-processor comms.
756 
757  // Calculate topology for the patches (processor-processor comms etc.)
758  boundary_.updateMesh();
759 
760  // Calculate the geometry for the patches (transformation tensors etc.)
761  boundary_.calcGeometry();
762 
763  // Warn if global empty mesh
764  if
765  (
766  (returnReduce(nPoints(), sumOp<label>()) == 0)
767  || (returnReduce(nCells(), sumOp<label>()) == 0)
768  )
769  {
771  (
772  "polyMesh::polyMesh::resetPrimitives\n"
773  "(\n"
774  " const Xfer<pointField>&,\n"
775  " const Xfer<faceList>&,\n"
776  " const Xfer<labelList>& owner,\n"
777  " const Xfer<labelList>& neighbour,\n"
778  " const labelList& patchSizes,\n"
779  " const labelList& patchStarts\n"
780  " const bool validBoundary\n"
781  ")\n"
782  ) << "no points or no cells in mesh" << endl;
783  }
784  }
785 }
786 
787 
788 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
789 
791 {
792  clearOut();
793  resetMotion();
794 }
795 
796 
797 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
798 
800 {
802  {
803  return parent().dbDir();
804  }
805  else
806  {
807  return objectRegistry::dbDir();
808  }
809 }
810 
811 
813 {
814  return dbDir()/meshSubDir;
815 }
816 
817 
819 {
820  return points_.instance();
821 }
822 
823 
825 {
826  return faces_.instance();
827 }
828 
829 
831 {
832  if (geometricD_.x() == 0)
833  {
834  calcDirections();
835  }
836 
837  return geometricD_;
838 }
839 
840 
842 {
843  return cmptSum(geometricD() + Vector<label>::one)/2;
844 }
845 
846 
848 {
849  if (solutionD_.x() == 0)
850  {
851  calcDirections();
852  }
853 
854  return solutionD_;
855 }
856 
857 
859 {
860  return cmptSum(solutionD() + Vector<label>::one)/2;
861 }
862 
863 
865 {
866  if (tetBasePtIsPtr_.empty())
867  {
868  if (debug)
869  {
870  WarningIn("const labelList& polyMesh::tetBasePtIs() const")
871  << "Tet base point indices not available. "
872  << "Forcing storage of base points."
873  << endl;
874  }
875 
876  tetBasePtIsPtr_.reset
877  (
878  new labelList
879  (
881  )
882  );
883  }
884 
885  return tetBasePtIsPtr_();
886 }
887 
888 
891 {
892  if (cellTreePtr_.empty())
893  {
894  treeBoundBox overallBb(points());
895 
896  Random rndGen(261782);
897 
898  overallBb = overallBb.extend(rndGen, 1e-4);
899  overallBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
900  overallBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
901 
902  cellTreePtr_.reset
903  (
905  (
907  (
908  false, // not cache bb
909  *this,
910  CELL_TETS // use tet-decomposition for any inside test
911  ),
912  overallBb,
913  8, // maxLevel
914  10, // leafsize
915  5.0 // duplicity
916  )
917  );
918  }
919 
920  return cellTreePtr_();
921 }
922 
923 
925 (
926  const List<polyPatch*>& p,
927  const bool validBoundary
928 )
929 {
930  if (boundaryMesh().size())
931  {
933  (
934  "void polyMesh::addPatches(const List<polyPatch*>&, const bool)"
935  ) << "boundary already exists"
936  << abort(FatalError);
937  }
938 
939  // Reset valid directions
940  geometricD_ = Vector<label>::zero;
941  solutionD_ = Vector<label>::zero;
942 
943  boundary_.setSize(p.size());
944 
945  // Copy the patch pointers
946  forAll(p, pI)
947  {
948  boundary_.set(pI, p[pI]);
949  }
950 
951  // parallelData depends on the processorPatch ordering so force
952  // recalculation. Problem: should really be done in removeBoundary but
953  // there is some info in parallelData which might be interesting inbetween
954  // removeBoundary and addPatches.
955  globalMeshDataPtr_.clear();
956 
957  if (validBoundary)
958  {
959  // Calculate topology for the patches (processor-processor comms etc.)
960  boundary_.updateMesh();
961 
962  // Calculate the geometry for the patches (transformation tensors etc.)
963  boundary_.calcGeometry();
964 
965  boundary_.checkDefinition();
966  }
967 }
968 
969 
971 (
972  const List<pointZone*>& pz,
973  const List<faceZone*>& fz,
974  const List<cellZone*>& cz
975 )
976 {
977  if (pointZones().size() || faceZones().size() || cellZones().size())
978  {
980  (
981  "void addZones\n"
982  "(\n"
983  " const List<pointZone*>&,\n"
984  " const List<faceZone*>&,\n"
985  " const List<cellZone*>&\n"
986  ")"
987  ) << "point, face or cell zone already exists"
988  << abort(FatalError);
989  }
990 
991  // Point zones
992  if (pz.size())
993  {
994  pointZones_.setSize(pz.size());
995 
996  // Copy the zone pointers
997  forAll(pz, pI)
998  {
999  pointZones_.set(pI, pz[pI]);
1000  }
1001 
1002  pointZones_.writeOpt() = IOobject::AUTO_WRITE;
1003  }
1004 
1005  // Face zones
1006  if (fz.size())
1007  {
1008  faceZones_.setSize(fz.size());
1009 
1010  // Copy the zone pointers
1011  forAll(fz, fI)
1012  {
1013  faceZones_.set(fI, fz[fI]);
1014  }
1015 
1016  faceZones_.writeOpt() = IOobject::AUTO_WRITE;
1017  }
1018 
1019  // Cell zones
1020  if (cz.size())
1021  {
1022  cellZones_.setSize(cz.size());
1023 
1024  // Copy the zone pointers
1025  forAll(cz, cI)
1026  {
1027  cellZones_.set(cI, cz[cI]);
1028  }
1029 
1030  cellZones_.writeOpt() = IOobject::AUTO_WRITE;
1031  }
1032 }
1033 
1034 
1036 {
1037  if (clearedPrimitives_)
1038  {
1039  FatalErrorIn("const pointField& polyMesh::points() const")
1040  << "points deallocated"
1041  << abort(FatalError);
1042  }
1043 
1044  return points_;
1045 }
1046 
1047 
1049 {
1050  return io.upToDate(points_);
1051 }
1052 
1053 
1055 {
1056  io.eventNo() = points_.eventNo();
1057 }
1058 
1059 
1061 {
1062  if (clearedPrimitives_)
1063  {
1064  FatalErrorIn("const faceList& polyMesh::faces() const")
1065  << "faces deallocated"
1066  << abort(FatalError);
1067  }
1068 
1069  return faces_;
1070 }
1071 
1072 
1074 {
1075  return owner_;
1076 }
1077 
1078 
1080 {
1081  return neighbour_;
1082 }
1083 
1084 
1086 {
1087  if (oldPointsPtr_.empty())
1088  {
1089  if (debug)
1090  {
1091  WarningIn("const pointField& polyMesh::oldPoints() const")
1092  << "Old points not available. Forcing storage of old points"
1093  << endl;
1094  }
1095 
1096  oldPointsPtr_.reset(new pointField(points_));
1097  curMotionTimeIndex_ = time().timeIndex();
1098  }
1099 
1100  return oldPointsPtr_();
1101 }
1102 
1103 
1106  const pointField& newPoints
1107 )
1108 {
1109  if (debug)
1110  {
1111  Info<< "tmp<scalarField> polyMesh::movePoints(const pointField&) : "
1112  << " Moving points for time " << time().value()
1113  << " index " << time().timeIndex() << endl;
1114  }
1115 
1116  moving(true);
1117 
1118  // Pick up old points
1119  if (curMotionTimeIndex_ != time().timeIndex())
1120  {
1121  // Mesh motion in the new time step
1122  oldPointsPtr_.clear();
1123  oldPointsPtr_.reset(new pointField(points_));
1124  curMotionTimeIndex_ = time().timeIndex();
1125  }
1126 
1127  points_ = newPoints;
1128 
1129  bool moveError = false;
1130  if (debug)
1131  {
1132  // Check mesh motion
1133  if (checkMeshMotion(points_, true))
1134  {
1135  moveError = true;
1136 
1137  Info<< "tmp<scalarField> polyMesh::movePoints"
1138  << "(const pointField&) : "
1139  << "Moving the mesh with given points will "
1140  << "invalidate the mesh." << nl
1141  << "Mesh motion should not be executed." << endl;
1142  }
1143  }
1144 
1145  points_.writeOpt() = IOobject::AUTO_WRITE;
1146  points_.instance() = time().timeName();
1147  points_.eventNo() = getEvent();
1148 
1150  (
1151  points_,
1152  oldPoints()
1153  );
1154 
1155  // Adjust parallel shared points
1156  if (globalMeshDataPtr_.valid())
1157  {
1158  globalMeshDataPtr_().movePoints(points_);
1159  }
1160 
1161  // Force recalculation of all geometric data with new points
1162 
1163  bounds_ = boundBox(points_);
1164  boundary_.movePoints(points_);
1165 
1166  pointZones_.movePoints(points_);
1167  faceZones_.movePoints(points_);
1168  cellZones_.movePoints(points_);
1169 
1170  // Reset valid directions (could change with rotation)
1171  geometricD_ = Vector<label>::zero;
1172  solutionD_ = Vector<label>::zero;
1173 
1174  meshObject::movePoints<polyMesh>(*this);
1175  meshObject::movePoints<pointMesh>(*this);
1176 
1177  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1178 
1179 
1180  if (debug && moveError)
1181  {
1182  // Write mesh to ease debugging. Note we want to avoid calling
1183  // e.g. fvMesh::write since meshPhi not yet complete.
1184  polyMesh::write();
1185  }
1186 
1187  return sweptVols;
1188 }
1189 
1190 
1191 // Reset motion by deleting old points
1193 {
1194  curMotionTimeIndex_ = 0;
1195  oldPointsPtr_.clear();
1196 }
1197 
1198 
1199 // Return parallel info
1201 {
1202  if (globalMeshDataPtr_.empty())
1203  {
1204  if (debug)
1205  {
1206  Pout<< "polyMesh::globalData() const : "
1207  << "Constructing parallelData from processor topology"
1208  << endl;
1209  }
1210  // Construct globalMeshData using processorPatch information only.
1211  globalMeshDataPtr_.reset(new globalMeshData(*this));
1212  }
1213 
1214  return globalMeshDataPtr_();
1215 }
1216 
1217 
1219 {
1220  return comm_;
1221 }
1222 
1223 
1225 {
1226  return comm_;
1227 }
1228 
1229 
1230 void Foam::polyMesh::removeFiles(const fileName& instanceDir) const
1231 {
1232  fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
1233 
1234  rm(meshFilesPath/"points");
1235  rm(meshFilesPath/"faces");
1236  rm(meshFilesPath/"owner");
1237  rm(meshFilesPath/"neighbour");
1238  rm(meshFilesPath/"cells");
1239  rm(meshFilesPath/"boundary");
1240  rm(meshFilesPath/"pointZones");
1241  rm(meshFilesPath/"faceZones");
1242  rm(meshFilesPath/"cellZones");
1243  rm(meshFilesPath/"meshModifiers");
1244  rm(meshFilesPath/"parallelData");
1245 
1246  // remove subdirectories
1247  if (isDir(meshFilesPath/"sets"))
1248  {
1249  rmDir(meshFilesPath/"sets");
1250  }
1251 }
1252 
1253 
1255 {
1256  removeFiles(instance());
1257 }
1258 
1259 
1262  const point& p,
1263  label& celli,
1264  label& tetFacei,
1265  label& tetPti
1266 ) const
1267 {
1268  celli = -1;
1269  tetFacei = -1;
1270  tetPti = -1;
1271 
1272  const indexedOctree<treeDataCell>& tree = cellTree();
1273 
1274  // Find nearest cell to the point
1275  pointIndexHit info = tree.findNearest(p, sqr(GREAT));
1276 
1277  if (info.hit())
1278  {
1279  label nearestCellI = tree.shapes().cellLabels()[info.index()];
1280 
1281  // Check the nearest cell to see if the point is inside.
1282  findTetFacePt(nearestCellI, p, tetFacei, tetPti);
1283 
1284  if (tetFacei != -1)
1285  {
1286  // Point was in the nearest cell
1287 
1288  celli = nearestCellI;
1289 
1290  return;
1291  }
1292  else
1293  {
1294  // Check the other possible cells that the point may be in
1295 
1296  labelList testCells = tree.findIndices(p);
1297 
1298  forAll(testCells, pCI)
1299  {
1300  label testCellI = tree.shapes().cellLabels()[testCells[pCI]];
1301 
1302  if (testCellI == nearestCellI)
1303  {
1304  // Don't retest the nearest cell
1305 
1306  continue;
1307  }
1308 
1309  // Check the test cell to see if the point is inside.
1310  findTetFacePt(testCellI, p, tetFacei, tetPti);
1311 
1312  if (tetFacei != -1)
1313  {
1314  // Point was in the test cell
1315 
1316  celli = testCellI;
1317 
1318  return;
1319  }
1320  }
1321  }
1322  }
1323  else
1324  {
1325  FatalErrorIn
1326  (
1327  "void Foam::polyMesh::findCellFacePt"
1328  "("
1329  "const point& p, "
1330  "label& celli, "
1331  "label& tetFacei, "
1332  "label& tetPti"
1333  ") const"
1334  ) << "Did not find nearest cell in search tree."
1335  << abort(FatalError);
1336  }
1337 }
1338 
1339 
1342  const label celli,
1343  const point& p,
1344  label& tetFacei,
1345  label& tetPti
1346 ) const
1347 {
1348  const polyMesh& mesh = *this;
1349 
1350  tetIndices tet(polyMeshTetDecomposition::findTet(mesh, celli, p));
1351  tetFacei = tet.face();
1352  tetPti = tet.tetPt();
1353 }
1354 
1355 
1358  const point& p,
1359  label celli,
1360  const cellDecomposition decompMode
1361 ) const
1362 {
1363  switch (decompMode)
1364  {
1365  case FACE_PLANES:
1366  {
1367  return primitiveMesh::pointInCell(p, celli);
1368  }
1369  break;
1370 
1371  case FACE_CENTRE_TRIS:
1372  {
1373  // only test that point is on inside of plane defined by cell face
1374  // triangles
1375  const cell& cFaces = cells()[celli];
1376 
1377  forAll(cFaces, cFacei)
1378  {
1379  label facei = cFaces[cFacei];
1380  const face& f = faces_[facei];
1381  const point& fc = faceCentres()[facei];
1382  bool isOwn = (owner_[facei] == celli);
1383 
1384  forAll(f, fp)
1385  {
1386  label pointI;
1387  label nextPointI;
1388 
1389  if (isOwn)
1390  {
1391  pointI = f[fp];
1392  nextPointI = f.nextLabel(fp);
1393  }
1394  else
1395  {
1396  pointI = f.nextLabel(fp);
1397  nextPointI = f[fp];
1398  }
1399 
1400  triPointRef faceTri
1401  (
1402  points()[pointI],
1403  points()[nextPointI],
1404  fc
1405  );
1406 
1407  vector proj = p - faceTri.centre();
1408 
1409  if ((faceTri.normal() & proj) > 0)
1410  {
1411  return false;
1412  }
1413  }
1414  }
1415  return true;
1416  }
1417  break;
1418 
1419  case FACE_DIAG_TRIS:
1420  {
1421  // only test that point is on inside of plane defined by cell face
1422  // triangles
1423  const cell& cFaces = cells()[celli];
1424 
1425  forAll(cFaces, cFacei)
1426  {
1427  label facei = cFaces[cFacei];
1428  const face& f = faces_[facei];
1429 
1430  for (label tetPti = 1; tetPti < f.size() - 1; tetPti++)
1431  {
1432  // Get tetIndices of face triangle
1433  tetIndices faceTetIs
1434  (
1436  (
1437  *this,
1438  facei,
1439  celli,
1440  tetPti
1441  )
1442  );
1443 
1444  triPointRef faceTri = faceTetIs.faceTri(*this);
1445 
1446  vector proj = p - faceTri.centre();
1447 
1448  if ((faceTri.normal() & proj) > 0)
1449  {
1450  return false;
1451  }
1452  }
1453  }
1454 
1455  return true;
1456  }
1457  break;
1458 
1459  case CELL_TETS:
1460  {
1461  label tetFacei;
1462  label tetPti;
1463 
1464  findTetFacePt(celli, p, tetFacei, tetPti);
1465 
1466  return tetFacei != -1;
1467  }
1468  break;
1469  }
1470 
1471  return false;
1472 }
1473 
1474 
1477  const point& p,
1478  const cellDecomposition decompMode
1479 ) const
1480 {
1481  if
1482  (
1483  Pstream::parRun()
1484  && (decompMode == FACE_DIAG_TRIS || decompMode == CELL_TETS)
1485  )
1486  {
1487  // Force construction of face-diagonal decomposition before testing
1488  // for zero cells.
1489  //
1490  // If parallel running a local domain might have zero cells so never
1491  // construct the face-diagonal decomposition which uses parallel
1492  // transfers.
1493  (void)tetBasePtIs();
1494  }
1495 
1496  if (nCells() == 0)
1497  {
1498  return -1;
1499  }
1500 
1501  if (decompMode == CELL_TETS)
1502  {
1503  // Advanced search method utilizing an octree
1504  // and tet-decomposition of the cells
1505 
1506  label celli;
1507  label tetFacei;
1508  label tetPti;
1509 
1510  findCellFacePt(p, celli, tetFacei, tetPti);
1511 
1512  return celli;
1513  }
1514  else
1515  {
1516  // Approximate search avoiding the construction of an octree
1517  // and cell decomposition
1518 
1519  // Find the nearest cell centre to this location
1520  label celli = findNearestCell(p);
1521 
1522  // If point is in the nearest cell return
1523  if (pointInCell(p, celli, decompMode))
1524  {
1525  return celli;
1526  }
1527  else
1528  {
1529  // Point is not in the nearest cell so search all cells
1530 
1531  for (label celli = 0; celli < nCells(); celli++)
1532  {
1533  if (pointInCell(p, celli, decompMode))
1534  {
1535  return celli;
1536  }
1537  }
1538 
1539  return -1;
1540  }
1541  }
1542 }
1543 
1544 
1545 // ************************************************************************* //
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Definition: polyMesh.H:309
const cellZoneMesh & cellZones() const
Return cell zone mesh.
Definition: polyMesh.H:469
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:380
A List of objects of type <T> with automated input and output using a compact storage. Behaves like IOList except when binary output in case it writes a CompactListList.
Definition: CompactIOList.H:53
void resetMotion() const
Reset motion.
Definition: polyMesh.C:1192
Simple random number generator.
Definition: Random.H:49
const faceZoneMesh & faceZones() const
Return face zone mesh.
Definition: polyMesh.H:463
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: polyMesh.C:1105
unsigned char direction
Definition: direction.H:43
cachedRandom rndGen(label(0),-1)
const point & min() const
Minimum describing the bounding box.
Definition: boundBoxI.H:54
Inter-processor communications stream.
Definition: UPstream.H:58
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:142
label eventNo() const
Event number at last update.
Definition: regIOobjectI.H:82
label nGeometricD() const
Return the number of valid geometric dimensions in the mesh.
Definition: polyMesh.C:841
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:1341
bool rmDir(const fileName &)
Remove a dirctory and its contents.
Definition: POSIX.C:975
readOption readOpt() const
Definition: IOobject.H:304
static tetIndices triangleTetIndices(const polyMesh &mesh, label fI, label cI, const label tetPtI)
Return the tet decomposition of the given triangle of the given face.
static tetIndices findTet(const polyMesh &mesh, label cI, const point &pt)
Find the tet decomposition of the cell containing the given point.
bool set(const label) const
Is element set.
Definition: PtrListI.H:107
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
vector point
Point is a vector.
Definition: point.H:41
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:32
fileName path() const
Return path.
Definition: Time.H:281
void clearAddressing()
Clear topological data.
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
label nSolutionD() const
Return the number of valid solved-for dimensions in the mesh.
Definition: polyMesh.C:858
dimensioned< scalar > mag(const dimensioned< Type > &)
label getEvent() const
Return new event number.
A cell is defined as a list of faces with extra functionality.
Definition: cell.H:56
labelList f(nPoints)
static labelList findFaceBasePts(const polyMesh &mesh, scalar tol=minTetQuality, bool report=false)
Find a suitable base point for each face for decomposition.
const labelList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:864
virtual const pointField & oldPoints() const
Return old points for mesh motion.
Definition: polyMesh.C:1085
const Vector< label > & solutionD() const
Return the vector of solved-for directions in mesh.
Definition: polyMesh.C:847
const Type & shapes() const
Reference to shape.
bool pointInCell(const point &p, label celli) const
Return true if the point is in the cell.
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
label timeIndex
Definition: getTimeIndex.H:4
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
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:741
Standard boundBox + extra functionality for use in octree.
Definition: treeBoundBox.H:75
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
const fileName & instance() const
Definition: IOobject.H:337
void updateMesh()
Correct polyBoundaryMesh after topology update.
label nCells() const
const cellList & cells() const
bool exists(const fileName &, const bool checkGzip=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:609
virtual bool checkMeshMotion(const pointField &newPoints, const bool report=false, const bool detailedReport=false) const
Check mesh motion for correctness given motion points.
const pointZoneMesh & pointZones() const
Return point zone mesh.
Definition: polyMesh.H:457
bool checkDefinition(const bool report=false) const
Check boundary definition. Return true if in error.
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
messageStream Info
bool hit() const
Is there a hit.
label nextLabel(const label i) const
Next vertex on face.
Definition: faceI.H:117
dynamicFvMesh & mesh
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:818
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:57
virtual const fileName & dbDir() const
Local directory path of this objectRegistry relative to the time.
void addPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches.
Definition: polyMesh.C:925
label index() const
Return index.
bool rm(const fileName &)
Remove a file, returning true if successful otherwise false.
Definition: POSIX.C:955
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:57
Namespace for OpenFOAM.
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
Definition: polyMesh.C:799
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
bool upToDate(const regIOobject &) const
Return true if up-to-date with respect to given object.
Definition: regIOobject.C:326
label findNearestCell(const point &location) const
Find the cell with the nearest cell centre to location.
PtrList< polyPatch > polyPatchList
container classes for polyPatch
Definition: polyPatchList.H:45
virtual bool write() const
Write using setting from DB.
void resetPrimitives(const Xfer< pointField > &points, const Xfer< faceList > &faces, const Xfer< labelList > &owner, const Xfer< labelList > &neighbour, const labelList &patchSizes, const labelList &patchStarts, const bool validBoundary=true)
Reset mesh primitive data. Assumes all patch info correct.
Definition: polyMesh.C:666
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Number of components in this vector space.
Definition: VectorSpace.H:88
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
Cell-face mesh analysis engine.
Definition: primitiveMesh.H:74
static const char nl
Definition: Ostream.H:260
const double e
Elementary charge.
Definition: doubleFloat.H:78
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
#define WarningIn(functionName)
Report a warning using Foam::Warning.
treeBoundBox extend(Random &, const scalar s) const
Return slightly wider bounding box.
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1035
label timeIndex() const
Return current time index.
Definition: TimeState.C:73
vector normal() const
Return vector normal.
Definition: triangleI.H:103
primitiveMesh()
Construct null.
Definition: primitiveMesh.C:39
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
#define forAll(list, i)
Definition: UList.H:421
writeOption writeOpt() const
Definition: IOobject.H:314
virtual bool upToDatePoints(const regIOobject &io) const
Return true if io is up-to-date with points.
Definition: polyMesh.C:1048
A class representing the concept of 0 used to avoid unnecessary manipulations for objects that are kn...
Definition: zero.H:47
label patchi
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:363
const Cmpt & x() const
Definition: VectorI.H:65
label findCell(const point &p, const cellDecomposition=CELL_TETS) const
Find cell enclosing this location and return index.
Definition: polyMesh.C:1476
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
const point & max() const
Maximum describing the bounding box.
Definition: boundBoxI.H:60
const indexedOctree< treeDataCell > & cellTree() const
Return the cell search tree.
Definition: polyMesh.C:890
label size() const
Return number of elements in table.
const objectRegistry & thisDb() const
Return the object registry.
Definition: polyMesh.H:484
errorManip< error > abort(error &err)
Definition: errorManip.H:131
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1073
Point centre() const
Return centre (centroid)
Definition: triangleI.H:89
label comm() const
Return communicator used for parallel communication.
Definition: polyMesh.C:1218
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
InfoProxy< IOobject > info() const
Return info proxy.
Definition: IOobject.H:421
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:421
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A bounding box defined in terms of the points at its extremities.
Definition: boundBox.H:55
bool isDir(const fileName &)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:616
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:824
void movePoints(const pointField &)
Correct polyBoundaryMesh after moving points.
virtual void setUpToDatePoints(regIOobject &io) const
Set io to be up-to-date with points.
Definition: polyMesh.C:1054
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:306
Cmpt cmptSum(const VectorSpace< Form, Cmpt, nCmpt > &vs)
Definition: VectorSpaceI.H:414
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:60
const objectRegistry & parent() const
Return the parent objectRegistry.
error FatalError
const Vector< label > & geometricD() const
Return the vector of geometric directions in mesh.
Definition: polyMesh.C:830
Registry of regIOobjects.
void addZones(const List< pointZone * > &pz, const List< faceZone * > &fz, const List< cellZone * > &cz)
Add mesh zones.
Definition: polyMesh.C:971
A class for handling file names.
Definition: fileName.H:69
static const Vector zero
Definition: Vector.H:80
tmp< scalarField > movePoints(const pointField &p, const pointField &oldP)
Move points, returns volumes swept by faces in motion.
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
triPointRef faceTri(const polyMesh &mesh) const
Return the geometry corresponding to the tri on the.
Definition: tetIndicesI.H:109
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: polyMesh.C:812
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
void removeFiles() const
Remove all files from mesh instance()
Definition: polyMesh.C:1254
const Time & time() const
Return time.
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1060
label tetPt() const
Return the characterising tetPtI.
Definition: tetIndicesI.H:60
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
virtual const labelList & faceNeighbour() const
Return face neighbour.
Definition: polyMesh.C:1079
Encapsulation of data needed to search in/for cells. Used to find the cell containing a point (e...
Definition: treeDataCell.H:54
virtual ~polyMesh()
Destructor.
Definition: polyMesh.C:790
Storage and named access for the indices of a tet which is part of the decomposition of a cell...
Definition: tetIndices.H:73
void movePoints(const pointField &)
Correct zone mesh after moving points.
Definition: ZoneMesh.C:520
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:261
cellDecomposition
Enumeration defining the decomposition of the cell for.
Definition: polyMesh.H:98
bool moving() const
Is mesh moving.
Definition: polyMesh.H:493
bool pointInCell(const point &p, label celli, const cellDecomposition=CELL_TETS) const
Test if point p is in the celli.
Definition: polyMesh.C:1357
A class for managing temporary objects.
Definition: PtrList.H:118
label nPoints() const
const globalMeshData & globalData() const
Return parallel info.
Definition: polyMesh.C:1200
void findCellFacePt(const point &p, label &celli, label &tetFacei, label &tetPti) const
Find the cell, tetFacei and tetPti for point p.
Definition: polyMesh.C:1261
const Type & value() const
Return const reference to value.
defineTypeNameAndDebug(combustionModel, 0)
word timeName
Definition: getTimeIndex.H:3
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
const vectorField & faceCentres() const
const labelList & findIndices(const point &) const
Find the shape indices that occupy the result of findNode.
label face() const
Return the face.
Definition: tetIndicesI.H:36