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