Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
10License
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
31// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32
33namespace Foam
34{
36
38 (
42 );
43
45 (
48 displacement
49 );
50}
51
52
53// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54
55Foam::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 {
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);
110
111 // Re-register so only our 'pointDisplacement' is on the database.
113}
114
115
116Foam::multiDisplacementMotionSolver::
117multiDisplacementMotionSolver
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
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
262void Foam::multiDisplacementMotionSolver::updateMesh(const mapPolyMesh& mpm)
263{
264 for (auto& ms : motionSolvers_)
265 {
266 ms.updateMesh(mpm);
267 }
268}
269
270
271// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
label size() const noexcept
The number of elements in list.
Definition DLListBase.H:194
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
IOdictionary(const IOobject &io, const dictionary *fallback=nullptr)
Construct given an IOobject and optional fallback dictionary content.
@ NO_READ
Nothing to be read.
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
dictionary()
Default construct, a top-level empty dictionary.
Definition dictionary.C:68
friend class entry
Declare friendship with the entry class for IO.
Definition dictionary.H:338
Virtual base class for displacement motion solver.
pointVectorField & pointDisplacement() noexcept
Return reference to the point motion displacement field.
displacementMotionSolver(const displacementMotionSolver &)=delete
No copy construct.
static autoPtr< displacementMotionSolver > New(const word &solverTypeName, const polyMesh &, const IOdictionary &, const pointVectorField &pointDisplacement, const pointIOField &points0)
Select constructed from polyMesh, dictionary and components.
A keyword and a list of tokens is an 'entry'.
Definition entry.H:66
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Virtual base class for mesh motion solver.
const polyMesh & mesh() const
Return reference to mesh.
static autoPtr< motionSolver > New(const polyMesh &)
Select constructed from polyMesh.
virtual tmp< pointField > newPoints()
Provide new points for motion. Solves for motion.
Mesh motion solver for a polyMesh. Applies multiple (displacement) motion solvers in order.
virtual tmp< pointField > curPoints() const
Provide current points for motion.
virtual void movePoints(const pointField &)
Update local data for geometry changes.
virtual void updateMesh(const mapPolyMesh &)
Update local data for topology changes.
pointField & points0() noexcept
Return reference to the reference ('0') pointField.
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
bool checkOut()
Remove object from registry, and remove all file watches.
bool checkIn()
Add object to registry, if not already registered.
A class for managing temporary objects.
Definition tmp.H:75
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
const auto & io
const pointField & points
Namespace for OpenFOAM.
GeometricField< vector, pointPatchField, pointMesh > pointVectorField
vectorIOField pointIOField
pointIOField is a vectorIOField.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
dictionary dict
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))