dynamicMotionSolverFvMeshAMI.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2019-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
30 #include "motionSolver.H"
31 #include "volFields.H"
32 #include "surfaceFields.H"
33 #include "cyclicAMIPolyPatch.H"
34 #include "cyclicACMIPolyPatch.H"
35 #include "polyTopoChange.H"
36 #include "MeshObject.H"
37 #include "lduMesh.H"
38 #include "surfaceInterpolate.H"
39 
40 #include "processorFvPatch.H"
41 
42 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46  defineTypeNameAndDebug(dynamicMotionSolverFvMeshAMI, 0);
48  (
49  dynamicFvMesh,
50  dynamicMotionSolverFvMeshAMI,
51  IOobject
52  );
54  (
55  dynamicFvMesh,
56  dynamicMotionSolverFvMeshAMI,
57  doInit
58  );
59 }
60 
61 
62 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
63 
64 Foam::dynamicMotionSolverFvMeshAMI::dynamicMotionSolverFvMeshAMI
65 (
66  const IOobject& io,
67  const bool doInit
68 )
69 :
70  dynamicFvMesh(io, doInit)
71 {
72  if (doInit)
73  {
74  init(false); // do not initialise lower levels
75  }
76 }
77 
78 
79 bool Foam::dynamicMotionSolverFvMeshAMI::init(const bool doInit)
80 {
81  if (doInit)
82  {
83  dynamicFvMesh::init(doInit);
84  }
85 
86  motionPtr_ = motionSolver::New(*this);
87 
88  // allow restarts during initialization to match patch field values if
89  // required
90  const auto& pbm = boundaryMesh();
91  bool changeRequired = false;
92  for (label patchi = 0; patchi < pbm.nNonProcessor(); ++patchi)
93  {
94  const auto* cycAmiPtr = isA<cyclicAMIPolyPatch>(pbm[patchi]);
95 
96  if (cycAmiPtr)
97  {
98  changeRequired = cycAmiPtr->createAMIFaces() || changeRequired;
99  }
100  else
101  {
102  const auto* cycAcmiPtr = isA<cyclicACMIPolyPatch>(pbm[patchi]);
103  if (cycAcmiPtr)
104  {
105  changeRequired =
106  cycAcmiPtr->cyclicAMIPolyPatch::createAMIFaces()
107  || changeRequired;
108  }
109  }
110  }
111  if (returnReduceOr(changeRequired))
112  {
113  update();
114  }
115 
116  return true;
117 }
118 
119 
120 Foam::dynamicMotionSolverFvMeshAMI::dynamicMotionSolverFvMeshAMI
121 (
122  const IOobject& io,
123  pointField&& points,
124  faceList&& faces,
125  labelList&& allOwner,
126  labelList&& allNeighbour,
127  const bool syncPar
128 )
129 :
130  dynamicFvMesh
131  (
132  io,
133  std::move(points),
134  std::move(faces),
135  std::move(allOwner),
136  std::move(allNeighbour),
137  syncPar
138  ),
139  motionPtr_(motionSolver::New(*this))
140 {}
141 
142 
143 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
146 {
147  return *motionPtr_;
148 }
149 
150 
152 {
153  // Mesh not moved/changed yet
154  moving(false);
155  topoChanging(false);
156 
157  if (debug)
158  {
159  for (const fvPatch& fvp : boundary())
160  {
161  if (!isA<processorFvPatch>(fvp))
162  {
163  Info<< "1 --- patch:" << fvp.patch().name()
164  << " area:" << gSum(fvp.magSf()) << endl;
165  }
166  }
167  }
168 
169  pointField newPoints(motionPtr_->curPoints());
170 
171  polyBoundaryMesh& pbm = const_cast<polyBoundaryMesh&>(boundaryMesh());
172 
173  // Scan all patches and see if we want to apply a mesh topology update
174  bool changeRequired = false;
175  for (label patchi = 0; patchi < pbm.nNonProcessor(); ++patchi)
176  {
177  const polyPatch& pp = pbm[patchi];
178 
179  DebugInfo
180  << "pre-topology change: patch " << pp.name()
181  << " size:" << returnReduce(pp.size(), sumOp<label>())
182  << " mag(faceAreas):" << gSum(mag(pp.faceAreas())) << endl;
183 
184  //changeRequired = pp.changeTopology(newPoints) || changeRequired;
185  changeRequired = pp.changeTopology() || changeRequired;
186  }
187 
188  if (returnReduceOr(changeRequired))
189  {
190  polyTopoChange polyTopo(*this);
191 
192  // Set new point positions in polyTopo object
193  polyTopo.movePoints(newPoints);
194 
195  // Accumulate the patch-based mesh changes on the current mesh
196  // Note:
197  // - updates the AMIs using the new points
198  // - creates a topo change object that removes old added faces and
199  // adds the new faces
200  for (polyPatch& pp : pbm)
201  {
202  pp.setTopology(polyTopo);
203  }
204 
205  // Update geometry
206  // Note
207  // - changeMesh leads to polyMesh::resetPrimitives which will also
208  // trigger polyBoundaryMesh::updateMesh (init and update) and
209  // ::calcGeometry (with topoChanging = false)
210  // - BUT: mesh still corresponds to original (non-extended mesh) so
211  // we want to bypass these calls...
212  // - after changes topoChanging = true
213  autoPtr<mapPolyMesh> map =
214  polyTopo.changeMesh
215  (
216  *this,
217  true // We will be calling movePoints after this update
218  );
219 
220  // Apply topology change - update fv geometry and map fields
221  // - polyMesh::updateMesh
222  // - fires initUpdateMesh and updateMesh in AMI BCs - called before
223  // mapFields
224  // - AMI addressing must be up-to-date - used by, e.g. FaceCellWave
225  // - will trigger (again) polyBoundaryMesh::updateMesh (init and update)
226  updateMesh(map());
227 
228  // Move points and update derived properties
229  // Note:
230  // - resets face areas based on raw point locations!
231  // - polyBoundaryMesh::updateMesh (init and update)
232  // Note:
233  // - processorPolyPatches will trigger calculation of faceCentres
234  // (and therefore cell volumes), so need to update faceAreas in
235  // initMovePoints since proc patches will be evaluated later than
236  // AMI patches
237  if (map().hasMotionPoints())
238  {
239  movePoints(map().preMotionPoints());
240  }
241  }
242  else
243  {
244  fvMesh::movePoints(newPoints);
245  }
246 
247  volVectorField* Uptr = getObjectPtr<volVectorField>("U");
248 
249  if (Uptr)
250  {
252 
253  surfaceVectorField* UfPtr = getObjectPtr<surfaceVectorField>("Uf");
254  if (UfPtr)
255  {
256  *UfPtr = fvc::interpolate(*Uptr);
257  }
258  }
259 
260  if (debug)
261  {
262  for (const fvPatch& fvp : boundary())
263  {
264  if (!isA<processorFvPatch>(fvp))
265  {
266  Info<< "2 --- patch:" << fvp.patch().name()
267  << " area:" << gSum(fvp.magSf()) << endl;
268  }
269  }
270  }
271 
272  return true;
273 }
274 
275 
276 // ************************************************************************* //
Foam::surfaceFields.
faceListList boundary
const Field< point_type > & faceAreas() const
Return face area vectors for patch.
const polyBoundaryMesh & pbm
virtual bool update()
Update the mesh for both mesh motion and topology change.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
virtual bool movePoints()
Do what is necessary if the mesh has moved.
Virtual base class for mesh motion solver.
Definition: motionSolver.H:54
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
Definition: dynamicFvMesh.C:84
static autoPtr< motionSolver > New(const polyMesh &)
Select constructed from polyMesh.
Definition: motionSolver.C:143
GeometricField< vector, fvPatchField, volMesh > volVectorField
Definition: volFieldsFwd.H:76
const motionSolver & motion() const
Return the motionSolver.
Macros for easy insertion into run-time selection tables.
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
Type gSum(const FieldField< Field, Type > &f)
const pointField & points
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
#define DebugInfo
Report an information message using Foam::Info.
int debug
Static debugging option.
mesh update()
defineTypeNameAndDebug(combustionModel, 0)
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
Abstract base class for geometry and/or topology changing fvMesh.
Definition: dynamicFvMesh.H:74
void correctBoundaryConditions()
Correct boundary field.
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< label > labelList
A List of labels.
Definition: List.H:61
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
label nNonProcessor() const
The number of patches before the first processor patch.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
virtual bool init(const bool doInit)
Initialise all non-demand-driven data.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)