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
650  );
651 
652  V00();
653  }
654 
655  // Check the existence of the mesh fluxes and read if present
656  if (fileHandler().isFile(time().timePath()/"meshPhi"))
657  {
658  phiPtr_ = new surfaceScalarField
659  (
660  IOobject
661  (
662  "meshPhi",
663  time().name(),
664  *this,
667  true
668  ),
669  *this
670  );
671  }
672  }
673 
674  // Generate the zones after the mesh manipulators have been constructed
675  // to support motion-specific zone generators requiring access to the mover
676  if (zones)
677  {
678  zonesGenerator::New(*this);
679  }
680 }
681 
682 
684 {
685  return topoChanger_.valid() && topoChanger_->dynamic();
686 }
687 
688 
690 {
691  return distributor_.valid() && distributor_->dynamic();
692 }
693 
694 
696 {
697  return
698  (topoChanger_.valid() && topoChanger_->dynamic())
699  || (mover_.valid() && mover_->dynamic());
700 }
701 
702 
704 {
705  if
706  (
707  stitcher_->stitches()
708  || topoChanger_->dynamic()
709  || distributor_->dynamic()
710  )
711  {
713  }
714 
715  // Remove the oldest cell volume field
716  if (V00Ptr_)
717  {
718  nullDemandDrivenData(V00Ptr_);
719  }
720  else
721  {
722  nullDemandDrivenData(V0Ptr_);
723  }
724 
725  // Remove the oldest mesh flux field
726  if (phiPtr_)
727  {
728  phiPtr_->nullOldestTime();
729  }
730 
731  // Set topoChanged_ false before any mesh change. Topo-changing can switch
732  // on and off during a run.
733  topoChanged_ = false;
734 
735  topoChanged_ = topoChanger_->update();
736 
737  const bool distributed = distributor_->update();
738 
739  return topoChanged_ || distributed;
740 }
741 
742 
744 {
745  // Do not set moving_ false before any mesh motion. Once the mesh starts
746  // moving it is considered to be moving for the rest of the run.
747  const bool moved = mover_->update();
748 
749  curTimeIndex_ = time().timeIndex();
750 
751  stitcher_->connect(true, true, false);
752 
753  return moved;
754 }
755 
756 
758 (
759  const List<polyPatch*>& p,
760  const bool validBoundary
761 )
762 {
763  if (boundary().size())
764  {
766  << " boundary already exists"
767  << abort(FatalError);
768  }
769 
770  // first add polyPatches
771  addPatches(p, validBoundary);
772  boundary_.addPatches(poly().boundary());
773 }
774 
775 
777 {
778  DebugInFunction << "Removing boundary patches." << endl;
779 
780  // Remove fvBoundaryMesh data first.
781  boundary_.clear();
782  boundary_.setSize(0);
784 
785  clearOut();
786 }
787 
788 
789 void Foam::fvMesh::swap(fvMesh& otherMesh)
790 {
791  // Clear the sliced fields
792  clearFvGeom();
793 
794  // Clear the current volume and other geometry factors
796 
797  // Clear any non-updateable addressing
798  clearAddressing(true);
799 
800  polyMesh::swap(otherMesh);
801 
802  auto updatePatches = []
803  (
804  const polyPatchList& patches,
805  fvBoundaryMesh& boundaryMesh
806  )
807  {
808  boundaryMesh.setSize(patches.size());
809 
811  {
812  // Construct new processor patches, as the decomposition may have
813  // changed. Leave other patches as is.
814 
815  if (isA<processorPolyPatch>(patches[patchi]))
816  {
817  boundaryMesh.set
818  (
819  patchi,
821  (
822  patches[patchi],
823  boundaryMesh
824  )
825  );
826  }
827  }
828  };
829 
830  updatePatches(poly().boundary(), boundary_);
831  updatePatches(otherMesh.poly().boundary(), otherMesh.boundary_);
832 }
833 
834 
836 (
837  const stitchType stitch
838 )
839 {
840  // Determine if this update moves forward in time. If so, searching back in
841  // time for data files will only go back as far as the previous instance.
842  const fileName instance0 = instance();
843  const bool forward = readUpdateIsForward();
844 
845  // Update the polyMesh and the mesh instance
847 
848  DebugInFunction << "Updating the fvMesh:" << endl;
849 
850  if (debug)
851  {
852  switch (state)
853  {
855  Info<< " Boundary and topological change" << endl;
856  break;
858  Info<< " Topological change" << endl;
859  break;
861  Info<< " Point motion" << endl;
862  break;
863  default:
864  Info<< " No change" << endl;
865  break;
866  }
867  }
868 
869  const bool reStitch =
870  stitcher_.valid()
871  && stitcher_->stitches()
872  && stitch != stitchType::none
873  && (
874  !conformal()
875  || time().findInstance
876  (
877  dbDir()/typeName,
878  "polyFaces",
880  forward ? word(instance0) : word::null
881  )
882  != (forward ? instance0 : polyFacesBfIOPtr_->instance())
883  );
884 
885  if (reStitch)
886  {
887  stitcher_->disconnect(false, false);
888  }
889  else if (state != polyMesh::UNCHANGED)
890  {
891  conform();
892  }
893 
894  switch (state)
895  {
897  boundary_.readUpdate(poly().boundary());
898  clearOut();
899  break;
901  clearOut();
902  break;
904  clearFvGeom();
905  break;
906  default:
907  break;
908  }
909 
910  if (reStitch && stitch != stitchType::none)
911  {
912  stitcher_->connect(false, stitch == stitchType::geometric, true);
913  }
914 
915  // Return the corresponding fvMesh read update state
916  switch (state)
917  {
918  case polyMesh::UNCHANGED:
919  return reStitch ? STITCHED : UNCHANGED;
921  return reStitch ? STITCHED : POINTS_MOVED;
923  return TOPO_CHANGE;
925  return TOPO_PATCH_CHANGE;
926  }
927 
928  return UNCHANGED;
929 }
930 
931 
933 {
934  return boundary_;
935 }
936 
937 
939 {
940  if (!lduPtr_)
941  {
942  lduPtr_ = new fvMeshLduAddressing(*this);
943  }
944 
945  return *lduPtr_;
946 }
947 
948 
950 {
951  return !(polyFacesBfPtr_ && SfPtr_);
952 }
953 
954 
956 {
957  if (!polyFacesBfPtr_)
958  {
959  polyFacesBfIOPtr_ =
960  new IOobject
961  (
962  "polyFaces",
963  facesInstance(),
964  typeName,
965  *this,
968  false
969  );
970 
971  polyFacesBfPtr_ =
973  (
974  boundary(),
976  polyFacesPatchTypes(),
977  poly().boundary().types()
978  );
979  }
980 
981  return *polyFacesBfPtr_;
982 }
983 
984 
987 {
988  if (!polyBFacePatchesPtr_)
989  {
990  const label nPolyBFaces = nFaces() - nInternalFaces();
991 
992  // Count face-poly-bFaces to get the offsets
993  polyBFaceOffsetsPtr_ = new labelList(nPolyBFaces + 1, 0);
994  labelList& offsets = *polyBFaceOffsetsPtr_;
996  {
997  forAll(boundary()[patchi], patchFacei)
998  {
999  const label polyBFacei =
1000  (
1001  polyFacesBfPtr_
1002  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1003  : boundary()[patchi].start() + patchFacei
1004  )
1005  - nInternalFaces();
1006 
1007  offsets[polyBFacei + 1] ++;
1008  }
1009  }
1010  for (label polyBFacei = 0; polyBFacei < nPolyBFaces; ++ polyBFacei)
1011  {
1012  offsets[polyBFacei + 1] += offsets[polyBFacei];
1013  }
1014 
1015  // Set the poly-bFace patches and patch-faces, using the offsets as
1016  // counters
1017  polyBFaceOffsetPatchesPtr_ = new labelList(offsets.last());
1018  polyBFaceOffsetPatchFacesPtr_ = new labelList(offsets.last());
1019  labelUList& patches = *polyBFaceOffsetPatchesPtr_;
1020  labelUList& patchFaces = *polyBFaceOffsetPatchFacesPtr_;
1021  forAll(boundary(), patchi)
1022  {
1023  forAll(boundary()[patchi], patchFacei)
1024  {
1025  const label polyBFacei =
1026  (
1027  polyFacesBfPtr_
1028  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1029  : boundary()[patchi].start() + patchFacei
1030  )
1031  - nInternalFaces();
1032  patches[offsets[polyBFacei]] = patchi;
1033  patchFaces[offsets[polyBFacei]] = patchFacei;
1034  offsets[polyBFacei] ++;
1035  }
1036  }
1037 
1038  // Restore the offsets by removing the count
1039  for
1040  (
1041  label polyBFacei = nPolyBFaces - 1;
1042  polyBFacei >= 0;
1043  -- polyBFacei
1044  )
1045  {
1046  offsets[polyBFacei + 1] = offsets[polyBFacei];
1047  }
1048  offsets[0] = 0;
1049 
1050  // List-lists
1051  polyBFacePatchesPtr_ =
1052  new UCompactListList<label>(offsets, patches);
1053  polyBFacePatchFacesPtr_ =
1054  new UCompactListList<label>(offsets, patchFaces);
1055  }
1056 
1057  return *polyBFacePatchesPtr_;
1058 }
1059 
1060 
1063 {
1064  if (!polyBFacePatchFacesPtr_)
1065  {
1066  polyBFacePatches();
1067  }
1068 
1069  return *polyBFacePatchFacesPtr_;
1070 }
1071 
1072 
1074 {
1075  if (!ownerBfPtr_)
1076  {
1077  ownerBfPtr_ =
1079  (
1080  boundary(),
1082  wordList
1083  (
1084  boundary().size(),
1086  ),
1087  poly().boundary().types()
1088  );
1089 
1090  forAll(boundary(), patchi)
1091  {
1092  (*ownerBfPtr_)[patchi] =
1093  labelField(faceOwner(), polyFacesBf()[patchi]);
1094  }
1095  }
1096 
1097  return *ownerBfPtr_;
1098 }
1099 
1100 
1102 {
1103  return stitcher_();
1104 }
1105 
1106 
1108 {
1109  return stitcher_();
1110 }
1111 
1112 
1114 {
1115  return topoChanger_();
1116 }
1117 
1118 
1120 {
1121  return distributor_();
1122 }
1123 
1124 
1126 {
1127  return mover_();
1128 }
1129 
1130 
1132 {
1134  << " nOldCells:" << map.nOldCells()
1135  << " nCells:" << nCells()
1136  << " nOldFaces:" << map.nOldFaces()
1137  << " nFaces:" << nFaces()
1138  << endl;
1139 
1140  // We require geometric properties valid for the old mesh
1141  if
1142  (
1143  map.cellMap().size() != nCells()
1144  || map.faceMap().size() != nFaces()
1145  )
1146  {
1148  << "polyTopoChangeMap does not correspond to the old mesh."
1149  << " nCells:" << nCells()
1150  << " cellMap:" << map.cellMap().size()
1151  << " nOldCells:" << map.nOldCells()
1152  << " nFaces:" << nFaces()
1153  << " faceMap:" << map.faceMap().size()
1154  << " nOldFaces:" << map.nOldFaces()
1155  << exit(FatalError);
1156  }
1157 
1158  // Create a fv mapper
1159  const fvMeshMapper fvMap(*this, map);
1160 
1161  // Map all the volFields in the objectRegistry
1162  #define mapVolFieldType(Type, nullArg) \
1163  MapGeometricFields<Type, fvMeshMapper, fvMesh>(fvMap);
1165 
1166  // Map all the surfaceFields in the objectRegistry
1167  #define mapSurfaceFieldType(Type, nullArg) \
1168  MapGeometricFields<Type, fvMeshMapper, surfaceMesh>(fvMap);
1170 
1171  // Map all the dimensionedFields in the objectRegistry
1172  #define mapVolInternalFieldType(Type, nullArg) \
1173  MapDimensionedFields<Type, fvMeshMapper, fvMesh>(fvMap);
1175 
1176  if (pointMesh::found(*this))
1177  {
1178  // Create the pointMesh mapper
1179  const pointMeshMapper mapper(pointMesh::New(*this), map);
1180 
1181  #define mapPointFieldType(Type, nullArg) \
1182  MapGeometricFields<Type, pointMeshMapper, pointMesh>(mapper);
1184  }
1185 }
1186 
1187 
1189 {
1190  stitcher_->disconnect(true, true);
1191 }
1192 
1193 
1195 {
1197 
1198  clearFvGeom();
1199 
1200  // Update other local data
1202 
1203  meshObjects::movePoints<fvMesh>(*this);
1204  meshObjects::movePoints<lduMesh>(*this);
1205 
1206  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1207 }
1208 
1209 
1211 {
1212  preChange();
1213 
1214  // Set the mesh to be moving. This remains true for the rest of the run.
1215  moving_ = true;
1216 
1217  // Create old-time volumes, if necessary, at the start of a new timestep
1218  if (curTimeIndex_ < time().timeIndex())
1219  {
1220  if (V00Ptr_ && notNull(V00Ptr_))
1221  {
1223  << "Old-old volumes should not be maintained across mesh "
1224  << "changes" << exit(FatalError);
1225  }
1226 
1227  // If old-old-volumes are necessary then copy them from the old-volumes
1228  if (Foam::isNull(V00Ptr_))
1229  {
1230  V00Ptr_ = new DimensionedField<scalar, fvMesh>
1231  (
1232  IOobject
1233  (
1234  "Vc00",
1235  time().name(),
1236  *this,
1239  true
1240  ),
1241  V0()
1242  );
1243  }
1244 
1245  // Copy old-volumes from the volumes
1246  if (!V0Ptr_ || Foam::isNull(V0Ptr_))
1247  {
1249  (
1250  IOobject
1251  (
1252  "Vc0",
1253  time().name(),
1254  *this,
1257  true
1258  ),
1259  V()
1260  );
1261  }
1262  else
1263  {
1264  V0Ptr_->scalarField::operator=(V());
1265  }
1266  }
1267 
1268  // Create mesh motion flux, if necessary
1269  if (!phiPtr_)
1270  {
1271  phiPtr_ = new surfaceScalarField
1272  (
1273  IOobject
1274  (
1275  "meshPhi",
1276  this->time().name(),
1277  *this,
1280  true
1281  ),
1282  *this,
1284  );
1285  }
1286  else
1287  {
1288  phiPtr_->storeOldTimes();
1289  }
1290 
1291  surfaceScalarField& phi = *phiPtr_;
1292 
1293  // Move the polyMesh and set the mesh motion fluxes to the swept-volumes
1294 
1295  scalar rDeltaT = 1.0/time().deltaTValue();
1296 
1297  tmp<scalarField> tsweptVols = polyMesh::movePoints(p);
1298 
1299  scalarField& sweptVols = tsweptVols.ref();
1300 
1301  phi.primitiveFieldRef() =
1302  scalarField::subField(sweptVols, nInternalFaces());
1303  phi.primitiveFieldRef() *= rDeltaT;
1304 
1305  const fvPatchList& patches = boundary();
1306 
1308 
1310  {
1311  phibf[patchi] = patches[patchi].patchSlice(sweptVols);
1312  phibf[patchi] *= rDeltaT;
1313  }
1314 
1315  // Update or delete the local geometric properties as early as possible so
1316  // they can be used if necessary. These get recreated here instead of
1317  // demand driven since they might do parallel transfers which can conflict
1318  // with when they're actually being used.
1319  // Note that between above "polyMesh::movePoints(p)" and here nothing
1320  // should use the local geometric properties.
1321  updateGeomNotOldVol();
1322 
1323  // Update other local data
1325 
1326  meshObjects::movePoints<fvMesh>(*this);
1327  meshObjects::movePoints<lduMesh>(*this);
1328 
1329  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1330 
1331  return tsweptVols;
1332 }
1333 
1334 
1336 {
1337  if (!conformal())
1338  {
1340  << "The mesh was not disconnected prior to topology change"
1341  << exit(FatalError);
1342  }
1343 
1344  // Update polyMesh. This needs to keep volume existent!
1345  polyMesh::topoChange(map);
1346 
1347  // Clear the sliced fields
1348  clearFvGeomNotOldVol();
1349 
1350  // Check that we're not trying to maintain old-time mesh geometry
1351  if (V0Ptr_ && Foam::notNull(V0Ptr_))
1352  {
1354  << "It is not possible to use mesh motion, topology change, and "
1355  << "second order time schemes simultaneously"
1356  << exit(FatalError);
1357  }
1358 
1359  // Map all fields
1360  mapFields(map);
1361 
1362  // Clear the current volume and other geometry factors
1364 
1365  // Clear any non-updateable addressing
1366  clearAddressing(true);
1367 
1368  meshObjects::topoChange<fvMesh>(*this, map);
1369  meshObjects::topoChange<lduMesh>(*this, map);
1370 
1371  const_cast<Time&>(time()).functionObjects().topoChange(map);
1372 
1373  if (stitcher_.valid())
1374  {
1375  stitcher_->topoChange(map);
1376  }
1377 
1378  if (topoChanger_.valid())
1379  {
1380  topoChanger_->topoChange(map);
1381  }
1382 
1383  if (distributor_.valid())
1384  {
1385  distributor_->topoChange(map);
1386  }
1387 
1388  if (mover_.valid())
1389  {
1390  mover_->topoChange(map);
1391  }
1392 }
1393 
1394 
1396 {
1397  if (!conformal())
1398  {
1400  << "The mesh was not disconnected prior to mesh-to-mesh mapping"
1401  << exit(FatalError);
1402  }
1403 
1404  // Distribute polyMesh data
1405  polyMesh::mapMesh(map);
1406 
1407  // Clear the sliced fields
1408  clearFvGeomNotOldVol();
1409 
1410  // Clear the current volume and other geometry factors
1412 
1413  // Clear any non-updateable addressing
1414  clearAddressing(true);
1415 
1416  meshObjects::mapMesh<fvMesh>(*this, map);
1417  meshObjects::mapMesh<lduMesh>(*this, map);
1418 
1419  const_cast<Time&>(time()).functionObjects().mapMesh(map);
1420 
1421  stitcher_->mapMesh(map);
1422  topoChanger_->mapMesh(map);
1423  distributor_->mapMesh(map);
1424  mover_->mapMesh(map);
1425 }
1426 
1427 
1429 {
1430  if (!conformal())
1431  {
1433  << "The mesh was not disconnected prior to distribution"
1434  << exit(FatalError);
1435  }
1436 
1437  // Distribute polyMesh data
1438  polyMesh::distribute(map);
1439 
1440  // Clear the sliced fields
1441  clearFvGeomNotOldVol();
1442 
1443  // Clear the current volume and other geometry factors
1445 
1446  // Clear any non-updateable addressing
1447  clearAddressing(true);
1448 
1449  meshObjects::distribute<fvMesh>(*this, map);
1450  meshObjects::distribute<lduMesh>(*this, map);
1451 
1452  const_cast<Time&>(time()).functionObjects().distribute(map);
1453 
1454  stitcher_->distribute(map);
1455  topoChanger_->distribute(map);
1456  distributor_->distribute(map);
1457  mover_->distribute(map);
1458 }
1459 
1460 
1462 {
1463  if (!polyFacesBfPtr_)
1464  {
1465  return;
1466  }
1467 
1468  polyFacesBfIOPtr_->instance() = inst;
1469  polyFacesBfIOPtr_->writeOpt() = IOobject::AUTO_WRITE;
1470 }
1471 
1472 
1474 {
1475  if (!polyFacesBfPtr_)
1476  {
1477  return facesInstance();
1478  }
1479 
1480  return polyFacesBfIOPtr_->instance();
1481 }
1482 
1483 
1485 {
1486  // Clear the geometry fields
1487  clearFvGeomNotOldVol();
1488 
1489  // Clear the current volume and other geometry factors
1491 
1492  // Clear any non-updateable addressing
1493  clearAddressing(true);
1494 
1495  // Modify the mesh fluxes, if necessary
1496  if (notNull(phi) && phiPtr_)
1497  {
1498  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1499  {
1500  phiRef().oldTimeRef(i) == phi.oldTime(i);
1501  }
1502  }
1503 }
1504 
1505 
1507 (
1508  const surfaceLabelField::Boundary& polyFacesBf,
1509  const surfaceVectorField& Sf,
1510  const surfaceVectorField& Cf,
1511  const surfaceScalarField& phi,
1512  const bool sync
1513 )
1514 {
1515  // Clear the geometry fields
1516  clearFvGeomNotOldVol();
1517 
1518  // Clear the current volume and other geometry factors
1520 
1521  // Clear any non-updateable addressing
1522  clearAddressing(true);
1523 
1524  // Create non-sliced copies of geometry fields
1525  SfRef();
1526  magSfRef();
1527  CRef();
1528  CfRef();
1529 
1530  // Set the topology
1531  forAll(polyFacesBf, patchi)
1532  {
1533  polyFacesBfRef()[patchi].reset(polyFacesBf[patchi]);
1534  }
1535 
1536  // Set the face geometry
1537  SfRef() == Sf;
1538  magSfRef() == max(mag(Sf), dimensionedScalar(dimArea, rootVSmall));
1539  CRef().boundaryFieldRef() == Cf.boundaryField();
1540  CfRef() == Cf;
1541 
1542  // Communicate processor-coupled cell geometry. Cell-centre processor patch
1543  // fields must contain the (transformed) cell-centre locations on the other
1544  // side of the coupling. This is so that non-conformal patches can
1545  // construct weights and deltas without reference to the poly mesh
1546  // geometry.
1547  //
1548  // Note that the initEvaluate/evaluate communication does a transformation,
1549  // but it is wrong in this instance. A vector field gets transformed as if
1550  // it were a displacement, but the cell-centres need a positional
1551  // transformation. That's why there's the un-transform and re-transform bit
1552  // below just after the evaluate call.
1553  //
1554  // This transform handling is a bit of a hack. It would be nicer to have a
1555  // field attribute which identifies a field as needing a positional
1556  // transformation, and for it to apply automatically within the coupled
1557  // patch field. However, at the moment, the cell centres field is the only
1558  // vol-field containing an absolute position, so the hack is functionally
1559  // sufficient for now.
1560  if (sync && time().completeCase())
1561  {
1562  volVectorField::Boundary& CBf = CRef().boundaryFieldRef();
1563 
1564  const label nReq = Pstream::nRequests();
1565 
1566  forAll(CBf, patchi)
1567  {
1568  if (isA<processorFvPatch>(CBf[patchi].patch()))
1569  {
1570  CBf[patchi].initEvaluate(Pstream::defaultCommsType);
1571  }
1572  }
1573 
1574  if
1575  (
1576  Pstream::parRun()
1578  )
1579  {
1580  Pstream::waitRequests(nReq);
1581  }
1582 
1583  forAll(CBf, patchi)
1584  {
1585  if (isA<processorFvPatch>(CBf[patchi].patch()))
1586  {
1588 
1589  const transformer& t =
1590  refCast<const processorFvPatch>(CBf[patchi].patch())
1591  .transform();
1592 
1593  t.invTransform(CBf[patchi], CBf[patchi]);
1594  t.transformPosition(CBf[patchi], CBf[patchi]);
1595  }
1596  }
1597  }
1598 
1599  // Modify the mesh fluxes, if necessary
1600  if (notNull(phi) && phiPtr_)
1601  {
1602  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1603  {
1604  phiRef().oldTimeRef(i) == phi.oldTime(i);
1605  }
1606  }
1607 }
1608 
1609 
1611 (
1612  const label insertPatchi,
1613  const polyPatch& patch
1614 )
1615 {
1616  // Remove my local data (see topoChange)
1617  // Clear mesh motion flux
1618  deleteDemandDrivenData(phiPtr_);
1619 
1620  // Clear the sliced fields
1621  clearFvGeomNotOldVol();
1622 
1623  // Clear the current volume and other geometry factors
1625 
1626  // Clear any non-updateable addressing
1627  clearAddressing(true);
1628 
1629  const label boundarySize0 = boundary_.size();
1630 
1631  polyMesh::addPatch(insertPatchi, patch);
1632 
1633  boundary_.setSize(boundarySize0 + 1);
1634  boundary_.set
1635  (
1636  insertPatchi,
1637  fvPatch::New
1638  (
1639  poly().boundary()[insertPatchi],
1640  boundary_
1641  )
1642  );
1643 
1644  #define AddPatchFieldsType(Type, FieldType, DefaultPatchFieldType) \
1645  AddPatchFields<FieldType<Type>> \
1646  ( \
1647  const_cast<objectRegistry&>(db()), \
1648  insertPatchi, \
1649  DefaultPatchFieldType \
1650  );
1652  (
1654  VolField,
1656  );
1658  (
1660  SurfaceField,
1662  );
1663  #undef AddPatchFieldsType
1664 }
1665 
1666 
1668 (
1669  const labelUList& newToOld,
1670  const bool validBoundary
1671 )
1672 {
1673  polyMesh::reorderPatches(newToOld, validBoundary);
1674 
1675  boundary_.shuffle(newToOld, validBoundary);
1676 
1677  #define ReorderPatchFieldsType(Type, FieldType) \
1678  ReorderPatchFields<FieldType<Type>> \
1679  ( \
1680  const_cast<objectRegistry&>(db()), \
1681  newToOld \
1682  );
1685  #undef ReorderPatchFieldsType
1686 }
1687 
1688 
1690 (
1694  const bool write
1695 ) const
1696 {
1697  bool ok = true;
1698 
1699  if (!conformal() && polyFacesBfIOPtr_->writeOpt() == IOobject::AUTO_WRITE)
1700  {
1701  // Create a full surface field with the polyFacesBf boundary field to
1702  // write to disk. Make the internal field uniform to save disk space.
1703 
1704  surfaceLabelField polyFaces
1705  (
1706  *polyFacesBfIOPtr_,
1707  *this,
1708  dimless,
1709  labelField(nInternalFaces(), -1),
1710  *polyFacesBfPtr_
1711  );
1712 
1713  ok = ok & polyFaces.write(write);
1714  }
1715 
1716  // Write geometry out at a higher precision
1717  unsigned int precision0 =
1719 
1720  // Write the mesh flux if old-old-time volumes exist
1721  if (phiPtr_ && V00Ptr_)
1722  {
1723  ok = ok && phiPtr_->write(write);
1724  }
1725 
1726  // Write old-time volumes if old-old-time volumes exist
1727  if (V0Ptr_ && V00Ptr_)
1728  {
1729  ok = ok && V0Ptr_->write(write);
1730  }
1731 
1732  // Restore the default precision
1733  IOstream::defaultPrecision(precision0);
1734 
1735  if (stitcher_.valid())
1736  {
1737  stitcher_->write(write);
1738  }
1739 
1740  if (topoChanger_.valid())
1741  {
1742  topoChanger_->write(write);
1743  }
1744 
1745  if (distributor_.valid())
1746  {
1747  distributor_->write(write);
1748  }
1749 
1750  if (mover_.valid())
1751  {
1752  mover_->write(write);
1753  }
1754 
1755  return ok && polyMesh::writeObject(fmt, ver, cmp, write);
1756 }
1757 
1758 
1760 {
1761  bool ok = true;
1762 
1763  if (!conformal() && polyFacesBfIOPtr_->writeOpt() == IOobject::AUTO_WRITE)
1764  {
1765  // Create a full surface field with the polyFacesBf boundary field to
1766  // write to disk. Make the internal field uniform to save disk space.
1767 
1768  surfaceLabelField polyFaces
1769  (
1770  *polyFacesBfIOPtr_,
1771  *this,
1772  dimless,
1773  labelField(nInternalFaces(), -1),
1774  *polyFacesBfPtr_
1775  );
1776 
1777  ok = ok & polyFaces.write();
1778  }
1779 
1780  return ok && polyMesh::writeMesh();
1781 }
1782 
1783 
1784 template<>
1786 Foam::fvMesh::validComponents<Foam::sphericalTensor>() const
1787 {
1789 }
1790 
1791 
1793 {
1794  if (!fvSchemes_.valid())
1795  {
1796  fvSchemes_ = new fvSchemes(*this);
1797  }
1798 
1799  return fvSchemes_;
1800 }
1801 
1802 
1804 {
1805  if (!fvSolution_.valid())
1806  {
1807  fvSolution_ = new fvSolution(*this);
1808  }
1809 
1810  return fvSolution_;
1811 }
1812 
1813 
1814 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1815 
1816 bool Foam::fvMesh::operator!=(const fvMesh& bm) const
1817 {
1818  return &bm != this;
1819 }
1820 
1821 
1822 bool Foam::fvMesh::operator==(const fvMesh& bm) const
1823 {
1824  return &bm == this;
1825 }
1826 
1827 
1828 
1829 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
1830 
1832 {
1833  const IOobject& io = refCast<const IOobject>(dict);
1834  return refCast<const fvMesh>(io.db());
1835 }
1836 
1837 
1838 // ************************************************************************* //
#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:1473
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:932
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:938
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:986
const fvMeshDistributor & distributor() const
Return the distributor function class.
Definition: fvMesh.C:1119
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1792
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:1073
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:1101
void preChange()
Prepare for a mesh change.
Definition: fvMesh.C:1188
const fvSolution & solution() const
Return the fvSolution.
Definition: fvMesh.C:1803
void addFvPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches. Constructor helper.
Definition: fvMesh.C:758
void swap(fvMesh &)
Swap mesh.
Definition: fvMesh.C:789
const GeometricBoundaryField< label, surfaceMesh > & polyFacesBf() const
Return face-poly-face addressing.
Definition: fvMesh.C:955
bool operator==(const fvMesh &) const
Definition: fvMesh.C:1822
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:1062
bool operator!=(const fvMesh &) const
Definition: fvMesh.C:1816
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:1690
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: fvMesh.C:1395
void mapFields(const polyTopoChangeMap &map)
Map all fields in time using given map.
Definition: fvMesh.C:1131
bool update()
Update the mesh for topology change, mesh to mesh mapping.
Definition: fvMesh.C:703
void setPolyFacesBfInstance(const fileName &)
Set the instance for the poly faces boundary field.
Definition: fvMesh.C:1461
virtual void distribute(const polyDistributionMap &map)
Redistribute or update using the given distribution map.
Definition: fvMesh.C:1428
void removeFvBoundary()
Remove boundary patches. Warning: fvPatchFields hold ref to.
Definition: fvMesh.C:776
bool distributing() const
Does the mesh get redistributed?
Definition: fvMesh.C:689
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:1668
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:1507
bool dynamic() const
Is this mesh dynamic?
Definition: fvMesh.C:695
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:1113
virtual void topoChange(const polyTopoChangeMap &map)
Update mesh corresponding to the given map.
Definition: fvMesh.C:1335
bool topoChanging() const
Does the mesh topology change?
Definition: fvMesh.C:683
virtual bool writeMesh() const
Write the mesh data only.
Definition: fvMesh.C:1759
virtual void addPatch(const label insertPatchi, const polyPatch &patch)
Add/insert single patch.
Definition: fvMesh.C:1611
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:301
bool move()
Move the mesh.
Definition: fvMesh.C:743
virtual void setPoints(const pointField &)
Reset the points.
Definition: fvMesh.C:1194
const fvMeshMover & mover() const
Return the mover function class.
Definition: fvMesh.C:1125
void conform(const surfaceScalarField &phi=NullObjectRef< surfaceScalarField >())
Conform the fvMesh to the polyMesh.
Definition: fvMesh.C:1484
bool conformal() const
Return whether the fvMesh is conformal with the polyMesh.
Definition: fvMesh.C:949
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
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 time
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
const dimensionSet & dimless
Definition: dimensions.C:138
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:150
const fvMesh & region(const dictionary &dict)
Cast the give dictionary to the corresponding region fvMesh.
Definition: fvMesh.C:1831
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:142
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:149
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.