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-2024 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 "IndirectList.H"
36 #include "areaFields.H"
37 #include "edgeFields.H"
38 #include "faMeshLduAddressing.H"
39 #include "processorFaPatch.H"
40 #include "wedgeFaPatch.H"
41 #include "faPatchData.H"
42 #include "registerSwitch.H"
43 
44 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 
46 namespace Foam
47 {
48  defineTypeNameAndDebug(faMesh, 0);
49 
51  (
52  debug::optimisationSwitch("fa:geometryOrder", 2)
53  );
55  (
56  "fa:geometryOrder",
57  int,
59  );
60 }
61 
62 
63 const Foam::word Foam::faMesh::prefix_("finite-area");
64 
66 
67 const int Foam::faMesh::quadricsFit_ = 0; // Tuning (experimental)
68 
69 
70 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
71 
73 {
74  return prefix_;
75 }
76 
77 
78 Foam::fileName Foam::faMesh::dbDir(const word& areaRegion)
79 {
80  if (areaRegion.empty() || areaRegion == polyMesh::defaultRegion)
81  {
82  return faMesh::prefix();
83  }
84 
85  return (faMesh::prefix() / areaRegion);
86 }
87 
88 
90 (
91  const word& volRegion,
92  const word& areaRegion
93 )
94 {
95  return
96  (
97  polyMesh::regionName(volRegion)
99  / polyMesh::regionName(areaRegion)
100  );
101 }
102 
103 
105 (
106  const polyMesh& pMesh,
107  const word& areaRegion
108 )
109 {
110  return faMesh::dbDir(pMesh.regionName(), areaRegion);
111 }
112 
113 
114 Foam::fileName Foam::faMesh::meshDir(const word& areaRegion)
115 {
116  if (areaRegion.empty() || areaRegion == polyMesh::defaultRegion)
117  {
118  return faMesh::meshSubDir;
119  }
120 
121  return (areaRegion / faMesh::meshSubDir);
122 }
123 
124 
126 (
127  const word& volRegion,
128  const word& areaRegion
129 )
130 {
131  return
132  (
133  polyMesh::regionName(volRegion)
134  / faMesh::prefix()
135  / polyMesh::regionName(areaRegion)
137  );
138 }
139 
140 
142 (
143  const polyMesh& pMesh,
144  const word& areaRegion
145 )
146 {
147  return faMesh::meshDir(pMesh.regionName(), areaRegion);
148 }
149 
150 
152 {
153  return pMesh.cfindObject<objectRegistry>(faMesh::prefix());
154 }
155 
156 
157 // const Foam::objectRegistry* Foam::faMesh::registry(const objectRegistry& obr)
158 // {
159 // return obr.cfindObject<objectRegistry>(faMesh::prefix());
160 // }
161 
162 
164 (
165  const polyMesh& pMesh
166 )
167 {
168  return faMesh::mesh(pMesh, polyMesh::defaultRegion);
169 }
170 
171 
173 (
174  const polyMesh& pMesh,
175  const word& areaRegion
176 )
177 {
178  const objectRegistry* obr = faMesh::registry(pMesh);
179 
180  if (!obr)
181  {
182  // Fallback - not really valid, but will fail at the next stage
183  obr = &(pMesh.thisDb());
184  }
185 
186  if (areaRegion.empty())
187  {
188  return obr->lookupObject<faMesh>(polyMesh::defaultRegion);
189  }
190 
191  return obr->lookupObject<faMesh>(areaRegion);
192 }
193 
194 
195 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
196 
197 namespace Foam
198 {
199 
200 // Convert patch names to face labels. Preserve patch order
202 (
203  const polyBoundaryMesh& pbm,
204  const wordRes& polyPatchNames
205 )
206 {
207  const labelList patchIDs
208  (
209  pbm.indices(polyPatchNames, true) // useGroups
210  );
211 
212  if (patchIDs.empty())
213  {
215  << "No matching patches: " << polyPatchNames << nl
216  << exit(FatalError);
217  }
218 
219  label nFaceLabels = 0;
220  for (const label patchi : patchIDs)
221  {
222  nFaceLabels += pbm[patchi].size();
223  }
224 
226 
227  nFaceLabels = 0;
228  for (const label patchi : patchIDs)
229  {
230  for (const label facei : pbm[patchi].range())
231  {
232  faceLabels[nFaceLabels] = facei;
233  ++nFaceLabels;
234  }
235  }
236 
237  return faceLabels;
238 }
239 
240 } // End namespace Foam
241 
242 
243 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
244 
245 void Foam::faMesh::checkBoundaryEdgeLabelRange
246 (
247  const labelUList& edgeLabels
248 ) const
249 {
250  label nErrors = 0;
251 
252  for (const label edgei : edgeLabels)
253  {
254  if (edgei < nInternalEdges_ || edgei >= nEdges_)
255  {
256  if (!nErrors++)
257  {
259  << "Boundary edge label out of range "
260  << nInternalEdges_ << ".." << (nEdges_-1) << nl
261  << " ";
262  }
263 
264  FatalError<< ' ' << edgei;
265  }
266  }
267 
268  if (nErrors)
269  {
270  FatalError << nl << exit(FatalError);
271  }
272 }
273 
274 
275 void Foam::faMesh::initPatch() const
276 {
277  patchPtr_ = std::make_unique<uindirectPrimitivePatch>
278  (
279  UIndirectList<face>(mesh().faces(), faceLabels_),
280  mesh().points()
281  );
282 
283  // Could set some basic primitive data here...
284  // nEdges_ = patchPtr_->nEdges();
285  // nInternalEdges_ = patchPtr_->nInternalEdges();
286  // nFaces_ = patchPtr_->size();
287  // nPoints_ = patchPtr_->nPoints();
288  bndConnectPtr_.reset(nullptr);
289  haloMapPtr_.reset(nullptr);
290  haloFaceCentresPtr_.reset(nullptr);
291  haloFaceNormalsPtr_.reset(nullptr);
292 }
293 
294 
295 void Foam::faMesh::setPrimitiveMeshData()
296 {
297  DebugInFunction << "Setting primitive data" << endl;
298 
299  const uindirectPrimitivePatch& bp = patch();
300  const labelListList& edgeFaces = bp.edgeFaces();
301 
302  // Dimensions
303 
304  nEdges_ = bp.nEdges();
305  nInternalEdges_ = bp.nInternalEdges();
306  nFaces_ = bp.size();
307  nPoints_ = bp.nPoints();
308 
309  edges_.resize(nEdges_);
310  edgeOwner_.resize(nEdges_);
311  edgeNeighbour_.resize(nInternalEdges_);
312 
313  // Internal edges
314  for (label edgei = 0; edgei < nInternalEdges_; ++edgei)
315  {
316  edges_[edgei] = bp.edges()[edgei];
317 
318  edgeOwner_[edgei] = edgeFaces[edgei][0];
319 
320  edgeNeighbour_[edgei] = edgeFaces[edgei][1];
321  }
322 
323  // Continue with boundary edges
324  label edgei = nInternalEdges_;
325 
326  for (const faPatch& p : boundary())
327  {
328  for (const label patchEdgei : p.edgeLabels())
329  {
330  edges_[edgei] = bp.edges()[patchEdgei];
331 
332  edgeOwner_[edgei] = edgeFaces[patchEdgei][0];
333 
334  ++edgei;
335  }
336  }
337 }
338 
339 
340 void Foam::faMesh::clearHalo() const
341 {
342  DebugInFunction << "Clearing halo information" << endl;
343 
344  haloMapPtr_.reset(nullptr);
345  haloFaceCentresPtr_.reset(nullptr);
346  haloFaceNormalsPtr_.reset(nullptr);
347 }
348 
349 
350 void Foam::faMesh::clearGeomNotAreas() const
351 {
352  DebugInFunction << "Clearing geometry" << endl;
353 
354  clearHalo();
355  patchPtr_.reset(nullptr);
356  polyPatchFacesPtr_.reset(nullptr);
357  polyPatchIdsPtr_.reset(nullptr);
358  bndConnectPtr_.reset(nullptr);
359  SPtr_.reset(nullptr);
360  patchStartsPtr_.reset(nullptr);
361  LePtr_.reset(nullptr);
362  magLePtr_.reset(nullptr);
363  faceCentresPtr_.reset(nullptr);
364  edgeCentresPtr_.reset(nullptr);
365  faceAreaNormalsPtr_.reset(nullptr);
366  edgeAreaNormalsPtr_.reset(nullptr);
367  pointAreaNormalsPtr_.reset(nullptr);
368  faceCurvaturesPtr_.reset(nullptr);
369  edgeTransformTensorsPtr_.reset(nullptr);
370 }
371 
372 
373 void Foam::faMesh::clearGeom() const
374 {
375  DebugInFunction << "Clearing geometry" << endl;
376 
377  clearGeomNotAreas();
378  S0Ptr_.reset(nullptr);
379  S00Ptr_.reset(nullptr);
380  correctPatchPointNormalsPtr_.reset(nullptr);
381 }
382 
383 
384 void Foam::faMesh::clearAddressing() const
385 {
386  DebugInFunction << "Clearing addressing" << endl;
387 
388  lduPtr_.reset(nullptr);
389 }
390 
391 
392 void Foam::faMesh::clearOut() const
393 {
394  clearGeom();
395  clearAddressing();
396  globalMeshDataPtr_.reset(nullptr);
397 }
398 
399 
400 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
401 
403 {
404  if (UPstream::parRun())
405  {
406  // areaCentres()
407  if (faceCentresPtr_)
408  {
409  faceCentresPtr_->boundaryFieldRef()
410  .evaluateCoupled<processorFaPatch>();
411  }
412 
413  // faceAreaNormals()
414  if (faceAreaNormalsPtr_)
415  {
416  faceAreaNormalsPtr_->boundaryFieldRef()
417  .evaluateCoupled<processorFaPatch>();
418  }
419  }
420 }
421 
422 
423 bool Foam::faMesh::init(const bool doInit)
424 {
425  if (doInit)
426  {
427  setPrimitiveMeshData();
428  }
429 
430  // Create global mesh data
431  if (UPstream::parRun())
432  {
433  (void)globalData();
434  }
435 
436  // Calculate topology for the patches (processor-processor comms etc.)
437  boundary_.updateMesh();
438 
439  // Calculate the geometry for the patches (transformation tensors etc.)
440  boundary_.calcGeometry();
441 
442  syncGeom();
443 
444  return false;
445 }
446 
447 
448 // * * * * * * * * * * * * * Forwarding Constructors * * * * * * * * * * * * //
449 
451 (
452  const word& meshName,
453  const polyMesh& pMesh,
454  Foam::zero
455 )
456 :
457  faMesh(meshName, pMesh, labelList())
458 {}
459 
460 
462 (
463  const polyMesh& pMesh,
465 )
466 :
467  faMesh(polyMesh::defaultRegion, pMesh, labelList())
468 {}
469 
470 
471 Foam::faMesh::faMesh(const polyMesh& pMesh, const bool doInit)
472 :
473  faMesh(polyMesh::defaultRegion, pMesh, doInit)
474 {}
475 
476 
478 (
479  const word& meshName,
480  const faMesh& baseMesh,
481  Foam::zero
482 )
483 :
484  faMesh(meshName, baseMesh, labelList())
485 {}
486 
487 
489 (
490  const faMesh& baseMesh,
491  Foam::zero
492 )
493 :
494  faMesh(polyMesh::defaultRegion, baseMesh, labelList())
495 {}
496 
497 
499 (
500  const word& meshName,
501  const faMesh& baseMesh,
503 )
504 :
505  faMesh
506  (
507  meshName,
508  baseMesh,
509  std::move(faceLabels),
510  static_cast<IOobjectOption>(baseMesh.thisDb())
511  )
512 {}
513 
514 
516 (
517  const faMesh& baseMesh,
519 )
520 :
521  faMesh
522  (
523  polyMesh::defaultRegion,
524  baseMesh,
525  std::move(faceLabels),
526  static_cast<IOobjectOption>(baseMesh.thisDb())
527  )
528 {}
529 
530 
532 (
533  const polyMesh& pMesh,
535  IOobjectOption ioOpt
536 )
537 :
538  faMesh
539  (
540  polyMesh::defaultRegion,
541  pMesh,
542  std::move(faceLabels),
543  ioOpt
544  )
545 {}
546 
547 
549 (
550  const polyMesh& pMesh,
552 )
553 :
554  faMesh(polyMesh::defaultRegion, pMesh, std::move(faceLabels))
555 {}
556 
557 
559 (
560  const polyPatch& pp,
561  const bool doInit
562 )
563 :
564  faMesh(polyMesh::defaultRegion, pp, doInit)
565 {}
566 
567 
569 (
570  const polyMesh& pMesh,
571  const dictionary& faMeshDefinition,
572  const bool doInit
573 )
574 :
575  faMesh
576  (
577  polyMesh::defaultRegion,
578  pMesh,
579  faMeshDefinition,
580  doInit
581  )
582 {}
583 
584 
585 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
586 
588 (
589  const word& meshName,
590  const polyMesh& pMesh,
591  const bool doInit
592 )
593 :
594  faMeshRegistry(meshName, pMesh),
595  faSchemes
596  (
597  faMesh::thisDb(),
598  IOobjectOption::MUST_READ
599  ),
600  faSolution
601  (
602  faMesh::thisDb(),
603  IOobjectOption::MUST_READ
604  ),
605  edgeInterpolation(*this),
606  faceLabels_
607  (
608  IOobject
609  (
610  "faceLabels",
611  time().findInstance(meshDir(), "faceLabels"),
612  faMesh::meshSubDir,
613  faMesh::thisDb(),
614  IOobject::MUST_READ,
615  IOobject::NO_WRITE
616  )
617  ),
618  boundary_
619  (
620  IOobject
621  (
622  "faBoundary",
623  // Allow boundary file that is newer than faceLabels
624  time().findInstance
625  (
626  meshDir(),
627  "faBoundary",
628  IOobject::MUST_READ,
629  faceLabels_.instance()
630  ),
631  faMesh::meshSubDir,
632  faMesh::thisDb(),
633  IOobject::MUST_READ,
634  IOobject::NO_WRITE
635  ),
636  *this
637  ),
638  comm_(UPstream::worldComm),
639  curTimeIndex_(time().timeIndex())
640 {
641  DebugInFunction << "Creating from IOobject" << endl;
642 
643  setPrimitiveMeshData();
644 
645  if (doInit)
646  {
647  faMesh::init(false); // do not init lower levels
648  }
649 
650  if (doInit)
651  {
652  // Read some optional fields
653  // - logic as per fvMesh
654 
655  IOobject rio
656  (
657  "any-name",
658  time().timeName(),
660  faMesh::thisDb(),
664  );
665 
666  // Read old surface areas (if present)
667  rio.resetHeader("S0");
668  if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
669  {
670  S0Ptr_ = std::make_unique<DimensionedField<scalar, areaMesh>>
671  (
672  rio,
673  *this,
675  );
676  }
677  }
678 }
679 
680 
682 (
683  const word& meshName,
684  const polyMesh& pMesh,
686 )
687 :
688  faMeshRegistry(meshName, pMesh),
689  faSchemes
690  (
691  faMesh::thisDb(),
692  IOobjectOption::MUST_READ
693  ),
694  faSolution
695  (
696  faMesh::thisDb(),
697  IOobjectOption::MUST_READ
698  ),
699  edgeInterpolation(*this),
700  faceLabels_
701  (
702  IOobject
703  (
704  "faceLabels",
705  pMesh.facesInstance(),
706  faMesh::meshSubDir,
707  faMesh::thisDb(),
708  IOobject::NO_READ,
709  IOobject::NO_WRITE
710  ),
711  std::move(faceLabels)
712  ),
713  boundary_
714  (
715  IOobject
716  (
717  "faBoundary",
718  faceLabels_.instance(),
719  faMesh::meshSubDir,
720  faMesh::thisDb(),
721  IOobject::NO_READ,
722  IOobject::NO_WRITE
723  ),
724  *this,
725  Foam::zero{}
726  ),
727  comm_(UPstream::worldComm),
728  curTimeIndex_(time().timeIndex())
729 {
730  // Not yet much for primitive mesh data possible...
731  nPoints_ = 0;
732  nEdges_ = 0;
733  nInternalEdges_ = 0;
734  nFaces_ = faceLabels_.size();
735 
736  // TDB: can we make a NO_READ readOption persistent for
737  // faSchemes/faSolution? Or not needed anymore?
738 }
739 
741 (
742  const word& meshName,
743  const polyMesh& pMesh,
745  IOobjectOption ioOpt
746 )
747 :
748  faMeshRegistry(meshName, pMesh),
749  faSchemes
750  (
751  faMesh::thisDb(),
752  ioOpt.readOpt()
753  ),
754  faSolution
755  (
756  faMesh::thisDb(),
757  ioOpt.readOpt()
758  ),
759  edgeInterpolation(*this),
760  faceLabels_
761  (
762  IOobject
763  (
764  "faceLabels",
765  pMesh.facesInstance(),
766  faMesh::meshSubDir,
767  faMesh::thisDb(),
768  IOobject::NO_READ,
769  IOobject::NO_WRITE
770  ),
771  std::move(faceLabels)
772  ),
773  boundary_
774  (
775  IOobject
776  (
777  "faBoundary",
778  faceLabels_.instance(),
779  faMesh::meshSubDir,
780  faMesh::thisDb(),
781  IOobject::NO_READ,
782  IOobject::NO_WRITE
783  ),
784  *this,
785  Foam::zero{}
786  ),
787  comm_(UPstream::worldComm),
788  curTimeIndex_(time().timeIndex())
789 {
790  // Not yet much for primitive mesh data possible...
791  nPoints_ = 0;
792  nEdges_ = 0;
793  nInternalEdges_ = 0;
794  nFaces_ = faceLabels_.size();
795 
796  // TDB: can we make a NO_READ readOption persistent for
797  // faSchemes/faSolution? Or not needed anymore?
798 }
799 
800 
801 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
802 
804 (
805  const word& meshName,
806  const faMesh& baseMesh,
808  IOobjectOption ioOpt
809 )
810 :
811  faMeshRegistry(meshName, baseMesh.mesh()),
812  faSchemes
813  (
814  faMesh::thisDb(),
815  ioOpt.readOpt(),
816  static_cast<const dictionary*>(baseMesh.hasSchemes())
817  ),
818  faSolution
819  (
820  faMesh::thisDb(),
821  ioOpt.readOpt(),
822  static_cast<const dictionary*>(baseMesh.hasSolution())
823  ),
824  edgeInterpolation(*this),
825  faceLabels_
826  (
827  IOobject
828  (
829  "faceLabels",
830  // Topological instance from polyMesh
831  baseMesh.mesh().facesInstance(),
832  faMesh::meshSubDir,
833  faMesh::thisDb(),
834  IOobject::NO_READ,
835  IOobject::NO_WRITE
836  ),
837  std::move(faceLabels)
838  ),
839  boundary_
840  (
841  IOobject
842  (
843  "faBoundary",
844  faceLabels_.instance(),
845  faMesh::meshSubDir,
846  faMesh::thisDb(),
847  IOobject::NO_READ,
848  IOobject::NO_WRITE
849  ),
850  *this,
851  Foam::zero{}
852  ),
853  comm_(UPstream::worldComm),
854  curTimeIndex_(time().timeIndex())
855 {
856  // Not yet much for primitive mesh data possible...
857  nPoints_ = 0;
858  nEdges_ = 0;
859  nInternalEdges_ = 0;
860  nFaces_ = faceLabels_.size();
861 }
862 
863 
865 (
866  const word& meshName,
867  const polyPatch& pp,
868  const bool doInit
869 )
870 :
871  faMesh
872  (
873  meshName,
874  pp.boundaryMesh().mesh(),
875  identity(pp.range())
876  )
877 {
878  DebugInFunction << "Creating from polyPatch:" << pp.name() << endl;
879 
880  // Add single faPatch "default", but with processor connections
881  faPatchList newPatches
882  (
883  createOnePatch("default")
884  );
885 
886  addFaPatches(newPatches);
887 
888  setPrimitiveMeshData();
889 
890  if (doInit)
891  {
892  faMesh::init(false); // do not init lower levels
893  }
894 }
895 
896 
898 (
899  const word& meshName,
900  const polyMesh& pMesh,
901  const dictionary& faMeshDefinition,
902  const bool doInit
903 )
904 :
905  faMesh
906  (
907  meshName,
908  pMesh,
910  (
911  pMesh.boundaryMesh(),
912  faMeshDefinition.get<wordRes>("polyMeshPatches")
913  )
914  )
915 {
916  DebugInFunction << "Creating from definition (dictionary)" << endl;
917 
918  faPatchList newPatches
919  (
920  createPatchList
921  (
922  faMeshDefinition.subDict("boundary"),
923 
924  // Optional 'empty' patch
925  faMeshDefinition.getOrDefault<word>("emptyPatch", word::null),
926 
927  // Optional specification for default patch
928  faMeshDefinition.findDict("defaultPatch")
929  )
930  );
931 
932  addFaPatches(newPatches);
933 
934  if (doInit)
935  {
936  faMesh::init(false); // do not init lower levels
937  }
938 
939  if (doInit)
940  {
941  // Read old surface areas (if present)
942  // - logic as per fvMesh
943 
944  IOobject rio
945  (
946  "any-name",
947  time().timeName(),
949  faMesh::thisDb(),
953  );
954 
955  // Read old surface areas (if present)
956  rio.resetHeader("S0");
957  if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
958  {
959  S0Ptr_ = std::make_unique<DimensionedField<scalar, areaMesh>>
960  (
961  rio,
962  *this,
964  );
965  }
966  }
967 }
968 
969 
970 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
971 
973 {
974  clearOut();
975 }
976 
977 
978 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
981 {
982  return static_cast<const faSchemes*>(this);
983 }
984 
987 {
988  return static_cast<const faSolution*>(this);
989 }
990 
993 {
994  return static_cast<const faSchemes&>(*this);
995 }
996 
999 {
1000  return static_cast<faSchemes&>(*this);
1001 }
1002 
1005 {
1006  return static_cast<const faSolution&>(*this);
1007 }
1008 
1011 {
1012  return static_cast<faSolution&>(*this);
1013 }
1014 
1016 const Foam::polyMesh& Foam::faMesh::mesh() const
1017 {
1018  return refCast<const polyMesh>(faMeshRegistry::parent().parent());
1019 }
1020 
1023 {
1024  return dbDir()/faMesh::meshSubDir;
1025 }
1026 
1028 const Foam::Time& Foam::faMesh::time() const
1029 {
1030  return faMeshRegistry::time();
1031 }
1032 
1035 {
1036  return mesh().pointsInstance();
1037 }
1038 
1041 {
1042  return mesh().facesInstance();
1043 }
1044 
1046 const Foam::word& Foam::faMesh::regionName() const
1047 {
1049 }
1050 
1051 
1053 {
1054  const labelList& faceOwner = this->mesh().faceOwner();
1055 
1056  labelList list(faceLabels_);
1057 
1058  for (label& val : list)
1059  {
1060  // Transcribe from faceId to cellId (owner)
1061  val = faceOwner[val];
1062  }
1063 
1064  return list;
1065 }
1066 
1067 
1068 void Foam::faMesh::removeFiles(const fileName& instanceDir) const
1069 {
1070  fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
1071 
1072  Foam::rm(meshFilesPath/"faceLabels");
1073  Foam::rm(meshFilesPath/"faBoundary");
1074 }
1075 
1077 void Foam::faMesh::removeFiles() const
1078 {
1079  removeFiles(thisDb().instance());
1080 }
1081 
1082 
1084 {
1085  if (!patchStartsPtr_)
1086  {
1087  calcPatchStarts();
1088  }
1089 
1090  return *patchStartsPtr_;
1091 }
1092 
1093 
1095 {
1096  if (!LePtr_)
1097  {
1098  calcLe();
1099  }
1100 
1101  return *LePtr_;
1102 }
1103 
1104 
1106 {
1107  if (!magLePtr_)
1108  {
1109  calcMagLe();
1110  }
1111 
1112  return *magLePtr_;
1113 }
1114 
1115 
1117 {
1118  if (!faceCentresPtr_)
1119  {
1120  calcFaceCentres();
1121  }
1122 
1123  return *faceCentresPtr_;
1124 }
1125 
1126 
1128 {
1129  if (!edgeCentresPtr_)
1130  {
1131  calcEdgeCentres();
1132  }
1133 
1134  return *edgeCentresPtr_;
1135 }
1136 
1137 
1139 Foam::faMesh::S() const
1140 {
1141  if (!SPtr_)
1142  {
1143  calcS();
1144  }
1145 
1146  return *SPtr_;
1147 }
1148 
1149 
1151 Foam::faMesh::S0() const
1152 {
1153  if (!S0Ptr_)
1154  {
1156  << "S0 is not available"
1157  << abort(FatalError);
1158  }
1159 
1160  return *S0Ptr_;
1161 }
1162 
1163 
1165 Foam::faMesh::S00() const
1166 {
1167  if (!S00Ptr_)
1168  {
1169  S00Ptr_ = std::make_unique<DimensionedField<scalar, areaMesh>>
1170  (
1171  IOobject
1172  (
1173  "S00",
1174  time().timeName(),
1175  *this,
1178  ),
1179  S0()
1180  );
1181 
1182  S0Ptr_->writeOpt(IOobject::AUTO_WRITE);
1183  }
1184 
1185  return *S00Ptr_;
1186 }
1187 
1188 
1190 {
1191  if (!faceAreaNormalsPtr_)
1192  {
1193  calcFaceAreaNormals();
1194  }
1195 
1196  return *faceAreaNormalsPtr_;
1197 }
1198 
1199 
1201 {
1202  if (!edgeAreaNormalsPtr_)
1203  {
1204  calcEdgeAreaNormals();
1205  }
1206 
1207  return *edgeAreaNormalsPtr_;
1208 }
1209 
1210 
1212 {
1213  if (!pointAreaNormalsPtr_)
1214  {
1215  pointAreaNormalsPtr_ = std::make_unique<vectorField>(nPoints());
1216 
1217  calcPointAreaNormals(*pointAreaNormalsPtr_);
1218 
1219  if (quadricsFit_ > 0)
1220  {
1221  calcPointAreaNormalsByQuadricsFit(*pointAreaNormalsPtr_);
1222  }
1223  }
1224 
1225  return *pointAreaNormalsPtr_;
1226 }
1227 
1228 
1230 {
1231  if (!faceCurvaturesPtr_)
1232  {
1233  calcFaceCurvatures();
1234  }
1235 
1236  return *faceCurvaturesPtr_;
1237 }
1238 
1239 
1242 {
1243  if (!edgeTransformTensorsPtr_)
1244  {
1245  calcEdgeTransformTensors();
1246  }
1247 
1248  return *edgeTransformTensorsPtr_;
1249 }
1250 
1253 {
1254  return bool(globalMeshDataPtr_);
1255 }
1256 
1257 
1259 {
1260  if (!globalMeshDataPtr_)
1261  {
1262  globalMeshDataPtr_.reset(new faGlobalMeshData(*this));
1263  }
1264 
1265  return *globalMeshDataPtr_;
1266 }
1267 
1268 
1270 {
1271  if (!lduPtr_)
1272  {
1273  calcLduAddressing();
1274  }
1275 
1276  return *lduPtr_;
1277 }
1278 
1279 
1281 {
1282  // Grab point motion from polyMesh
1283  const vectorField& newPoints = mesh().points();
1284 
1285  // Grab old time areas if the time has been incremented
1286  if (curTimeIndex_ < time().timeIndex())
1287  {
1288  if (S00Ptr_ && S0Ptr_)
1289  {
1290  DebugInfo<< "Copy old-old S" << endl;
1291  *S00Ptr_ = *S0Ptr_;
1292  }
1293 
1294  if (S0Ptr_)
1295  {
1296  DebugInfo<< "Copy old S" << endl;
1297  *S0Ptr_ = S();
1298  }
1299  else
1300  {
1301  DebugInfo<< "Creating old cell volumes." << endl;
1302 
1303  S0Ptr_ = std::make_unique<DimensionedField<scalar, areaMesh>>
1304  (
1305  IOobject
1306  (
1307  "S0",
1308  time().timeName(),
1309  *this,
1313  ),
1314  S()
1315  );
1316  }
1317 
1318  curTimeIndex_ = time().timeIndex();
1319  }
1320 
1321  clearGeomNotAreas();
1322 
1323  if (patchPtr_)
1324  {
1325  patchPtr_->movePoints(newPoints);
1326  }
1327 
1328  // Move boundary points
1329  boundary_.movePoints(newPoints);
1330 
1331  // Move interpolation
1333 
1334  // Note: Fluxes were dummy?
1336  syncGeom();
1337 
1338  return true;
1339 }
1340 
1341 
1342 bool Foam::faMesh::correctPatchPointNormals(const label patchID) const
1343 {
1344  if
1345  (
1346  bool(correctPatchPointNormalsPtr_)
1347  && patchID >= 0 && patchID < boundary().size()
1348  )
1349  {
1350  return (*correctPatchPointNormalsPtr_)[patchID];
1351  }
1352 
1353  return false;
1354 }
1355 
1356 
1358 {
1359  if (!correctPatchPointNormalsPtr_)
1360  {
1361  correctPatchPointNormalsPtr_ =
1362  std::make_unique<boolList>(boundary().size(), false);
1363  }
1364 
1365  return *correctPatchPointNormalsPtr_;
1366 }
1367 
1368 
1369 bool Foam::faMesh::write(const bool writeOnProc) const
1370 {
1371  faceLabels_.write();
1372  boundary_.write();
1374  return false;
1375 }
1376 
1377 
1378 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1380 bool Foam::faMesh::operator!=(const faMesh& m) const
1381 {
1382  return &m != this;
1383 }
1384 
1385 
1386 bool Foam::faMesh::operator==(const faMesh& m) const
1387 {
1388  return &m == this;
1389 }
1390 
1391 
1392 // ************************************************************************* //
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:133
faceListList boundary
const labelList patchIDs(pbm.indices(polyPatchNames, true))
const polyBoundaryMesh & pbm
faMesh(const faMesh &)=delete
No copy construct.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
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:1158
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: polyMesh.C:844
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:600
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:832
const Time & time() const
Return reference to time.
Definition: faMesh.C:1021
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
void syncGeom()
Processor/processor synchronisation for geometry fields.
Definition: faMesh.C:395
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:697
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
The objectRegistry for faMesh.
Definition: faMesh.H:93
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:529
const DimensionedField< scalar, areaMesh > & S() const
Return face areas.
Definition: faMesh.C:1132
Face to edge interpolation scheme. Included in faMesh.
bool operator!=(const faMesh &m) const
Definition: faMesh.C:1373
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1586
Various mesh related information for a parallel run.
Generic GeometricField class.
const faGlobalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: faMesh.C:1251
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:1076
Ignore writing from objectRegistry::writeObject()
bool movePoints() const
Do what is necessary if the mesh has moved.
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:987
const Type * cfindObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
const word & regionName() const
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: faMesh.C:1039
const areaVectorField & areaCentres() const
Return face centres as areaVectorField.
Definition: faMesh.C:1109
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
const edgeScalarField & magLe() const
Return edge length magnitudes.
Definition: faMesh.C:1098
bool hasGlobalData() const noexcept
Is demand-driven parallel info available?
Definition: faMesh.C:1245
scalar range
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:51
virtual const objectRegistry & thisDb() const
Reference to the mesh database.
Definition: faMesh.H:1203
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1063
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching patch groups.
virtual const fileName & dbDir() const
Local directory path of the objectRegistry relative to Time with override for the single-region case...
Definition: faMesh.H:1212
word timeName
Definition: getTimeIndex.H:3
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:838
dynamicFvMesh & mesh
virtual ~faMesh()
Destructor.
Definition: faMesh.C:965
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:1015
bool operator==(const faMesh &m) const
Definition: faMesh.C:1379
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
Definition: faMesh.C:1262
const Time & time() const noexcept
Return time registry.
#define DebugInFunction
Report an information message using Foam::Info.
wordRes polyPatchNames
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:406
const edgeVectorField & Le() const
Return edge length vectors.
Definition: faMesh.C:1087
label nFaceLabels
label size() const noexcept
The number of entries in the list.
Definition: UPtrListI.H:106
virtual const labelList & faceOwner() const
Return face owner.
Definition: polyMesh.C:1101
static const word null
An empty word.
Definition: word.H:84
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1088
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
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:1234
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh...
static labelList selectPatchFaces(const polyBoundaryMesh &pbm, const wordRes &polyPatchNames)
Definition: faMesh.C:195
const direction noexcept
Definition: scalarImpl.H:255
virtual bool movePoints()
Update after mesh motion.
Definition: faMesh.C:1273
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:1362
defineTypeNameAndDebug(combustionModel, 0)
const polyMesh & mesh() const
Return access to polyMesh.
Definition: faMesh.C:1009
const areaScalarField & faceCurvatures() const
Return face curvatures.
Definition: faMesh.C:1222
boolList & correctPatchPointNormals() const
Set whether point normals should be corrected for a patch.
Definition: faMesh.C:1350
static word meshSubDir
The mesh sub-directory name (usually "faMesh")
Definition: faMesh.H:750
const fileName & facesInstance() const
Return the current instance directory for faces.
Definition: faMesh.C:1033
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:1120
const objectRegistry & parent() const noexcept
Return the parent objectRegistry.
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:54
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...
const faSchemes * hasSchemes() const
Non-null if faSchemes exists (can test as bool).
Definition: faMesh.C:973
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:1027
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:1193
const objectRegistry & thisDb() const noexcept
Return the object registry.
Definition: polyMesh.H:690
bool init(const bool doInit)
Initialise non-demand-driven data etc.
Definition: faMesh.C:416
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:1045
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:144
static int geometryOrder_
Geometry treatment.
Definition: faMesh.H:734
The class contains the addressing required by the lduMatrix: upper, lower and losort.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:75
List< label > labelList
A List of labels.
Definition: List.H:61
volScalarField & p
void removeFiles() const
Remove all files from mesh instance()
Definition: faMesh.C:1070
Registry of regIOobjects.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
static const word & prefix() noexcept
The prefix to the parent registry name: finite-area.
Definition: faMesh.C:65
const vectorField & pointAreaNormals() const
Return point area normals.
Definition: faMesh.C:1204
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
const areaVectorField & faceAreaNormals() const
Return face area normals.
Definition: faMesh.C:1182
const faSolution & solution() const
Read-access to the faSolution controls.
Definition: faMesh.C:997
const faSolution * hasSolution() const
Non-null if faSolution exists (can test as bool).
Definition: faMesh.C:979
static const word & regionName(const word &region)
The mesh region name or word::null if polyMesh::defaultRegion.
Definition: polyMesh.C:796
Inter-processor communications stream.
Definition: UPstream.H:65
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:1144
label timeIndex
Definition: getTimeIndex.H:24
Processor patch.
const faSchemes & schemes() const
Read-access to the faSchemes controls.
Definition: faMesh.C:985
bool rm(const fileName &file)
Remove a file (or its gz equivalent), returning true if successful.
Definition: POSIX.C:1406
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127