faMesh.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2020-2023 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 "faMesh.H"
30 #include "faMeshBoundaryHalo.H"
31 #include "faGlobalMeshData.H"
32 #include "Time.H"
33 #include "polyMesh.H"
34 #include "primitiveMesh.H"
35 #include "demandDrivenData.H"
36 #include "IndirectList.H"
37 #include "areaFields.H"
38 #include "edgeFields.H"
39 #include "faMeshLduAddressing.H"
40 #include "processorFaPatch.H"
41 #include "wedgeFaPatch.H"
42 #include "faPatchData.H"
43 #include "registerSwitch.H"
44 
45 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
46 
47 namespace Foam
48 {
49  defineTypeNameAndDebug(faMesh, 0);
50 
52  (
53  debug::optimisationSwitch("fa:geometryOrder", 2)
54  );
56  (
57  "fa:geometryOrder",
58  int,
60  );
61 }
62 
63 
64 const Foam::word Foam::faMesh::prefix("finite-area");
65 
67 
68 const int Foam::faMesh::quadricsFit_ = 0; // Tuning (experimental)
69 
70 
71 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
72 
74 {
75  // This will change in the near future
76  return &static_cast<const objectRegistry&>(pMesh);
77 }
78 
79 
81 (
82  const polyMesh& pMesh
83 )
84 {
85  // This will change in the near future
86  return pMesh.lookupObject<faMesh>("faMesh");
87 }
88 
89 
90 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
91 
92 namespace Foam
93 {
94 
95 // Convert patch names to face labels. Preserve patch order
97 (
98  const polyBoundaryMesh& pbm,
99  const wordRes& polyPatchNames
100 )
101 {
102  const labelList patchIDs
103  (
104  pbm.indices(polyPatchNames, true) // useGroups
105  );
106 
107  if (patchIDs.empty())
108  {
110  << "No matching patches: " << polyPatchNames << nl
111  << exit(FatalError);
112  }
113 
114  label nFaceLabels = 0;
115  for (const label patchi : patchIDs)
116  {
117  nFaceLabels += pbm[patchi].size();
118  }
119 
121 
122  nFaceLabels = 0;
123  for (const label patchi : patchIDs)
124  {
125  for (const label facei : pbm[patchi].range())
126  {
127  faceLabels[nFaceLabels] = facei;
128  ++nFaceLabels;
129  }
130  }
131 
132  return faceLabels;
133 }
134 
135 } // End namespace Foam
136 
137 
138 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
139 
140 void Foam::faMesh::checkBoundaryEdgeLabelRange
141 (
142  const labelUList& edgeLabels
143 ) const
144 {
145  label nErrors = 0;
146 
147  for (const label edgei : edgeLabels)
148  {
149  if (edgei < nInternalEdges_ || edgei >= nEdges_)
150  {
151  if (!nErrors++)
152  {
154  << "Boundary edge label out of range "
155  << nInternalEdges_ << ".." << (nEdges_-1) << nl
156  << " ";
157  }
158 
159  FatalError<< ' ' << edgei;
160  }
161  }
162 
163  if (nErrors)
164  {
165  FatalError << nl << exit(FatalError);
166  }
167 }
168 
169 
170 void Foam::faMesh::initPatch() const
171 {
172  patchPtr_.reset
173  (
175  (
176  UIndirectList<face>(mesh().faces(), faceLabels_),
177  mesh().points()
178  )
179  );
180  // Could set some basic primitive data here...
181  // nEdges_ = patchPtr_->nEdges();
182  // nInternalEdges_ = patchPtr_->nInternalEdges();
183  // nFaces_ = patchPtr_->size();
184  // nPoints_ = patchPtr_->nPoints();
185  bndConnectPtr_.reset(nullptr);
186  haloMapPtr_.reset(nullptr);
187  haloFaceCentresPtr_.reset(nullptr);
188  haloFaceNormalsPtr_.reset(nullptr);
189 }
190 
191 
192 void Foam::faMesh::setPrimitiveMeshData()
193 {
194  DebugInFunction << "Setting primitive data" << endl;
195 
196  const uindirectPrimitivePatch& bp = patch();
197  const labelListList& edgeFaces = bp.edgeFaces();
198 
199  // Dimensions
200 
201  nEdges_ = bp.nEdges();
202  nInternalEdges_ = bp.nInternalEdges();
203  nFaces_ = bp.size();
204  nPoints_ = bp.nPoints();
205 
206  edges_.resize(nEdges_);
207  edgeOwner_.resize(nEdges_);
208  edgeNeighbour_.resize(nInternalEdges_);
209 
210  // Internal edges
211  for (label edgei = 0; edgei < nInternalEdges_; ++edgei)
212  {
213  edges_[edgei] = bp.edges()[edgei];
214 
215  edgeOwner_[edgei] = edgeFaces[edgei][0];
216 
217  edgeNeighbour_[edgei] = edgeFaces[edgei][1];
218  }
219 
220  // Continue with boundary edges
221  label edgei = nInternalEdges_;
222 
223  for (const faPatch& p : boundary())
224  {
225  for (const label patchEdgei : p.edgeLabels())
226  {
227  edges_[edgei] = bp.edges()[patchEdgei];
228 
229  edgeOwner_[edgei] = edgeFaces[patchEdgei][0];
230 
231  ++edgei;
232  }
233  }
234 }
235 
236 
237 void Foam::faMesh::clearHalo() const
238 {
239  DebugInFunction << "Clearing halo information" << endl;
240 
241  haloMapPtr_.reset(nullptr);
242  haloFaceCentresPtr_.reset(nullptr);
243  haloFaceNormalsPtr_.reset(nullptr);
244 }
245 
246 
247 void Foam::faMesh::clearGeomNotAreas() const
248 {
249  DebugInFunction << "Clearing geometry" << endl;
250 
251  clearHalo();
252  patchPtr_.reset(nullptr);
253  polyPatchFacesPtr_.reset(nullptr);
254  polyPatchIdsPtr_.reset(nullptr);
255  bndConnectPtr_.reset(nullptr);
256  deleteDemandDrivenData(SPtr_);
257  deleteDemandDrivenData(patchStartsPtr_);
258  deleteDemandDrivenData(LePtr_);
259  deleteDemandDrivenData(magLePtr_);
260  deleteDemandDrivenData(faceCentresPtr_);
261  deleteDemandDrivenData(edgeCentresPtr_);
262  deleteDemandDrivenData(faceAreaNormalsPtr_);
263  deleteDemandDrivenData(edgeAreaNormalsPtr_);
264  pointAreaNormalsPtr_.reset(nullptr);
265  deleteDemandDrivenData(faceCurvaturesPtr_);
266  deleteDemandDrivenData(edgeTransformTensorsPtr_);
267 }
268 
269 
270 void Foam::faMesh::clearGeom() const
271 {
272  DebugInFunction << "Clearing geometry" << endl;
273 
274  clearGeomNotAreas();
275  deleteDemandDrivenData(S0Ptr_);
276  deleteDemandDrivenData(S00Ptr_);
277  deleteDemandDrivenData(correctPatchPointNormalsPtr_);
278 }
279 
280 
281 void Foam::faMesh::clearAddressing() const
282 {
283  DebugInFunction << "Clearing addressing" << endl;
284 
285  deleteDemandDrivenData(lduPtr_);
286 }
287 
288 
289 void Foam::faMesh::clearOut() const
290 {
291  clearGeom();
292  clearAddressing();
293  globalMeshDataPtr_.reset(nullptr);
294 }
295 
296 
297 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
298 
300 {
301  if (UPstream::parRun())
302  {
303  // areaCentres()
304  if (faceCentresPtr_)
305  {
306  faceCentresPtr_->boundaryFieldRef()
307  .evaluateCoupled<processorFaPatch>();
308  }
309 
310  // faceAreaNormals()
311  if (faceAreaNormalsPtr_)
312  {
313  faceAreaNormalsPtr_->boundaryFieldRef()
314  .evaluateCoupled<processorFaPatch>();
315  }
316  }
317 }
318 
319 
320 bool Foam::faMesh::init(const bool doInit)
321 {
322  if (doInit)
323  {
324  setPrimitiveMeshData();
325  }
326 
327  // Create global mesh data
328  if (UPstream::parRun())
329  {
330  (void)globalData();
331  }
332 
333  // Calculate topology for the patches (processor-processor comms etc.)
334  boundary_.updateMesh();
335 
336  // Calculate the geometry for the patches (transformation tensors etc.)
337  boundary_.calcGeometry();
339  syncGeom();
340 
341  return false;
342 }
343 
345 Foam::faMesh::faMesh(const polyMesh& pMesh, const Foam::zero)
346 :
347  faMesh(pMesh, labelList(), static_cast<IOobjectOption>(pMesh))
348 {}
349 
350 
351 Foam::faMesh::faMesh(const faMesh& baseMesh, const Foam::zero)
352 :
353  faMesh
354  (
355  baseMesh,
357  IOobjectOption(IOobjectOption::NO_READ, IOobjectOption::NO_WRITE)
358  )
359 {}
360 
361 
362 Foam::faMesh::faMesh
363 (
364  const polyMesh& pMesh,
365  const bool doInit
366 )
367 :
369  faSchemes(mesh()),
370  edgeInterpolation(*this),
371  faSolution(mesh()),
372  faceLabels_
373  (
374  IOobject
375  (
376  "faceLabels",
377  time().findInstance(meshDir(), "faceLabels"),
378  faMesh::meshSubDir,
379  faMesh::thisDb(),
380  IOobject::MUST_READ,
381  IOobject::NO_WRITE
382  )
383  ),
384  boundary_
385  (
386  IOobject
387  (
388  "faBoundary",
389  // Allow boundary file that is newer than faceLabels
390  time().findInstance
391  (
392  meshDir(),
393  "faBoundary",
394  IOobject::MUST_READ,
395  faceLabels_.instance()
396  ),
397  faMesh::meshSubDir,
398  faMesh::thisDb(),
399  IOobject::MUST_READ,
400  IOobject::NO_WRITE
401  ),
402  *this
403  ),
404  comm_(UPstream::worldComm),
405  curTimeIndex_(time().timeIndex()),
406 
407  patchPtr_(nullptr),
408  polyPatchFacesPtr_(nullptr),
409  polyPatchIdsPtr_(nullptr),
410  bndConnectPtr_(nullptr),
411  lduPtr_(nullptr),
412 
413  SPtr_(nullptr),
414  S0Ptr_(nullptr),
415  S00Ptr_(nullptr),
416  patchStartsPtr_(nullptr),
417  LePtr_(nullptr),
418  magLePtr_(nullptr),
419  faceCentresPtr_(nullptr),
420  edgeCentresPtr_(nullptr),
421  faceAreaNormalsPtr_(nullptr),
422  edgeAreaNormalsPtr_(nullptr),
423  pointAreaNormalsPtr_(nullptr),
424  faceCurvaturesPtr_(nullptr),
425  edgeTransformTensorsPtr_(nullptr),
426  correctPatchPointNormalsPtr_(nullptr),
427  globalMeshDataPtr_(nullptr),
428 
429  haloMapPtr_(nullptr),
430  haloFaceCentresPtr_(nullptr),
431  haloFaceNormalsPtr_(nullptr)
432 {
433  DebugInFunction << "Creating from IOobject" << endl;
434 
435  setPrimitiveMeshData();
436 
437  if (doInit)
438  {
439  faMesh::init(false); // do not init lower levels
440  }
441 
442  if (doInit)
443  {
444  // Read some optional fields
445  // - logic as per fvMesh
446 
447  IOobject rio
448  (
449  "name",
450  time().timeName(),
452  faMesh::thisDb(),
456  );
457 
458  // Read old surface areas (if present)
459  rio.resetHeader("S0");
460  if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
461  {
462  S0Ptr_ = new DimensionedField<scalar, areaMesh>
463  (
464  rio,
465  *this,
467  );
468  }
469  }
470 }
471 
472 
473 Foam::faMesh::faMesh
474 (
475  const polyMesh& pMesh,
477 )
478 :
479  faMesh
480  (
481  pMesh,
482  std::move(faceLabels),
483  static_cast<IOobjectOption>(pMesh)
484  )
485 {}
486 
487 
488 Foam::faMesh::faMesh
489 (
490  const polyMesh& pMesh,
492  IOobjectOption ioOpt
493 )
494 :
496  faSchemes(mesh(), ioOpt.readOpt()),
497  edgeInterpolation(*this),
498  faSolution(mesh(), ioOpt.readOpt()),
499  faceLabels_
500  (
501  IOobject
502  (
503  "faceLabels",
504  mesh().facesInstance(),
505  faMesh::meshSubDir,
506  faMesh::thisDb(),
507  IOobject::NO_READ,
508  IOobject::NO_WRITE
509  ),
510  std::move(faceLabels)
511  ),
512  boundary_
513  (
514  IOobject
515  (
516  "faBoundary",
517  mesh().facesInstance(),
518  faMesh::meshSubDir,
519  faMesh::thisDb(),
520  IOobject::NO_READ,
521  IOobject::NO_WRITE
522  ),
523  *this,
524  label(0)
525  ),
526  comm_(UPstream::worldComm),
527  curTimeIndex_(time().timeIndex()),
528 
529  patchPtr_(nullptr),
530  polyPatchFacesPtr_(nullptr),
531  polyPatchIdsPtr_(nullptr),
532  bndConnectPtr_(nullptr),
533  lduPtr_(nullptr),
534 
535  SPtr_(nullptr),
536  S0Ptr_(nullptr),
537  S00Ptr_(nullptr),
538  patchStartsPtr_(nullptr),
539  LePtr_(nullptr),
540  magLePtr_(nullptr),
541  faceCentresPtr_(nullptr),
542  edgeCentresPtr_(nullptr),
543  faceAreaNormalsPtr_(nullptr),
544  edgeAreaNormalsPtr_(nullptr),
545  pointAreaNormalsPtr_(nullptr),
546  faceCurvaturesPtr_(nullptr),
547  edgeTransformTensorsPtr_(nullptr),
548  correctPatchPointNormalsPtr_(nullptr),
549  globalMeshDataPtr_(nullptr),
550 
551  haloMapPtr_(nullptr),
552  haloFaceCentresPtr_(nullptr),
553  haloFaceNormalsPtr_(nullptr)
554 {
555  // Not yet much for primitive mesh data possible...
556  nPoints_ = 0;
557  nEdges_ = 0;
558  nInternalEdges_ = 0;
559  nFaces_ = faceLabels_.size();
560 }
561 
562 
563 Foam::faMesh::faMesh
564 (
565  const faMesh& baseMesh,
567  IOobjectOption ioOpt
568 )
569 :
571  faSchemes
572  (
573  faMesh::thisDb(),
574  ioOpt.readOpt(),
575  static_cast<const dictionary*>(baseMesh.hasSchemes())
576  ),
577  edgeInterpolation(*this),
578  faSolution
579  (
580  faMesh::thisDb(),
581  ioOpt.readOpt(),
582  static_cast<const dictionary*>(baseMesh.hasSolution())
583  ),
584  faceLabels_
585  (
586  IOobject
587  (
588  "faceLabels",
589  mesh().facesInstance(),
590  faMesh::meshSubDir,
591  faMesh::thisDb(),
592  IOobject::NO_READ,
593  IOobject::NO_WRITE
594  ),
595  std::move(faceLabels)
596  ),
597  boundary_
598  (
599  IOobject
600  (
601  "faBoundary",
602  mesh().facesInstance(),
603  faMesh::meshSubDir,
604  faMesh::thisDb(),
605  IOobject::NO_READ,
606  IOobject::NO_WRITE
607  ),
608  *this,
609  label(0)
610  ),
611  comm_(UPstream::worldComm),
612  curTimeIndex_(time().timeIndex()),
613 
614  patchPtr_(nullptr),
615  polyPatchFacesPtr_(nullptr),
616  polyPatchIdsPtr_(nullptr),
617  bndConnectPtr_(nullptr),
618  lduPtr_(nullptr),
619 
620  SPtr_(nullptr),
621  S0Ptr_(nullptr),
622  S00Ptr_(nullptr),
623  patchStartsPtr_(nullptr),
624  LePtr_(nullptr),
625  magLePtr_(nullptr),
626  faceCentresPtr_(nullptr),
627  edgeCentresPtr_(nullptr),
628  faceAreaNormalsPtr_(nullptr),
629  edgeAreaNormalsPtr_(nullptr),
630  pointAreaNormalsPtr_(nullptr),
631  faceCurvaturesPtr_(nullptr),
632  edgeTransformTensorsPtr_(nullptr),
633  correctPatchPointNormalsPtr_(nullptr),
634  globalMeshDataPtr_(nullptr),
635 
636  haloMapPtr_(nullptr),
637  haloFaceCentresPtr_(nullptr),
638  haloFaceNormalsPtr_(nullptr)
639 {
640  // Not yet much for primitive mesh data possible...
641  nPoints_ = 0;
642  nEdges_ = 0;
643  nInternalEdges_ = 0;
644  nFaces_ = faceLabels_.size();
645 }
646 
647 
648 Foam::faMesh::faMesh(const polyPatch& pp, const bool doInit)
649 :
650  faMesh
651  (
652  pp.boundaryMesh().mesh(),
653  identity(pp.range())
654  )
655 {
656  DebugInFunction << "Creating from polyPatch:" << pp.name() << endl;
657 
658  // Add single faPatch "default", but with processor connections
659  faPatchList newPatches
660  (
661  createOnePatch("default")
662  );
663 
664  addFaPatches(newPatches);
665 
666  setPrimitiveMeshData();
667 
668  if (doInit)
669  {
670  faMesh::init(false); // do not init lower levels
671  }
672 }
673 
674 
675 Foam::faMesh::faMesh
676 (
677  const polyMesh& pMesh,
678  const dictionary& faMeshDefinition,
679  const bool doInit
680 )
681 :
682  faMesh
683  (
684  pMesh,
686  (
687  pMesh.boundaryMesh(),
688  faMeshDefinition.get<wordRes>("polyMeshPatches")
689  )
690  )
691 {
692  DebugInFunction << "Creating from definition (dictionary)" << endl;
693 
694  faPatchList newPatches
695  (
696  createPatchList
697  (
698  faMeshDefinition.subDict("boundary"),
699 
700  // Optional 'empty' patch
701  faMeshDefinition.getOrDefault<word>("emptyPatch", word::null),
702 
703  // Optional specification for default patch
704  faMeshDefinition.findDict("defaultPatch")
705  )
706  );
707 
708  addFaPatches(newPatches);
709 
710  if (doInit)
711  {
712  faMesh::init(false); // do not init lower levels
713  }
714 
715  if (doInit)
716  {
717  // Read old surface areas (if present)
718  // - logic as per fvMesh
719 
720  IOobject rio
721  (
722  "name",
723  time().timeName(),
725  faMesh::thisDb(),
729  );
730 
731  // Read old surface areas (if present)
732  rio.resetHeader("S0");
733  if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
734  {
735  S0Ptr_ = new DimensionedField<scalar, areaMesh>
736  (
737  rio,
738  *this,
740  );
741  }
742  }
743 }
744 
745 
746 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
747 
749 {
750  clearOut();
751 }
752 
753 
754 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
757 {
758  return static_cast<const faSchemes*>(this);
759 }
760 
763 {
764  return static_cast<const faSolution*>(this);
765 }
766 
769 {
770  return static_cast<const faSchemes&>(*this);
771 }
772 
775 {
776  return static_cast<faSchemes&>(*this);
777 }
778 
781 {
782  return static_cast<const faSolution&>(*this);
783 }
784 
787 {
788  return static_cast<faSolution&>(*this);
789 }
790 
793 {
794  return mesh().dbDir()/faMesh::meshSubDir;
795 }
796 
798 const Foam::Time& Foam::faMesh::time() const
799 {
800  return mesh().time();
801 }
802 
805 {
806  return mesh().pointsInstance();
807 }
808 
811 {
812  return mesh().facesInstance();
813 }
814 
816 bool Foam::faMesh::hasDb() const
817 {
818  return true;
819 }
820 
823 {
824  return mesh().thisDb();
825 }
826 
829 {
830  return polyMesh::regionName(thisDb().name());
831 }
832 
833 
835 {
836  const labelList& faceOwner = this->mesh().faceOwner();
837 
838  labelList list(faceLabels_);
839 
840  for (label& val : list)
841  {
842  // Transcribe from faceId to cellId (owner)
843  val = faceOwner[val];
844  }
845 
846  return list;
847 }
848 
849 
850 void Foam::faMesh::removeFiles(const fileName& instanceDir) const
851 {
852  fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
853 
854  Foam::rm(meshFilesPath/"faceLabels");
855  Foam::rm(meshFilesPath/"faBoundary");
856 }
857 
859 void Foam::faMesh::removeFiles() const
860 {
861  removeFiles(thisDb().instance());
862 }
863 
864 
866 {
867  if (!patchStartsPtr_)
868  {
869  calcPatchStarts();
870  }
871 
872  return *patchStartsPtr_;
873 }
874 
875 
877 {
878  if (!LePtr_)
879  {
880  calcLe();
881  }
882 
883  return *LePtr_;
884 }
885 
886 
888 {
889  if (!magLePtr_)
890  {
891  calcMagLe();
892  }
893 
894  return *magLePtr_;
895 }
896 
897 
899 {
900  if (!faceCentresPtr_)
901  {
902  calcFaceCentres();
903  }
904 
905  return *faceCentresPtr_;
906 }
907 
908 
910 {
911  if (!edgeCentresPtr_)
912  {
913  calcEdgeCentres();
914  }
915 
916  return *edgeCentresPtr_;
917 }
918 
919 
921 Foam::faMesh::S() const
922 {
923  if (!SPtr_)
924  {
925  calcS();
926  }
927 
928  return *SPtr_;
929 }
930 
931 
933 Foam::faMesh::S0() const
934 {
935  if (!S0Ptr_)
936  {
938  << "S0 is not available"
939  << abort(FatalError);
940  }
941 
942  return *S0Ptr_;
943 }
944 
945 
947 Foam::faMesh::S00() const
948 {
949  if (!S00Ptr_)
950  {
951  S00Ptr_ = new DimensionedField<scalar, areaMesh>
952  (
953  IOobject
954  (
955  "S00",
956  time().timeName(),
957  faMesh::thisDb(),
960  ),
961  S0()
962  );
963 
964  S0Ptr_->writeOpt(IOobject::AUTO_WRITE);
965  }
966 
967  return *S00Ptr_;
968 }
969 
970 
972 {
973  if (!faceAreaNormalsPtr_)
974  {
975  calcFaceAreaNormals();
976  }
977 
978  return *faceAreaNormalsPtr_;
979 }
980 
981 
983 {
984  if (!edgeAreaNormalsPtr_)
985  {
986  calcEdgeAreaNormals();
987  }
988 
989  return *edgeAreaNormalsPtr_;
990 }
991 
992 
994 {
995  if (!pointAreaNormalsPtr_)
996  {
997  pointAreaNormalsPtr_.reset(new vectorField(nPoints()));
998 
999  calcPointAreaNormals(*pointAreaNormalsPtr_);
1000 
1001  if (quadricsFit_ > 0)
1002  {
1003  calcPointAreaNormalsByQuadricsFit(*pointAreaNormalsPtr_);
1004  }
1005  }
1006 
1007  return *pointAreaNormalsPtr_;
1008 }
1009 
1010 
1012 {
1013  if (!faceCurvaturesPtr_)
1014  {
1015  calcFaceCurvatures();
1016  }
1017 
1018  return *faceCurvaturesPtr_;
1019 }
1020 
1021 
1024 {
1025  if (!edgeTransformTensorsPtr_)
1026  {
1027  calcEdgeTransformTensors();
1028  }
1029 
1030  return *edgeTransformTensorsPtr_;
1031 }
1032 
1035 {
1036  return bool(globalMeshDataPtr_);
1037 }
1038 
1039 
1041 {
1042  if (!globalMeshDataPtr_)
1043  {
1044  globalMeshDataPtr_.reset(new faGlobalMeshData(*this));
1045  }
1046 
1047  return *globalMeshDataPtr_;
1048 }
1049 
1050 
1052 {
1053  if (!lduPtr_)
1054  {
1055  calcLduAddressing();
1056  }
1057 
1058  return *lduPtr_;
1059 }
1060 
1061 
1063 {
1064  // Grab point motion from polyMesh
1065  const vectorField& newPoints = mesh().points();
1066 
1067  // Grab old time areas if the time has been incremented
1068  if (curTimeIndex_ < time().timeIndex())
1069  {
1070  if (S00Ptr_ && S0Ptr_)
1071  {
1072  DebugInfo<< "Copy old-old S" << endl;
1073  *S00Ptr_ = *S0Ptr_;
1074  }
1075 
1076  if (S0Ptr_)
1077  {
1078  DebugInfo<< "Copy old S" << endl;
1079  *S0Ptr_ = S();
1080  }
1081  else
1082  {
1083  DebugInfo<< "Creating old cell volumes." << endl;
1084 
1085  S0Ptr_ = new DimensionedField<scalar, areaMesh>
1086  (
1087  IOobject
1088  (
1089  "S0",
1090  time().timeName(),
1091  faMesh::thisDb(),
1095  ),
1096  S()
1097  );
1098  }
1099 
1100  curTimeIndex_ = time().timeIndex();
1101  }
1102 
1103  clearGeomNotAreas();
1104 
1105  if (patchPtr_)
1106  {
1107  patchPtr_->movePoints(newPoints);
1108  }
1109 
1110  // Move boundary points
1111  boundary_.movePoints(newPoints);
1112 
1113  // Move interpolation
1115 
1116  // Note: Fluxes were dummy?
1118  syncGeom();
1119 
1120  return true;
1121 }
1122 
1123 
1124 bool Foam::faMesh::correctPatchPointNormals(const label patchID) const
1125 {
1126  if
1127  (
1128  bool(correctPatchPointNormalsPtr_)
1129  && patchID >= 0 && patchID < boundary().size()
1130  )
1131  {
1132  return (*correctPatchPointNormalsPtr_)[patchID];
1133  }
1134 
1135  return false;
1136 }
1137 
1138 
1140 {
1141  if (!correctPatchPointNormalsPtr_)
1142  {
1143  correctPatchPointNormalsPtr_ = new boolList(boundary().size(), false);
1144  }
1145 
1146  return *correctPatchPointNormalsPtr_;
1147 }
1148 
1149 
1150 bool Foam::faMesh::write(const bool writeOnProc) const
1151 {
1152  faceLabels_.write();
1153  boundary_.write();
1155  return false;
1156 }
1157 
1158 
1159 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1161 bool Foam::faMesh::operator!=(const faMesh& m) const
1162 {
1163  return &m != this;
1164 }
1165 
1166 
1167 bool Foam::faMesh::operator==(const faMesh& m) const
1168 {
1169  return &m == this;
1170 }
1171 
1172 
1173 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
PtrList< faPatch > faPatchList
Store lists of faPatch as a PtrList.
Definition: faPatch.H:59
registerOptSwitch("fa:geometryOrder", int, faMesh::geometryOrder_)
Finite area mesh (used for 2-D non-Euclidian finite area method) defined using a patch of faces on a ...
Definition: faMesh.H:87
faceListList boundary
const labelList patchIDs(pbm.indices(polyPatchNames, true))
const polyBoundaryMesh & pbm
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
void addFaPatches(faPatchList &plist, const bool validBoundary=true)
Add boundary patches. Constructor helper.
Definition: faMeshPatches.C:68
A class for handling file names.
Definition: fileName.H:72
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
const DimensionedField< scalar, areaMesh > & S00() const
Return old-old-time face areas.
Definition: faMesh.C:940
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:859
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:847
const Time & time() const
Return reference to time.
Definition: faMesh.C:791
void syncGeom()
Processor/processor synchronisation for geometry fields.
Definition: faMesh.C:292
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:666
regIOobject(const IOobject &io, const bool isTimeObject=false)
Construct from IOobject. The optional flag adds special handling if the object is the top-level regIO...
Definition: regIOobject.C:43
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Definition: boundaryMesh.H:58
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
const DimensionedField< scalar, areaMesh > & S() const
Return face areas.
Definition: faMesh.C:914
Face to edge interpolation scheme. Included in faMesh.
bool operator!=(const faMesh &m) const
Definition: faMesh.C:1154
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
Various mesh related information for a parallel run.
Generic GeometricField class.
Definition: areaFieldsFwd.H:50
const faGlobalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: faMesh.C:1033
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
Definition: polyMesh.C:830
static std::string path(const std::string &str)
Return directory path name (part before last /)
Definition: fileNameI.H:169
const labelList & patchStarts() const
Return patch starts.
Definition: faMesh.C:858
Ignore writing from objectRegistry::writeObject()
bool movePoints() const
Do what is necessary if the mesh has moved.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: faMesh.C:821
const areaVectorField & areaCentres() const
Return face centres as areaVectorField.
Definition: faMesh.C:891
labelList faceLabels(nFaceLabels)
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual const objectRegistry & thisDb() const
Return reference to the mesh database.
Definition: faMesh.C:815
const edgeScalarField & magLe() const
Return edge length magnitudes.
Definition: faMesh.C:880
bool hasGlobalData() const noexcept
Is demand-driven parallel info available?
Definition: faMesh.C:1027
scalar range
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
virtual const objectRegistry & thisDb() const
Return the object registry - resolve conflict polyMesh/lduMesh.
Definition: fvMesh.H:376
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1078
labelList indices(const wordRe &matcher, const bool useGroups=true) const
Return (sorted) patch indices for all matches.
Templated abstract base-class for optional mesh objects used to automate their allocation to the mesh...
Definition: MeshObject.H:85
virtual bool hasDb() const
Return true if thisDb() is a valid DB.
Definition: faMesh.C:809
word timeName
Definition: getTimeIndex.H:3
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:853
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
const pointField & points
virtual ~faMesh()
Destructor.
Definition: faMesh.C:741
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
fileName meshDir() const
Return the local mesh directory (dbDir()/meshSubDir)
Definition: faMesh.C:785
bool operator==(const faMesh &m) const
Definition: faMesh.C:1160
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
Definition: faMesh.C:1044
#define DebugInFunction
Report an information message using Foam::Info.
wordRes polyPatchNames
const edgeVectorField & Le() const
Return edge length vectors.
Definition: faMesh.C:869
label nFaceLabels
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
static const word prefix
The prefix to local: finite-area.
Definition: faMesh.H:696
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1116
static const word null
An empty word.
Definition: word.H:84
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
errorManip< error > abort(error &err)
Definition: errorManip.H:139
#define DebugInfo
Report an information message using Foam::Info.
const FieldField< Field, tensor > & edgeTransformTensors() const
Return edge transformation tensors.
Definition: faMesh.C:1016
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
static labelList selectPatchFaces(const polyBoundaryMesh &pbm, const wordRes &polyPatchNames)
Definition: faMesh.C:90
const direction noexcept
Definition: Scalar.H:258
virtual bool movePoints()
Update after mesh motion.
Definition: faMesh.C:1055
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:234
virtual bool write(const bool writeOnProc=true) const
Write mesh.
Definition: faMesh.C:1143
defineTypeNameAndDebug(combustionModel, 0)
const polyMesh & mesh() const
Return access to polyMesh.
Definition: faMeshI.H:24
const areaScalarField & faceCurvatures() const
Return face curvatures.
Definition: faMesh.C:1004
boolList & correctPatchPointNormals() const
Set whether point normals should be corrected for a patch.
Definition: faMesh.C:1132
Template functions to aid in the implementation of demand driven data.
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Definition: faMesh.H:701
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: faMesh.C:803
PrimitivePatch< UIndirectList< face >, const pointField & > uindirectPrimitivePatch
A PrimitivePatch with UIndirectList for the faces, const reference for the point field.
Selector class for finite area differencing schemes. faMesh is derived from faSchemes so that all fie...
Definition: faSchemes.H:51
const edgeVectorField & edgeCentres() const
Return edge centres as edgeVectorField.
Definition: faMesh.C:902
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
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.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: areaFieldsFwd.H:42
const faSchemes * hasSchemes() const
Non-null if faSchemes exists (can test as bool).
Definition: faMesh.C:749
Nothing to be read.
Automatically write from objectRegistry::writeObject()
const std::string patch
OpenFOAM patch number as a std::string.
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: faMesh.C:797
Selector class for finite area solution. faMesh is derived from faSolution so that all fields have ac...
Definition: faSolution.H:51
const edgeVectorField & edgeAreaNormals() const
Return edge area normals.
Definition: faMesh.C:975
bool init(const bool doInit)
Initialise non-demand-driven data etc.
Definition: faMesh.C:313
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
labelList faceCells() const
The volume (owner) cells associated with the area-mesh.
Definition: faMesh.C:827
Reading is optional [identical to READ_IF_PRESENT].
Field< vector > vectorField
Specialisation of Field<T> for vector.
static const objectRegistry * registry(const polyMesh &pMesh)
The parent registry containing all finite-area meshes on the polyMesh.
Definition: faMesh.C:66
static int geometryOrder_
Geometry treatment.
Definition: faMesh.H:685
The class contains the addressing required by the lduMatrix: upper, lower and losort.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
void removeFiles() const
Remove all files from mesh instance()
Definition: faMesh.C:852
Registry of regIOobjects.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
void deleteDemandDrivenData(DataPtr &dataPtr)
const vectorField & pointAreaNormals() const
Return point area normals.
Definition: faMesh.C:986
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
const areaVectorField & faceAreaNormals() const
Return face area normals.
Definition: faMesh.C:964
const faSolution & solution() const
Read-access to the faSolution controls.
Definition: faMesh.C:773
List< bool > boolList
A List of bools.
Definition: List.H:60
const faSolution * hasSolution() const
Non-null if faSolution exists (can test as bool).
Definition: faMesh.C:755
Inter-processor communications stream.
Definition: UPstream.H:60
Do not request registration (bool: false)
const dimensionSet dimArea(sqr(dimLength))
Definition: dimensionSets.H:57
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
const DimensionedField< scalar, areaMesh > & S0() const
Return old-time face areas.
Definition: faMesh.C:926
label timeIndex
Definition: getTimeIndex.H:24
Processor patch.
const faSchemes & schemes() const
Read-access to the faSchemes controls.
Definition: faMesh.C:761
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1404
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127