1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2009-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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 PARTICLUAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "sixDoFRigidBodyMotion.H"
29 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31 void Foam::sixDoFRigidBodyMotion::applyRestraints()
33 if (restraints_.empty())
38 if (Pstream::master())
40 forAll(restraints_, rI)
44 Info<< "Restraint " << restraintNames_[rI] << ": ";
48 point rP = vector::zero;
51 vector rF = vector::zero;
54 vector rM = vector::zero;
56 restraints_[rI].restrain(*this, rP, rF, rM);
60 // Moments are returned in global axes, transforming to
61 // body local to add to torque.
62 tau() += Q().T() & (rM + ((rP - centreOfMass()) ^ rF));
68 void Foam::sixDoFRigidBodyMotion::applyConstraints(scalar deltaT)
70 if (constraints_.empty())
75 if (Pstream::master())
79 bool allConverged = true;
81 // constraint force accumulator
82 vector cFA = vector::zero;
84 // constraint moment accumulator
85 vector cMA = vector::zero;
91 forAll(constraints_, cI)
93 if (sixDoFRigidBodyMotionConstraint::debug)
95 Info<< "Constraint " << constraintNames_[cI] << ": ";
98 // constraint position
99 point cP = vector::zero;
102 vector cF = vector::zero;
105 vector cM = vector::zero;
107 bool constraintConverged = constraints_[cI].constrain
118 allConverged = allConverged && constraintConverged;
120 // Accumulate constraint force
123 // Accumulate constraint moment
124 cMA += cM + ((cP - centreOfMass()) ^ cF);
127 } while(++iteration < maxConstraintIterations_ && !allConverged);
129 if (iteration >= maxConstraintIterations_)
133 "Foam::sixDoFRigidBodyMotion::applyConstraints"
136 << nl << "Maximum number of sixDoFRigidBodyMotion constraint "
138 << maxConstraintIterations_
139 << ") exceeded." << nl
143 Info<< "sixDoFRigidBodyMotion constraints converged in "
144 << iteration << " iterations" << endl;
148 Info<< "Constraint force: " << cFA << nl
149 << "Constraint moment: " << cMA
153 // Add the constraint forces and moments to the motion state variables
156 // The moment of constraint forces has already been added
157 // during accumulation. Moments are returned in global axes,
158 // transforming to body local
159 tau() += Q().T() & cMA;
164 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
166 Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion()
173 maxConstraintIterations_(0),
174 initialCentreOfMass_(vector::zero),
176 momentOfInertia_(diagTensor::one*VSMALL),
182 Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion
184 const point& centreOfMass,
191 const point& initialCentreOfMass,
192 const tensor& initialQ,
193 const diagTensor& momentOfInertia,
210 maxConstraintIterations_(0),
211 initialCentreOfMass_(initialCentreOfMass),
213 momentOfInertia_(momentOfInertia),
219 Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion(const dictionary& dict)
226 maxConstraintIterations_(0),
229 dict.lookupOrDefault("initialCentreOfMass", centreOfMass())
233 dict.lookupOrDefault("initialOrientation", Q())
235 momentOfInertia_(dict.lookup("momentOfInertia")),
236 mass_(readScalar(dict.lookup("mass"))),
237 report_(dict.lookupOrDefault<Switch>("report", false))
241 addConstraints(dict);
245 Foam::sixDoFRigidBodyMotion::sixDoFRigidBodyMotion
247 const sixDoFRigidBodyMotion& sDoFRBM
250 motionState_(sDoFRBM.motionState()),
251 restraints_(sDoFRBM.restraints()),
252 restraintNames_(sDoFRBM.restraintNames()),
253 constraints_(sDoFRBM.constraints()),
254 constraintNames_(sDoFRBM.constraintNames()),
255 maxConstraintIterations_(sDoFRBM.maxConstraintIterations()),
256 initialCentreOfMass_(sDoFRBM.initialCentreOfMass()),
257 initialQ_(sDoFRBM.initialQ()),
258 momentOfInertia_(sDoFRBM.momentOfInertia()),
259 mass_(sDoFRBM.mass()),
260 report_(sDoFRBM.report())
264 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
266 Foam::sixDoFRigidBodyMotion::~sixDoFRigidBodyMotion()
270 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
272 void Foam::sixDoFRigidBodyMotion::addRestraints
274 const dictionary& dict
277 if (dict.found("restraints"))
279 const dictionary& restraintDict = dict.subDict("restraints");
283 restraints_.setSize(restraintDict.size());
285 restraintNames_.setSize(restraintDict.size());
287 forAllConstIter(IDLList<entry>, restraintDict, iter)
291 // Info<< "Adding restraint: " << iter().keyword() << endl;
296 sixDoFRigidBodyMotionRestraint::New(iter().dict())
299 restraintNames_[i] = iter().keyword();
305 restraints_.setSize(i);
307 restraintNames_.setSize(i);
312 void Foam::sixDoFRigidBodyMotion::addConstraints
314 const dictionary& dict
317 if (dict.found("constraints"))
319 const dictionary& constraintDict = dict.subDict("constraints");
323 constraints_.setSize(constraintDict.size());
325 constraintNames_.setSize(constraintDict.size());
327 forAllConstIter(IDLList<entry>, constraintDict, iter)
331 // Info<< "Adding constraint: " << iter().keyword() << endl;
336 sixDoFRigidBodyMotionConstraint::New(iter().dict())
339 constraintNames_[i] = iter().keyword();
345 constraints_.setSize(i);
347 constraintNames_.setSize(i);
349 if (!constraints_.empty())
351 maxConstraintIterations_ = readLabel
353 constraintDict.lookup("maxIterations")
360 void Foam::sixDoFRigidBodyMotion::updatePosition
365 // First leapfrog velocity adjust and motion part, required before
368 if (Pstream::master())
370 v() += 0.5*deltaT*a();
372 pi() += 0.5*deltaT*tau();
374 // Leapfrog move part
375 centreOfMass() += deltaT*v();
377 // Leapfrog orientation adjustment
379 rotate(Q(), pi(), deltaT);
382 Pstream::scatter(motionState_);
386 void Foam::sixDoFRigidBodyMotion::updateForce
388 const vector& fGlobal,
389 const vector& tauGlobal,
393 // Second leapfrog velocity adjust part, required after motion and
396 if (Pstream::master())
400 tau() = (Q().T() & tauGlobal);
404 applyConstraints(deltaT);
406 v() += 0.5*deltaT*a();
408 pi() += 0.5*deltaT*tau();
416 Pstream::scatter(motionState_);
420 void Foam::sixDoFRigidBodyMotion::updateForce
422 const pointField& positions,
423 const vectorField& forces,
427 vector a = vector::zero;
429 vector tau = vector::zero;
431 if (Pstream::master())
435 const vector& f = forces[i];
439 tau += Q().T() & ((positions[i] - centreOfMass()) ^ f);
443 updateForce(a, tau, deltaT);
447 Foam::point Foam::sixDoFRigidBodyMotion::predictedPosition
449 const point& pInitial,
450 const vector& deltaForce,
451 const vector& deltaMoment,
455 vector vTemp = v() + deltaT*(a() + deltaForce/mass_);
457 vector piTemp = pi() + deltaT*(tau() + (Q().T() & deltaMoment));
459 point centreOfMassTemp = centreOfMass() + deltaT*vTemp;
463 rotate(QTemp, piTemp, deltaT);
468 + (QTemp & initialQ_.T() & (pInitial - initialCentreOfMass_))
473 Foam::vector Foam::sixDoFRigidBodyMotion::predictedOrientation
475 const vector& vInitial,
476 const vector& deltaMoment,
480 vector piTemp = pi() + deltaT*(tau() + (Q().T() & deltaMoment));
484 rotate(QTemp, piTemp, deltaT);
486 return (QTemp & initialQ_.T() & vInitial);
490 void Foam::sixDoFRigidBodyMotion::status() const
492 Info<< "Centre of mass: " << centreOfMass() << nl
493 << "Linear velocity: " << v() << nl
494 << "Angular velocity: " << omega()
499 // ************************************************************************* //