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