rigidBodyMotion.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) 2016-2017 OpenFOAM Foundation
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 
28 #include "rigidBodyMotion.H"
29 #include "rigidBodySolver.H"
30 #include "septernion.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void Foam::RBD::rigidBodyMotion::initialize()
35 {
36  // Calculate the initial body-state
37  forwardDynamicsCorrection(rigidBodyModelState(*this));
38  X00_ = X0_;
39 
40  // Update the body-state to correspond to the current joint-state
41  forwardDynamicsCorrection(motionState_);
42 }
43 
44 
45 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 
47 Foam::RBD::rigidBodyMotion::rigidBodyMotion(const Time& time)
48 :
49  rigidBodyModel(time),
50  motionState_(*this),
51  motionState0_(*this),
52  aRelax_(1.0),
53  aDamp_(1.0),
54  report_(false),
55  solver_(nullptr)
56 {}
57 
58 Foam::RBD::rigidBodyMotion::rigidBodyMotion
59 (
60  const Time& time,
61  const dictionary& dict
62 )
63 :
64  rigidBodyModel(time, dict),
65  motionState_(*this, dict),
66  motionState0_(motionState_),
67  X00_(X0_.size()),
68  aRelax_(dict.lookupOrDefault<scalar>("accelerationRelaxation", 1.0)),
69  aDamp_(dict.lookupOrDefault<scalar>("accelerationDamping", 1.0)),
70  report_(dict.lookupOrDefault<Switch>("report", false)),
71  solver_(rigidBodySolver::New(*this, dict.subDict("solver")))
72 {
73  if (dict.found("g"))
74  {
75  g() = dict.get<vector>("g");
76  }
77 
78  initialize();
79 }
80 
81 
82 Foam::RBD::rigidBodyMotion::rigidBodyMotion
83 (
84  const Time& time,
85  const dictionary& dict,
86  const dictionary& stateDict
87 )
88 :
89  rigidBodyModel(time, dict),
90  motionState_(*this, stateDict),
91  motionState0_(motionState_),
92  X00_(X0_.size()),
93  aRelax_(dict.lookupOrDefault<scalar>("accelerationRelaxation", 1.0)),
94  aDamp_(dict.lookupOrDefault<scalar>("accelerationDamping", 1.0)),
95  report_(dict.lookupOrDefault<Switch>("report", false)),
96  solver_(rigidBodySolver::New(*this, dict.subDict("solver")))
97 {
98  if (dict.found("g"))
99  {
100  g() = dict.get<vector>("g");
101  }
102 
103  initialize();
104 }
105 
106 
107 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
108 
110 {}
111 
112 
113 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
114 
116 (
117  const label bodyId
118 ) const
119 {
120  if (merged(bodyId))
121  {
122  const subBody& mBody = mergedBody(bodyId);
123  return mBody.masterXT() & X00_[mBody.masterID()];
124  }
125  else
126  {
127  return X00_[bodyId];
128  }
129 }
130 
131 
133 (
134  rigidBodyModelState& state,
135  const scalarField& tau,
136  const Field<spatialVector>& fx
137 ) const
138 {
139  scalarField qDdotPrev = state.qDdot();
140  rigidBodyModel::forwardDynamics(state, tau, fx);
141  state.qDdot() = aDamp_*(aRelax_*state.qDdot() + (1 - aRelax_)*qDdotPrev);
142 }
143 
144 
146 (
147  const scalar t,
148  const scalar deltaT,
149  const scalarField& tau,
150  const Field<spatialVector>& fx
151 )
152 {
153  motionState_.t() = t;
154  motionState_.deltaT() = deltaT;
155 
156  if (motionState0_.deltaT() < SMALL)
157  {
158  motionState0_.t() = t;
159  motionState0_.deltaT() = deltaT;
160  }
161 
162  if (Pstream::master())
163  {
164  solver_->solve(tau, fx);
165  }
166 
167  Pstream::scatter(motionState_);
168 
169  // Update the body-state to correspond to the current joint-state
170  forwardDynamicsCorrection(motionState_);
171 }
172 
173 
175 {
176  const spatialTransform CofR(X0(bodyID));
177  const spatialVector vCofR(v(bodyID, Zero));
178 
179  Info<< "Rigid-body motion of the " << name(bodyID) << nl
180  << " Centre of rotation: " << CofR.r() << nl
181  << " Orientation: " << CofR.E() << nl
182  << " Linear velocity: " << vCofR.l() << nl
183  << " Angular velocity: " << vCofR.w()
184  << endl;
185 }
186 
187 
189 (
190  const label bodyID,
191  const pointField& initialPoints
192 ) const
193 {
194  // Calculate the transform from the initial state in the global frame
195  // to the current state in the global frame
196  spatialTransform X(X0(bodyID).inv() & X00(bodyID));
197 
198  tmp<pointField> tpoints(new pointField(initialPoints.size()));
199  pointField& points = tpoints.ref();
200 
201  forAll(points, i)
202  {
203  points[i] = X.transformPoint(initialPoints[i]);
204  }
205 
206  return tpoints;
207 }
208 
209 
211 (
212  const label bodyID,
213  const scalarField& weight,
214  const pointField& initialPoints
215 ) const
216 {
217  // Calculate the transform from the initial state in the global frame
218  // to the current state in the global frame
219  spatialTransform X(X0(bodyID).inv() & X00(bodyID));
220 
221  // Calculate the septernion equivalent of the transformation for 'slerp'
222  // interpolation
223  septernion s(X);
224 
225  tmp<pointField> tpoints(new pointField(initialPoints));
226  pointField& points = tpoints.ref();
227 
228  forAll(points, i)
229  {
230  // Move non-stationary points
231  if (weight[i] > SMALL)
232  {
233  // Use solid-body motion where weight = 1
234  if (weight[i] > 1 - SMALL)
235  {
236  points[i] = X.transformPoint(initialPoints[i]);
237  }
238  // Slerp septernion interpolation
239  else
240  {
241  points[i] =
242  slerp(septernion::I, s, weight[i])
243  .transformPoint(initialPoints[i]);
244  }
245  }
246  }
247 
248  return tpoints;
249 }
250 
251 
253 (
254  const labelList& bodyIDs,
255  const List<const scalarField*>& weights,
256  const pointField& initialPoints
257 ) const
258 {
259  List<septernion> ss(bodyIDs.size() + 1);
260  ss[bodyIDs.size()] = septernion::I;
261 
262  forAll(bodyIDs, bi)
263  {
264  const label bodyID = bodyIDs[bi];
265 
266  // Calculate the transform from the initial state in the global frame
267  // to the current state in the global frame
268  spatialTransform X(X0(bodyID).inv() & X00(bodyID));
269 
270  // Calculate the septernion equivalent of the transformation
271  ss[bi] = septernion(X);
272  }
273 
274  tmp<pointField> tpoints(new pointField(initialPoints));
275  pointField& points = tpoints.ref();
276 
277  List<scalar> w(ss.size());
278 
279  forAll(points, i)
280  {
281  // Initialize to 1 for the far-field weight
282  scalar sum1mw = 1;
283 
284  forAll(bodyIDs, bi)
285  {
286  w[bi] = (*(weights[bi]))[i];
287  sum1mw += w[bi]/(1 + SMALL - w[bi]);
288  }
289 
290  // Calculate the limiter for wi/(1 - wi) to ensure the sum(wi) = 1
291  scalar lambda = 1/sum1mw;
292 
293  // Limit wi/(1 - wi) and sum the resulting wi
294  scalar sumw = 0;
295  forAll(bodyIDs, bi)
296  {
297  w[bi] = lambda*w[bi]/(1 + SMALL - w[bi]);
298  sumw += w[bi];
299  }
300 
301  // Calculate the weight for the stationary far-field
302  w[bodyIDs.size()] = 1 - sumw;
303 
304  points[i] = average(ss, w).transformPoint(initialPoints[i]);
305  }
306 
307  return tpoints;
308 }
309 
310 
311 // ************************************************************************* //
Foam::RBD::rigidBodyMotion::solve
void solve(const scalar t, const scalar deltaT, const scalarField &tau, const Field< spatialVector > &fx)
Integrate velocities, orientation and position.
Definition: rigidBodyMotion.C:146
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
rigidBodySolver.H
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:70
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::RBD::rigidBodyModelState
Holds the motion state of rigid-body model.
Definition: rigidBodyModelState.H:67
Foam::RBD::rigidBodyModelState::qDdot
const scalarField & qDdot() const
Return access to the joint acceleration.
Definition: rigidBodyModelStateI.H:42
Foam::septernion
Septernion class used to perform translations and rotations in 3D space.
Definition: septernion.H:66
s
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputSpray.H:25
Foam::spatialTransform
Compact representation of the Plücker spatial transformation tensor in terms of the rotation tensor E...
Definition: spatialTransform.H:70
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
X0
scalarList X0(nSpecie, Zero)
Foam::slerp
quaternion slerp(const quaternion &qa, const quaternion &qb, const scalar t)
Spherical linear interpolation of quaternions.
Definition: quaternion.C:78
Foam::RBD::rigidBodyMotion::status
void status(const label bodyID) const
Report the status of the motion of the given body.
Definition: rigidBodyMotion.C:174
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::RBD::subBody::masterID
label masterID() const
Return the master body Id.
Definition: subBodyI.H:71
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::RBD::rigidBodyModel::X0_
DynamicList< spatialTransform > X0_
Transform for external forces to the bodies reference frame.
Definition: rigidBodyModel.H:154
Foam::RBD::rigidBodySolver::New
static autoPtr< rigidBodySolver > New(rigidBodyMotion &body, const dictionary &dict)
Definition: newRigidBodySolver.C:34
Foam::RBD::rigidBodyModel::forwardDynamicsCorrection
void forwardDynamicsCorrection(const rigidBodyModelState &state) const
Correct the velocity and acceleration of the bodies in the model.
Definition: forwardDynamics.C:210
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:258
septernion.H
Foam::label
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:62
Foam::Field< scalar >
Foam::spatialTransform::r
const vector & r() const
Return the translation vector.
Definition: spatialTransformI.H:89
Foam::inv
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
Definition: dimensionedSphericalTensor.C:73
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::SpatialVector::l
Vector< Cmpt > l() const
Return the linear part of the spatial vector as a vector.
Definition: SpatialVectorI.H:195
Foam::SpatialVector< scalar >
Foam::RBD::subBody
Definition: subBody.H:57
Foam::spatialTransform::E
const tensor & E() const
Return the rotation tensor.
Definition: spatialTransformI.H:79
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::RBD::rigidBodyModel
Basic rigid-body model representing a system of rigid-bodies connected by 1-6 DoF joints.
Definition: rigidBodyModel.H:83
rigidBodyMotion.H
Foam::spatialTransform::transformPoint
vector transformPoint(const vector &p) const
Transform position p.
Definition: spatialTransformI.H:173
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
lambda
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
Foam::RBD::rigidBodyMotion::X00
spatialTransform X00(const label bodyId) const
Return the initial transform to the global frame for the.
Definition: rigidBodyMotion.C:116
g
const uniformDimensionedVectorField & g
Definition: createFluidFields.H:24
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
Foam::RBD::rigidBodyModel::forwardDynamics
void forwardDynamics(rigidBodyModelState &state, const scalarField &tau, const Field< spatialVector > &fx) const
Calculate the joint acceleration qDdot from the joint state q,.
Definition: forwardDynamics.C:57
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Vector< scalar >
Foam::List< label >
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::RBD::rigidBodyMotion::~rigidBodyMotion
~rigidBodyMotion()
Destructor.
Definition: rigidBodyMotion.C:109
Foam::septernion::I
static const septernion I
Definition: septernion.H:84
Foam::RBD::subBody::masterXT
const spatialTransform & masterXT() const
Return the transform with respect to the master body.
Definition: subBodyI.H:77
Foam::RBD::rigidBodyMotion::transformPoints
tmp< pointField > transformPoints(const label bodyID, const pointField &initialPoints) const
Transform the given initial pointField of the specified body.
Definition: rigidBodyMotion.C:189
Foam::RBD::rigidBodyMotion::forwardDynamics
void forwardDynamics(rigidBodyModelState &state, const scalarField &tau, const Field< spatialVector > &fx) const
Calculate and optionally relax the joint acceleration qDdot from.
Definition: rigidBodyMotion.C:133
Foam::SpatialVector::w
Vector< Cmpt > w() const
Return the angular part of the spatial vector as a vector.
Definition: SpatialVectorI.H:189
Foam::average
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:328