diff --git a/applications/test/rigidBodyDynamics/spring/Make/files b/applications/test/rigidBodyDynamics/spring/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..397706b3ac9f99d312b44de7802400c655226388 --- /dev/null +++ b/applications/test/rigidBodyDynamics/spring/Make/files @@ -0,0 +1,3 @@ +spring.C + +EXE = $(FOAM_USER_APPBIN)/Test-spring diff --git a/applications/test/rigidBodyDynamics/spring/Make/options b/applications/test/rigidBodyDynamics/spring/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..4a9d828b67c8d2e6090ad4601496f7cd38dbe731 --- /dev/null +++ b/applications/test/rigidBodyDynamics/spring/Make/options @@ -0,0 +1,5 @@ +EXE_INC = \ + -I$(LIB_SRC)/rigidBodyDynamics/lnInclude + +EXE_LIBS = \ + -lrigidBodyDynamics diff --git a/applications/test/rigidBodyDynamics/spring/spring b/applications/test/rigidBodyDynamics/spring/spring new file mode 100644 index 0000000000000000000000000000000000000000..3024b0622b795eeeecca0f66da91cf3b5dd6a393 --- /dev/null +++ b/applications/test/rigidBodyDynamics/spring/spring @@ -0,0 +1,30 @@ +bodies +{ + weight + { + type rigidBody; + mass 9.6; + centreOfMass (0 0 0); + inertia (0.1052 0 0 0.1052 0 0.1778); + parent root; + transform (1 0 0 0 1 0 0 0 1) (0 0 0); + joint + { + type Pz; + } + } +} + +restraints +{ + spring + { + type linearSpring; + body weight; + anchor (0 0 0.5); + refAttachmentPt (0 0 0); + stiffness 5000; + damping 50; + restLength 0.4; + } +} diff --git a/applications/test/rigidBodyDynamics/spring/spring.C b/applications/test/rigidBodyDynamics/spring/spring.C new file mode 100644 index 0000000000000000000000000000000000000000..65c6e88a5a74297240643620a7d672cbfca29b25 --- /dev/null +++ b/applications/test/rigidBodyDynamics/spring/spring.C @@ -0,0 +1,109 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + spring + +Description + Simple weight and damped-spirng simulation with 1-DoF. + +\*---------------------------------------------------------------------------*/ + +#include "rigidBodyModel.H" +#include "masslessBody.H" +#include "sphere.H" +#include "joints.H" +#include "IFstream.H" +#include "OFstream.H" + +using namespace Foam; +using namespace RBD; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + // Create the spring model from dictionary + rigidBodyModel spring(dictionary(IFstream("spring")())); + + Info<< spring << endl; + + // Create the joint-space state fields + scalarField q(spring.nDoF(), Zero); + scalarField w(spring.nw(), Zero); + scalarField qDot(spring.nDoF(), Zero); + scalarField qDdot(spring.nDoF(), Zero); + scalarField tau(spring.nDoF(), Zero); + Field<spatialVector> fx(spring.nBodies(), Zero); + + OFstream qFile("qVsTime"); + OFstream qDotFile("qDotVsTime"); + + // Integrate the motion of the spring for 4s using a symplectic method + scalar deltaT = 0.002; + for (scalar t=0; t<4; t+=deltaT) + { + qDot += 0.5*deltaT*qDdot; + q += deltaT*qDot; + + // Update the body-state prior to the evaluation of the restraints + spring.forwardDynamicsCorrection + ( + q, + w, + qDot, + qDdot + ); + + // Accumulate the restraint forces + fx = Zero; + spring.applyRestraints(fx); + + // Calculate the body acceleration for the given state + // and restraint forces + spring.forwardDynamics + ( + q, + w, + qDot, + tau, + fx, + qDdot + ); + + // Update the velocity + qDot += 0.5*deltaT*qDdot; + + // Write the results for graph generation + // using 'gnuplot spring.gnuplot' + qFile << t << " " << q[0] << endl; + qDotFile << t << " " << qDot[0] << endl; + } + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/rigidBodyDynamics/spring/spring.gnuplot b/applications/test/rigidBodyDynamics/spring/spring.gnuplot new file mode 100644 index 0000000000000000000000000000000000000000..28813508f43c6d8ac405e9a7c3007f7468226546 --- /dev/null +++ b/applications/test/rigidBodyDynamics/spring/spring.gnuplot @@ -0,0 +1,76 @@ +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation +# \\/ M anipulation | +#------------------------------------------------------------------------------- +# License +# This file is part of OpenFOAM. +# +# OpenFOAM is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. +# +# Script +# spring.gnuplot +# +# Description +# Creates an PostScript graph file of Test-spring results vs +# the analytical solution. +# +#------------------------------------------------------------------------------ + +reset + +set samples 2000 + +k = 5000.0 +m = 9.6 +c = 50.0 +a = -0.1 + +omega = sqrt(k/m) +zeta = c/(2.0*m*omega) + +phi = atan((sqrt(1.0 - zeta**2))/zeta) +A = a/sin(phi) + +pos(A, t, omega, phi, zeta) = A*exp(-zeta*omega*t)*sin(sqrt(1-zeta**2)*omega*t + phi) +vel(A, t, omega, phi, zeta) = \ +A*exp(-zeta*omega*t)*\ +( \ + sqrt(1-zeta**2)*omega*cos(sqrt(1-zeta**2)*omega*t + phi) \ +- zeta*omega*sin(sqrt(1-zeta**2)*omega*t + phi) \ +) + +set xlabel "Time/[s]" +set ylabel "Position" + +set ytics nomirror +set y2tics + +set yrange [-0.1:0.1] +set y2range [-2:2] + +set xzeroaxis + +set terminal postscript eps color enhanced solid +set output "spring.eps" + +plot \ + "qVsTime" u 1:($2 - 0.1) w l t "Simulation, centre of mass relative to start", \ + pos(A, x, omega, phi, zeta) w l t "Analytical solution, centre of mass", \ + "qDotVsTime" u 1:2 w l axes x1y2 t "Simulation, vertical velocity", \ + vel(A, x, omega, phi, zeta) w l axes x1y2 t "Analytical solution, vertical velocity" + +#------------------------------------------------------------------------------ diff --git a/src/rigidBodyDynamics/Make/files b/src/rigidBodyDynamics/Make/files index 5849d63b1ea1872d008c983599b990fd11a19877..ad592dc7ef55ea41c5c897759e87d8834fd721a0 100644 --- a/src/rigidBodyDynamics/Make/files +++ b/src/rigidBodyDynamics/Make/files @@ -25,6 +25,10 @@ joints/Pz/Pz.C joints/Pa/Pa.C joints/Pxyz/Pxyz.C +restraints/restraint/rigidBodyRestraint.C +restraints/restraint/rigidBodyRestraintNew.C +restraints/linearSpring/linearSpring.C + rigidBodyModel/rigidBodyModel.C rigidBodyModel/forwardDynamics.C diff --git a/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.C b/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.C new file mode 100644 index 0000000000000000000000000000000000000000..ed1efb7f4244c410869f8d555ea80de379814e0c --- /dev/null +++ b/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.C @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "linearSpring.H" +#include "rigidBodyModel.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace RBD +{ +namespace restraints +{ + defineTypeNameAndDebug(linearSpring, 0); + + addToRunTimeSelectionTable + ( + restraint, + linearSpring, + dictionary + ); +} +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::RBD::restraints::linearSpring::linearSpring +( + const word& name, + const dictionary& dict, + const rigidBodyModel& model +) +: + restraint(name, dict, model), + anchor_(), + refAttachmentPt_(), + stiffness_(), + damping_(), + restLength_() +{ + read(dict); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::RBD::restraints::linearSpring::~linearSpring() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +Foam::spatialVector Foam::RBD::restraints::linearSpring::restrain() const +{ + spatialVector attachmentPt + ( + model_.X0(bodyIndex_).inv() && spatialVector(Zero, refAttachmentPt_) + ); + + // Current axis of the spring + vector r = attachmentPt.l() - anchor_; + scalar magR = mag(r); + r /= (magR + VSMALL); + + // Velocity of the end of the spring + vector v = model_.v(bodyIndex_, refAttachmentPt_).l(); + + // Force and moment including optional damping + vector force = (-stiffness_*(magR - restLength_) - damping_*(r & v))*r; + vector moment = (attachmentPt.l() - model_.X0(bodyIndex_).r()) ^ force; + + if (model_.debug) + { + Info<< " attachmentPt - anchor " << r*magR + << " spring length " << magR + << " force " << force + << " moment " << moment + << endl; + } + + return spatialVector(moment, force); +} + + +bool Foam::RBD::restraints::linearSpring::read +( + const dictionary& dict +) +{ + restraint::read(dict); + + coeffs_.lookup("anchor") >> anchor_; + coeffs_.lookup("refAttachmentPt") >> refAttachmentPt_; + coeffs_.lookup("stiffness") >> stiffness_; + coeffs_.lookup("damping") >> damping_; + coeffs_.lookup("restLength") >> restLength_; + + return true; +} + + +void Foam::RBD::restraints::linearSpring::write +( + Ostream& os +) const +{ + restraint::write(os); + + os.writeKeyword("anchor") + << anchor_ << token::END_STATEMENT << nl; + + os.writeKeyword("refAttachmentPt") + << refAttachmentPt_ << token::END_STATEMENT << nl; + + os.writeKeyword("stiffness") + << stiffness_ << token::END_STATEMENT << nl; + + os.writeKeyword("damping") + << damping_ << token::END_STATEMENT << nl; + + os.writeKeyword("restLength") + << restLength_ << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // diff --git a/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.H b/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.H new file mode 100644 index 0000000000000000000000000000000000000000..83d26b512eba232a78b08b394b8e2567bf54dc6d --- /dev/null +++ b/src/rigidBodyDynamics/restraints/linearSpring/linearSpring.H @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::RBD::restraints::linearSpring + +Description + Linear spring restraint. + +SourceFiles + linearSpring.C + +\*---------------------------------------------------------------------------*/ + +#ifndef linearSpring_H +#define linearSpring_H + +#include "rigidBodyRestraint.H" +#include "point.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace RBD +{ +namespace restraints +{ + +/*---------------------------------------------------------------------------*\ + Class linearSpring Declaration +\*---------------------------------------------------------------------------*/ + +class linearSpring +: + public restraint +{ + // Private data + + //- Anchor point, where the spring is attached to an immovable + // object + point anchor_; + + //- Reference point of attachment to the solid body + point refAttachmentPt_; + + //- Spring stiffness coefficient (N/m) + scalar stiffness_; + + //- Damping coefficient (Ns/m) + scalar damping_; + + //- Rest length - length of spring when no forces are applied to it + scalar restLength_; + + +public: + + //- Runtime type information + TypeName("linearSpring"); + + + // Constructors + + //- Construct from components + linearSpring + ( + const word& name, + const dictionary& dict, + const rigidBodyModel& model + ); + + //- Construct and return a clone + virtual autoPtr<restraint> clone() const + { + return autoPtr<restraint> + ( + new linearSpring(*this) + ); + } + + + //- Destructor + virtual ~linearSpring(); + + + // Member Functions + + //- Return the external force applied to the body by this restraint + virtual spatialVector restrain() const; + + //- Update properties from given dictionary + virtual bool read(const dictionary& dict); + + //- Write + virtual void write(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace restraints +} // End namespace RBD +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.C b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.C new file mode 100644 index 0000000000000000000000000000000000000000..3a75c4efbba5aa0015732cbad2f6c6a4d16530d6 --- /dev/null +++ b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.C @@ -0,0 +1,84 @@ +/*---------------------------------------------------------------------------* \ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "rigidBodyRestraint.H" +#include "rigidBodyModel.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace RBD +{ + defineTypeNameAndDebug(restraint, 0); + defineRunTimeSelectionTable(restraint, dictionary); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::RBD::restraint::restraint +( + const word& name, + const dictionary& dict, + const rigidBodyModel& model +) +: + name_(name), + bodyIndex_(model.bodyID(dict.lookup("body"))), + coeffs_(dict), + model_(model) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::RBD::restraint::~restraint() +{} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +const Foam::dictionary& Foam::RBD::restraint::coeffDict() const +{ + return coeffs_; +} + + +bool Foam::RBD::restraint::read(const dictionary& dict) +{ + coeffs_ = dict; + return true; +} + + +void Foam::RBD::restraint::write(Ostream& os) const +{ + os.writeKeyword("type") << type() << token::END_STATEMENT << nl; +} + + +// ************************************************************************* // diff --git a/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.H b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.H new file mode 100644 index 0000000000000000000000000000000000000000..917e2e6e1993886f87fe05a898c6bc4ebd2667b9 --- /dev/null +++ b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraint.H @@ -0,0 +1,171 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Namespace + Foam::RBD::restraints + +Description + Namespace for rigid-body dynamics restraints + +Class + Foam::RBD::restraint + +Description + Base class for defining restraints for rigid-body dynamics + +SourceFiles + rigidBodyRestraint.C + rigidBodyRestraintNew.C + +\*---------------------------------------------------------------------------*/ + +#ifndef RBD_restraint_H +#define RBD_restraint_H + +#include "dictionary.H" +#include "autoPtr.H" +#include "spatialVector.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace RBD +{ + +// Forward declaration of classes +class rigidBodyModel; + +/*---------------------------------------------------------------------------*\ + Class restraint Declaration +\*---------------------------------------------------------------------------*/ + +class restraint +{ + +protected: + + // Protected data + + //- Name of the restraint + word name_; + + //- Index of the body the restraint is applied to + label bodyIndex_; + + //- Restraint model specific coefficient dictionary + dictionary coeffs_; + + //- Reference to the model + const rigidBodyModel& model_; + + +public: + + //- Runtime type information + TypeName("restraint"); + + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + restraint, + dictionary, + ( + const word& name, + const dictionary& dict, + const rigidBodyModel& model + ), + (name, dict, model) + ); + + + // Constructors + + //- Construct from the dict dictionary and Time + restraint + ( + const word& name, + const dictionary& dict, + const rigidBodyModel& model + ); + + //- Construct and return a clone + virtual autoPtr<restraint> clone() const = 0; + + + // Selectors + + //- Select constructed from the dict dictionary and Time + static autoPtr<restraint> New + ( + const word& name, + const dictionary& dict, + const rigidBodyModel& model + ); + + + //- Destructor + virtual ~restraint(); + + + // Member Functions + + //- Return the name + const word& name() const + { + return name_; + } + + label bodyIndex() const + { + return bodyIndex_; + } + + //- Return the external force applied to the body by this restraint + virtual spatialVector restrain() const = 0; + + //- Update properties from given dictionary + virtual bool read(const dictionary& dict); + + //- Return access to coeffs + const dictionary& coeffDict() const; + + //- Write + virtual void write(Ostream&) const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace RBD +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraintNew.C b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraintNew.C new file mode 100644 index 0000000000000000000000000000000000000000..ee8e0f2f1c844e8a7bc65e8d018d81cedf37bb05 --- /dev/null +++ b/src/rigidBodyDynamics/restraints/restraint/rigidBodyRestraintNew.C @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "rigidBodyRestraint.H" + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::RBD::restraint> +Foam::RBD::restraint::New +( + const word& name, + const dictionary& dict, + const rigidBodyModel& model +) +{ + const word restraintType(dict.lookup("type")); + + dictionaryConstructorTable::iterator cstrIter = + dictionaryConstructorTablePtr_->find(restraintType); + + if (cstrIter == dictionaryConstructorTablePtr_->end()) + { + FatalErrorInFunction + << "Unknown restraint type " + << restraintType << nl << nl + << "Valid restraint types are : " << endl + << dictionaryConstructorTablePtr_->sortedToc() + << exit(FatalError); + } + + return autoPtr<restraint>(cstrIter()(name, dict, model)); +} + + +// ************************************************************************* // diff --git a/src/rigidBodyDynamics/rigidBodyModel/forwardDynamics.C b/src/rigidBodyDynamics/rigidBodyModel/forwardDynamics.C index fc7bfd5e0c93e4bdf2688e5fe37a449d2e573f8a..411404dd85532e025d425424b532a267c2e5f971 100644 --- a/src/rigidBodyDynamics/rigidBodyModel/forwardDynamics.C +++ b/src/rigidBodyDynamics/rigidBodyModel/forwardDynamics.C @@ -27,6 +27,23 @@ License // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // +void Foam::RBD::rigidBodyModel::applyRestraints(Field<spatialVector>& fx) const +{ + if (restraints_.empty()) + { + return; + } + + forAll(restraints_, ri) + { + DebugInfo << "Restraint " << restraints_[ri].name(); + + // Accumulate the restraint forces + fx[restraints_[ri].bodyIndex()] += restraints_[ri].restrain(); + } +} + + void Foam::RBD::rigidBodyModel::forwardDynamics ( const scalarField& q, diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C index e292fcb525d9fa1d596862ee96dcc66c43e5fc9b..fe6471ac30a61b345c88465d30a781f6a9f5fc8e 100644 --- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C +++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.C @@ -78,6 +78,41 @@ void Foam::RBD::rigidBodyModel::resizeState() } +void Foam::RBD::rigidBodyModel::addRestraints +( + const dictionary& dict +) +{ + if (dict.found("restraints")) + { + const dictionary& restraintDict = dict.subDict("restraints"); + + label i = 0; + + restraints_.setSize(restraintDict.size()); + + forAllConstIter(IDLList<entry>, restraintDict, iter) + { + if (iter().isDict()) + { + restraints_.set + ( + i++, + restraint::New + ( + iter().keyword(), + iter().dict(), + *this + ) + ); + } + } + + restraints_.setSize(i); + } +} + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * // Foam::RBD::rigidBodyModel::rigidBodyModel() @@ -120,6 +155,9 @@ Foam::RBD::rigidBodyModel::rigidBodyModel(const dictionary& dict) ); } } + + // Read the restraints and any other re-readable settings. + read(dict); } @@ -144,8 +182,8 @@ Foam::label Foam::RBD::rigidBodyModel::join_ if (merged(parentID)) { const subBody& sBody = mergedBody(parentID); - lambda_.append(sBody.parentID()); - XT_.append(XT & sBody.parentXT()); + lambda_.append(sBody.masterID()); + XT_.append(XT & sBody.masterXT()); } else { @@ -279,16 +317,16 @@ Foam::label Foam::RBD::rigidBodyModel::merge { const subBody& sBody = mergedBody(parentID); - makeComposite(sBody.parentID()); + makeComposite(sBody.masterID()); sBodyPtr.set ( new subBody ( bodyPtr, - bodies_[sBody.parentID()].name(), - sBody.parentID(), - XT & sBody.parentXT() + bodies_[sBody.masterID()].name(), + sBody.masterID(), + XT & sBody.masterXT() ) ); } @@ -312,7 +350,7 @@ Foam::label Foam::RBD::rigidBodyModel::merge mergedBodies_.append(sBodyPtr); // Merge the sub-body with the parent - bodies_[sBody.parentID()].merge(sBody); + bodies_[sBody.masterID()].merge(sBody); const label sBodyID = mergedBodyID(mergedBodies_.size() - 1); bodyIDs_.insert(sBody.name(), sBodyID); @@ -329,7 +367,7 @@ Foam::spatialTransform Foam::RBD::rigidBodyModel::X0 if (merged(bodyId)) { const subBody& mBody = mergedBody(bodyId); - return mBody.parentXT() & X0_[mBody.parentID()]; + return mBody.masterXT() & X0_[mBody.masterID()]; } else { @@ -376,15 +414,45 @@ void Foam::RBD::rigidBodyModel::write(Ostream& os) const mergedBodies_[i].body().write(os); os.writeKeyword("transform") - << mergedBodies_[i].parentXT() << token::END_STATEMENT << nl; + << mergedBodies_[i].masterXT() << token::END_STATEMENT << nl; os.writeKeyword("mergeWith") - << mergedBodies_[i].parentName() << token::END_STATEMENT << nl; + << mergedBodies_[i].masterName() << token::END_STATEMENT << nl; os << decrIndent << indent << token::END_BLOCK << endl; } os << decrIndent << indent << token::END_BLOCK << nl; + + + if (!restraints_.empty()) + { + os << indent << "restraints" << nl + << indent << token::BEGIN_BLOCK << incrIndent << nl; + + forAll(restraints_, ri) + { + word restraintType = restraints_[ri].type(); + + os << indent << restraints_[ri].name() << nl + << indent << token::BEGIN_BLOCK << incrIndent << endl; + + restraints_[ri].write(os); + + os << decrIndent << indent << token::END_BLOCK << endl; + } + + os << decrIndent << indent << token::END_BLOCK << nl; + } +} + + +bool Foam::RBD::rigidBodyModel::read(const dictionary& dict) +{ + restraints_.clear(); + addRestraints(dict); + + return true; } diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H index ff7a0a5391a47bca971a45546deab113fcfbc0d8..5f4d18fb0dfde690fce43bcc1b8035846c046d24 100644 --- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H +++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModel.H @@ -53,6 +53,7 @@ SourceFiles #include "subBody.H" #include "joint.H" #include "compositeJoint.H" +#include "rigidBodyRestraint.H" #include "PtrList.H" #include "HashTable.H" @@ -85,6 +86,9 @@ class rigidBodyModel //- Convert the body with given ID into a composite-body void makeComposite(const label bodyID); + //- Add restraints to the motion + void addRestraints(const dictionary& dict); + protected: @@ -124,6 +128,9 @@ protected: // joint. label nw_; + //- Motion restraints + PtrList<restraint> restraints_; + // Other protected member data @@ -288,6 +295,10 @@ public: //- Return true if the body with given ID has been merged with a parent inline bool merged(label bodyID) const; + //- Return the ID of the master body for a sub-body otherwise + // return the given body ID + inline label master(label bodyID) const; + //- Return the index of the merged body in the mergedBody list // from the given body ID inline label mergedBodyIndex(const label mergedBodyID) const; @@ -305,6 +316,16 @@ public: //- Return the current transform to the global frame for the given body spatialTransform X0(const label bodyId) const; + // Find the corresponding point in the master body frame + vector masterPoint(const label bodyID, const vector& p) const; + + //- Return the velocity of the given point on the given body + spatialVector v(const label bodyID, const vector& p) const; + + //- Apply the restraints and accumulate the external forces + // into the fx field + void applyRestraints(Field<spatialVector>& fx) const; + //- Calculate the joint acceleration qDdot from the joint state q, // velocity qDot, internal force tau (in the joint frame) and // external force fx (in the global frame) using the articulated body @@ -333,6 +354,10 @@ public: //- Write virtual void write(Ostream&) const; + //- Read coefficients dictionary and update system parameters, + // restraints but not the current state + bool read(const dictionary& dict); + // Ostream Operator diff --git a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModelI.H b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModelI.H index 34fa0670ef822543cab3a7d4796606ef9cf94b71..478547892e9c96d63f2b4d6e0d52785d782e2ab3 100644 --- a/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModelI.H +++ b/src/rigidBodyDynamics/rigidBodyModel/rigidBodyModelI.H @@ -89,6 +89,19 @@ inline bool Foam::RBD::rigidBodyModel::merged(label bodyID) const } +inline Foam::label Foam::RBD::rigidBodyModel::master(label bodyID) const +{ + if (bodyID < 0) + { + return mergedBody(bodyID).masterID(); + } + else + { + return bodyID; + } +} + + inline Foam::label Foam::RBD::rigidBodyModel::mergedBodyID(const label mergedBodyIndex) const { @@ -123,4 +136,43 @@ inline Foam::label Foam::RBD::rigidBodyModel::bodyID(const word& name) const } +inline Foam::vector Foam::RBD::rigidBodyModel::masterPoint +( + const label bodyID, + const vector& p +) const +{ + if (merged(bodyID)) + { + return + ( + mergedBody(bodyID).masterXT().inv() + && spatialVector(Zero, p) + ).l(); + } + else + { + return p; + } +} + + +inline Foam::spatialVector Foam::RBD::rigidBodyModel::v +( + const label bodyID, + const vector& p +) const +{ + return + ( + spatialTransform + ( + X0_[master(bodyID)].E().T(), + masterPoint(bodyID, p) + ) + & v_[master(bodyID)] + ); +} + + // ************************************************************************* //