fvMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "fvMesh.H"
27 #include "volFields.H"
28 #include "surfaceFields.H"
29 #include "pointFields.H"
30 #include "slicedVolFields.H"
31 #include "slicedSurfaceFields.H"
32 #include "SubField.H"
33 #include "demandDrivenData.H"
34 #include "zonesGenerator.H"
35 #include "fvMeshLduAddressing.H"
36 #include "fvMeshTopoChanger.H"
37 #include "fvMeshDistributor.H"
38 #include "fvMeshMover.H"
39 #include "fvMeshStitcher.H"
40 #include "nonConformalFvPatch.H"
42 #include "polyTopoChangeMap.H"
43 #include "MapFvFields.H"
44 #include "fvMeshMapper.H"
45 #include "pointMesh.H"
46 #include "pointMeshMapper.H"
47 #include "MapPointField.H"
48 #include "meshObjects.H"
49 #include "HashPtrTable.H"
50 #include "CompactListList.H"
51 
52 #include "fvcSurfaceIntegrate.H"
53 #include "fvcReconstruct.H"
54 #include "surfaceInterpolate.H"
55 
56 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
57 
58 namespace Foam
59 {
61 }
62 
64 {
65  "Vc",
66  "Vc0",
67  "Vc00",
68  "Sf",
69  "magSf",
70  "Cc",
71  "Cf",
72  "meshPhi",
73  "meshPhi_0"
74 };
75 
77 {
78  "Vc",
79  "Sf",
80  "magSf",
81  "Cc",
82  "Cf"
83 };
84 
85 
86 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
87 
88 void Foam::fvMesh::clearFvGeomNotOldVol()
89 {
90  DebugInFunction << "Clearing current-time FV geometry" << endl;
91 
93  <
94  fvMesh,
95  DeletableMeshObject,
96  MoveableMeshObject
97  >(*this);
98 
100  <
101  lduMesh,
102  DeletableMeshObject,
103  MoveableMeshObject
104  >(*this);
105 
106  deleteDemandDrivenData(VPtr_);
107  deleteDemandDrivenData(SfSlicePtr_);
108  deleteDemandDrivenData(SfPtr_);
109  deleteDemandDrivenData(magSfSlicePtr_);
110  deleteDemandDrivenData(magSfPtr_);
111  deleteDemandDrivenData(CSlicePtr_);
112  deleteDemandDrivenData(CPtr_);
113  deleteDemandDrivenData(CfSlicePtr_);
114  deleteDemandDrivenData(CfPtr_);
115 }
116 
117 
118 void Foam::fvMesh::clearFvGeom()
119 {
120  DebugInFunction << "Clearing FV Geometry" << endl;
121 
122  clearFvGeomNotOldVol();
123 
124  deleteDemandDrivenData(phiPtr_);
125  deleteDemandDrivenData(V0Ptr_);
126  deleteDemandDrivenData(V00Ptr_);
127 }
128 
129 
130 void Foam::fvMesh::updateGeomNotOldVol()
131 {
132  bool haveV = (VPtr_ != nullptr);
133  bool haveSf = (SfSlicePtr_ != nullptr || SfPtr_ != nullptr);
134  bool haveMagSf = (magSfSlicePtr_ != nullptr || magSfPtr_ != nullptr);
135  bool haveCP = (CSlicePtr_ != nullptr || CPtr_ != nullptr);
136  bool haveCf = (CfSlicePtr_ != nullptr || CfPtr_ != nullptr);
137 
138  clearFvGeomNotOldVol();
139 
140  // Now recreate the fields
141  if (haveV)
142  {
143  (void)V();
144  }
145  if (haveSf)
146  {
147  (void)Sf();
148  }
149  if (haveMagSf)
150  {
151  (void)magSf();
152  }
153  if (haveCP)
154  {
155  (void)C();
156  }
157  if (haveCf)
158  {
159  (void)Cf();
160  }
161 }
162 
163 
164 void Foam::fvMesh::storeOldTimeFields()
165 {
166  storeOldTimeFields<PointField>();
167  storeOldTimeFields<VolField>();
168  storeOldTimeFields<SurfaceField>();
169 }
170 
171 
172 void Foam::fvMesh::nullOldestTimeFields()
173 {
174  nullOldestTimeFields<PointField>();
175  nullOldestTimeFields<VolField>();
176  nullOldestTimeFields<SurfaceField>();
177 }
178 
179 
181 {
183 
184  Pout<< "fvMesh allocated :" << endl;
185 
186  if (lduPtr_)
187  {
188  Pout<< " Ldu Addressing" << endl;
189  }
190 
191  if (polyFacesBfPtr_)
192  {
193  Pout<< " Poly-faces boundary field" << endl;
194  }
195 
196  if (polyBFacePatchesPtr_)
197  {
198  Pout<< " Poly-boundary-face to fv-patch and fv-patch-face map"
199  << endl;
200  }
201 
202  if (ownerBfPtr_)
203  {
204  Pout<< " Owner boundary field" << endl;
205  }
206 
207  if (V0Ptr_)
208  {
209  Pout<< " Old-time cell volumes field" << endl;
210  }
211 
212  if (V00Ptr_)
213  {
214  Pout<< " Old-old-time cell volumes field" << endl;
215  }
216 
217  if (SfPtr_)
218  {
219  Pout<< " Non-sliced face areas field" << endl;
220  }
221 
222  if (magSfPtr_)
223  {
224  Pout<< " Non-sliced face area magnitudes field" << endl;
225  }
226 
227  if (CPtr_)
228  {
229  Pout<< " Non-sliced cell centres field" << endl;
230  }
231 
232  if (CfPtr_)
233  {
234  Pout<< " Non-sliced face centres field" << endl;
235  }
236 
237  if (phiPtr_)
238  {
239  Pout<< " Mesh flux field" << endl;
240  }
241 
243 }
244 
245 
247 {
248  DebugInFunction << "Clearing geometry" << endl;
249 
250  clearFvGeom();
251 
253 }
254 
255 
256 void Foam::fvMesh::clearAddressing(const bool isMeshUpdate)
257 {
258  DebugInFunction << "isMeshUpdate: " << isMeshUpdate << endl;
259 
260  if (isMeshUpdate)
261  {
262  // Part of a mesh update. Keep meshObjects that have an topoChange
263  // callback
265  <
266  fvMesh,
269  >
270  (
271  *this
272  );
274  <
275  lduMesh,
278  >
279  (
280  *this
281  );
282  }
283  else
284  {
285  meshObjects::clear<fvMesh, DeletableMeshObject>(*this);
286  meshObjects::clear<lduMesh, DeletableMeshObject>(*this);
287  }
288 
289  deleteDemandDrivenData(lduPtr_);
290  deleteDemandDrivenData(polyFacesBfIOPtr_);
291  deleteDemandDrivenData(polyFacesBfPtr_);
292  deleteDemandDrivenData(polyBFaceOffsetsPtr_);
293  deleteDemandDrivenData(polyBFaceOffsetPatchesPtr_);
294  deleteDemandDrivenData(polyBFaceOffsetPatchFacesPtr_);
295  deleteDemandDrivenData(polyBFacePatchesPtr_);
296  deleteDemandDrivenData(polyBFacePatchFacesPtr_);
297  deleteDemandDrivenData(ownerBfPtr_);
298 }
299 
300 
302 {
303  clearFvGeom();
304 
306 
307  clearAddressing();
308 
310 }
311 
312 
313 Foam::wordList Foam::fvMesh::polyFacesPatchTypes() const
314 {
315  wordList wantedPatchTypes
316  (
317  boundary().size(),
319  );
320 
322  {
323  const fvPatch& fvp = boundary()[patchi];
324 
325  if (isA<nonConformalFvPatch>(fvp))
326  {
327  wantedPatchTypes[patchi] =
328  refCast<const nonConformalFvPatch>(fvp).polyFacesType();
329  }
330  }
331 
332  return wantedPatchTypes;
333 }
334 
335 
336 Foam::surfaceLabelField::Boundary& Foam::fvMesh::polyFacesBfRef()
337 {
338  if (!polyFacesBfPtr_)
339  {
340  polyFacesBf();
341  }
342 
343  setPolyFacesBfInstance(time().name());
344 
345  return *polyFacesBfPtr_;
346 }
347 
348 
349 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
350 
352 (
353  const IOobject& io,
354  const bool doPost
355  // const bool doZones
356 )
357 :
358  polyMesh(io),
359  surfaceMesh(*this),
360  surfaceInterpolation(*this),
361  boundary_(*this, poly().boundary()),
362  stitcher_(nullptr),
363  topoChanger_(nullptr),
364  distributor_(nullptr),
365  mover_(nullptr),
366  lduPtr_(nullptr),
367  polyFacesBfIOPtr_(nullptr),
368  polyFacesBfPtr_(nullptr),
369  polyBFaceOffsetsPtr_(nullptr),
370  polyBFaceOffsetPatchesPtr_(nullptr),
371  polyBFaceOffsetPatchFacesPtr_(nullptr),
372  polyBFacePatchesPtr_(nullptr),
373  polyBFacePatchFacesPtr_(nullptr),
374  ownerBfPtr_(nullptr),
375  curTimeIndex_(time().timeIndex()),
376  VPtr_(nullptr),
377  V0Ptr_(nullptr),
378  V00Ptr_(nullptr),
379  SfSlicePtr_(nullptr),
380  SfPtr_(nullptr),
381  magSfSlicePtr_(nullptr),
382  magSfPtr_(nullptr),
383  CSlicePtr_(nullptr),
384  CPtr_(nullptr),
385  CfSlicePtr_(nullptr),
386  CfPtr_(nullptr),
387  phiPtr_(nullptr)
388 {
389  DebugInFunction << "Constructing fvMesh from IOobject" << endl;
390 
391  if (doPost)
392  {
394  }
395 }
396 
397 
399 (
400  const IOobject& io,
401  pointField&& points,
402  const cellShapeList& shapes,
403  const faceListList& boundaryFaces,
404  const wordList& boundaryPatchNames,
405  const PtrList<dictionary>& boundaryDicts,
406  const word& defaultBoundaryPatchName,
407  const word& defaultBoundaryPatchType,
408  const bool syncPar
409 )
410 :
411  polyMesh
412  (
413  io,
414  std::move(points),
415  shapes,
416  boundaryFaces,
417  boundaryPatchNames,
418  boundaryDicts,
419  defaultBoundaryPatchName,
420  defaultBoundaryPatchType,
421  syncPar
422  ),
423  surfaceMesh(*this),
424  surfaceInterpolation(*this),
425  boundary_(*this, poly().boundary()),
426  stitcher_(nullptr),
427  topoChanger_(nullptr),
428  distributor_(nullptr),
429  mover_(nullptr),
430  lduPtr_(nullptr),
431  polyFacesBfIOPtr_(nullptr),
432  polyFacesBfPtr_(nullptr),
433  polyBFaceOffsetsPtr_(nullptr),
434  polyBFaceOffsetPatchesPtr_(nullptr),
435  polyBFaceOffsetPatchFacesPtr_(nullptr),
436  polyBFacePatchesPtr_(nullptr),
437  polyBFacePatchFacesPtr_(nullptr),
438  ownerBfPtr_(nullptr),
439  curTimeIndex_(time().timeIndex()),
440  VPtr_(nullptr),
441  V0Ptr_(nullptr),
442  V00Ptr_(nullptr),
443  SfSlicePtr_(nullptr),
444  SfPtr_(nullptr),
445  magSfSlicePtr_(nullptr),
446  magSfPtr_(nullptr),
447  CSlicePtr_(nullptr),
448  CPtr_(nullptr),
449  CfSlicePtr_(nullptr),
450  CfPtr_(nullptr),
451  phiPtr_(nullptr)
452 {
453  DebugInFunction << "Constructing fvMesh from shapes" << endl;
454 }
455 
456 
458 (
459  const IOobject& io,
460  pointField&& points,
461  faceList&& faces,
462  labelList&& allOwner,
463  labelList&& allNeighbour,
464  const bool syncPar
465 )
466 :
467  polyMesh
468  (
469  io,
470  std::move(points),
471  std::move(faces),
472  std::move(allOwner),
473  std::move(allNeighbour),
474  syncPar
475  ),
476  surfaceMesh(*this),
477  surfaceInterpolation(*this),
478  boundary_(*this, poly().boundary()),
479  stitcher_(nullptr),
480  topoChanger_(nullptr),
481  distributor_(nullptr),
482  mover_(nullptr),
483  lduPtr_(nullptr),
484  polyFacesBfIOPtr_(nullptr),
485  polyFacesBfPtr_(nullptr),
486  polyBFaceOffsetsPtr_(nullptr),
487  polyBFaceOffsetPatchesPtr_(nullptr),
488  polyBFaceOffsetPatchFacesPtr_(nullptr),
489  polyBFacePatchesPtr_(nullptr),
490  polyBFacePatchFacesPtr_(nullptr),
491  ownerBfPtr_(nullptr),
492  curTimeIndex_(time().timeIndex()),
493  VPtr_(nullptr),
494  V0Ptr_(nullptr),
495  V00Ptr_(nullptr),
496  SfSlicePtr_(nullptr),
497  SfPtr_(nullptr),
498  magSfSlicePtr_(nullptr),
499  magSfPtr_(nullptr),
500  CSlicePtr_(nullptr),
501  CPtr_(nullptr),
502  CfSlicePtr_(nullptr),
503  CfPtr_(nullptr),
504  phiPtr_(nullptr)
505 {
506  DebugInFunction << "Constructing fvMesh from components" << endl;
507 }
508 
509 
511 (
512  const IOobject& io,
513  pointField&& points,
514  faceList&& faces,
515  cellList&& cells,
516  const bool syncPar
517 )
518 :
519  polyMesh
520  (
521  io,
522  std::move(points),
523  std::move(faces),
524  std::move(cells),
525  syncPar
526  ),
527  surfaceMesh(*this),
528  surfaceInterpolation(*this),
529  boundary_(*this),
530  stitcher_(nullptr),
531  topoChanger_(nullptr),
532  distributor_(nullptr),
533  mover_(nullptr),
534  lduPtr_(nullptr),
535  polyFacesBfIOPtr_(nullptr),
536  polyFacesBfPtr_(nullptr),
537  polyBFaceOffsetsPtr_(nullptr),
538  polyBFaceOffsetPatchesPtr_(nullptr),
539  polyBFaceOffsetPatchFacesPtr_(nullptr),
540  polyBFacePatchesPtr_(nullptr),
541  polyBFacePatchFacesPtr_(nullptr),
542  ownerBfPtr_(nullptr),
543  curTimeIndex_(time().timeIndex()),
544  VPtr_(nullptr),
545  V0Ptr_(nullptr),
546  V00Ptr_(nullptr),
547  SfSlicePtr_(nullptr),
548  SfPtr_(nullptr),
549  magSfSlicePtr_(nullptr),
550  magSfPtr_(nullptr),
551  CSlicePtr_(nullptr),
552  CPtr_(nullptr),
553  CfSlicePtr_(nullptr),
554  CfPtr_(nullptr),
555  phiPtr_(nullptr)
556 {
557  DebugInFunction << "Constructing fvMesh from components" << endl;
558 }
559 
560 
562 :
563  polyMesh(Foam::move(mesh)),
564  surfaceMesh(*this),
566  boundary_(Foam::move(mesh.boundary_)),
567  stitcher_(Foam::move(mesh.stitcher_)),
568  topoChanger_(Foam::move(mesh.topoChanger_)),
569  distributor_(Foam::move(mesh.distributor_)),
570  mover_(Foam::move(mesh.mover_)),
571  lduPtr_(Foam::move(mesh.lduPtr_)),
572  polyFacesBfIOPtr_(Foam::move(mesh.polyFacesBfIOPtr_)),
573  polyFacesBfPtr_(Foam::move(mesh.polyFacesBfPtr_)),
574  polyBFaceOffsetsPtr_(Foam::move(mesh.polyBFaceOffsetsPtr_)),
575  polyBFaceOffsetPatchesPtr_(Foam::move(mesh.polyBFaceOffsetPatchesPtr_)),
576  polyBFaceOffsetPatchFacesPtr_
577  (
578  Foam::move(mesh.polyBFaceOffsetPatchFacesPtr_)
579  ),
580  polyBFacePatchesPtr_(Foam::move(mesh.polyBFacePatchesPtr_)),
581  polyBFacePatchFacesPtr_(Foam::move(mesh.polyBFacePatchFacesPtr_)),
582  ownerBfPtr_(Foam::move(mesh.ownerBfPtr_)),
583  curTimeIndex_(mesh.curTimeIndex_),
584  VPtr_(Foam::move(mesh.VPtr_)),
585  V0Ptr_(Foam::move(mesh.V0Ptr_)),
586  V00Ptr_(Foam::move(mesh.V00Ptr_)),
587  SfSlicePtr_(Foam::move(mesh.SfSlicePtr_)),
588  SfPtr_(Foam::move(mesh.SfPtr_)),
589  magSfSlicePtr_(Foam::move(mesh.magSfSlicePtr_)),
590  magSfPtr_(Foam::move(mesh.magSfPtr_)),
591  CSlicePtr_(Foam::move(mesh.CSlicePtr_)),
592  CPtr_(Foam::move(mesh.CPtr_)),
593  CfSlicePtr_(Foam::move(mesh.CfSlicePtr_)),
594  CfPtr_(Foam::move(mesh.CfPtr_)),
595  phiPtr_(Foam::move(mesh.phiPtr_))
596 {
597  DebugInFunction << "Move-constructing fvMesh" << endl;
598 }
599 
600 
601 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
602 
604 {
605  clearOut();
606 }
607 
608 
609 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
610 
612 (
613  const bool changers,
614  const bool zones,
615  const stitchType stitch
616 )
617 {
618  // Construct the stitcher
619  stitcher_.set(fvMeshStitcher::New(*this, changers).ptr());
620 
621  // Stitch or Re-stitch if necessary
622  if (stitch != stitchType::none)
623  {
624  stitcher_->connect(false, stitch == stitchType::geometric, true);
625  }
626 
627  // Construct changers
628  if (changers)
629  {
630  topoChanger_.set(fvMeshTopoChanger::New(*this).ptr());
631  distributor_.set(fvMeshDistributor::New(*this).ptr());
632  mover_.set(fvMeshMover::New(*this).ptr());
633 
634  // Check the existence of the cell volumes and read if present
635  // and set the storage of V00
636  if (fileHandler().isFile(time().timePath()/"Vc0"))
637  {
639  (
640  IOobject
641  (
642  "Vc0",
643  time().name(),
644  *this,
647  true
648  ),
649  *this,
651  );
652 
653  V00();
654  }
655 
656  // Check the existence of the mesh fluxes and read if present
657  if (fileHandler().isFile(time().timePath()/"meshPhi"))
658  {
659  phiPtr_ = new surfaceScalarField
660  (
661  IOobject
662  (
663  "meshPhi",
664  time().name(),
665  *this,
668  true
669  ),
670  *this,
672  );
673  }
674  }
675 
676  // Generate the zones after the mesh manipulators have been constructed
677  // to support motion-specific zone generators requiring access to the mover
678  if (zones)
679  {
680  zonesGenerator::New(*this);
681  }
682 }
683 
684 
686 {
687  return topoChanger_.valid() && topoChanger_->dynamic();
688 }
689 
690 
692 {
693  return distributor_.valid() && distributor_->dynamic();
694 }
695 
696 
698 {
699  return
700  (topoChanger_.valid() && topoChanger_->dynamic())
701  || (mover_.valid() && mover_->dynamic());
702 }
703 
704 
706 {
707  if
708  (
709  stitcher_->stitches()
710  || topoChanger_->dynamic()
711  || distributor_->dynamic()
712  )
713  {
715  }
716 
717  // Remove the oldest cell volume field
718  if (V00Ptr_)
719  {
720  nullDemandDrivenData(V00Ptr_);
721  }
722  else
723  {
724  nullDemandDrivenData(V0Ptr_);
725  }
726 
727  // Remove the oldest mesh flux field
728  if (phiPtr_)
729  {
730  phiPtr_->nullOldestTime();
731  }
732 
733  // Set topoChanged_ false before any mesh change. Topo-changing can switch
734  // on and off during a run.
735  topoChanged_ = false;
736 
737  topoChanged_ = topoChanger_->update();
738 
739  const bool distributed = distributor_->update();
740 
741  return topoChanged_ || distributed;
742 }
743 
744 
746 {
747  // Do not set moving_ false before any mesh motion. Once the mesh starts
748  // moving it is considered to be moving for the rest of the run.
749  const bool moved = mover_->update();
750 
751  curTimeIndex_ = time().timeIndex();
752 
753  stitcher_->connect(true, true, false);
754 
755  return moved;
756 }
757 
758 
760 (
761  const List<polyPatch*>& p,
762  const bool validBoundary
763 )
764 {
765  if (boundary().size())
766  {
768  << " boundary already exists"
769  << abort(FatalError);
770  }
771 
772  // first add polyPatches
773  addPatches(p, validBoundary);
774  boundary_.addPatches(poly().boundary());
775 }
776 
777 
779 {
780  DebugInFunction << "Removing boundary patches." << endl;
781 
782  // Remove fvBoundaryMesh data first.
783  boundary_.clear();
784  boundary_.setSize(0);
786 
787  clearOut();
788 }
789 
790 
791 void Foam::fvMesh::swap(fvMesh& otherMesh)
792 {
793  // Clear the sliced fields
794  clearFvGeom();
795 
796  // Clear the current volume and other geometry factors
798 
799  // Clear any non-updateable addressing
800  clearAddressing(true);
801 
802  polyMesh::swap(otherMesh);
803 
804  auto updatePatches = []
805  (
806  const polyPatchList& patches,
807  fvBoundaryMesh& boundaryMesh
808  )
809  {
810  boundaryMesh.setSize(patches.size());
811 
813  {
814  // Construct new processor patches, as the decomposition may have
815  // changed. Leave other patches as is.
816 
817  if (isA<processorPolyPatch>(patches[patchi]))
818  {
819  boundaryMesh.set
820  (
821  patchi,
823  (
824  patches[patchi],
825  boundaryMesh
826  )
827  );
828  }
829  }
830  };
831 
832  updatePatches(poly().boundary(), boundary_);
833  updatePatches(otherMesh.poly().boundary(), otherMesh.boundary_);
834 }
835 
836 
838 (
839  const stitchType stitch
840 )
841 {
842  // Determine if this update moves forward in time. If so, searching back in
843  // time for data files will only go back as far as the previous instance.
844  const fileName instance0 = instance();
845  const bool forward = readUpdateIsForward();
846 
847  // Update the polyMesh and the mesh instance
849 
850  DebugInFunction << "Updating the fvMesh:" << endl;
851 
852  if (debug)
853  {
854  switch (state)
855  {
857  Info<< " Boundary and topological change" << endl;
858  break;
860  Info<< " Topological change" << endl;
861  break;
863  Info<< " Point motion" << endl;
864  break;
865  default:
866  Info<< " No change" << endl;
867  break;
868  }
869  }
870 
871  const bool reStitch =
872  stitcher_.valid()
873  && stitcher_->stitches()
874  && stitch != stitchType::none
875  && (
876  !conformal()
877  || time().findInstance
878  (
879  dbDir()/typeName,
880  "polyFaces",
882  forward ? word(instance0) : word::null
883  )
884  != (forward ? instance0 : polyFacesBfIOPtr_->instance())
885  );
886 
887  if (reStitch)
888  {
889  stitcher_->disconnect(false, false);
890  }
891  else if (state != polyMesh::UNCHANGED)
892  {
893  conform();
894  }
895 
896  switch (state)
897  {
899  boundary_.readUpdate(poly().boundary());
900  clearOut();
901  break;
903  clearOut();
904  break;
906  clearFvGeom();
907  break;
908  default:
909  break;
910  }
911 
912  if (reStitch && stitch != stitchType::none)
913  {
914  stitcher_->connect(false, stitch == stitchType::geometric, true);
915  }
916 
917  // Return the corresponding fvMesh read update state
918  switch (state)
919  {
920  case polyMesh::UNCHANGED:
921  return reStitch ? STITCHED : UNCHANGED;
923  return reStitch ? STITCHED : POINTS_MOVED;
925  return TOPO_CHANGE;
927  return TOPO_PATCH_CHANGE;
928  }
929 
930  return UNCHANGED;
931 }
932 
933 
935 {
936  return boundary_;
937 }
938 
939 
941 {
942  if (!lduPtr_)
943  {
944  lduPtr_ = new fvMeshLduAddressing(*this);
945  }
946 
947  return *lduPtr_;
948 }
949 
950 
952 {
953  return !(polyFacesBfPtr_ && SfPtr_);
954 }
955 
956 
958 {
959  if (!polyFacesBfPtr_)
960  {
961  polyFacesBfIOPtr_ =
962  new IOobject
963  (
964  "polyFaces",
965  facesInstance(),
966  typeName,
967  *this,
970  false
971  );
972 
973  polyFacesBfPtr_ =
975  (
976  boundary(),
978  polyFacesPatchTypes(),
979  poly().boundary().types()
980  );
981  }
982 
983  return *polyFacesBfPtr_;
984 }
985 
986 
989 {
990  if (!polyBFacePatchesPtr_)
991  {
992  const label nPolyBFaces = nFaces() - nInternalFaces();
993 
994  // Count face-poly-bFaces to get the offsets
995  polyBFaceOffsetsPtr_ = new labelList(nPolyBFaces + 1, 0);
996  labelList& offsets = *polyBFaceOffsetsPtr_;
998  {
999  forAll(boundary()[patchi], patchFacei)
1000  {
1001  const label polyBFacei =
1002  (
1003  polyFacesBfPtr_
1004  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1005  : boundary()[patchi].start() + patchFacei
1006  )
1007  - nInternalFaces();
1008 
1009  offsets[polyBFacei + 1] ++;
1010  }
1011  }
1012  for (label polyBFacei = 0; polyBFacei < nPolyBFaces; ++ polyBFacei)
1013  {
1014  offsets[polyBFacei + 1] += offsets[polyBFacei];
1015  }
1016 
1017  // Set the poly-bFace patches and patch-faces, using the offsets as
1018  // counters
1019  polyBFaceOffsetPatchesPtr_ = new labelList(offsets.last());
1020  polyBFaceOffsetPatchFacesPtr_ = new labelList(offsets.last());
1021  labelUList& patches = *polyBFaceOffsetPatchesPtr_;
1022  labelUList& patchFaces = *polyBFaceOffsetPatchFacesPtr_;
1023  forAll(boundary(), patchi)
1024  {
1025  forAll(boundary()[patchi], patchFacei)
1026  {
1027  const label polyBFacei =
1028  (
1029  polyFacesBfPtr_
1030  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1031  : boundary()[patchi].start() + patchFacei
1032  )
1033  - nInternalFaces();
1034  patches[offsets[polyBFacei]] = patchi;
1035  patchFaces[offsets[polyBFacei]] = patchFacei;
1036  offsets[polyBFacei] ++;
1037  }
1038  }
1039 
1040  // Restore the offsets by removing the count
1041  for
1042  (
1043  label polyBFacei = nPolyBFaces - 1;
1044  polyBFacei >= 0;
1045  -- polyBFacei
1046  )
1047  {
1048  offsets[polyBFacei + 1] = offsets[polyBFacei];
1049  }
1050  offsets[0] = 0;
1051 
1052  // List-lists
1053  polyBFacePatchesPtr_ =
1054  new UCompactListList<label>(offsets, patches);
1055  polyBFacePatchFacesPtr_ =
1056  new UCompactListList<label>(offsets, patchFaces);
1057  }
1058 
1059  return *polyBFacePatchesPtr_;
1060 }
1061 
1062 
1065 {
1066  if (!polyBFacePatchFacesPtr_)
1067  {
1068  polyBFacePatches();
1069  }
1070 
1071  return *polyBFacePatchFacesPtr_;
1072 }
1073 
1074 
1076 {
1077  if (!ownerBfPtr_)
1078  {
1079  ownerBfPtr_ =
1081  (
1082  boundary(),
1084  wordList
1085  (
1086  boundary().size(),
1088  ),
1089  poly().boundary().types()
1090  );
1091 
1092  forAll(boundary(), patchi)
1093  {
1094  (*ownerBfPtr_)[patchi] =
1095  labelField(faceOwner(), polyFacesBf()[patchi]);
1096  }
1097  }
1098 
1099  return *ownerBfPtr_;
1100 }
1101 
1102 
1104 {
1105  return stitcher_();
1106 }
1107 
1108 
1110 {
1111  return stitcher_();
1112 }
1113 
1114 
1116 {
1117  return topoChanger_();
1118 }
1119 
1120 
1122 {
1123  return distributor_();
1124 }
1125 
1126 
1128 {
1129  return mover_();
1130 }
1131 
1132 
1134 {
1136  << " nOldCells:" << map.nOldCells()
1137  << " nCells:" << nCells()
1138  << " nOldFaces:" << map.nOldFaces()
1139  << " nFaces:" << nFaces()
1140  << endl;
1141 
1142  // We require geometric properties valid for the old mesh
1143  if
1144  (
1145  map.cellMap().size() != nCells()
1146  || map.faceMap().size() != nFaces()
1147  )
1148  {
1150  << "polyTopoChangeMap does not correspond to the old mesh."
1151  << " nCells:" << nCells()
1152  << " cellMap:" << map.cellMap().size()
1153  << " nOldCells:" << map.nOldCells()
1154  << " nFaces:" << nFaces()
1155  << " faceMap:" << map.faceMap().size()
1156  << " nOldFaces:" << map.nOldFaces()
1157  << exit(FatalError);
1158  }
1159 
1160  // Create a fv mapper
1161  const fvMeshMapper fvMap(*this, map);
1162 
1163  // Map all the volFields in the objectRegistry
1164  #define mapVolFieldType(Type, nullArg) \
1165  MapGeometricFields<Type, fvMeshMapper, fvMesh>(fvMap);
1167 
1168  // Map all the surfaceFields in the objectRegistry
1169  #define mapSurfaceFieldType(Type, nullArg) \
1170  MapGeometricFields<Type, fvMeshMapper, surfaceMesh>(fvMap);
1172 
1173  // Map all the dimensionedFields in the objectRegistry
1174  #define mapVolInternalFieldType(Type, nullArg) \
1175  MapDimensionedFields<Type, fvMeshMapper, fvMesh>(fvMap);
1177 
1178  if (pointMesh::found(*this))
1179  {
1180  // Create the pointMesh mapper
1181  const pointMeshMapper mapper(pointMesh::New(*this), map);
1182 
1183  #define mapPointFieldType(Type, nullArg) \
1184  MapGeometricFields<Type, pointMeshMapper, pointMesh>(mapper);
1186  }
1187 }
1188 
1189 
1191 {
1192  stitcher_->disconnect(true, true);
1193 }
1194 
1195 
1197 {
1199 
1200  clearFvGeom();
1201 
1202  // Update other local data
1204 
1205  meshObjects::movePoints<fvMesh>(*this);
1206  meshObjects::movePoints<lduMesh>(*this);
1207 
1208  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1209 }
1210 
1211 
1213 {
1214  preChange();
1215 
1216  // Set the mesh to be moving. This remains true for the rest of the run.
1217  moving_ = true;
1218 
1219  // Create old-time volumes, if necessary, at the start of a new timestep
1220  if (curTimeIndex_ < time().timeIndex())
1221  {
1222  if (V00Ptr_ && notNull(V00Ptr_))
1223  {
1225  << "Old-old volumes should not be maintained across mesh "
1226  << "changes" << exit(FatalError);
1227  }
1228 
1229  // If old-old-volumes are necessary then copy them from the old-volumes
1230  if (Foam::isNull(V00Ptr_))
1231  {
1232  V00Ptr_ = new DimensionedField<scalar, fvMesh>
1233  (
1234  IOobject
1235  (
1236  "Vc00",
1237  time().name(),
1238  *this,
1241  true
1242  ),
1243  V0()
1244  );
1245  }
1246 
1247  // Copy old-volumes from the volumes
1248  if (!V0Ptr_ || Foam::isNull(V0Ptr_))
1249  {
1251  (
1252  IOobject
1253  (
1254  "Vc0",
1255  time().name(),
1256  *this,
1259  true
1260  ),
1261  V()
1262  );
1263  }
1264  else
1265  {
1266  V0Ptr_->scalarField::operator=(V());
1267  }
1268  }
1269 
1270  // Create mesh motion flux, if necessary
1271  if (!phiPtr_)
1272  {
1273  phiPtr_ = new surfaceScalarField
1274  (
1275  IOobject
1276  (
1277  "meshPhi",
1278  this->time().name(),
1279  *this,
1282  true
1283  ),
1284  *this,
1287  );
1288  }
1289  else
1290  {
1291  phiPtr_->storeOldTimes();
1292  }
1293 
1294  surfaceScalarField& phi = *phiPtr_;
1295 
1296  // Move the polyMesh and set the mesh motion fluxes to the swept-volumes
1297 
1298  scalar rDeltaT = 1.0/time().deltaTValue();
1299 
1300  tmp<scalarField> tsweptVols = polyMesh::movePoints(p);
1301 
1302  scalarField& sweptVols = tsweptVols.ref();
1303 
1304  phi.primitiveFieldRef() =
1305  scalarField::subField(sweptVols, nInternalFaces());
1306  phi.primitiveFieldRef() *= rDeltaT;
1307 
1308  const fvPatchList& patches = boundary();
1309 
1311 
1313  {
1314  phibf[patchi] = patches[patchi].patchSlice(sweptVols);
1315  phibf[patchi] *= rDeltaT;
1316  }
1317 
1318  // Update or delete the local geometric properties as early as possible so
1319  // they can be used if necessary. These get recreated here instead of
1320  // demand driven since they might do parallel transfers which can conflict
1321  // with when they're actually being used.
1322  // Note that between above "polyMesh::movePoints(p)" and here nothing
1323  // should use the local geometric properties.
1324  updateGeomNotOldVol();
1325 
1326  // Update other local data
1328 
1329  meshObjects::movePoints<fvMesh>(*this);
1330  meshObjects::movePoints<lduMesh>(*this);
1331 
1332  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1333 
1334  return tsweptVols;
1335 }
1336 
1337 
1339 {
1340  if (!conformal())
1341  {
1343  << "The mesh was not disconnected prior to topology change"
1344  << exit(FatalError);
1345  }
1346 
1347  // Update polyMesh. This needs to keep volume existent!
1348  polyMesh::topoChange(map);
1349 
1350  // Clear the sliced fields
1351  clearFvGeomNotOldVol();
1352 
1353  // Check that we're not trying to maintain old-time mesh geometry
1354  if (V0Ptr_ && Foam::notNull(V0Ptr_))
1355  {
1357  << "It is not possible to use mesh motion, topology change, and "
1358  << "second order time schemes simultaneously"
1359  << exit(FatalError);
1360  }
1361 
1362  // Map all fields
1363  mapFields(map);
1364 
1365  // Clear the current volume and other geometry factors
1367 
1368  // Clear any non-updateable addressing
1369  clearAddressing(true);
1370 
1371  meshObjects::topoChange<fvMesh>(*this, map);
1372  meshObjects::topoChange<lduMesh>(*this, map);
1373 
1374  const_cast<Time&>(time()).functionObjects().topoChange(map);
1375 
1376  if (stitcher_.valid())
1377  {
1378  stitcher_->topoChange(map);
1379  }
1380 
1381  if (topoChanger_.valid())
1382  {
1383  topoChanger_->topoChange(map);
1384  }
1385 
1386  if (distributor_.valid())
1387  {
1388  distributor_->topoChange(map);
1389  }
1390 
1391  if (mover_.valid())
1392  {
1393  mover_->topoChange(map);
1394  }
1395 }
1396 
1397 
1399 {
1400  if (!conformal())
1401  {
1403  << "The mesh was not disconnected prior to mesh-to-mesh mapping"
1404  << exit(FatalError);
1405  }
1406 
1407  // Distribute polyMesh data
1408  polyMesh::mapMesh(map);
1409 
1410  // Clear the sliced fields
1411  clearFvGeomNotOldVol();
1412 
1413  // Clear the current volume and other geometry factors
1415 
1416  // Clear any non-updateable addressing
1417  clearAddressing(true);
1418 
1419  meshObjects::mapMesh<fvMesh>(*this, map);
1420  meshObjects::mapMesh<lduMesh>(*this, map);
1421 
1422  const_cast<Time&>(time()).functionObjects().mapMesh(map);
1423 
1424  stitcher_->mapMesh(map);
1425  topoChanger_->mapMesh(map);
1426  distributor_->mapMesh(map);
1427  mover_->mapMesh(map);
1428 }
1429 
1430 
1432 {
1433  if (!conformal())
1434  {
1436  << "The mesh was not disconnected prior to distribution"
1437  << exit(FatalError);
1438  }
1439 
1440  // Distribute polyMesh data
1441  polyMesh::distribute(map);
1442 
1443  // Clear the sliced fields
1444  clearFvGeomNotOldVol();
1445 
1446  // Clear the current volume and other geometry factors
1448 
1449  // Clear any non-updateable addressing
1450  clearAddressing(true);
1451 
1452  meshObjects::distribute<fvMesh>(*this, map);
1453  meshObjects::distribute<lduMesh>(*this, map);
1454 
1455  const_cast<Time&>(time()).functionObjects().distribute(map);
1456 
1457  stitcher_->distribute(map);
1458  topoChanger_->distribute(map);
1459  distributor_->distribute(map);
1460  mover_->distribute(map);
1461 }
1462 
1463 
1465 {
1466  if (!polyFacesBfPtr_)
1467  {
1468  return;
1469  }
1470 
1471  polyFacesBfIOPtr_->instance() = inst;
1472  polyFacesBfIOPtr_->writeOpt() = IOobject::AUTO_WRITE;
1473 }
1474 
1475 
1477 {
1478  if (!polyFacesBfPtr_)
1479  {
1480  return facesInstance();
1481  }
1482 
1483  return polyFacesBfIOPtr_->instance();
1484 }
1485 
1486 
1488 {
1489  // Clear the geometry fields
1490  clearFvGeomNotOldVol();
1491 
1492  // Clear the current volume and other geometry factors
1494 
1495  // Clear any non-updateable addressing
1496  clearAddressing(true);
1497 
1498  // Modify the mesh fluxes, if necessary
1499  if (notNull(phi) && phiPtr_)
1500  {
1501  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1502  {
1503  phiRef().oldTimeRef(i) == phi.oldTime(i);
1504  }
1505  }
1506 }
1507 
1508 
1510 (
1511  const surfaceLabelField::Boundary& polyFacesBf,
1512  const surfaceVectorField& Sf,
1513  const surfaceVectorField& Cf,
1514  const surfaceScalarField& phi,
1515  const bool sync
1516 )
1517 {
1518  // Clear the geometry fields
1519  clearFvGeomNotOldVol();
1520 
1521  // Clear the current volume and other geometry factors
1523 
1524  // Clear any non-updateable addressing
1525  clearAddressing(true);
1526 
1527  // Create non-sliced copies of geometry fields
1528  SfRef();
1529  magSfRef();
1530  CRef();
1531  CfRef();
1532 
1533  // Set the topology
1534  forAll(polyFacesBf, patchi)
1535  {
1536  polyFacesBfRef()[patchi].reset(polyFacesBf[patchi]);
1537  }
1538 
1539  // Set the face geometry
1540  SfRef() == Sf;
1541  magSfRef() == max(mag(Sf), dimensionedScalar(dimArea, rootVSmall));
1542  CRef().boundaryFieldRef() == Cf.boundaryField();
1543  CfRef() == Cf;
1544 
1545  // Communicate processor-coupled cell geometry. Cell-centre processor patch
1546  // fields must contain the (transformed) cell-centre locations on the other
1547  // side of the coupling. This is so that non-conformal patches can
1548  // construct weights and deltas without reference to the poly mesh
1549  // geometry.
1550  //
1551  // Note that the initEvaluate/evaluate communication does a transformation,
1552  // but it is wrong in this instance. A vector field gets transformed as if
1553  // it were a displacement, but the cell-centres need a positional
1554  // transformation. That's why there's the un-transform and re-transform bit
1555  // below just after the evaluate call.
1556  //
1557  // This transform handling is a bit of a hack. It would be nicer to have a
1558  // field attribute which identifies a field as needing a positional
1559  // transformation, and for it to apply automatically within the coupled
1560  // patch field. However, at the moment, the cell centres field is the only
1561  // vol-field containing an absolute position, so the hack is functionally
1562  // sufficient for now.
1563  if (sync && time().completeCase())
1564  {
1565  volVectorField::Boundary& CBf = CRef().boundaryFieldRef();
1566 
1567  const label nReq = Pstream::nRequests();
1568 
1569  forAll(CBf, patchi)
1570  {
1571  if (isA<processorFvPatch>(CBf[patchi].patch()))
1572  {
1573  CBf[patchi].initEvaluate(Pstream::defaultCommsType);
1574  }
1575  }
1576 
1577  if
1578  (
1579  Pstream::parRun()
1581  )
1582  {
1583  Pstream::waitRequests(nReq);
1584  }
1585 
1586  forAll(CBf, patchi)
1587  {
1588  if (isA<processorFvPatch>(CBf[patchi].patch()))
1589  {
1591 
1592  const transformer& t =
1593  refCast<const processorFvPatch>(CBf[patchi].patch())
1594  .transform();
1595 
1596  t.invTransform(CBf[patchi], CBf[patchi]);
1597  t.transformPosition(CBf[patchi], CBf[patchi]);
1598  }
1599  }
1600  }
1601 
1602  // Modify the mesh fluxes, if necessary
1603  if (notNull(phi) && phiPtr_)
1604  {
1605  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1606  {
1607  phiRef().oldTimeRef(i) == phi.oldTime(i);
1608  }
1609  }
1610 }
1611 
1612 
1614 (
1615  const label insertPatchi,
1616  const polyPatch& patch
1617 )
1618 {
1619  // Remove my local data (see topoChange)
1620  // Clear mesh motion flux
1621  deleteDemandDrivenData(phiPtr_);
1622 
1623  // Clear the sliced fields
1624  clearFvGeomNotOldVol();
1625 
1626  // Clear the current volume and other geometry factors
1628 
1629  // Clear any non-updateable addressing
1630  clearAddressing(true);
1631 
1632  const label boundarySize0 = boundary_.size();
1633 
1634  polyMesh::addPatch(insertPatchi, patch);
1635 
1636  boundary_.setSize(boundarySize0 + 1);
1637  boundary_.set
1638  (
1639  insertPatchi,
1640  fvPatch::New
1641  (
1642  poly().boundary()[insertPatchi],
1643  boundary_
1644  )
1645  );
1646 
1647  #define AddPatchFieldsType(Type, FieldType, DefaultPatchFieldType) \
1648  AddPatchFields<FieldType<Type>> \
1649  ( \
1650  const_cast<objectRegistry&>(db()), \
1651  insertPatchi, \
1652  DefaultPatchFieldType \
1653  );
1655  (
1657  VolField,
1659  );
1661  (
1663  SurfaceField,
1665  );
1666  #undef AddPatchFieldsType
1667 }
1668 
1669 
1671 (
1672  const labelUList& newToOld,
1673  const bool validBoundary
1674 )
1675 {
1676  polyMesh::reorderPatches(newToOld, validBoundary);
1677 
1678  boundary_.shuffle(newToOld, validBoundary);
1679 
1680  #define ReorderPatchFieldsType(Type, FieldType) \
1681  ReorderPatchFields<FieldType<Type>> \
1682  ( \
1683  const_cast<objectRegistry&>(db()), \
1684  newToOld \
1685  );
1688  #undef ReorderPatchFieldsType
1689 }
1690 
1691 
1693 (
1697  const bool write
1698 ) const
1699 {
1700  bool ok = true;
1701 
1702  if (!conformal() && polyFacesBfIOPtr_->writeOpt() == IOobject::AUTO_WRITE)
1703  {
1704  // Create a full surface field with the polyFacesBf boundary field to
1705  // write to disk. Make the internal field uniform to save disk space.
1706 
1707  surfaceLabelField polyFaces
1708  (
1709  *polyFacesBfIOPtr_,
1710  *this,
1711  dimless,
1712  labelField(nInternalFaces(), -1),
1713  *polyFacesBfPtr_
1714  );
1715 
1716  ok = ok & polyFaces.write(write);
1717  }
1718 
1719  // Write geometry out at a higher precision
1720  unsigned int precision0 =
1722 
1723  // Write the mesh flux if old-old-time volumes exist
1724  if (phiPtr_ && V00Ptr_)
1725  {
1726  ok = ok && phiPtr_->write(write);
1727  }
1728 
1729  // Write old-time volumes if old-old-time volumes exist
1730  if (V0Ptr_ && V00Ptr_)
1731  {
1732  ok = ok && V0Ptr_->write(write);
1733  }
1734 
1735  // Restore the default precision
1736  IOstream::defaultPrecision(precision0);
1737 
1738  if (stitcher_.valid())
1739  {
1740  stitcher_->write(write);
1741  }
1742 
1743  if (topoChanger_.valid())
1744  {
1745  topoChanger_->write(write);
1746  }
1747 
1748  if (distributor_.valid())
1749  {
1750  distributor_->write(write);
1751  }
1752 
1753  if (mover_.valid())
1754  {
1755  mover_->write(write);
1756  }
1757 
1758  return ok && polyMesh::writeObject(fmt, ver, cmp, write);
1759 }
1760 
1761 
1763 {
1764  bool ok = true;
1765 
1766  if (!conformal() && polyFacesBfIOPtr_->writeOpt() == IOobject::AUTO_WRITE)
1767  {
1768  // Create a full surface field with the polyFacesBf boundary field to
1769  // write to disk. Make the internal field uniform to save disk space.
1770 
1771  surfaceLabelField polyFaces
1772  (
1773  *polyFacesBfIOPtr_,
1774  *this,
1775  dimless,
1776  labelField(nInternalFaces(), -1),
1777  *polyFacesBfPtr_
1778  );
1779 
1780  ok = ok & polyFaces.write();
1781  }
1782 
1783  return ok && polyMesh::writeMesh();
1784 }
1785 
1786 
1787 template<>
1789 Foam::fvMesh::validComponents<Foam::sphericalTensor>() const
1790 {
1792 }
1793 
1794 
1796 {
1797  if (!fvSchemes_.valid())
1798  {
1799  fvSchemes_ = new fvSchemes(*this);
1800  }
1801 
1802  return fvSchemes_;
1803 }
1804 
1805 
1807 {
1808  if (!fvSolution_.valid())
1809  {
1810  fvSolution_ = new fvSolution(*this);
1811  }
1812 
1813  return fvSolution_;
1814 }
1815 
1816 
1817 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1818 
1819 bool Foam::fvMesh::operator!=(const fvMesh& bm) const
1820 {
1821  return &bm != this;
1822 }
1823 
1824 
1825 bool Foam::fvMesh::operator==(const fvMesh& bm) const
1826 {
1827  return &bm == this;
1828 }
1829 
1830 
1831 
1832 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1833 
1835 {
1836  const IOobject& io = refCast<const IOobject>(dict);
1837  return refCast<const fvMesh>(io.db());
1838 }
1839 
1840 
1841 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
MeshObject types:
Definition: MeshObjects.H:70
static bool found(const word &name, const polyMesh &mesh)
Return true if the DemandDrivenMeshObject with the given name.
static zonesGenerator & New(const word &name, const polyMesh &mesh)
Construct and return the named DemandDrivenMeshObject.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
SubField< scalar > subField
Declare type of subField.
Definition: Field.H:101
static const char *const typeName
Definition: Field.H:106
Generic GeometricBoundaryField class.
void evaluate()
Evaluate boundary conditions.
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Internal::FieldType & primitiveFieldRef()
Return a reference to the primitive field.
GeometricBoundaryField< Type, GeoMesh, PrimitiveField > Boundary
Type of the boundary field.
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
static const GeometricField< Type, GeoMesh, PrimitiveField > & null()
Return a null geometric field.
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const objectRegistry & db() const
Return the local objectRegistry.
Definition: IOobject.C:309
Version number type.
Definition: IOstream.H:97
static unsigned int fullPrecision()
Return a full precision for writing data that is *very*.
Definition: IOstream.C:98
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
static unsigned int defaultPrecision()
Return the default precision.
Definition: IOstream.H:473
compressionType
Enumeration for the format of data in the stream.
Definition: IOstream.H:194
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label nOldTimes(const bool includeNull=true) const
Return the number of old-time fields stored.
Definition: OldTimeField.C:298
const Field0Type & oldTime() const
Return the old-time field.
Definition: OldTimeField.C:322
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
Unallocated base class of CompactListList.
T & last()
Return the last element of the list.
Definition: UListI.H:128
static label nRequests()
Get number of outstanding requests.
Definition: UPstream.C:137
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:147
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:272
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
Foam::calculatedFvsPatchField.
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
This boundary condition applies a zero-gradient condition from the patch internal field onto the patc...
A class for handling file names.
Definition: fileName.H:82
Foam::fvBoundaryMesh.
Abstract base class for fvMesh movers.
static autoPtr< fvMeshDistributor > New(fvMesh &)
Select, construct and return the fvMeshDistributor.
Foam::fvMeshLduAddressing.
Class holds all the necessary information for mapping fields associated with fvMesh.
Definition: fvMeshMapper.H:56
Abstract base class for fvMesh movers.
Definition: fvMeshMover.H:53
static autoPtr< fvMeshMover > New(fvMesh &)
Select, construct and return the fvMeshMover.
Mesh manipulator that uses the intersection provided by the cyclic non-conformal poly patches to crea...
static autoPtr< fvMeshStitcher > New(fvMesh &, bool changing)
Select, construct and return the fvMeshStitcher.
Abstract base class for fvMesh topology changers.
static autoPtr< fvMeshTopoChanger > New(fvMesh &, const dictionary &dict)
Select, construct and return the fvMeshTopoChanger.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
static const HashSet< word > curGeometryFields
Set of names of registered current-time geometric fields.
Definition: fvMesh.H:339
const fileName & polyFacesBfInstance() const
Get the current instance for the poly faces boundary field.
Definition: fvMesh.C:1476
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:934
stitchType
Extent to which to stitch on read and readUpdate. By default, a.
Definition: fvMesh.H:122
void postConstruct(const bool changers, const bool zones, const stitchType stitch)
Complete construction of the mesh.
Definition: fvMesh.C:612
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
Definition: fvMesh.C:940
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:988
const fvMeshDistributor & distributor() const
Return the distributor function class.
Definition: fvMesh.C:1121
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1795
void clearGeom()
Clear geometry.
Definition: fvMesh.C:246
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: fvMesh.H:107
virtual ~fvMesh()
Destructor.
Definition: fvMesh.C:603
const GeometricBoundaryField< label, surfaceMesh > & ownerBf() const
Return face-owner addressing.
Definition: fvMesh.C:1075
static const HashSet< word > geometryFields
Set of names of registered geometric fields.
Definition: fvMesh.H:335
const fvMeshStitcher & stitcher() const
Return the stitcher function class.
Definition: fvMesh.C:1103
void preChange()
Prepare for a mesh change.
Definition: fvMesh.C:1190
const fvSolution & solution() const
Return the fvSolution.
Definition: fvMesh.C:1806
void addFvPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches. Constructor helper.
Definition: fvMesh.C:760
void swap(fvMesh &)
Swap mesh.
Definition: fvMesh.C:791
const GeometricBoundaryField< label, surfaceMesh > & polyFacesBf() const
Return face-poly-face addressing.
Definition: fvMesh.C:957
bool operator==(const fvMesh &) const
Definition: fvMesh.C:1825
void clearAddressing(const bool isMeshUpdate=false)
Clear addressing.
Definition: fvMesh.C:256
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1064
bool operator!=(const fvMesh &) const
Definition: fvMesh.C:1819
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write the mesh data and all objects in the registry.
Definition: fvMesh.C:1693
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: fvMesh.C:1398
void mapFields(const polyTopoChangeMap &map)
Map all fields in time using given map.
Definition: fvMesh.C:1133
bool update()
Update the mesh for topology change, mesh to mesh mapping.
Definition: fvMesh.C:705
void setPolyFacesBfInstance(const fileName &)
Set the instance for the poly faces boundary field.
Definition: fvMesh.C:1464
virtual void distribute(const polyDistributionMap &map)
Redistribute or update using the given distribution map.
Definition: fvMesh.C:1431
void removeFvBoundary()
Remove boundary patches. Warning: fvPatchFields hold ref to.
Definition: fvMesh.C:778
bool distributing() const
Does the mesh get redistributed?
Definition: fvMesh.C:691
void printAllocated() const
Print a list of all the currently allocated mesh data.
Definition: fvMesh.C:180
virtual void reorderPatches(const labelUList &newToOld, const bool validBoundary)
Reorder and trim existing patches. If validBoundary the new.
Definition: fvMesh.C:1671
void unconform(const GeometricBoundaryField< label, surfaceMesh > &polyFacesBf, const surfaceVectorField &Sf, const surfaceVectorField &Cf, const surfaceScalarField &phi=NullObjectRef< surfaceScalarField >(), const bool sync=true)
Unconform the fvMesh from the polyMesh.
Definition: fvMesh.C:1510
bool dynamic() const
Is this mesh dynamic?
Definition: fvMesh.C:697
fvMesh(const IOobject &io, const bool doPost=true)
Construct from IOobject.
Definition: fvMesh.C:352
const fvMeshTopoChanger & topoChanger() const
Return the topo-changer function class.
Definition: fvMesh.C:1115
virtual void topoChange(const polyTopoChangeMap &map)
Update mesh corresponding to the given map.
Definition: fvMesh.C:1338
bool topoChanging() const
Does the mesh topology change?
Definition: fvMesh.C:685
virtual bool writeMesh() const
Write the mesh data only.
Definition: fvMesh.C:1762
virtual void addPatch(const label insertPatchi, const polyPatch &patch)
Add/insert single patch.
Definition: fvMesh.C:1614
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:301
bool move()
Move the mesh.
Definition: fvMesh.C:745
virtual void setPoints(const pointField &)
Reset the points.
Definition: fvMesh.C:1196
const fvMeshMover & mover() const
Return the mover function class.
Definition: fvMesh.C:1127
void conform(const surfaceScalarField &phi=NullObjectRef< surfaceScalarField >())
Conform the fvMesh to the polyMesh.
Definition: fvMesh.C:1487
bool conformal() const
Return whether the fvMesh is conformal with the polyMesh.
Definition: fvMesh.C:951
const polyMesh & poly() const
Return reference to polyMesh.
Definition: fvMesh.H:456
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:58
static autoPtr< fvPatch > New(const polyPatch &, const fvBoundaryMesh &)
Return a pointer to a new patch created on freestore from polyPatch.
Definition: fvPatchNew.C:32
Selector class for finite volume differencing schemes. fvMesh is derived from fvSchemes so that all f...
Definition: fvSchemes.H:53
Selector class for finite volume solution solution. fvMesh is derived from fvSolution so that all fie...
Definition: fvSolution.H:50
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
Definition: fvsPatchField.H:86
The class contains the addressing required by the lduMatrix: upper, lower and losort.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:60
static void clearUpto(objectRegistry &)
Clear all meshObjects derived from FromType up to (but not including)
Traits class for primitives.
Definition: pTraits.H:53
Class holds all the necessary information for mapping fields associated with pointMesh.
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Class containing mesh-to-mesh mapping information.
Definition: polyMeshMap.H:51
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
const polyBoundaryMesh & boundary() const
Return boundary mesh.
Definition: polyMesh.H:393
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: polyMesh.C:1407
void clearGeom()
Clear geometry.
Definition: polyMeshClear.C:60
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:88
@ TOPO_PATCH_CHANGE
Definition: polyMesh.H:92
virtual void topoChange(const polyTopoChangeMap &)
Update topology using the given map.
void swap(polyMesh &)
Swap mesh.
Definition: polyMesh.C:817
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write the mesh data and all objects in the registry.
Definition: polyMeshIO.C:556
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
readUpdateState readUpdate()
Update the mesh based on the mesh files saved in.
Definition: polyMeshIO.C:132
virtual void distribute(const polyDistributionMap &map)
Redistribute or update using the given distribution map.
void printAllocated() const
Print a list of all the currently allocated mesh data.
Definition: polyMeshClear.C:47
void removeBoundary()
Remove boundary patches.
Definition: polyMeshClear.C:33
virtual void reorderPatches(const labelUList &newToOld, const bool validBoundary)
Reorder and trim existing patches. If validBoundary the new.
Definition: polyMesh.C:1187
virtual bool writeMesh() const
Write the mesh data only.
Definition: polyMeshIO.C:611
virtual void addPatch(const label insertPatchi, const polyPatch &patch)
Add/insert single patch.
Definition: polyMesh.C:1220
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
Definition: polyMeshClear.C:99
virtual void setPoints(const pointField &)
Reset the points.
Definition: polyMesh.C:1371
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:71
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
label nOldCells() const
Number of old cells.
const labelList & cellMap() const
Old cell map.
label nOldFaces() const
Number of old faces.
const labelList & faceMap() const
Old face map.
virtual bool write(const bool write=true) const
Write using setting from DB.
Cell to surface interpolation scheme. Included in fvMesh.
bool movePoints()
Do what is necessary if the mesh has moved.
void printAllocated() const
Print a list of all the currently allocated data.
void clearOut()
Clear all geometry and addressing.
Mesh data for surface fields.
Definition: surfaceMesh.H:51
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
Vector-tensor class used to perform translations, rotations and scaling operations in 3D space.
Definition: transformer.H:84
Type invTransform(const Type &) const
Inverse transform the given type.
vector transformPosition(const vector &v) const
Transform the given position.
Definition: transformerI.H:153
Type transform(const Type &) const
Transform the given type.
Template function which returns the un-mangled name of a given type. Useful for types which do not ha...
A class for handling words, derived from string.
Definition: word.H:63
static const word null
An empty word.
Definition: word.H:78
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
#define nullOldestTimeFields(Type, nullArg)
#define ReorderPatchFieldsType(Type, FieldType)
#define mapVolInternalFieldType(Type, nullArg)
#define mapPointFieldType(Type, nullArg)
#define AddPatchFieldsType(Type, FieldType, DefaultPatchFieldType)
#define mapVolFieldType(Type, nullArg)
#define mapSurfaceFieldType(Type, nullArg)
Reconstruct volField from a face flux field.
Surface integrate surfaceField creating a volField. Surface sum a surfaceField creating a volField.
label patchi
const pointField & points
const cellShapeList & cells
const fvPatchList & patches
#define DebugInFunction
Report an information message using Foam::Info.
const dimensionSet dimless
const dimensionSet time
const dimensionSet volumetricFlux
const dimensionSet volume
Definition: annulus.H:177
static const coefficient C("C", dimTemperature, 234.5)
const unitSet none
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
Namespace for OpenFOAM.
bool isFile(const fileName &, const bool checkVariants=true, const bool followLink=true)
Does the name exist as a file in the file system?
Definition: POSIX.C:555
const fileOperation & fileHandler()
Get current file handler.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
String typeName(const std::type_info &info)
Return the un-mangled name given the standard type info.
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
SurfaceField< scalar > surfaceScalarField
FOR_ALL_FIELD_TYPES(makeDimensionedPointFieldFunctions)
messageStream Info
const dimensionSet & dimVolume
Definition: dimensions.C:282
const fvMesh & region(const dictionary &dict)
Cast the give dictionary to the corresponding region fvMesh.
Definition: fvMesh.C:1834
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:64
const dimensionSet & dimTime
Definition: dimensions.C:277
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:49
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
bool isNull(const T &t)
Return true if t is a reference to the nullObject of type T.
Definition: nullObjectI.H:58
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
error FatalError
const dimensionSet & dimArea
Definition: dimensions.C:281
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
void nullDemandDrivenData(DataType *&dataPtr)
label timeIndex
Definition: getTimeIndex.H:4
faceListList boundary(nPatches)
dictionary dict
volScalarField & p
Foam::surfaceFields.