FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

linearAxialAngularSpring.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "linearAxialAngularSpring.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <forces/sixDoFRigidBodyMotion.H>
00029 #include <OpenFOAM/transform.H>
00030 
00031 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00032 
00033 namespace Foam
00034 {
00035 namespace sixDoFRigidBodyMotionRestraints
00036 {
00037     defineTypeNameAndDebug(linearAxialAngularSpring, 0);
00038     addToRunTimeSelectionTable
00039     (
00040         sixDoFRigidBodyMotionRestraint,
00041         linearAxialAngularSpring,
00042         dictionary
00043     );
00044 };
00045 };
00046 
00047 
00048 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00049 
00050 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::
00051 linearAxialAngularSpring
00052 (
00053     const dictionary& sDoFRBMRDict
00054 )
00055 :
00056     sixDoFRigidBodyMotionRestraint(sDoFRBMRDict),
00057     refQ_(),
00058     axis_(),
00059     stiffness_(),
00060     damping_()
00061 {
00062     read(sDoFRBMRDict);
00063 }
00064 
00065 
00066 // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
00067 
00068 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::
00069 ~linearAxialAngularSpring()
00070 {}
00071 
00072 
00073 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
00074 
00075 void
00076 Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::restrain
00077 (
00078     const sixDoFRigidBodyMotion& motion,
00079     vector& restraintPosition,
00080     vector& restraintForce,
00081     vector& restraintMoment
00082 ) const
00083 {
00084     vector refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 1, 0);
00085 
00086     vector oldDir = refQ_ & refDir;
00087 
00088     vector newDir = motion.orientation() & refDir;
00089 
00090     if (mag(oldDir & axis_) > 0.95 || mag(newDir & axis_) > 0.95)
00091     {
00092         // Directions getting close to the axis, change reference
00093 
00094         refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 0, 1);
00095 
00096         vector oldDir = refQ_ & refDir;
00097 
00098         vector newDir = motion.orientation() & refDir;
00099     }
00100 
00101     // Removing any axis component from oldDir and newDir and normalising
00102     oldDir -= (axis_ & oldDir)*axis_;
00103     oldDir /= (mag(oldDir) + VSMALL);
00104 
00105     newDir -= (axis_ & newDir)*axis_;
00106     newDir /= (mag(newDir) + VSMALL);
00107 
00108     scalar theta = mag(acos(min(oldDir & newDir, 1.0)));
00109 
00110     // Temporary axis with sign information.
00111     vector a = (oldDir ^ newDir);
00112 
00113     // Remove any component that is not along axis that may creep in
00114     a = (a & axis_)*axis_;
00115 
00116     scalar magA = mag(a);
00117 
00118     if (magA > VSMALL)
00119     {
00120         a /= magA;
00121     }
00122     else
00123     {
00124         a = vector::zero;
00125     }
00126 
00127     // Damping of along axis angular velocity only
00128     restraintMoment = -stiffness_*theta*a - damping_*(motion.omega() & a)*a;
00129 
00130     restraintForce = vector::zero;
00131 
00132     // Not needed to be altered as restraintForce is zero, but set to
00133     // centreOfMass to be sure of no spurious moment
00134     restraintPosition = motion.centreOfMass();
00135 
00136     if (motion.report())
00137     {
00138         Info<< " angle " << theta*sign(a & axis_)
00139             << " force " << restraintForce
00140             << " moment " << restraintMoment
00141             << endl;
00142     }
00143 }
00144 
00145 
00146 bool Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::read
00147 (
00148     const dictionary& sDoFRBMRDict
00149 )
00150 {
00151     sixDoFRigidBodyMotionRestraint::read(sDoFRBMRDict);
00152 
00153     refQ_ = sDoFRBMRCoeffs_.lookupOrDefault<tensor>("referenceOrientation", I);
00154 
00155     if (mag(mag(refQ_) - sqrt(3.0)) > 1e-9)
00156     {
00157         FatalErrorIn
00158         (
00159             "Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::"
00160             "read"
00161             "("
00162                 "const dictionary& sDoFRBMRDict"
00163             ")"
00164         )
00165             << "referenceOrientation " << refQ_ << " is not a rotation tensor. "
00166             << "mag(referenceOrientation) - sqrt(3) = "
00167             << mag(refQ_) - sqrt(3.0) << nl
00168             << exit(FatalError);
00169     }
00170 
00171     axis_ = sDoFRBMRCoeffs_.lookup("axis");
00172 
00173     scalar magAxis(mag(axis_));
00174 
00175     if (magAxis > VSMALL)
00176     {
00177         axis_ /= magAxis;
00178     }
00179     else
00180     {
00181         FatalErrorIn
00182         (
00183             "Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::"
00184             "read"
00185             "("
00186                 "const dictionary& sDoFRBMCDict"
00187             ")"
00188         )
00189             << "axis has zero length"
00190             << abort(FatalError);
00191     }
00192 
00193     sDoFRBMRCoeffs_.lookup("stiffness") >> stiffness_;
00194 
00195     sDoFRBMRCoeffs_.lookup("damping") >> damping_;
00196 
00197     return true;
00198 }
00199 
00200 
00201 void Foam::sixDoFRigidBodyMotionRestraints::linearAxialAngularSpring::write
00202 (
00203     Ostream& os
00204 ) const
00205 {
00206     os.writeKeyword("referenceOrientation")
00207         << refQ_ << token::END_STATEMENT << nl;
00208 
00209     os.writeKeyword("axis")
00210         << axis_ << token::END_STATEMENT << nl;
00211 
00212     os.writeKeyword("stiffness")
00213         << stiffness_ << token::END_STATEMENT << nl;
00214 
00215     os.writeKeyword("damping")
00216         << damping_ << token::END_STATEMENT << nl;
00217 }
00218 
00219 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines