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