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