sixDoFRigidBodyMotionSolver.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) 2013-2017 OpenFOAM Foundation
9  Copyright (C) 2019-2020 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
31 #include "polyMesh.H"
32 #include "pointPatchDist.H"
33 #include "pointConstraints.H"
35 #include "forces.H"
36 #include "mathematicalConstants.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(sixDoFRigidBodyMotionSolver, 0);
43 
45  (
46  motionSolver,
47  sixDoFRigidBodyMotionSolver,
48  dictionary
49  );
50 }
51 
52 
53 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
54 
55 Foam::sixDoFRigidBodyMotionSolver::sixDoFRigidBodyMotionSolver
56 (
57  const polyMesh& mesh,
58  const IOdictionary& dict
59 )
60 :
62  motion_
63  (
64  coeffDict(),
65  IOobject
66  (
67  "sixDoFRigidBodyMotionState",
68  mesh.time().timeName(),
69  "uniform",
70  mesh
71  ).typeHeaderOk<IOdictionary>(true)
72  ? IOdictionary
73  (
74  IOobject
75  (
76  "sixDoFRigidBodyMotionState",
77  mesh.time().timeName(),
78  "uniform",
79  mesh,
80  IOobject::READ_IF_PRESENT,
81  IOobject::NO_WRITE,
82  IOobject::NO_REGISTER
83  )
84  )
85  : coeffDict(),
86  mesh.time()
87  ),
88  patches_(coeffDict().get<wordRes>("patches")),
89  patchSet_(mesh.boundaryMesh().patchSet(patches_)),
90  di_(coeffDict().get<scalar>("innerDistance")),
91  do_(coeffDict().get<scalar>("outerDistance")),
92  test_(coeffDict().getOrDefault("test", false)),
93  rhoInf_(1.0),
94  rhoName_(coeffDict().getOrDefault<word>("rho", "rho")),
95  scale_
96  (
97  IOobject
98  (
99  "motionScale",
100  mesh.time().timeName(),
101  mesh,
102  IOobject::NO_READ,
103  IOobject::NO_WRITE,
104  IOobject::NO_REGISTER
105  ),
106  pointMesh::New(mesh),
108  ),
109  curTimeIndex_(-1),
110  cOfGdisplacement_(coeffDict().getOrDefault<word>("cOfGdisplacement", "none"))
111 {
112  if (rhoName_ == "rhoInf")
113  {
114  coeffDict().readEntry("rhoInf", rhoInf_);
115  }
116 
117  // Calculate scaling factor everywhere
118  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119 
120  {
121  const pointMesh& pMesh = pointMesh::New(mesh);
122 
123  pointPatchDist pDist(pMesh, patchSet_, points0());
124 
125  // Scaling: 1 up to di then linear down to 0 at do away from patches
126  scale_.primitiveFieldRef() =
127  min
128  (
129  max
130  (
131  (do_ - pDist.primitiveField())/(do_ - di_),
132  scalar(0)
133  ),
134  scalar(1)
135  );
136 
137  // Convert the scale function to a cosine
138  scale_.primitiveFieldRef() =
139  min
140  (
141  max
142  (
143  0.5
144  - 0.5
145  *cos(scale_.primitiveField()
147  scalar(0)
148  ),
149  scalar(1)
150  );
151 
152  pointConstraints::New(pMesh).constrain(scale_);
153  scale_.write();
154  }
155 }
156 
157 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
158 
161 {
162  return motion_;
163 }
164 
165 
168 {
169  tmp<pointField> newPoints
170  (
171  points0() + pointDisplacement_.primitiveField()
172  );
173 
174  if (!moveAllCells())
175  {
176  auto ttransformedPts = tmp<pointField>::New(mesh().points());
177  auto& transformedPts = ttransformedPts.ref();
178 
179  UIndirectList<point>(transformedPts, pointIDs()) =
180  pointField(newPoints.ref(), pointIDs());
181 
182  return ttransformedPts;
183  }
184 
185  return newPoints;
186 }
187 
188 
190 {
191  const Time& t = mesh().time();
192 
193  if (mesh().nPoints() != points0().size())
194  {
196  << "The number of points in the mesh seems to have changed." << endl
197  << "In constant/polyMesh there are " << points0().size()
198  << " points; in the current mesh there are " << mesh().nPoints()
199  << " points." << exit(FatalError);
200  }
201 
202  // Store the motion state at the beginning of the time-step
203  bool firstIter = false;
204  if (curTimeIndex_ != this->db().time().timeIndex())
205  {
206  motion_.newTime();
207  curTimeIndex_ = this->db().time().timeIndex();
208  firstIter = true;
209  }
210 
212 
213  if (db().time().foundObject<uniformDimensionedVectorField>("g"))
214  {
216  }
217  else
218  {
219  coeffDict().readIfPresent("g", g);
220  }
221 
222  // const scalar ramp = clamp((this->db().time().value() - 5)/10, 0, 1);
223  const scalar ramp = 1.0;
224 
225  if (test_)
226  {
227  motion_.update
228  (
229  firstIter,
230  ramp*(motion_.mass()*g.value()),
231  ramp*(motion_.mass()*(motion_.momentArm() ^ g.value())),
232  t.deltaTValue(),
233  t.deltaT0Value()
234  );
235  }
236  else
237  {
238  dictionary forcesDict;
239 
240  forcesDict.add("type", functionObjects::forces::typeName);
241  forcesDict.add("patches", patches_);
242  forcesDict.add("rhoInf", rhoInf_);
243  forcesDict.add("rho", rhoName_);
244  forcesDict.add("CofR", motion_.centreOfRotation());
245 
246  vector oldPos = motion_.centreOfRotation();
247 
248  functionObjects::forces f("forces", db(), forcesDict);
249 
250  f.calcForcesMoments();
251 
252  motion_.update
253  (
254  firstIter,
255  ramp*(f.forceEff() + motion_.mass()*g.value()),
256  ramp
257  *(
258  f.momentEff()
259  + motion_.mass()*(motion_.momentArm() ^ g.value())
260  ),
261  t.deltaTValue(),
262  t.deltaT0Value()
263  );
264 
265  if (cOfGdisplacement_ != "none")
266  {
267  if
268  (
269  db().time().foundObject<uniformDimensionedVectorField>
270  (
271  cOfGdisplacement_
272  )
273  )
274  {
275  auto& disp =
276  db().time().lookupObjectRef<uniformDimensionedVectorField>
277  (
278  cOfGdisplacement_
279  );
280 
281  disp += (motion_.centreOfRotation() - oldPos);
282  }
283  }
284  }
285 
286  // Update the displacements
287  pointDisplacement_.primitiveFieldRef() =
288  motion_.transform(points0(), scale_) - points0();
289 
290  // Displacement has changed. Update boundary conditions
292  (
293  pointDisplacement_.mesh()
294  ).constrainDisplacement(pointDisplacement_);
295 }
296 
297 
299 (
300  IOstreamOption streamOpt,
301  const bool writeOnProc
302 ) const
303 {
305  (
306  IOobject
307  (
308  "sixDoFRigidBodyMotionState",
309  mesh().time().timeName(),
310  "uniform",
311  mesh(),
315  )
316  );
317 
318  motion_.state().write(dict);
319  return dict.regIOobject::writeObject(streamOpt, writeOnProc);
320 }
321 
322 
324 {
326  {
327  motion_.read(coeffDict());
328 
329  return true;
330  }
331 
332  return false;
333 }
334 
335 
336 // ************************************************************************* //
Six degree of freedom motion for a rigid body.
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
const Type & value() const noexcept
Return const reference to value.
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Virtual base class for displacement motion solver.
const Type & lookupObject(const word &name, const bool recursive=false) const
Lookup and return const reference to the object of the given Type. Fatal if not found or the wrong ty...
const Internal::FieldType & primitiveField() const noexcept
Return a const-reference to the internal field values.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
UniformDimensionedField< vector > uniformDimensionedVectorField
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
bool readIfPresent(const dictionary &dict)
Update the value of dimensioned<Type> if found in the dictionary, lookup in dictionary with the name(...
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
Various UniformDimensionedField types.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Definition: boundaryMesh.H:58
dimensioned< vector > dimensionedVector
Dimensioned vector obtained from generic dimensioned type.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:529
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.
A simple container for options an IOstream can normally have.
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
const dictionary & coeffDict() const
Const access to the coefficients dictionary.
Definition: motionSolver.H:173
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:360
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
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:45
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect...
word timeName
Definition: getTimeIndex.H:3
const dimensionSet dimAcceleration
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
dimensionedScalar cos(const dimensionedScalar &ds)
const pointField & points
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
virtual tmp< pointField > curPoints() const
Return point location obtained from the current motion field.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
constexpr scalar pi(M_PI)
Vector< scalar > vector
Definition: vector.H:57
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
const Time & time() const noexcept
Return Time associated with the objectRegistry.
Definition: IOobject.C:456
virtual bool read()
Read dynamicMeshDict dictionary.
Definition: motionSolver.C:220
const uniformDimensionedVectorField & g
defineTypeNameAndDebug(combustionModel, 0)
labelList f(nPoints)
virtual bool writeObject(IOstreamOption streamOpt, const bool writeOnProc) const
Write state using stream options.
virtual void solve()
Solve for motion.
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
A List with indirect addressing. Like IndirectList but does not store addressing. ...
Definition: faMatrix.H:52
Nothing to be read.
virtual bool read()
Read dynamicMeshDict dictionary.
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
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
void constrain(GeometricField< Type, pointPatchField, pointMesh > &pf, const bool overrideValue=false) const
Apply boundary conditions (single-patch constraints) and.
Do not request registration (bool: false)
const sixDoFRigidBodyMotion & motion() const
Return the six DoF motion object.
Namespace for OpenFOAM.
label timeIndex
Definition: getTimeIndex.H:24
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127