multiDisplacementMotionSolver.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) 2024 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 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35  defineTypeNameAndDebug(multiDisplacementMotionSolver, 0);
36 
38  (
39  motionSolver,
40  multiDisplacementMotionSolver,
41  dictionary
42  );
43 
45  (
46  displacementMotionSolver,
47  multiDisplacementMotionSolver,
48  displacement
49  );
50 }
51 
52 
53 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 
55 Foam::multiDisplacementMotionSolver::multiDisplacementMotionSolver
56 (
57  const polyMesh& mesh,
58  const IOdictionary& dict
59 )
60 :
62  curPoints_(mesh.points())
63 {
64  // Make pointDisplacement is not registered since all lower levels
65  // have a pointDisplacement as well.
67 
68  label i = 0;
69 
70  const dictionary& solverDict = dict.subDict("solvers");
71 
72  motionSolvers_.setSize(solverDict.size());
73 
74  for (const entry& dEntry : solverDict)
75  {
76  if (dEntry.isDict())
77  {
78  IOobject io(dict);
79  io.readOpt(IOobject::NO_READ);
80  io.writeOpt(IOobject::AUTO_WRITE);
81  io.rename(dEntry.dict().dictName());
82 
83  IOdictionary IOsolverDict
84  (
85  io,
86  dEntry.dict()
87  );
88 
89  auto* msPtr = motionSolver::New(mesh, IOsolverDict).ptr();
90 
91  motionSolvers_.set
92  (
93  i,
94  dynamic_cast<displacementMotionSolver*>(msPtr)
95  );
96 
97  // Avoid conflicts with multiple registrations
98  motionSolvers_[i].pointDisplacement().checkOut();
99 
100  i++;
101  }
102  }
103  motionSolvers_.setSize(i);
104 
105  if (i == 0)
106  {
107  FatalErrorInFunction << "No displacementMotionSolvers in dictionary "
108  << dict << exit(FatalError);
109  }
110 
111  // Re-register so only our 'pointDisplacement' is on the database.
113 }
114 
115 
116 Foam::multiDisplacementMotionSolver::
117 multiDisplacementMotionSolver
118 (
119  const polyMesh& mesh,
120  const IOdictionary& dict,
121  const pointVectorField& pointDisplacement,
122  const pointIOField& points0
123 )
124 :
125  displacementMotionSolver(mesh, dict, pointDisplacement, points0, typeName),
126  curPoints_(mesh.points())
127 {
128  // Make pointDisplacement is not registered since all lower levels
129  // have a pointDisplacement as well.
130  this->pointDisplacement().checkOut();
131 
132  label i = 0;
133 
134  const dictionary& solverDict = dict.subDict("solvers");
135 
136  motionSolvers_.setSize(solverDict.size());
137 
138  for (const entry& dEntry : solverDict)
139  {
140  if (dEntry.isDict())
141  {
142  IOobject io(dict);
143  io.readOpt(IOobject::NO_READ);
144  io.writeOpt(IOobject::AUTO_WRITE);
145  io.rename(dEntry.dict().dictName());
146 
147  IOdictionary IOsolverDict
148  (
149  io,
150  dEntry.dict()
151  );
152 
153  auto msPtr = displacementMotionSolver::New
154  (
155  dEntry.keyword(),
156  mesh,
157  IOsolverDict,
159  points0
160  );
161 
162  // Avoid conflicts with multiple registrations
163  msPtr->pointDisplacement().checkOut();
164 
165  motionSolvers_.set(i++, msPtr);
166  }
167  }
168  motionSolvers_.setSize(i);
169 
170  if (i == 0)
171  {
172  FatalErrorInFunction << "No displacementMotionSolvers in dictionary "
173  << dict << exit(FatalError);
174  }
175 
176  // Re-register so only our 'pointDisplacement' is on the database.
178 }
179 
180 
181 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
182 
185 {
186  return curPoints_;
187 }
188 
189 
191 {
192  if (!motionSolvers_.size())
193  {
194  return;
195  }
196 
197  // Bit tricky:
198  // - make sure only one copy of pointDisplacement is registered. This is
199  // for if cellDisplacement tries to look up the pointDisplacement it
200  // looks up its version. Or maybe we always should use our own version
201  // only?
202  // - copy the last set of calculated points into our copy (curPoints_)
203  // - move the mesh to update the faceCentres, cellCentres etc. This assumes
204  // that we can call movePoints() multiple times inside a time step.
205  // (note that this is supported in pimpleFoam with the
206  // moveMeshOuterCorrectors option)
207 
208  pointDisplacement().checkOut();
209 
210  // Doing first motion solver
211  motionSolvers_[0].pointDisplacement().checkIn();
212  // Take over my bc values
213  motionSolvers_[0].pointDisplacement() == pointDisplacement();
214 
215  motionSolvers_[0].solve();
216  motionSolvers_[0].pointDisplacement().checkOut();
217 
218  // Update my values
219  curPoints_ = motionSolvers_[0].curPoints();
220  pointDisplacement() == motionSolvers_[0].pointDisplacement();
221 
222  for (label i = 1; i < motionSolvers_.size(); i++)
223  {
224  // Doing other motion solvers using new locations/face/cellCentres etc.
225  const_cast<polyMesh&>(mesh()).movePoints(curPoints_);
226  motionSolvers_[i].pointDisplacement().checkIn();
227 
228  // Take over my bc values
229  motionSolvers_[i].pointDisplacement() == pointDisplacement();
230 
231  motionSolvers_[i].solve();
232  motionSolvers_[i].pointDisplacement().checkOut();
233 
234  // Update my values
235  curPoints_ = motionSolvers_[i].curPoints();
236  pointDisplacement() == motionSolvers_[i].pointDisplacement();
237  }
238 
239  pointDisplacement().checkIn();
240 
241  // Push my pointDisplacement onto all motionSolvers
242  for (auto& ms : motionSolvers_)
243  {
244  ms.pointDisplacement() == pointDisplacement();
245  }
246 }
247 
248 
250 (
251  const pointField& newPoints
252 )
253 {
254  curPoints_ = newPoints;
255  for (auto& ms : motionSolvers_)
256  {
257  ms.movePoints(newPoints);
258  }
259 }
260 
261 
262 void Foam::multiDisplacementMotionSolver::updateMesh(const mapPolyMesh& mpm)
263 {
264  for (auto& ms : motionSolvers_)
265  {
266  ms.updateMesh(mpm);
267  }
268 }
269 
270 
271 // ************************************************************************* //
dictionary dict
Virtual base class for displacement motion solver.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
virtual tmp< pointField > curPoints() const
Provide current points for motion.
pointVectorField & pointDisplacement() noexcept
Return reference to the point motion displacement field.
virtual void updateMesh(const mapPolyMesh &)
Update local data for topology changes.
static autoPtr< motionSolver > New(const polyMesh &)
Select constructed from polyMesh.
Definition: motionSolver.C:143
Macros for easy insertion into run-time selection tables.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:50
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
const pointField & points
virtual void movePoints(const pointField &)
Update local data for geometry changes.
bool checkOut()
Remove object from registry, and remove all file watches.
Definition: regIOobject.C:221
defineTypeNameAndDebug(combustionModel, 0)
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))
Nothing to be read.
Automatically write from objectRegistry::writeObject()
static autoPtr< displacementMotionSolver > New(const word &solverTypeName, const polyMesh &, const IOdictionary &, const pointVectorField &pointDisplacement, const pointIOField &points0)
Select constructed from polyMesh, dictionary and components.
pointField & points0() noexcept
Return reference to the reference (&#39;0&#39;) pointField.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:75
const polyMesh & mesh() const
Return reference to mesh.
Definition: motionSolver.H:165
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
A primitive field of type <T> with automated input and output.
bool checkIn()
Add object to registry, if not already registered.
Definition: regIOobject.C:184
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:63
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)