1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-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 PARTICULAR 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 "linearAxialAngularSpring.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "sixDoFRigidBodyMotion.H"
30 #include "transform.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 namespace sixDoFRigidBodyMotionRestraints
38 defineTypeNameAndDebug(linearAxialAngularSpring, 0);
39 addToRunTimeSelectionTable
41 sixDoFRigidBodyMotionRestraint,
42 linearAxialAngularSpring,
49 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::
52 linearAxialAngularSpring
54 const dictionary& sDoFRBMRDict
57 sixDoFRigidBodyMotionRestraint(sDoFRBMRDict),
67 // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
69 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::
70 ~linearAxialAngularSpring()
74 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
77 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::restrain
79 const sixDoFRigidBodyMotion& motion,
80 vector& restraintPosition,
81 vector& restraintForce,
82 vector& restraintMoment
85 vector refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 1, 0);
87 vector oldDir = refQ_ & refDir;
89 vector newDir = motion.orientation() & refDir;
91 if (mag(oldDir & axis_) > 0.95 || mag(newDir & axis_) > 0.95)
93 // Directions getting close to the axis, change reference
95 refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 0, 1);
97 vector oldDir = refQ_ & refDir;
99 vector newDir = motion.orientation() & refDir;
102 // Removing any axis component from oldDir and newDir and normalising
103 oldDir -= (axis_ & oldDir)*axis_;
104 oldDir /= (mag(oldDir) + VSMALL);
106 newDir -= (axis_ & newDir)*axis_;
107 newDir /= (mag(newDir) + VSMALL);
109 scalar theta = mag(acos(min(oldDir & newDir, 1.0)));
111 // Temporary axis with sign information.
112 vector a = (oldDir ^ newDir);
114 // Remove any component that is not along axis that may creep in
115 a = (a & axis_)*axis_;
117 scalar magA = mag(a);
128 // Damping of along axis angular velocity only
129 restraintMoment = -stiffness_*theta*a - damping_*(motion.omega() & a)*a;
131 restraintForce = vector::zero;
133 // Not needed to be altered as restraintForce is zero, but set to
134 // centreOfMass to be sure of no spurious moment
135 restraintPosition = motion.centreOfMass();
139 Info<< " angle " << theta*sign(a & axis_)
140 << " force " << restraintForce
141 << " moment " << restraintMoment
147 bool Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::read
149 const dictionary& sDoFRBMRDict
152 sixDoFRigidBodyMotionRestraint::read(sDoFRBMRDict);
154 refQ_ = sDoFRBMRCoeffs_.lookupOrDefault<tensor>("referenceOrientation", I);
156 if (mag(mag(refQ_) - sqrt(3.0)) > 1e-9)
160 "Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::"
163 "const dictionary& sDoFRBMRDict"
166 << "referenceOrientation " << refQ_ << " is not a rotation tensor. "
167 << "mag(referenceOrientation) - sqrt(3) = "
168 << mag(refQ_) - sqrt(3.0) << nl
172 axis_ = sDoFRBMRCoeffs_.lookup("axis");
174 scalar magAxis(mag(axis_));
176 if (magAxis > VSMALL)
184 "Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::"
187 "const dictionary& sDoFRBMCDict"
190 << "axis has zero length"
191 << abort(FatalError);
194 sDoFRBMRCoeffs_.lookup("stiffness") >> stiffness_;
196 sDoFRBMRCoeffs_.lookup("damping") >> damping_;
202 void Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::write
207 os.writeKeyword("referenceOrientation")
208 << refQ_ << token::END_STATEMENT << nl;
210 os.writeKeyword("axis")
211 << axis_ << token::END_STATEMENT << nl;
213 os.writeKeyword("stiffness")
214 << stiffness_ << token::END_STATEMENT << nl;
216 os.writeKeyword("damping")
217 << damping_ << token::END_STATEMENT << nl;
220 // ************************************************************************* //