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-2025 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  if (debug)
91  {
92  Pout<< FUNCTION_NAME << "clearFvGeomNotOldVol" << endl;
93  }
94 
96  <
97  fvMesh,
98  DeletableMeshObject,
99  MoveableMeshObject
100  >(*this);
101 
103  <
104  lduMesh,
105  DeletableMeshObject,
106  MoveableMeshObject
107  >(*this);
108 
109  deleteDemandDrivenData(VPtr_);
110  deleteDemandDrivenData(SfSlicePtr_);
111  deleteDemandDrivenData(SfPtr_);
112  deleteDemandDrivenData(magSfSlicePtr_);
113  deleteDemandDrivenData(magSfPtr_);
114  deleteDemandDrivenData(CSlicePtr_);
115  deleteDemandDrivenData(CPtr_);
116  deleteDemandDrivenData(CfSlicePtr_);
117  deleteDemandDrivenData(CfPtr_);
118 }
119 
120 
121 void Foam::fvMesh::clearFvGeom()
122 {
123  if (debug)
124  {
125  Pout<< FUNCTION_NAME << "clearFvGeom" << endl;
126  }
127 
128  clearFvGeomNotOldVol();
129 
130  deleteDemandDrivenData(phiPtr_);
131  deleteDemandDrivenData(V0Ptr_);
132  deleteDemandDrivenData(V00Ptr_);
133 }
134 
135 
136 void Foam::fvMesh::updateGeomNotOldVol()
137 {
138  bool haveV = (VPtr_ != nullptr);
139  bool haveSf = (SfSlicePtr_ != nullptr || SfPtr_ != nullptr);
140  bool haveMagSf = (magSfSlicePtr_ != nullptr || magSfPtr_ != nullptr);
141  bool haveCP = (CSlicePtr_ != nullptr || CPtr_ != nullptr);
142  bool haveCf = (CfSlicePtr_ != nullptr || CfPtr_ != nullptr);
143 
144  clearFvGeomNotOldVol();
145 
146  // Now recreate the fields
147  if (haveV)
148  {
149  (void)V();
150  }
151  if (haveSf)
152  {
153  (void)Sf();
154  }
155  if (haveMagSf)
156  {
157  (void)magSf();
158  }
159  if (haveCP)
160  {
161  (void)C();
162  }
163  if (haveCf)
164  {
165  (void)Cf();
166  }
167 }
168 
169 
170 void Foam::fvMesh::storeOldTimeFields()
171 {
172  storeOldTimeFields<PointField>();
173  storeOldTimeFields<VolField>();
174  storeOldTimeFields<SurfaceField>();
175 }
176 
177 
178 void Foam::fvMesh::nullOldestTimeFields()
179 {
180  nullOldestTimeFields<PointField>();
181  nullOldestTimeFields<VolField>();
182  nullOldestTimeFields<SurfaceField>();
183 }
184 
185 
187 {
189 
190  Pout<< "fvMesh allocated :" << endl;
191 
192  if (lduPtr_)
193  {
194  Pout<< " Ldu Addressing" << endl;
195  }
196 
197  if (polyFacesBfPtr_)
198  {
199  Pout<< " Poly-faces boundary field" << endl;
200  }
201 
202  if (polyBFacePatchesPtr_)
203  {
204  Pout<< " Poly-boundary-face to fv-patch and fv-patch-face map"
205  << endl;
206  }
207 
208  if (ownerBfPtr_)
209  {
210  Pout<< " Owner boundary field" << endl;
211  }
212 
213  if (V0Ptr_)
214  {
215  Pout<< " Old-time cell volumes field" << endl;
216  }
217 
218  if (V00Ptr_)
219  {
220  Pout<< " Old-old-time cell volumes field" << endl;
221  }
222 
223  if (SfPtr_)
224  {
225  Pout<< " Non-sliced face areas field" << endl;
226  }
227 
228  if (magSfPtr_)
229  {
230  Pout<< " Non-sliced face area magnitudes field" << endl;
231  }
232 
233  if (CPtr_)
234  {
235  Pout<< " Non-sliced cell centres field" << endl;
236  }
237 
238  if (CfPtr_)
239  {
240  Pout<< " Non-sliced face centres field" << endl;
241  }
242 
243  if (phiPtr_)
244  {
245  Pout<< " Mesh flux field" << endl;
246  }
247 
249 }
250 
251 
253 {
254  if (debug)
255  {
256  Pout<< FUNCTION_NAME << "Clearing geometric data" << endl;
257  }
258 
259  clearFvGeom();
260 
262 }
263 
264 
265 void Foam::fvMesh::clearAddressing(const bool isMeshUpdate)
266 {
267  if (debug)
268  {
269  Pout<< FUNCTION_NAME << "isMeshUpdate: " << isMeshUpdate << endl;
270  }
271 
272  if (isMeshUpdate)
273  {
274  // Part of a mesh update. Keep meshObjects that have an topoChange
275  // callback
277  <
278  fvMesh,
281  >
282  (
283  *this
284  );
286  <
287  lduMesh,
290  >
291  (
292  *this
293  );
294  }
295  else
296  {
297  meshObjects::clear<fvMesh, DeletableMeshObject>(*this);
298  meshObjects::clear<lduMesh, DeletableMeshObject>(*this);
299  }
300 
301  deleteDemandDrivenData(lduPtr_);
302  deleteDemandDrivenData(polyFacesBfIOPtr_);
303  deleteDemandDrivenData(polyFacesBfPtr_);
304  deleteDemandDrivenData(polyBFaceOffsetsPtr_);
305  deleteDemandDrivenData(polyBFaceOffsetPatchesPtr_);
306  deleteDemandDrivenData(polyBFaceOffsetPatchFacesPtr_);
307  deleteDemandDrivenData(polyBFacePatchesPtr_);
308  deleteDemandDrivenData(polyBFacePatchFacesPtr_);
309  deleteDemandDrivenData(ownerBfPtr_);
310 }
311 
312 
314 {
315  clearFvGeom();
316 
318 
319  clearAddressing();
320 
322 }
323 
324 
325 Foam::wordList Foam::fvMesh::polyFacesPatchTypes() const
326 {
327  wordList wantedPatchTypes
328  (
329  boundary().size(),
331  );
332 
334  {
335  const fvPatch& fvp = boundary()[patchi];
336 
337  if (isA<nonConformalFvPatch>(fvp))
338  {
339  wantedPatchTypes[patchi] =
340  refCast<const nonConformalFvPatch>(fvp).polyFacesType();
341  }
342  }
343 
344  return wantedPatchTypes;
345 }
346 
347 
348 Foam::surfaceLabelField::Boundary& Foam::fvMesh::polyFacesBfRef()
349 {
350  if (!polyFacesBfPtr_)
351  {
352  polyFacesBf();
353  }
354 
355  setPolyFacesBfInstance(time().name());
356 
357  return *polyFacesBfPtr_;
358 }
359 
360 
361 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
362 
364 (
365  const IOobject& io,
366  const bool doPost
367  // const bool doZones
368 )
369 :
370  polyMesh(io),
371  surfaceInterpolation(*this),
372  boundary_(*this, boundaryMesh()),
373  stitcher_(nullptr),
374  topoChanger_(nullptr),
375  distributor_(nullptr),
376  mover_(nullptr),
377  lduPtr_(nullptr),
378  polyFacesBfIOPtr_(nullptr),
379  polyFacesBfPtr_(nullptr),
380  polyBFaceOffsetsPtr_(nullptr),
381  polyBFaceOffsetPatchesPtr_(nullptr),
382  polyBFaceOffsetPatchFacesPtr_(nullptr),
383  polyBFacePatchesPtr_(nullptr),
384  polyBFacePatchFacesPtr_(nullptr),
385  ownerBfPtr_(nullptr),
386  curTimeIndex_(time().timeIndex()),
387  VPtr_(nullptr),
388  V0Ptr_(nullptr),
389  V00Ptr_(nullptr),
390  SfSlicePtr_(nullptr),
391  SfPtr_(nullptr),
392  magSfSlicePtr_(nullptr),
393  magSfPtr_(nullptr),
394  CSlicePtr_(nullptr),
395  CPtr_(nullptr),
396  CfSlicePtr_(nullptr),
397  CfPtr_(nullptr),
398  phiPtr_(nullptr)
399 {
400  if (debug)
401  {
402  Pout<< FUNCTION_NAME << "Constructing fvMesh from IOobject" << endl;
403  }
404 
405  if (doPost)
406  {
408  }
409 }
410 
411 
413 (
414  const IOobject& io,
415  pointField&& points,
416  const cellShapeList& shapes,
417  const faceListList& boundaryFaces,
418  const wordList& boundaryPatchNames,
419  const PtrList<dictionary>& boundaryDicts,
420  const word& defaultBoundaryPatchName,
421  const word& defaultBoundaryPatchType,
422  const bool syncPar
423 )
424 :
425  polyMesh
426  (
427  io,
428  std::move(points),
429  shapes,
430  boundaryFaces,
431  boundaryPatchNames,
432  boundaryDicts,
433  defaultBoundaryPatchName,
434  defaultBoundaryPatchType,
435  syncPar
436  ),
437  surfaceInterpolation(*this),
438  boundary_(*this, boundaryMesh()),
439  stitcher_(nullptr),
440  topoChanger_(nullptr),
441  distributor_(nullptr),
442  mover_(nullptr),
443  lduPtr_(nullptr),
444  polyFacesBfIOPtr_(nullptr),
445  polyFacesBfPtr_(nullptr),
446  polyBFaceOffsetsPtr_(nullptr),
447  polyBFaceOffsetPatchesPtr_(nullptr),
448  polyBFaceOffsetPatchFacesPtr_(nullptr),
449  polyBFacePatchesPtr_(nullptr),
450  polyBFacePatchFacesPtr_(nullptr),
451  ownerBfPtr_(nullptr),
452  curTimeIndex_(time().timeIndex()),
453  VPtr_(nullptr),
454  V0Ptr_(nullptr),
455  V00Ptr_(nullptr),
456  SfSlicePtr_(nullptr),
457  SfPtr_(nullptr),
458  magSfSlicePtr_(nullptr),
459  magSfPtr_(nullptr),
460  CSlicePtr_(nullptr),
461  CPtr_(nullptr),
462  CfSlicePtr_(nullptr),
463  CfPtr_(nullptr),
464  phiPtr_(nullptr)
465 {
466  if (debug)
467  {
468  Pout<< FUNCTION_NAME << "Constructing fvMesh from cellShapes" << endl;
469  }
470 }
471 
472 
474 (
475  const IOobject& io,
476  pointField&& points,
477  faceList&& faces,
478  labelList&& allOwner,
479  labelList&& allNeighbour,
480  const bool syncPar
481 )
482 :
483  polyMesh
484  (
485  io,
486  std::move(points),
487  std::move(faces),
488  std::move(allOwner),
489  std::move(allNeighbour),
490  syncPar
491  ),
492  surfaceInterpolation(*this),
493  boundary_(*this, boundaryMesh()),
494  stitcher_(nullptr),
495  topoChanger_(nullptr),
496  distributor_(nullptr),
497  mover_(nullptr),
498  lduPtr_(nullptr),
499  polyFacesBfIOPtr_(nullptr),
500  polyFacesBfPtr_(nullptr),
501  polyBFaceOffsetsPtr_(nullptr),
502  polyBFaceOffsetPatchesPtr_(nullptr),
503  polyBFaceOffsetPatchFacesPtr_(nullptr),
504  polyBFacePatchesPtr_(nullptr),
505  polyBFacePatchFacesPtr_(nullptr),
506  ownerBfPtr_(nullptr),
507  curTimeIndex_(time().timeIndex()),
508  VPtr_(nullptr),
509  V0Ptr_(nullptr),
510  V00Ptr_(nullptr),
511  SfSlicePtr_(nullptr),
512  SfPtr_(nullptr),
513  magSfSlicePtr_(nullptr),
514  magSfPtr_(nullptr),
515  CSlicePtr_(nullptr),
516  CPtr_(nullptr),
517  CfSlicePtr_(nullptr),
518  CfPtr_(nullptr),
519  phiPtr_(nullptr)
520 {
521  if (debug)
522  {
523  Pout<< FUNCTION_NAME << "Constructing fvMesh from components" << endl;
524  }
525 }
526 
527 
529 (
530  const IOobject& io,
531  pointField&& points,
532  faceList&& faces,
533  cellList&& cells,
534  const bool syncPar
535 )
536 :
537  polyMesh
538  (
539  io,
540  std::move(points),
541  std::move(faces),
542  std::move(cells),
543  syncPar
544  ),
545  surfaceInterpolation(*this),
546  boundary_(*this),
547  stitcher_(nullptr),
548  topoChanger_(nullptr),
549  distributor_(nullptr),
550  mover_(nullptr),
551  lduPtr_(nullptr),
552  polyFacesBfIOPtr_(nullptr),
553  polyFacesBfPtr_(nullptr),
554  polyBFaceOffsetsPtr_(nullptr),
555  polyBFaceOffsetPatchesPtr_(nullptr),
556  polyBFaceOffsetPatchFacesPtr_(nullptr),
557  polyBFacePatchesPtr_(nullptr),
558  polyBFacePatchFacesPtr_(nullptr),
559  ownerBfPtr_(nullptr),
560  curTimeIndex_(time().timeIndex()),
561  VPtr_(nullptr),
562  V0Ptr_(nullptr),
563  V00Ptr_(nullptr),
564  SfSlicePtr_(nullptr),
565  SfPtr_(nullptr),
566  magSfSlicePtr_(nullptr),
567  magSfPtr_(nullptr),
568  CSlicePtr_(nullptr),
569  CPtr_(nullptr),
570  CfSlicePtr_(nullptr),
571  CfPtr_(nullptr),
572  phiPtr_(nullptr)
573 {
574  if (debug)
575  {
576  Pout<< FUNCTION_NAME << "Constructing fvMesh from components" << endl;
577  }
578 }
579 
580 
582 :
583  polyMesh(Foam::move(mesh)),
585  boundary_(Foam::move(mesh.boundary_)),
586  stitcher_(Foam::move(mesh.stitcher_)),
587  topoChanger_(Foam::move(mesh.topoChanger_)),
588  distributor_(Foam::move(mesh.distributor_)),
589  mover_(Foam::move(mesh.mover_)),
590  lduPtr_(Foam::move(mesh.lduPtr_)),
591  polyFacesBfIOPtr_(Foam::move(mesh.polyFacesBfIOPtr_)),
592  polyFacesBfPtr_(Foam::move(mesh.polyFacesBfPtr_)),
593  polyBFaceOffsetsPtr_(Foam::move(mesh.polyBFaceOffsetsPtr_)),
594  polyBFaceOffsetPatchesPtr_(Foam::move(mesh.polyBFaceOffsetPatchesPtr_)),
595  polyBFaceOffsetPatchFacesPtr_
596  (
597  Foam::move(mesh.polyBFaceOffsetPatchFacesPtr_)
598  ),
599  polyBFacePatchesPtr_(Foam::move(mesh.polyBFacePatchesPtr_)),
600  polyBFacePatchFacesPtr_(Foam::move(mesh.polyBFacePatchFacesPtr_)),
601  ownerBfPtr_(Foam::move(mesh.ownerBfPtr_)),
602  curTimeIndex_(mesh.curTimeIndex_),
603  VPtr_(Foam::move(mesh.VPtr_)),
604  V0Ptr_(Foam::move(mesh.V0Ptr_)),
605  V00Ptr_(Foam::move(mesh.V00Ptr_)),
606  SfSlicePtr_(Foam::move(mesh.SfSlicePtr_)),
607  SfPtr_(Foam::move(mesh.SfPtr_)),
608  magSfSlicePtr_(Foam::move(mesh.magSfSlicePtr_)),
609  magSfPtr_(Foam::move(mesh.magSfPtr_)),
610  CSlicePtr_(Foam::move(mesh.CSlicePtr_)),
611  CPtr_(Foam::move(mesh.CPtr_)),
612  CfSlicePtr_(Foam::move(mesh.CfSlicePtr_)),
613  CfPtr_(Foam::move(mesh.CfPtr_)),
614  phiPtr_(Foam::move(mesh.phiPtr_))
615 {
616  if (debug)
617  {
618  Pout<< FUNCTION_NAME << "Moving fvMesh" << endl;
619  }
620 }
621 
622 
623 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
624 
626 {
627  clearOut();
628 }
629 
630 
631 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
632 
634 (
635  const bool changers,
636  const bool zones,
637  const stitchType stitch
638 )
639 {
640  // Construct the stitcher
641  stitcher_.set(fvMeshStitcher::New(*this, changers).ptr());
642 
643  // Stitch or Re-stitch if necessary
644  if (stitch != stitchType::none)
645  {
646  stitcher_->connect(false, stitch == stitchType::geometric, true);
647  }
648 
649  // Construct changers
650  if (changers)
651  {
652  topoChanger_.set(fvMeshTopoChanger::New(*this).ptr());
653  distributor_.set(fvMeshDistributor::New(*this).ptr());
654  mover_.set(fvMeshMover::New(*this).ptr());
655 
656  // Check the existence of the cell volumes and read if present
657  // and set the storage of V00
658  if (fileHandler().isFile(time().timePath()/"Vc0"))
659  {
661  (
662  IOobject
663  (
664  "Vc0",
665  time().name(),
666  *this,
669  true
670  ),
671  *this
672  );
673 
674  V00();
675  }
676 
677  // Check the existence of the mesh fluxes and read if present
678  if (fileHandler().isFile(time().timePath()/"meshPhi"))
679  {
680  phiPtr_ = new surfaceScalarField
681  (
682  IOobject
683  (
684  "meshPhi",
685  time().name(),
686  *this,
689  true
690  ),
691  *this
692  );
693  }
694  }
695 
696  // Generate the zones after the mesh manipulators have been constructed
697  // to support motion-specific zone generators requiring access to the mover
698  if (zones)
699  {
700  zonesGenerator::New(*this);
701  }
702 }
703 
704 
706 {
707  return topoChanger_.valid() && topoChanger_->dynamic();
708 }
709 
710 
712 {
713  return distributor_.valid() && distributor_->dynamic();
714 }
715 
716 
718 {
719  return
720  (topoChanger_.valid() && topoChanger_->dynamic())
721  || (mover_.valid() && mover_->dynamic());
722 }
723 
724 
726 {
727  if
728  (
729  stitcher_->stitches()
730  || topoChanger_->dynamic()
731  || distributor_->dynamic()
732  )
733  {
735  }
736 
737  // Remove the oldest cell volume field
738  if (V00Ptr_)
739  {
740  nullDemandDrivenData(V00Ptr_);
741  }
742  else
743  {
744  nullDemandDrivenData(V0Ptr_);
745  }
746 
747  // Remove the oldest mesh flux field
748  if (phiPtr_)
749  {
750  phiPtr_->nullOldestTime();
751  }
752 
753  // Set topoChanged_ false before any mesh change. Topo-changing can switch
754  // on and off during a run.
755  topoChanged_ = false;
756 
757  topoChanged_ = topoChanger_->update();
758 
759  const bool distributed = distributor_->update();
760 
761  return topoChanged_ || distributed;
762 }
763 
764 
766 {
767  // Do not set moving_ false before any mesh motion. Once the mesh starts
768  // moving it is considered to be moving for the rest of the run.
769  const bool moved = mover_->update();
770 
771  curTimeIndex_ = time().timeIndex();
772 
773  stitcher_->connect(true, true, false);
774 
775  return moved;
776 }
777 
778 
780 (
781  const List<polyPatch*>& p,
782  const bool validBoundary
783 )
784 {
785  if (boundary().size())
786  {
788  << " boundary already exists"
789  << abort(FatalError);
790  }
791 
792  // first add polyPatches
793  addPatches(p, validBoundary);
794  boundary_.addPatches(boundaryMesh());
795 }
796 
797 
799 {
800  if (debug)
801  {
802  Pout<< FUNCTION_NAME << "Removing boundary patches." << endl;
803  }
804 
805  // Remove fvBoundaryMesh data first.
806  boundary_.clear();
807  boundary_.setSize(0);
809 
810  clearOut();
811 }
812 
813 
814 void Foam::fvMesh::swap(fvMesh& otherMesh)
815 {
816  // Clear the sliced fields
817  clearFvGeom();
818 
819  // Clear the current volume and other geometry factors
821 
822  // Clear any non-updateable addressing
823  clearAddressing(true);
824 
825  polyMesh::swap(otherMesh);
826 
827  auto updatePatches = []
828  (
829  const polyPatchList& patches,
830  fvBoundaryMesh& boundaryMesh
831  )
832  {
833  boundaryMesh.setSize(patches.size());
834 
836  {
837  // Construct new processor patches, as the decomposition may have
838  // changed. Leave other patches as is.
839 
840  if (isA<processorPolyPatch>(patches[patchi]))
841  {
842  boundaryMesh.set
843  (
844  patchi,
846  (
847  patches[patchi],
848  boundaryMesh
849  )
850  );
851  }
852  }
853  };
854 
855  updatePatches(boundaryMesh(), boundary_);
856  updatePatches(otherMesh.boundaryMesh(), otherMesh.boundary_);
857 }
858 
859 
861 (
862  const stitchType stitch
863 )
864 {
865  if (debug)
866  {
867  Pout<< FUNCTION_NAME << "Updating fvMesh. ";
868  }
869 
871 
872  const fileName polyFacesInst =
873  time().findInstance
874  (
875  dbDir()/typeName,
876  "polyFaces",
878  );
879 
880  const bool reStitch =
881  stitcher_.valid()
882  && stitcher_->stitches()
883  && stitch != stitchType::none
884  && (!conformal() || polyFacesInst != polyFacesBfIOPtr_->instance());
885 
886  if (reStitch)
887  {
888  stitcher_->disconnect(false, false);
889  }
890  else if (state != polyMesh::UNCHANGED)
891  {
892  conform();
893  }
894 
895  if (state == polyMesh::TOPO_PATCH_CHANGE)
896  {
897  boundary_.readUpdate(boundaryMesh());
898  }
899 
900  if (state == polyMesh::TOPO_PATCH_CHANGE)
901  {
902  if (debug)
903  {
904  Info<< "Boundary and topological update" << endl;
905  }
906 
907  clearOut();
908  }
909  else if (state == polyMesh::TOPO_CHANGE)
910  {
911  if (debug)
912  {
913  Info<< "Topological update" << endl;
914  }
915 
916  clearOut();
917  }
918  else if (state == polyMesh::POINTS_MOVED)
919  {
920  if (debug)
921  {
922  Info<< "Point motion update" << endl;
923  }
924 
925  clearFvGeom();
926  }
927  else
928  {
929  if (debug)
930  {
931  Info<< "No update" << endl;
932  }
933  }
934 
935  if (reStitch && stitch != stitchType::none)
936  {
937  stitcher_->connect(false, stitch == stitchType::geometric, true);
938  }
939 
940  // Return the corresponding fvMesh read update state
941  switch (state)
942  {
943  case polyMesh::UNCHANGED:
944  return reStitch ? STITCHED : UNCHANGED;
946  return reStitch ? STITCHED : POINTS_MOVED;
948  return TOPO_CHANGE;
950  return TOPO_PATCH_CHANGE;
951  }
952 
953  return UNCHANGED;
954 }
955 
956 
958 {
959  return boundary_;
960 }
961 
962 
964 {
965  if (!lduPtr_)
966  {
967  lduPtr_ = new fvMeshLduAddressing(*this);
968  }
969 
970  return *lduPtr_;
971 }
972 
973 
975 {
976  return !(polyFacesBfPtr_ && SfPtr_);
977 }
978 
979 
981 {
982  if (!polyFacesBfPtr_)
983  {
984  polyFacesBfIOPtr_ =
985  new IOobject
986  (
987  "polyFaces",
988  facesInstance(),
989  typeName,
990  *this,
993  false
994  );
995 
996  polyFacesBfPtr_ =
998  (
999  boundary(),
1001  polyFacesPatchTypes(),
1002  boundaryMesh().types()
1003  );
1004  }
1005 
1006  return *polyFacesBfPtr_;
1007 }
1008 
1009 
1012 {
1013  if (!polyBFacePatchesPtr_)
1014  {
1015  const label nPolyBFaces = nFaces() - nInternalFaces();
1016 
1017  // Count face-poly-bFaces to get the offsets
1018  polyBFaceOffsetsPtr_ = new labelList(nPolyBFaces + 1, 0);
1019  labelList& offsets = *polyBFaceOffsetsPtr_;
1020  forAll(boundary(), patchi)
1021  {
1022  forAll(boundary()[patchi], patchFacei)
1023  {
1024  const label polyBFacei =
1025  (
1026  polyFacesBfPtr_
1027  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1028  : boundary()[patchi].start() + patchFacei
1029  )
1030  - nInternalFaces();
1031 
1032  offsets[polyBFacei + 1] ++;
1033  }
1034  }
1035  for (label polyBFacei = 0; polyBFacei < nPolyBFaces; ++ polyBFacei)
1036  {
1037  offsets[polyBFacei + 1] += offsets[polyBFacei];
1038  }
1039 
1040  // Set the poly-bFace patches and patch-faces, using the offsets as
1041  // counters
1042  polyBFaceOffsetPatchesPtr_ = new labelList(offsets.last());
1043  polyBFaceOffsetPatchFacesPtr_ = new labelList(offsets.last());
1044  labelUList& patches = *polyBFaceOffsetPatchesPtr_;
1045  labelUList& patchFaces = *polyBFaceOffsetPatchFacesPtr_;
1046  forAll(boundary(), patchi)
1047  {
1048  forAll(boundary()[patchi], patchFacei)
1049  {
1050  const label polyBFacei =
1051  (
1052  polyFacesBfPtr_
1053  ? (*polyFacesBfPtr_)[patchi][patchFacei]
1054  : boundary()[patchi].start() + patchFacei
1055  )
1056  - nInternalFaces();
1057  patches[offsets[polyBFacei]] = patchi;
1058  patchFaces[offsets[polyBFacei]] = patchFacei;
1059  offsets[polyBFacei] ++;
1060  }
1061  }
1062 
1063  // Restore the offsets by removing the count
1064  for
1065  (
1066  label polyBFacei = nPolyBFaces - 1;
1067  polyBFacei >= 0;
1068  -- polyBFacei
1069  )
1070  {
1071  offsets[polyBFacei + 1] = offsets[polyBFacei];
1072  }
1073  offsets[0] = 0;
1074 
1075  // List-lists
1076  polyBFacePatchesPtr_ =
1077  new UCompactListList<label>(offsets, patches);
1078  polyBFacePatchFacesPtr_ =
1079  new UCompactListList<label>(offsets, patchFaces);
1080  }
1081 
1082  return *polyBFacePatchesPtr_;
1083 }
1084 
1085 
1088 {
1089  if (!polyBFacePatchFacesPtr_)
1090  {
1091  polyBFacePatches();
1092  }
1093 
1094  return *polyBFacePatchFacesPtr_;
1095 }
1096 
1097 
1099 {
1100  if (!ownerBfPtr_)
1101  {
1102  ownerBfPtr_ =
1104  (
1105  boundary(),
1107  wordList
1108  (
1109  boundary().size(),
1110  calculatedFvsPatchLabelField::typeName
1111  ),
1112  boundaryMesh().types()
1113  );
1114 
1115  forAll(boundary(), patchi)
1116  {
1117  (*ownerBfPtr_)[patchi] =
1118  labelField(faceOwner(), polyFacesBf()[patchi]);
1119  }
1120  }
1121 
1122  return *ownerBfPtr_;
1123 }
1124 
1125 
1127 {
1128  return stitcher_();
1129 }
1130 
1131 
1133 {
1134  return stitcher_();
1135 }
1136 
1137 
1139 {
1140  return topoChanger_();
1141 }
1142 
1143 
1145 {
1146  return distributor_();
1147 }
1148 
1149 
1151 {
1152  return mover_();
1153 }
1154 
1155 
1157 {
1158  if (debug)
1159  {
1161  << " nOldCells:" << map.nOldCells()
1162  << " nCells:" << nCells()
1163  << " nOldFaces:" << map.nOldFaces()
1164  << " nFaces:" << nFaces()
1165  << endl;
1166  }
1167 
1168 
1169  // We require geometric properties valid for the old mesh
1170  if
1171  (
1172  map.cellMap().size() != nCells()
1173  || map.faceMap().size() != nFaces()
1174  )
1175  {
1177  << "polyTopoChangeMap does not correspond to the old mesh."
1178  << " nCells:" << nCells()
1179  << " cellMap:" << map.cellMap().size()
1180  << " nOldCells:" << map.nOldCells()
1181  << " nFaces:" << nFaces()
1182  << " faceMap:" << map.faceMap().size()
1183  << " nOldFaces:" << map.nOldFaces()
1184  << exit(FatalError);
1185  }
1186 
1187  // Create a fv mapper
1188  const fvMeshMapper fvMap(*this, map);
1189 
1190  // Map all the volFields in the objectRegistry
1191  #define mapVolFieldType(Type, nullArg) \
1192  MapGeometricFields<Type, fvMeshMapper, volMesh>(fvMap);
1194 
1195  // Map all the surfaceFields in the objectRegistry
1196  #define mapSurfaceFieldType(Type, nullArg) \
1197  MapGeometricFields<Type, fvMeshMapper, surfaceMesh>(fvMap);
1199 
1200  // Map all the dimensionedFields in the objectRegistry
1201  #define mapVolInternalFieldType(Type, nullArg) \
1202  MapDimensionedFields<Type, fvMeshMapper, volMesh>(fvMap);
1204 
1205  if (pointMesh::found(*this))
1206  {
1207  // Create the pointMesh mapper
1208  const pointMeshMapper mapper(pointMesh::New(*this), map);
1209 
1210  #define mapPointFieldType(Type, nullArg) \
1211  MapGeometricFields<Type, pointMeshMapper, pointMesh>(mapper);
1213  }
1214 }
1215 
1216 
1218 {
1219  stitcher_->disconnect(true, true);
1220 }
1221 
1222 
1224 {
1226 
1227  clearFvGeom();
1228 
1229  // Update other local data
1231 
1232  meshObjects::movePoints<fvMesh>(*this);
1233  meshObjects::movePoints<lduMesh>(*this);
1234 
1235  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1236 }
1237 
1238 
1240 {
1241  preChange();
1242 
1243  // Set the mesh to be moving. This remains true for the rest of the run.
1244  moving_ = true;
1245 
1246  // Create old-time volumes, if necessary, at the start of a new timestep
1247  if (curTimeIndex_ < time().timeIndex())
1248  {
1249  if (V00Ptr_ && notNull(V00Ptr_))
1250  {
1252  << "Old-old volumes should not be maintained across mesh "
1253  << "changes" << exit(FatalError);
1254  }
1255 
1256  // If old-old-volumes are necessary then copy them from the old-volumes
1257  if (Foam::isNull(V00Ptr_))
1258  {
1259  V00Ptr_ = new DimensionedField<scalar, volMesh>
1260  (
1261  IOobject
1262  (
1263  "Vc00",
1264  time().name(),
1265  *this,
1268  true
1269  ),
1270  V0()
1271  );
1272  }
1273 
1274  // Copy old-volumes from the volumes
1275  if (!V0Ptr_ || Foam::isNull(V0Ptr_))
1276  {
1278  (
1279  IOobject
1280  (
1281  "Vc0",
1282  time().name(),
1283  *this,
1286  true
1287  ),
1288  V()
1289  );
1290  }
1291  else
1292  {
1293  V0Ptr_->scalarField::operator=(V());
1294  }
1295  }
1296 
1297  // Create mesh motion flux, if necessary
1298  if (!phiPtr_)
1299  {
1300  phiPtr_ = new surfaceScalarField
1301  (
1302  IOobject
1303  (
1304  "meshPhi",
1305  this->time().name(),
1306  *this,
1309  true
1310  ),
1311  *this,
1313  );
1314  }
1315  else
1316  {
1317  phiPtr_->storeOldTimes();
1318  }
1319 
1320  surfaceScalarField& phi = *phiPtr_;
1321 
1322  // Move the polyMesh and set the mesh motion fluxes to the swept-volumes
1323 
1324  scalar rDeltaT = 1.0/time().deltaTValue();
1325 
1326  tmp<scalarField> tsweptVols = polyMesh::movePoints(p);
1327 
1328  scalarField& sweptVols = tsweptVols.ref();
1329 
1330  phi.primitiveFieldRef() =
1331  scalarField::subField(sweptVols, nInternalFaces());
1332  phi.primitiveFieldRef() *= rDeltaT;
1333 
1334  const fvPatchList& patches = boundary();
1335 
1337 
1339  {
1340  phibf[patchi] = patches[patchi].patchSlice(sweptVols);
1341  phibf[patchi] *= rDeltaT;
1342  }
1343 
1344  // Update or delete the local geometric properties as early as possible so
1345  // they can be used if necessary. These get recreated here instead of
1346  // demand driven since they might do parallel transfers which can conflict
1347  // with when they're actually being used.
1348  // Note that between above "polyMesh::movePoints(p)" and here nothing
1349  // should use the local geometric properties.
1350  updateGeomNotOldVol();
1351 
1352  // Update other local data
1354 
1355  meshObjects::movePoints<fvMesh>(*this);
1356  meshObjects::movePoints<lduMesh>(*this);
1357 
1358  const_cast<Time&>(time()).functionObjects().movePoints(*this);
1359 
1360  return tsweptVols;
1361 }
1362 
1363 
1365 {
1366  if (!conformal())
1367  {
1369  << "The mesh was not disconnected prior to topology change"
1370  << exit(FatalError);
1371  }
1372 
1373  // Update polyMesh. This needs to keep volume existent!
1374  polyMesh::topoChange(map);
1375 
1376  // Clear the sliced fields
1377  clearFvGeomNotOldVol();
1378 
1379  // Check that we're not trying to maintain old-time mesh geometry
1380  if (V0Ptr_ && Foam::notNull(V0Ptr_))
1381  {
1383  << "It is not possible to use mesh motion, topology change, and "
1384  << "second order time schemes simultaneously"
1385  << exit(FatalError);
1386  }
1387 
1388  // Map all fields
1389  mapFields(map);
1390 
1391  // Clear the current volume and other geometry factors
1393 
1394  // Clear any non-updateable addressing
1395  clearAddressing(true);
1396 
1397  meshObjects::topoChange<fvMesh>(*this, map);
1398  meshObjects::topoChange<lduMesh>(*this, map);
1399 
1400  const_cast<Time&>(time()).functionObjects().topoChange(map);
1401 
1402  if (stitcher_.valid())
1403  {
1404  stitcher_->topoChange(map);
1405  }
1406 
1407  if (topoChanger_.valid())
1408  {
1409  topoChanger_->topoChange(map);
1410  }
1411 
1412  if (distributor_.valid())
1413  {
1414  distributor_->topoChange(map);
1415  }
1416 
1417  if (mover_.valid())
1418  {
1419  mover_->topoChange(map);
1420  }
1421 }
1422 
1423 
1425 {
1426  if (!conformal())
1427  {
1429  << "The mesh was not disconnected prior to mesh-to-mesh mapping"
1430  << exit(FatalError);
1431  }
1432 
1433  // Distribute polyMesh data
1434  polyMesh::mapMesh(map);
1435 
1436  // Clear the sliced fields
1437  clearFvGeomNotOldVol();
1438 
1439  // Clear the current volume and other geometry factors
1441 
1442  // Clear any non-updateable addressing
1443  clearAddressing(true);
1444 
1445  meshObjects::mapMesh<fvMesh>(*this, map);
1446  meshObjects::mapMesh<lduMesh>(*this, map);
1447 
1448  const_cast<Time&>(time()).functionObjects().mapMesh(map);
1449 
1450  stitcher_->mapMesh(map);
1451  topoChanger_->mapMesh(map);
1452  distributor_->mapMesh(map);
1453  mover_->mapMesh(map);
1454 }
1455 
1456 
1458 {
1459  if (!conformal())
1460  {
1462  << "The mesh was not disconnected prior to distribution"
1463  << exit(FatalError);
1464  }
1465 
1466  // Distribute polyMesh data
1467  polyMesh::distribute(map);
1468 
1469  // Clear the sliced fields
1470  clearFvGeomNotOldVol();
1471 
1472  // Clear the current volume and other geometry factors
1474 
1475  // Clear any non-updateable addressing
1476  clearAddressing(true);
1477 
1478  meshObjects::distribute<fvMesh>(*this, map);
1479  meshObjects::distribute<lduMesh>(*this, map);
1480 
1481  const_cast<Time&>(time()).functionObjects().distribute(map);
1482 
1483  stitcher_->distribute(map);
1484  topoChanger_->distribute(map);
1485  distributor_->distribute(map);
1486  mover_->distribute(map);
1487 }
1488 
1489 
1491 {
1492  if (!polyFacesBfPtr_)
1493  {
1494  return;
1495  }
1496 
1497  polyFacesBfIOPtr_->instance() = inst;
1498  polyFacesBfIOPtr_->writeOpt() = IOobject::AUTO_WRITE;
1499 }
1500 
1501 
1503 {
1504  if (!polyFacesBfPtr_)
1505  {
1506  return facesInstance();
1507  }
1508 
1509  return polyFacesBfIOPtr_->instance();
1510 }
1511 
1512 
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  // Modify the mesh fluxes, if necessary
1525  if (notNull(phi) && phiPtr_)
1526  {
1527  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1528  {
1529  phiRef().oldTimeRef(i) == phi.oldTime(i);
1530  }
1531  }
1532 }
1533 
1534 
1536 (
1537  const surfaceLabelField::Boundary& polyFacesBf,
1538  const surfaceVectorField& Sf,
1539  const surfaceVectorField& Cf,
1540  const surfaceScalarField& phi,
1541  const bool sync
1542 )
1543 {
1544  // Clear the geometry fields
1545  clearFvGeomNotOldVol();
1546 
1547  // Clear the current volume and other geometry factors
1549 
1550  // Clear any non-updateable addressing
1551  clearAddressing(true);
1552 
1553  // Create non-sliced copies of geometry fields
1554  SfRef();
1555  magSfRef();
1556  CRef();
1557  CfRef();
1558 
1559  // Set the topology
1560  forAll(polyFacesBf, patchi)
1561  {
1562  polyFacesBfRef()[patchi].reset(polyFacesBf[patchi]);
1563  }
1564 
1565  // Set the face geometry
1566  SfRef() == Sf;
1567  magSfRef() == max(mag(Sf), dimensionedScalar(dimArea, rootVSmall));
1568  CRef().boundaryFieldRef() == Cf.boundaryField();
1569  CfRef() == Cf;
1570 
1571  // Communicate processor-coupled cell geometry. Cell-centre processor patch
1572  // fields must contain the (transformed) cell-centre locations on the other
1573  // side of the coupling. This is so that non-conformal patches can
1574  // construct weights and deltas without reference to the poly mesh
1575  // geometry.
1576  //
1577  // Note that the initEvaluate/evaluate communication does a transformation,
1578  // but it is wrong in this instance. A vector field gets transformed as if
1579  // it were a displacement, but the cell-centres need a positional
1580  // transformation. That's why there's the un-transform and re-transform bit
1581  // below just after the evaluate call.
1582  //
1583  // This transform handling is a bit of a hack. It would be nicer to have a
1584  // field attribute which identifies a field as needing a positional
1585  // transformation, and for it to apply automatically within the coupled
1586  // patch field. However, at the moment, the cell centres field is the only
1587  // vol-field containing an absolute position, so the hack is functionally
1588  // sufficient for now.
1589  if (sync && (Pstream::parRun() || !time().processorCase()))
1590  {
1591  volVectorField::Boundary& CBf = CRef().boundaryFieldRef();
1592 
1593  const label nReq = Pstream::nRequests();
1594 
1595  forAll(CBf, patchi)
1596  {
1597  if (isA<processorFvPatch>(CBf[patchi].patch()))
1598  {
1599  CBf[patchi].initEvaluate(Pstream::defaultCommsType);
1600  }
1601  }
1602 
1603  if
1604  (
1605  Pstream::parRun()
1607  )
1608  {
1609  Pstream::waitRequests(nReq);
1610  }
1611 
1612  forAll(CBf, patchi)
1613  {
1614  if (isA<processorFvPatch>(CBf[patchi].patch()))
1615  {
1617 
1618  const transformer& t =
1619  refCast<const processorFvPatch>(CBf[patchi].patch())
1620  .transform();
1621 
1622  t.invTransform(CBf[patchi], CBf[patchi]);
1623  t.transformPosition(CBf[patchi], CBf[patchi]);
1624  }
1625  }
1626  }
1627 
1628  // Modify the mesh fluxes, if necessary
1629  if (notNull(phi) && phiPtr_)
1630  {
1631  for (label i = 0; i <= phi.nOldTimes(); ++ i)
1632  {
1633  phiRef().oldTimeRef(i) == phi.oldTime(i);
1634  }
1635  }
1636 }
1637 
1638 
1640 (
1641  const label insertPatchi,
1642  const polyPatch& patch
1643 )
1644 {
1645  // Remove my local data (see topoChange)
1646  // Clear mesh motion flux
1647  deleteDemandDrivenData(phiPtr_);
1648 
1649  // Clear the sliced fields
1650  clearFvGeomNotOldVol();
1651 
1652  // Clear the current volume and other geometry factors
1654 
1655  // Clear any non-updateable addressing
1656  clearAddressing(true);
1657 
1658  const label boundarySize0 = boundary_.size();
1659 
1660  polyMesh::addPatch(insertPatchi, patch);
1661 
1662  boundary_.setSize(boundarySize0 + 1);
1663  boundary_.set
1664  (
1665  insertPatchi,
1666  fvPatch::New
1667  (
1668  boundaryMesh()[insertPatchi],
1669  boundary_
1670  )
1671  );
1672 
1673  #define AddPatchFieldsType(Type, FieldType, DefaultPatchFieldType) \
1674  AddPatchFields<FieldType<Type>> \
1675  ( \
1676  const_cast<objectRegistry&>(thisDb()), \
1677  insertPatchi, \
1678  DefaultPatchFieldType \
1679  );
1681  (
1683  VolField,
1685  );
1687  (
1689  SurfaceField,
1691  );
1692  #undef AddPatchFieldsType
1693 }
1694 
1695 
1697 (
1698  const labelUList& newToOld,
1699  const bool validBoundary
1700 )
1701 {
1702  polyMesh::reorderPatches(newToOld, validBoundary);
1703 
1704  boundary_.shuffle(newToOld, validBoundary);
1705 
1706  #define ReorderPatchFieldsType(Type, FieldType) \
1707  ReorderPatchFields<FieldType<Type>> \
1708  ( \
1709  const_cast<objectRegistry&>(thisDb()), \
1710  newToOld \
1711  );
1714  #undef ReorderPatchFieldsType
1715 }
1716 
1717 
1719 (
1723  const bool write
1724 ) const
1725 {
1726  bool ok = true;
1727 
1728  if (!conformal() && polyFacesBfIOPtr_->writeOpt() == IOobject::AUTO_WRITE)
1729  {
1730  // Create a full surface field with the polyFacesBf boundary field to
1731  // write to disk. Make the internal field uniform to save disk space.
1732 
1733  surfaceLabelField polyFaces
1734  (
1735  *polyFacesBfIOPtr_,
1736  *this,
1737  dimless,
1738  labelField(nInternalFaces(), -1),
1739  *polyFacesBfPtr_
1740  );
1741 
1742  ok = ok & polyFaces.write(write);
1743  }
1744 
1745  if (phiPtr_)
1746  {
1747  ok = ok && phiPtr_->write(write);
1748  }
1749 
1750  // Write V0 only if V00 exists
1751  if (V00Ptr_)
1752  {
1753  ok = ok && V0Ptr_->write(write);
1754  }
1755 
1756  if (stitcher_.valid())
1757  {
1758  stitcher_->write(write);
1759  }
1760 
1761  if (topoChanger_.valid())
1762  {
1763  topoChanger_->write(write);
1764  }
1765 
1766  if (distributor_.valid())
1767  {
1768  distributor_->write(write);
1769  }
1770 
1771  if (mover_.valid())
1772  {
1773  mover_->write(write);
1774  }
1775 
1776  return ok && polyMesh::writeObject(fmt, ver, cmp, write);
1777 }
1778 
1779 
1780 bool Foam::fvMesh::write(const bool write) const
1781 {
1782  return polyMesh::write(write);
1783 }
1784 
1785 
1786 template<>
1788 Foam::fvMesh::validComponents<Foam::sphericalTensor>() const
1789 {
1791 }
1792 
1793 
1795 {
1796  if (!fvSchemes_.valid())
1797  {
1798  fvSchemes_ = new fvSchemes(*this);
1799  }
1800 
1801  return fvSchemes_;
1802 }
1803 
1804 
1806 {
1807  if (!fvSolution_.valid())
1808  {
1809  fvSolution_ = new fvSolution(*this);
1810  }
1811 
1812  return fvSolution_;
1813 }
1814 
1815 
1816 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1817 
1818 bool Foam::fvMesh::operator!=(const fvMesh& bm) const
1819 {
1820  return &bm != this;
1821 }
1822 
1823 
1824 bool Foam::fvMesh::operator==(const fvMesh& bm) const
1825 {
1826  return &bm == this;
1827 }
1828 
1829 
1830 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
MeshObject types:
Definition: MeshObjects.H:67
static bool found(const word &name, const polyMesh &mesh)
Return true if the DemandDrivenMeshObject with the given name.
static pointMesh & 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
Version number type.
Definition: IOstream.H:97
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:87
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.
static autoPtr< dictionary > New(Istream &)
Construct top-level dictionary on freestore from Istream.
Definition: dictionaryIO.C:103
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
static bool valid(char)
Is this character valid for a fileName?
Definition: fileNameI.H:102
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:96
static const HashSet< word > curGeometryFields
Set of names of registered current-time geometric fields.
Definition: fvMesh.H:326
const fileName & polyFacesBfInstance() const
Get the current instance for the poly faces boundary field.
Definition: fvMesh.C:1502
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:957
stitchType
Extent to which to stitch on read and readUpdate. By default, a.
Definition: fvMesh.H:120
void postConstruct(const bool changers, const bool zones, const stitchType stitch)
Complete construction of the mesh.
Definition: fvMesh.C:634
virtual const lduAddressing & lduAddr() const
Return ldu addressing.
Definition: fvMesh.C:963
const UCompactListList< label > & polyBFacePatches() const
Return poly-bFace-patch addressing.
Definition: fvMesh.C:1011
const fvMeshDistributor & distributor() const
Return the distributor function class.
Definition: fvMesh.C:1144
const fvSchemes & schemes() const
Return the fvSchemes.
Definition: fvMesh.C:1794
void clearGeom()
Clear geometry.
Definition: fvMesh.C:252
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: fvMesh.H:105
virtual ~fvMesh()
Destructor.
Definition: fvMesh.C:625
const GeometricBoundaryField< label, surfaceMesh > & ownerBf() const
Return face-owner addressing.
Definition: fvMesh.C:1098
static const HashSet< word > geometryFields
Set of names of registered geometric fields.
Definition: fvMesh.H:322
const fvMeshStitcher & stitcher() const
Return the stitcher function class.
Definition: fvMesh.C:1126
void preChange()
Prepare for a mesh change.
Definition: fvMesh.C:1217
const fvSolution & solution() const
Return the fvSolution.
Definition: fvMesh.C:1805
void addFvPatches(const List< polyPatch * > &, const bool validBoundary=true)
Add boundary patches. Constructor helper.
Definition: fvMesh.C:780
void swap(fvMesh &)
Swap mesh.
Definition: fvMesh.C:814
const GeometricBoundaryField< label, surfaceMesh > & polyFacesBf() const
Return face-poly-face addressing.
Definition: fvMesh.C:980
bool operator==(const fvMesh &) const
Definition: fvMesh.C:1824
const UCompactListList< label > & polyBFacePatchFaces() const
Return poly-bFace-patch-face addressing.
Definition: fvMesh.C:1087
bool operator!=(const fvMesh &) const
Definition: fvMesh.C:1818
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write the underlying polyMesh and other data.
Definition: fvMesh.C:1719
virtual void mapMesh(const polyMeshMap &)
Update from another mesh using the given map.
Definition: fvMesh.C:1424
void mapFields(const polyTopoChangeMap &map)
Map all fields in time using given map.
Definition: fvMesh.C:1156
virtual bool write(const bool write=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:1780
bool update()
Update the mesh for topology change, mesh to mesh mapping.
Definition: fvMesh.C:725
void setPolyFacesBfInstance(const fileName &)
Set the instance for the poly faces boundary field.
Definition: fvMesh.C:1490
virtual void distribute(const polyDistributionMap &map)
Redistribute or update using the given distribution map.
Definition: fvMesh.C:1457
void removeFvBoundary()
Remove boundary patches. Warning: fvPatchFields hold ref to.
Definition: fvMesh.C:798
bool distributing() const
Does the mesh get redistributed?
Definition: fvMesh.C:711
void printAllocated() const
Print a list of all the currently allocated mesh data.
Definition: fvMesh.C:186
virtual void reorderPatches(const labelUList &newToOld, const bool validBoundary)
Reorder and trim existing patches. If validBoundary the new.
Definition: fvMesh.C:1697
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:1536
bool dynamic() const
Is this mesh dynamic?
Definition: fvMesh.C:717
fvMesh(const IOobject &io, const bool doPost=true)
Construct from IOobject.
Definition: fvMesh.C:364
const fvMeshTopoChanger & topoChanger() const
Return the topo-changer function class.
Definition: fvMesh.C:1138
virtual void topoChange(const polyTopoChangeMap &map)
Update mesh corresponding to the given map.
Definition: fvMesh.C:1364
bool topoChanging() const
Does the mesh topology change?
Definition: fvMesh.C:705
virtual void addPatch(const label insertPatchi, const polyPatch &patch)
Add/insert single patch.
Definition: fvMesh.C:1640
void clearOut()
Clear all geometry and addressing.
Definition: fvMesh.C:313
bool move()
Move the mesh.
Definition: fvMesh.C:765
virtual void setPoints(const pointField &)
Reset the points.
Definition: fvMesh.C:1223
const fvMeshMover & mover() const
Return the mover function class.
Definition: fvMesh.C:1150
void conform(const surfaceScalarField &phi=NullObjectRef< surfaceScalarField >())
Conform the fvMesh to the polyMesh.
Definition: fvMesh.C:1513
bool conformal() const
Return whether the fvMesh is conformal with the polyMesh.
Definition: fvMesh.C:974
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:64
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
virtual tmp< scalarField > movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
Definition: polyMesh.C:1418
void clearGeom()
Clear geometry.
Definition: polyMeshClear.C:64
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:815
virtual bool writeObject(IOstream::streamFormat fmt, IOstream::versionNumber ver, IOstream::compressionType cmp, const bool write=true) const
Write the underlying polyMesh.
Definition: polyMeshIO.C:526
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:124
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:382
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:51
void removeBoundary()
Remove boundary patches.
Definition: polyMeshClear.C:34
virtual void reorderPatches(const labelUList &newToOld, const bool validBoundary)
Reorder and trim existing patches. If validBoundary the new.
Definition: polyMesh.C:1174
virtual void addPatch(const label insertPatchi, const polyPatch &patch)
Add/insert single patch.
Definition: polyMesh.C:1217
void clearOut()
Clear all geometry and addressing unnecessary for CFD.
virtual void setPoints(const pointField &)
Reset the points.
Definition: polyMesh.C:1378
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
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.
void clearAddressing()
Clear topological data.
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.
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.
A class for handling words, derived from string.
Definition: word.H:62
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 FUNCTION_NAME
static const coefficient C("C", dimTemperature, 234.5)
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:258
void deleteDemandDrivenData(DataType *&dataPtr)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const dimensionSet dimless
SurfaceField< scalar > surfaceScalarField
messageStream Info
void mag(LagrangianPatchField< scalar > &f, const LagrangianPatchField< Type > &f1)
const dimensionSet dimTime
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 dimVolume
defineTypeNameAndDebug(combustionModel, 0)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
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
error FatalError
FOR_ALL_FIELD_TYPES(makeFieldSourceTypedef)
const dimensionSet dimArea
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
void nullDemandDrivenData(DataType *&dataPtr)
label timeIndex
Definition: getTimeIndex.H:4
faceListList boundary(nPatches)
volScalarField & p
Foam::surfaceFields.