sixDoFRigidBodyMotion.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-2026 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 "sixDoFRigidBodyMotion.H"
27 #include "sixDoFSolver.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 namespace Foam
32 {
34 }
35 
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 
38 void Foam::sixDoFRigidBodyMotion::applyRestraints()
39 {
40  if (restraints_.empty())
41  {
42  return;
43  }
44 
45  if (Pstream::master())
46  {
47  forAll(restraints_, rI)
48  {
49  if (report_)
50  {
51  Info<< "Restraint " << restraints_[rI].name() << ": ";
52  }
53 
54  // Restraint position
55  point rP = Zero;
56 
57  // Restraint force
58  vector rF = Zero;
59 
60  // Restraint moment
61  vector rM = Zero;
62 
63  // Accumulate the restraints
64  restraints_[rI].restrain(*this, rP, rF, rM);
65 
66  // Update the acceleration
67  a() += rF/mass_;
68 
69  // Moments are returned in global axes, transforming to
70  // body local to add to torque.
71  tau() += Q().T() & (rM + ((rP - centreOfRotation()) ^ rF));
72  }
73  }
74 }
75 
76 
77 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
78 
80 :
81  motionState_(),
82  motionState0_(),
83  restraints_(),
84  constraints_(),
85  tConstraints_(tensor::I),
86  rConstraints_(tensor::I),
87  initialCentreOfMass_(Zero),
88  initialCentreOfRotation_(Zero),
89  initialQ_(I),
90  mass_(vSmall),
91  momentOfInertia_(diagTensor::one*vSmall),
92  aRelax_(1.0),
93  aDamp_(1.0),
94  report_(false),
95  solver_(nullptr)
96 {}
97 
98 
100 (
101  const dictionary& dict,
102  const dictionary& stateDict
103 )
104 :
105  motionState_(stateDict),
106  motionState0_(),
107  restraints_(),
108  constraints_(),
109  tConstraints_(tensor::I),
110  rConstraints_(tensor::I),
111  initialCentreOfMass_
112  (
113  dict.lookupOrDefault
114  (
115  "initialCentreOfMass",
116  vector(dict.lookup("centreOfMass"))
117  )
118  ),
119  initialCentreOfRotation_(initialCentreOfMass_),
120  initialQ_
121  (
122  dict.lookupOrDefault
123  (
124  "initialOrientation",
125  dict.lookupOrDefault("orientation", tensor::I)
126  )
127  ),
128  mass_(dict.lookup<scalar>("mass")),
129  momentOfInertia_(dict.lookup("momentOfInertia")),
130  aRelax_(dict.lookupOrDefault<scalar>("accelerationRelaxation", 1.0)),
131  aDamp_(dict.lookupOrDefault<scalar>("accelerationDamping", 1.0)),
132  report_(dict.lookupOrDefault<Switch>("report", false)),
133  solver_(sixDoFSolver::New(dict.subDict("solver"), *this))
134 {
136 
137  // Set constraints and initial centre of rotation
138  // if different to the centre of mass
140 
141  // If the centres of mass and rotation are different ...
142  vector R(initialCentreOfMass_ - initialCentreOfRotation_);
143  if (magSqr(R) > vSmall)
144  {
145  // ... correct the moment of inertia tensor using parallel axes theorem
146  momentOfInertia_ += mass_*diag(I*magSqr(R) - sqr(R));
147 
148  // ... and if the centre of rotation is not specified for motion state
149  // update it
150  if (!stateDict.found("centreOfRotation"))
151  {
152  motionState_.centreOfRotation() = initialCentreOfRotation_;
153  }
154  }
155 
156  // Save the old-time motion state
157  motionState0_ = motionState_;
158 }
159 
160 
162 (
163  const sixDoFRigidBodyMotion& sDoFRBM
164 )
165 :
166  motionState_(sDoFRBM.motionState_),
167  motionState0_(sDoFRBM.motionState0_),
168  restraints_(sDoFRBM.restraints_),
169  constraints_(sDoFRBM.constraints_),
170  tConstraints_(sDoFRBM.tConstraints_),
171  rConstraints_(sDoFRBM.rConstraints_),
172  initialCentreOfMass_(sDoFRBM.initialCentreOfMass_),
173  initialCentreOfRotation_(sDoFRBM.initialCentreOfRotation_),
174  initialQ_(sDoFRBM.initialQ_),
175  mass_(sDoFRBM.mass_),
176  momentOfInertia_(sDoFRBM.momentOfInertia_),
177  aRelax_(sDoFRBM.aRelax_),
178  aDamp_(sDoFRBM.aDamp_),
179  report_(sDoFRBM.report_)
180 {}
181 
182 
183 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
184 
186 {}
187 
188 
189 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
190 
192 (
193  const dictionary& dict
194 )
195 {
196  if (dict.found("restraints"))
197  {
198  const dictionary& restraintDict = dict.subDict("restraints");
199 
200  label i = 0;
201 
202  restraints_.setSize(restraintDict.size());
203 
204  forAllConstIter(IDLList<entry>, restraintDict, iter)
205  {
206  if (iter().isDict())
207  {
208  restraints_.set
209  (
210  i++,
212  (
213  iter().keyword(),
214  iter().dict()
215  )
216  );
217  }
218  }
219 
220  restraints_.setSize(i);
221  }
222 }
223 
224 
226 (
227  const dictionary& dict
228 )
229 {
230  if (dict.found("constraints"))
231  {
232  const dictionary& constraintDict = dict.subDict("constraints");
233 
234  label i = 0;
235 
236  constraints_.setSize(constraintDict.size());
237 
238  pointConstraint pct;
239  pointConstraint pcr;
240 
241  forAllConstIter(IDLList<entry>, constraintDict, iter)
242  {
243  if (iter().isDict())
244  {
245  constraints_.set
246  (
247  i,
249  (
250  iter().keyword(),
251  iter().dict(),
252  *this
253  )
254  );
255 
256  constraints_[i].setCentreOfRotation(initialCentreOfRotation_);
257  constraints_[i].constrainTranslation(pct);
258  constraints_[i].constrainRotation(pcr);
259 
260  i++;
261  }
262  }
263 
264  constraints_.setSize(i);
265 
266  tConstraints_ = pct.constraintTransformation();
267  rConstraints_ = pcr.constraintTransformation();
268 
269  Info<< "Translational constraint tensor " << tConstraints_ << nl
270  << "Rotational constraint tensor " << rConstraints_ << endl;
271  }
272 }
273 
274 
275 void Foam::sixDoFRigidBodyMotion::updateAcceleration
276 (
277  const vector& fGlobal,
278  const vector& tauGlobal
279 )
280 {
281  static bool first = true;
282 
283  // Save the previous iteration accelerations for relaxation
284  vector aPrevIter = a();
285  vector tauPrevIter = tau();
286 
287  // Calculate new accelerations
288  a() = fGlobal/mass_;
289  tau() = (Q().T() & tauGlobal);
290  applyRestraints();
291 
292  // Relax accelerations on all but first iteration
293  if (!first)
294  {
295  a() = aRelax_*a() + (1 - aRelax_)*aPrevIter;
296  tau() = aRelax_*tau() + (1 - aRelax_)*tauPrevIter;
297  }
298  else
299  {
300  first = false;
301  }
302 }
303 
304 
306 (
307  bool firstIter,
308  const vector& fGlobal,
309  const vector& tauGlobal,
310  scalar deltaT,
311  scalar deltaT0
312 )
313 {
314  if (Pstream::master())
315  {
316  solver_->solve(firstIter, fGlobal, tauGlobal, deltaT, deltaT0);
317 
318  if (report_)
319  {
320  status();
321  }
322  }
323 
324  Pstream::scatter(motionState_);
325 }
326 
327 
329 {
330  Info<< "6-DoF rigid body motion" << nl
331  << " Centre of rotation: " << centreOfRotation() << nl
332  << " Centre of mass: " << centreOfMass() << nl
333  << " Orientation: " << orientation() << nl
334  << " Linear velocity: " << v() << nl
335  << " Angular velocity: " << omega()
336  << endl;
337 }
338 
339 
341 (
342  const pointField& initialPoints
343 ) const
344 {
345  return
346  (
347  centreOfRotation()
348  + (Q() & initialQ_.T() & (initialPoints - initialCentreOfRotation_))
349  );
350 }
351 
352 
353 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Template class for intrusive linked lists.
Definition: ILList.H:67
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:61
Tensor< Cmpt > T() const
Return transpose.
Definition: TensorI.H:331
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
const dictionary & subDict(const word &) const
Find and return a sub-dictionary.
Definition: dictionary.C:778
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:468
A class representing the concept of 1 (scalar(1)) used to avoid unnecessary manipulations for objects...
Definition: one.H:51
Accumulates point constraints through successive applications of the applyConstraint function.
tensor constraintTransformation() const
Return the accumulated constraint transformation tensor.
static autoPtr< sixDoFRigidBodyMotionConstraint > New(const word &name, const dictionary &sDoFRBMCDict, const sixDoFRigidBodyMotion &motion)
Select constructed from the sDoFRBMCDict dictionary and Time.
static autoPtr< sixDoFRigidBodyMotionRestraint > New(const word &name, const dictionary &sDoFRBMRDict)
Select constructed from the sDoFRBMRDict dictionary and Time.
const point & centreOfRotation() const
Return access to the centre of mass.
Six degree of freedom motion for a rigid body.
void update(bool firstIter, const vector &fGlobal, const vector &tauGlobal, scalar deltaT, scalar deltaT0)
Symplectic integration of velocities, orientation and position.
void status() const
Report the status of the motion.
void addConstraints(const dictionary &dict)
Add restraints to the motion, public to allow external.
virtual ~sixDoFRigidBodyMotion()
Destructor.
point transform(const point &initialPoint) const
Transform the given initial state point by the current motion.
void addRestraints(const dictionary &dict)
Add restraints to the motion, public to allow external.
const point & centreOfRotation() const
Return the current centre of rotation.
A class for managing temporary objects.
Definition: tmp.H:55
const scalar omega
const vector tau
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
static const zero Zero
Definition: zero.H:97
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
static const Identity< scalar > I
Definition: Identity.H:93
vector point
Point is a vector.
Definition: point.H:41
labelList first(const UList< labelPair > &p)
Definition: patchToPatch.C:39
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
static scalar R(const scalar a, const scalar x)
Definition: invIncGamma.C:102
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
defineTypeNameAndDebug(atmosphericBoundaryLayer, 0)
tmp< DimensionedField< TypeR, GeoMesh, Field > > New(const tmp< DimensionedField< TypeR, GeoMesh, Field >> &tdf1, const word &name, const dimensionSet &dimensions)
static const char nl
Definition: Ostream.H:297
dictionary dict