1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2010-2011 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "tabulatedAxialAngularSpring.H"
27 #include "addToRunTimeSelectionTable.H"
28 #include "sixDoFRigidBodyMotion.H"
29 #include "transform.H"
30 #include "unitConversion.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 namespace sixDoFRigidBodyMotionRestraints
38 defineTypeNameAndDebug(tabulatedAxialAngularSpring, 0);
40 addToRunTimeSelectionTable
42 sixDoFRigidBodyMotionRestraint,
43 tabulatedAxialAngularSpring,
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
52 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::
53 tabulatedAxialAngularSpring
55 const dictionary& sDoFRBMRDict
58 sixDoFRigidBodyMotionRestraint(sDoFRBMRDict),
69 // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
71 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::
72 ~tabulatedAxialAngularSpring()
76 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
79 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::restrain
81 const sixDoFRigidBodyMotion& motion,
82 vector& restraintPosition,
83 vector& restraintForce,
84 vector& restraintMoment
87 vector refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 1, 0);
89 vector oldDir = refQ_ & refDir;
90 vector newDir = motion.orientation() & refDir;
92 if (mag(oldDir & axis_) > 0.95 || mag(newDir & axis_) > 0.95)
94 // Directions getting close to the axis, change reference
96 refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 0, 1);
98 oldDir = refQ_ & refDir;
99 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 // Determining the sign of theta by comparing the cross product of
112 // the direction vectors with the axis
113 theta *= sign((oldDir ^ newDir) & axis_);
117 if (convertToDegrees_)
119 moment = moment_(radToDeg(theta));
123 moment = moment_(theta);
126 // Damping of along axis angular velocity only
127 restraintMoment = moment*axis_ - damping_*(motion.omega() & axis_)*axis_;
129 restraintForce = vector::zero;
131 // Not needed to be altered as restraintForce is zero, but set to
132 // centreOfMass to be sure of no spurious moment
133 restraintPosition = motion.centreOfMass();
137 Info<< " angle " << theta
138 << " force " << restraintForce
139 << " moment " << restraintMoment
145 bool Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::read
147 const dictionary& sDoFRBMRDict
150 sixDoFRigidBodyMotionRestraint::read(sDoFRBMRDict);
152 refQ_ = sDoFRBMRCoeffs_.lookupOrDefault<tensor>("referenceOrientation", I);
154 if (mag(mag(refQ_) - sqrt(3.0)) > 1e-9)
158 "Foam::sixDoFRigidBodyMotionRestraints::"
159 "tabulatedAxialAngularSpring::read"
161 "const dictionary& sDoFRBMRDict"
164 << "referenceOrientation " << refQ_ << " is not a rotation tensor. "
165 << "mag(referenceOrientation) - sqrt(3) = "
166 << mag(refQ_) - sqrt(3.0) << nl
170 axis_ = sDoFRBMRCoeffs_.lookup("axis");
172 scalar magAxis(mag(axis_));
174 if (magAxis > VSMALL)
182 "Foam::sixDoFRigidBodyMotionRestraints::"
183 "tabulatedAxialAngularSpring::read"
185 "const dictionary& sDoFRBMCDict"
188 << "axis has zero length"
189 << abort(FatalError);
192 moment_ = interpolationTable<scalar>(sDoFRBMRCoeffs_);
194 const word angleFormat = sDoFRBMRCoeffs_.lookup("angleFormat");
196 if (angleFormat == "degrees" || angleFormat == "degree")
198 convertToDegrees_ = true;
200 else if (angleFormat == "radians" || angleFormat == "radian")
202 convertToDegrees_ = false;
208 "Foam::sixDoFRigidBodyMotionRestraints::"
209 "tabulatedAxialAngularSpring::read"
214 << "angleFormat must be degree, degrees, radian or radians"
215 << abort(FatalError);
218 sDoFRBMRCoeffs_.lookup("damping") >> damping_;
224 void Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::write
229 os.writeKeyword("referenceOrientation")
230 << refQ_ << token::END_STATEMENT << nl;
232 os.writeKeyword("axis")
233 << axis_ << token::END_STATEMENT << nl;
237 os.writeKeyword("angleFormat");
239 if (convertToDegrees_)
241 os << "degrees" << token::END_STATEMENT << nl;
245 os << "radians" << token::END_STATEMENT << nl;
248 os.writeKeyword("damping")
249 << damping_ << token::END_STATEMENT << nl;
253 // ************************************************************************* //