rigidBodyModel.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 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 "rigidBodyModel.H"
29 #include "masslessBody.H"
30 #include "compositeBody.H"
31 #include "jointBody.H"
32 #include "nullJoint.H"
33 #include "rigidBodyRestraint.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace RBD
40 {
41  defineTypeNameAndDebug(rigidBodyModel, 0);
42 }
43 }
44 
45 
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 
48 void Foam::RBD::rigidBodyModel::initializeRootBody()
49 {
50  bodies_.append(new masslessBody("root"));
51  lambda_.append(0);
52  bodyIDs_.insert("root", 0);
53  joints_.append(new joints::null());
54  XT_.append(spatialTransform());
55 
56  nDoF_ = 0;
57  unitQuaternions_ = false;
58 
59  resizeState();
60 }
61 
62 
63 void Foam::RBD::rigidBodyModel::resizeState()
64 {
65  Xlambda_.append(spatialTransform());
66  X0_.append(spatialTransform());
67 
68  v_.append(Zero);
69  a_.append(Zero);
70  c_.append(Zero);
71 
72  IA_.append(spatialTensor::I);
73  pA_.append(Zero);
74 
75  S_.append(Zero);
76  S1_.append(Zero);
77  U_.append(Zero);
78  U1_.append(Zero);
79  Dinv_.append(Zero);
80  u_.append(Zero);
81 }
82 
83 
84 void Foam::RBD::rigidBodyModel::addRestraints
85 (
86  const dictionary& dict
87 )
88 {
89  if (dict.found("restraints"))
90  {
91  const dictionary& restraintDict = dict.subDict("restraints");
92 
93  label i = 0;
94 
95  restraints_.setSize(restraintDict.size());
96 
97  for (const entry& dEntry : restraintDict)
98  {
99  if (dEntry.isDict())
100  {
101  restraints_.set
102  (
103  i++,
105  (
106  dEntry.keyword(),
107  dEntry.dict(),
108  *this
109  )
110  );
111  }
112  }
113 
114  restraints_.setSize(i);
115  }
116 }
117 
118 
119 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
120 
122 (
123  const label parentID,
124  const spatialTransform& XT,
125  autoPtr<joint> jointPtr,
126  autoPtr<rigidBody> bodyPtr
127 )
128 {
129  // Append the body
130  const rigidBody& body = bodyPtr();
131  bodies_.append(bodyPtr);
132  const label bodyID = nBodies()-1;
133  bodyIDs_.insert(body.name(), bodyID);
134 
135  // If the parentID refers to a merged body find the parent into which it has
136  // been merged and set lambda and XT accordingly
137  if (merged(parentID))
138  {
139  const subBody& sBody = mergedBody(parentID);
140  lambda_.append(sBody.masterID());
141  XT_.append(XT & sBody.masterXT());
142  }
143  else
144  {
145  lambda_.append(parentID);
146  XT_.append(XT);
147  }
148 
149  // Append the joint
150  const joint& prevJoint = joints_[joints_.size() - 1];
151  joints_.append(jointPtr);
152  joint& curJoint = joints_[joints_.size() - 1];
153  curJoint.index() = joints_.size() - 1;
154  curJoint.qIndex() = prevJoint.qIndex() + prevJoint.nDoF();
155 
156  // Increment the degrees of freedom
157  nDoF_ += curJoint.nDoF();
158  unitQuaternions_ = unitQuaternions_ || curJoint.unitQuaternion();
159 
160  resizeState();
161 
162  return bodyID;
163 }
164 
165 
166 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
167 
169 :
170  time_(time),
171  g_(Zero)
172 {
173  initializeRootBody();
174 }
175 
176 
178 (
179  const Time& time,
180  const dictionary& dict
181 )
182 :
183  time_(time),
184  g_(Zero)
185 {
186  initializeRootBody();
187 
188  const dictionary& bodiesDict = dict.subDict("bodies");
189 
190  for (const entry& dEntry : bodiesDict)
191  {
192  const keyType& key = dEntry.keyword();
193  const dictionary& bodyDict = dEntry.dict();
194 
195  if (bodyDict.found("mergeWith"))
196  {
197  merge
198  (
199  bodyID(bodyDict.get<word>("mergeWith")),
200  bodyDict.lookup("transform"),
201  rigidBody::New(key, bodyDict)
202  );
203  }
204  else
205  {
206  join
207  (
208  bodyID(bodyDict.get<word>("parent")),
209  bodyDict.lookup("transform"),
210  joint::New(bodyDict.subDict("joint")),
211  rigidBody::New(key, bodyDict)
212  );
213  }
214  }
215 
216  // Read the restraints and any other re-readable settings.
217  read(dict);
218 }
219 
220 
221 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
222 
224 {}
225 
226 
227 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
228 
230 (
231  const label parentID,
232  const spatialTransform& XT,
233  autoPtr<joint> jointPtr,
234  autoPtr<rigidBody> bodyPtr
235 )
236 {
237  if (isA<joints::composite>(jointPtr()))
238  {
239  return join
240  (
241  parentID,
242  XT,
244  (
245  dynamic_cast<joints::composite*>(jointPtr.ptr())
246  ),
247  bodyPtr
248  );
249  }
250  else
251  {
252  return join_
253  (
254  parentID,
255  XT,
256  jointPtr,
257  bodyPtr
258  );
259  }
260 }
261 
262 
264 (
265  const label parentID,
266  const spatialTransform& XT,
267  autoPtr<joints::composite> cJointPtr,
268  autoPtr<rigidBody> bodyPtr
269 )
270 {
271  label parent = parentID;
272  joints::composite& cJoint = cJointPtr();
273 
274  // For all but the final joint in the set add a jointBody with the
275  // joint and transform
276  for (label j=0; j<cJoint.size()-1; j++)
277  {
278  parent = join_
279  (
280  parent,
281  j == 0 ? XT : spatialTransform(),
282  cJoint[j].clone(),
284  );
285  }
286 
287  // For the final joint in the set add the real body
288  parent = join_
289  (
290  parent,
291  cJoint.size() == 1 ? XT : spatialTransform(),
292  autoPtr<joint>(cJointPtr.ptr()),
293  bodyPtr
294  );
295 
296  // Set the properties of the last joint in the list to those set
297  // by rigidBodyModel
298  cJoint.setLastJoint();
299 
300  return parent;
301 }
302 
303 
304 void Foam::RBD::rigidBodyModel::makeComposite(const label bodyID)
305 {
306  if (!isA<compositeBody>(bodies_[bodyID]))
307  {
308  // Retrieve the un-merged body
309  autoPtr<rigidBody> bodyPtr = bodies_.release(bodyID);
310 
311  // Insert the compositeBody containing the original body
312  bodies_.set
313  (
314  bodyID,
315  new compositeBody(bodyPtr)
316  );
317  }
318 }
319 
320 
322 (
323  const label parentID,
324  const spatialTransform& XT,
325  autoPtr<rigidBody> bodyPtr
326 )
327 {
328  autoPtr<subBody> sBodyPtr;
329 
330  // If the parentID refers to a merged body find the parent into which it has
331  // been merged and merge this on into the same parent with the appropriate
332  // transform
333  if (merged(parentID))
334  {
335  const subBody& sBody = mergedBody(parentID);
336 
337  makeComposite(sBody.masterID());
338 
339  sBodyPtr.reset
340  (
341  new subBody
342  (
343  bodyPtr,
344  bodies_[sBody.masterID()].name(),
345  sBody.masterID(),
346  XT & sBody.masterXT()
347  )
348  );
349  }
350  else
351  {
352  makeComposite(parentID);
353 
354  sBodyPtr.reset
355  (
356  new subBody
357  (
358  bodyPtr,
359  bodies_[parentID].name(),
360  parentID,
361  XT
362  )
363  );
364  }
365 
366  const subBody& sBody = sBodyPtr();
367  mergedBodies_.append(sBodyPtr);
368 
369  // Merge the sub-body with the parent
370  bodies_[sBody.masterID()].merge(sBody);
371 
372  const label sBodyID = mergedBodyID(mergedBodies_.size() - 1);
373  bodyIDs_.insert(sBody.name(), sBodyID);
374 
375  return sBodyID;
376 }
377 
378 
380 (
381  const label bodyId
382 ) const
383 {
384  if (merged(bodyId))
385  {
386  const subBody& mBody = mergedBody(bodyId);
387  return mBody.masterXT() & X0_[mBody.masterID()];
388  }
389 
390  return X0_[bodyId];
391 }
392 
393 
395 {
396  os.beginBlock("bodies");
397 
398  // Write the moving bodies
399  for (label i=1; i<nBodies(); i++)
400  {
401  // Do not write joint-bodies created automatically to support elements
402  // of composite joints
403  if (!isType<jointBody>(bodies_[i]))
404  {
405  os.beginBlock(bodies_[i].name());
406 
407  bodies_[i].write(os);
408 
409  os.writeEntry("parent", bodies_[lambda_[i]].name());
410  os.writeEntry("transform", XT_[i]);
411 
412  os << indent << "joint" << nl
413  << joints_[i] << endl;
414 
415  os.endBlock();
416  }
417  }
418 
419  // Write the bodies merged into the parent bodies for efficiency
420  forAll(mergedBodies_, i)
421  {
422  os.beginBlock(mergedBodies_[i].name());
423 
424  mergedBodies_[i].body().write(os);
425 
426  os.writeEntry("transform", mergedBodies_[i].masterXT());
427  os.writeEntry("mergeWith", mergedBodies_[i].masterName());
428 
429  os.endBlock();
430  }
431 
432  os.endBlock();
433 
434 
435  if (!restraints_.empty())
436  {
437  os.beginBlock("restraints");
438 
439  forAll(restraints_, ri)
440  {
441  // const word& restraintType(restraints_[ri].type());
442 
443  os.beginBlock(restraints_[ri].name());
444 
445  restraints_[ri].write(os);
446 
447  os.endBlock();
448  }
449 
450  os.endBlock();
451  }
452 }
453 
454 
456 {
457  restraints_.clear();
458  addRestraints(dict);
459 
460  return true;
461 }
462 
463 
464 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
465 
467 {
468  rbm.write(os);
469  return os;
470 }
471 
472 
473 // ************************************************************************* //
Foam::RBD::rigidBody
Definition: rigidBody.H:65
nullJoint.H
Foam::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
compositeBody.H
Foam::RBD::rigidBodyModel::~rigidBodyModel
virtual ~rigidBodyModel()
Destructor.
Definition: rigidBodyModel.C:223
Foam::autoPtr::reset
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:158
Foam::RBD::joint::New
static autoPtr< joint > New(joint *jointPtr)
Simple selector to return an autoPtr<joint> of the given joint*.
Definition: joint.C:46
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::RBD::joint::nDoF
label nDoF() const
Return the number of degrees of freedom in this joint.
Definition: jointI.H:40
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::RBD::rigidBodyModel::X0
spatialTransform X0(const label bodyId) const
Return the current transform to the global frame for the given body.
Definition: rigidBodyModel.C:380
Foam::spatialTransform
Compact representation of the Plücker spatial transformation tensor in terms of the rotation tensor E...
Definition: spatialTransform.H:70
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::dictionary::found
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Search for an entry (const access) with the given keyword.
Definition: dictionary.C:359
Foam::RBD::joints::composite
Prismatic joint for translation along the specified arbitrary axis.
Definition: compositeJoint.H:69
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::HashTable::insert
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:168
Foam::RBD::rigidBodyModel::bodies_
PtrList< rigidBody > bodies_
List of the bodies.
Definition: rigidBodyModel.H:111
Foam::RBD::compositeBody
Definition: compositeBody.H:57
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Ostream::beginBlock
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:91
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:81
Foam::RBD::subBody::masterID
label masterID() const
Return the master body Id.
Definition: subBodyI.H:71
Foam::RBD::rigidBodyModel::rigidBodyModel
rigidBodyModel(const Time &time)
Null-constructor which adds the single root-body at the origin.
Definition: rigidBodyModel.C:168
masslessBody
Foam::RBD::operator<<
Ostream & operator<<(Ostream &, const rigidBody &)
Definition: rigidBodyI.H:75
rigidBodyModel.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::keyType
A class for handling keywords in dictionaries.
Definition: keyType.H:60
Foam::RBD::rigidBodyModel::lambda_
DynamicList< label > lambda_
List of indices of the parent of each body.
Definition: rigidBodyModel.H:123
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::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:472
Foam::autoPtr::release
T * release() noexcept
Return pointer to the managed object and release ownership.
Definition: autoPtrI.H:135
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:523
Foam::RBD::rigidBodyModel::unitQuaternions_
bool unitQuaternions_
True if any of the joints using quaternions.
Definition: rigidBodyModel.H:136
Foam::autoPtr::ptr
T * ptr() noexcept
Definition: autoPtrI.H:144
Foam::PtrList::append
void append(T *ptr)
Append an element to the end of the list.
Definition: PtrListI.H:115
Foam::RBD::subBody
Definition: subBody.H:57
Foam::SpatialTensor::I
static const SpatialTensor I
Identity matrix for square matrices.
Definition: SpatialTensor.H:83
Foam::dictionary::lookup
ITstream & lookup(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionary.C:419
Foam::RBD::defineTypeNameAndDebug
defineTypeNameAndDebug(cuboid, 0)
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
Foam::Ostream::endBlock
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:109
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::RBD::rigidBodyModel::joints_
PtrList< joint > joints_
Each body it attached with a joint which are held on this list.
Definition: rigidBodyModel.H:126
Foam::indent
Ostream & indent(Ostream &os)
Indent stream.
Definition: Ostream.H:307
Foam::RBD::rigidBodyModel::nDoF_
label nDoF_
The number of degrees of freedom of the model.
Definition: rigidBodyModel.H:133
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::RBD::rigidBody::name
const word & name() const
Return name.
Definition: rigidBodyI.H:67
Foam::RBD::rigidBodyModel::join_
virtual label join_(const label parentID, const spatialTransform &XT, autoPtr< joint > jointPtr, autoPtr< rigidBody > bodyPtr)
Join the given body to the parent with ID parentID via the given.
Definition: rigidBodyModel.C:122
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::RBD::rigidBodyModel::join
virtual label join(const label parentID, const spatialTransform &XT, autoPtr< joint > jointPtr, autoPtr< rigidBody > bodyPtr)
Join the given body to the parent with ID parentID via the given.
Definition: rigidBodyModel.C:230
Foam::RBD::rigidBodyModel::read
bool read(const dictionary &dict)
Read coefficients dictionary and update system parameters,.
Definition: rigidBodyModel.C:455
Foam::RBD::rigidBodyModel::write
virtual void write(Ostream &) const
Write.
Definition: rigidBodyModel.C:394
Foam::RBD::rigidBodyModel::XT_
DynamicList< spatialTransform > XT_
Transform from the parent body frame to the joint frame.
Definition: rigidBodyModel.H:129
Foam::RBD::jointBody
Definition: jointBody.H:55
jointBody.H
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:219
Foam::RBD::joint
Abstract base-class for all rigid-body joints.
Definition: joint.H:84
Foam::RBD::subBody::masterXT
const spatialTransform & masterXT() const
Return the transform with respect to the master body.
Definition: subBodyI.H:77
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::RBD::restraint::New
static autoPtr< restraint > New(const word &name, const dictionary &dict, const rigidBodyModel &model)
Select constructed from the dict dictionary and Time.
Definition: rigidBodyRestraintNew.C:35
Foam::RBD::joint::unitQuaternion
virtual bool unitQuaternion() const
Return true if this joint describes rotation using a quaternion.
Definition: jointI.H:45
Foam::RBD::rigidBodyModel::bodyIDs_
HashTable< label > bodyIDs_
Lookup-table of the IDs of the bodies.
Definition: rigidBodyModel.H:120
Foam::RBD::subBody::name
const word & name() const
Return the body name.
Definition: subBodyI.H:59
masslessBody.H
rigidBodyRestraint.H
Foam::RBD::rigidBody::New
static autoPtr< rigidBody > New(const word &name, const scalar &m, const vector &c, const symmTensor &Ic)
Select constructed from components.
Definition: rigidBody.C:63
Foam::RBD::rigidBodyModel::merge
label merge(const label parentID, const spatialTransform &X, autoPtr< rigidBody > bodyPtr)
Merge the given body with transform X into the parent with ID.
Definition: rigidBodyModel.C:322