forwardDynamics.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 | Copyright (C) 2016 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 "rigidBodyModel.H"
27 #include "rigidBodyModelState.H"
28 #include "rigidBodyRestraint.H"
29 
30 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
31 
33 (
34  scalarField& tau,
36 ) const
37 {
38  if (restraints_.empty())
39  {
40  return;
41  }
42 
43  forAll(restraints_, ri)
44  {
45  DebugInfo << "Restraint " << restraints_[ri].name();
46 
47  // Accumulate the restraint forces
48  restraints_[ri].restrain(tau, fx);
49  }
50 }
51 
52 
54 (
55  rigidBodyModelState& state,
56  const scalarField& tau,
57  const Field<spatialVector>& fx
58 ) const
59 {
60  const scalarField& q = state.q();
61  const scalarField& qDot = state.qDot();
62  scalarField& qDdot = state.qDdot();
63 
65  << "q = " << q << nl
66  << "qDot = " << qDot << nl
67  << "tau = " << tau << endl;
68 
69  // Joint state returned by jcalc
70  joint::XSvc J;
71 
72  v_[0] = Zero;
73 
74  for (label i=1; i<nBodies(); i++)
75  {
76  const joint& jnt = joints()[i];
77  jnt.jcalc(J, q, qDot);
78 
79  S_[i] = J.S;
80  S1_[i] = J.S1;
81 
82  Xlambda_[i] = J.X & XT_[i];
83 
84  const label lambdai = lambda_[i];
85 
86  if (lambdai != 0)
87  {
88  X0_[i] = Xlambda_[i] & X0_[lambdai];
89  }
90  else
91  {
92  X0_[i] = Xlambda_[i];
93  }
94 
95  v_[i] = (Xlambda_[i] & v_[lambdai]) + J.v;
96  c_[i] = J.c + (v_[i] ^ J.v);
97  IA_[i] = I(i);
98  pA_[i] = v_[i] ^* (I(i) & v_[i]);
99 
100  if (fx.size())
101  {
102  pA_[i] -= *X0_[i] & fx[i];
103  }
104  }
105 
106  for (label i=nBodies()-1; i>0; i--)
107  {
108  const joint& jnt = joints()[i];
109  const label qi = jnt.qIndex();
110 
111  if (jnt.nDoF() == 1)
112  {
113  U1_[i] = IA_[i] & S1_[i];
114  Dinv_[i].xx() = 1/(S1_[i] && U1_[i]);
115  u_[i].x() = tau[qi] - (S1_[i] && pA_[i]);
116 
117  const label lambdai = lambda_[i];
118 
119  if (lambdai != 0)
120  {
121  const spatialTensor Ia
122  (
123  IA_[i] - (U1_[i]*(Dinv_[i].xx()*U1_[i]))
124  );
125 
126  const spatialVector pa
127  (
128  pA_[i] + (Ia & c_[i]) + U1_[i]*(Dinv_[i].xx()*u_[i].x())
129  );
130 
131  IA_[lambdai] +=
132  spatialTensor(Xlambda_[i].T())
133  & Ia
134  & spatialTensor(Xlambda_[i]);
135 
136  pA_[lambdai] += Xlambda_[i].T() & pa;
137  }
138  }
139  else
140  {
141  U_[i] = IA_[i] & S_[i];
142  Dinv_[i] = (S_[i].T() & U_[i]).inv();
143 
144  u_[i] = tau.block<vector>(qi) - (S_[i].T() & pA_[i]);
145 
146  const label lambdai = lambda_[i];
147 
148  if (lambdai != 0)
149  {
150  spatialTensor Ia
151  (
152  IA_[i]
153  - (U_[i] & Dinv_[i] & U_[i].T())
154  );
155 
156  spatialVector pa
157  (
158  pA_[i]
159  + (Ia & c_[i])
160  + (U_[i] & Dinv_[i] & u_[i])
161  );
162 
163  IA_[lambdai] +=
164  spatialTensor(Xlambda_[i].T())
165  & Ia
166  & spatialTensor(Xlambda_[i]);
167 
168  pA_[lambdai] += Xlambda_[i].T() & pa;
169  }
170  }
171  }
172 
173  a_[0] = spatialVector(Zero, -g_);
174 
175  for (label i=1; i<nBodies(); i++)
176  {
177  const joint& jnt = joints()[i];
178  const label qi = jnt.qIndex();
179 
180  a_[i] = (Xlambda_[i] & a_[lambda_[i]]) + c_[i];
181 
182  if (jnt.nDoF() == 1)
183  {
184  qDdot[qi] = Dinv_[i].xx()*(u_[i].x() - (U1_[i] && a_[i]));
185  a_[i] += S1_[i]*qDdot[qi];
186  }
187  else
188  {
189  vector qDdoti(Dinv_[i] & (u_[i] - (U_[i].T() & a_[i])));
190 
191  // Need to add mutable "block<vector>" to Field
192  qDdot[qi] = qDdoti.x();
193  qDdot[qi+1] = qDdoti.y();
194  qDdot[qi+2] = qDdoti.z();
195 
196  a_[i] += (S_[i] & qDdoti);
197  }
198  }
199 
200  DebugInfo
201  << "qDdot = " << qDdot << nl
202  << "a = " << a_ << endl;
203 }
204 
205 
207 (
208  const rigidBodyModelState& state
209 ) const
210 {
212 
213  const scalarField& q = state.q();
214  const scalarField& qDot = state.qDot();
215  const scalarField& qDdot = state.qDdot();
216 
217  // Joint state returned by jcalc
218  joint::XSvc J;
219 
220  v_[0] = Zero;
221  a_[0] = spatialVector(Zero, -g_);
222 
223  for (label i=1; i<nBodies(); i++)
224  {
225  const joint& jnt = joints()[i];
226  const label qi = jnt.qIndex();
227 
228  jnt.jcalc(J, q, qDot);
229 
230  S_[i] = J.S;
231  S1_[i] = J.S1;
232 
233  Xlambda_[i] = J.X & XT_[i];
234 
235  const label lambdai = lambda_[i];
236 
237  if (lambdai != 0)
238  {
239  X0_[i] = Xlambda_[i] & X0_[lambdai];
240  }
241  else
242  {
243  X0_[i] = Xlambda_[i];
244  }
245 
246  v_[i] = (Xlambda_[i] & v_[lambdai]) + J.v;
247  c_[i] = J.c + (v_[i] ^ J.v);
248  a_[i] = (Xlambda_[i] & a_[lambdai]) + c_[i];
249 
250  if (jnt.nDoF() == 1)
251  {
252  a_[i] += S1_[i]*qDdot[qi];
253  }
254  else
255  {
256  a_[i] += S_[i] & qDdot.block<vector>(qi);
257  }
258  }
259 
260  DebugInfo<< "a = " << a_ << endl;
261 }
262 
263 
264 // ************************************************************************* //
Abstract base-class for all rigid-body joints.
Definition: joint.H:79
Templated 3D spatial tensor derived from MatrixSpace used to represent transformations of spatial vec...
Definition: SpatialTensor.H:64
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
spatialVector v
The constrained joint velocity.
Definition: joint.H:133
spatialVector S1
The joint motion sub-space (1-DoF)
Definition: joint.H:130
void forwardDynamicsCorrection(const rigidBodyModelState &state) const
Correct the velocity and acceleration of the bodies in the model.
compactSpatialTensor S
The joint motion sub-space (3-DoF)
Definition: joint.H:127
dimensionedSphericalTensor inv(const dimensionedSphericalTensor &dt)
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
void applyRestraints(scalarField &tau, Field< spatialVector > &fx) const
Apply the restraints and accumulate the internal joint forces.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
const Cmpt & z() const
Definition: VectorI.H:87
spatialVector c
The constrained joint acceleration correction.
Definition: joint.H:137
const Cmpt & y() const
Definition: VectorI.H:81
SpatialTensor< scalar > spatialTensor
SpatialTensor of scalars.
Definition: spatialTensor.H:47
Holds the motion state of rigid-body model.
Joint state returned by jcalc.
Definition: joint.H:119
static const Identity< scalar > I
Definition: Identity.H:93
const scalarField & q() const
Return access to the joint position and orientation.
SpatialVector< scalar > spatialVector
SpatialVector of scalars.
Definition: spatialVector.H:47
#define DebugInFunction
Report an information message using Foam::Info.
const scalarField & qDot() const
Return access to the joint quaternion.
static const zero Zero
Definition: zero.H:91
VSForm block(const label start) const
Definition: Field.C:705
const Cmpt & x() const
Definition: VectorI.H:75
#define DebugInfo
Report an information message using Foam::Info.
label nDoF() const
Return the number of degrees of freedom in this joint.
Definition: jointI.H:38
static const char nl
Definition: Ostream.H:262
virtual void jcalc(XSvc &J, const scalarField &q, const scalarField &qDot) const =0
Update the rigidBodyModel state for the joint given.
const volScalarField & T
spatialTransform X
The joint transformation.
Definition: joint.H:124
const scalarField & qDdot() const
Return access to the joint acceleration.
void forwardDynamics(rigidBodyModelState &state, const scalarField &tau, const Field< spatialVector > &fx) const
Calculate the joint acceleration qDdot from the joint state q,.