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

tabulatedAxialAngularSpring.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 "tabulatedAxialAngularSpring.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 #include <forces/sixDoFRigidBodyMotion.H>
00029 #include <OpenFOAM/transform.H>
00030 #include <OpenFOAM/mathematicalConstants.H>
00031 
00032 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00033 
00034 namespace Foam
00035 {
00036 namespace sixDoFRigidBodyMotionRestraints
00037 {
00038     defineTypeNameAndDebug(tabulatedAxialAngularSpring, 0);
00039     addToRunTimeSelectionTable
00040     (
00041         sixDoFRigidBodyMotionRestraint,
00042         tabulatedAxialAngularSpring,
00043         dictionary
00044     );
00045 };
00046 };
00047 
00048 
00049 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00050 
00051 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::
00052 tabulatedAxialAngularSpring
00053 (
00054     const dictionary& sDoFRBMRDict
00055 )
00056 :
00057     sixDoFRigidBodyMotionRestraint(sDoFRBMRDict),
00058     refQ_(),
00059     axis_(),
00060     moment_(),
00061     convertToDegrees_(),
00062     damping_()
00063 {
00064     read(sDoFRBMRDict);
00065 }
00066 
00067 
00068 // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
00069 
00070 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::
00071 ~tabulatedAxialAngularSpring()
00072 {}
00073 
00074 
00075 // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
00076 
00077 void
00078 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::restrain
00079 (
00080     const sixDoFRigidBodyMotion& motion,
00081     vector& restraintPosition,
00082     vector& restraintForce,
00083     vector& restraintMoment
00084 ) const
00085 {
00086     vector refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 1, 0);
00087 
00088     vector oldDir = refQ_ & refDir;
00089 
00090     vector newDir = motion.orientation() & refDir;
00091 
00092     if (mag(oldDir & axis_) > 0.95 || mag(newDir & axis_) > 0.95)
00093     {
00094         // Directions getting close to the axis, change reference
00095 
00096         refDir = rotationTensor(vector(1, 0 ,0), axis_) & vector(0, 0, 1);
00097 
00098         vector oldDir = refQ_ & refDir;
00099 
00100         vector newDir = motion.orientation() & refDir;
00101     }
00102 
00103     // Removing any axis component from oldDir and newDir and normalising
00104     oldDir -= (axis_ & oldDir)*axis_;
00105     oldDir /= (mag(oldDir) + VSMALL);
00106 
00107     newDir -= (axis_ & newDir)*axis_;
00108     newDir /= (mag(newDir) + VSMALL);
00109 
00110     scalar theta = mag(acos(min(oldDir & newDir, 1.0)));
00111 
00112     // Determining the sign of theta by comparing the cross product of
00113     // the direction vectors with the axis
00114     theta *= sign((oldDir ^ newDir) & axis_);
00115 
00116     scalar moment;
00117 
00118     if (convertToDegrees_)
00119     {
00120         moment = moment_(theta*180.0/mathematicalConstant::pi);
00121     }
00122     else
00123     {
00124         moment = moment_(theta);
00125     }
00126 
00127     // Damping of along axis angular velocity only
00128     restraintMoment = moment*axis_ - damping_*(motion.omega() & axis_)*axis_;
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
00139             << " force " << restraintForce
00140             << " moment " << restraintMoment
00141             << endl;
00142     }
00143 }
00144 
00145 
00146 bool Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::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::"
00160             "tabulatedAxialAngularSpring::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::"
00184             "tabulatedAxialAngularSpring::read"
00185             "("
00186                 "const dictionary& sDoFRBMCDict"
00187             ")"
00188         )
00189             << "axis has zero length"
00190             << abort(FatalError);
00191     }
00192 
00193     moment_ = interpolationTable<scalar>(sDoFRBMRCoeffs_);
00194 
00195     word angleFormat = sDoFRBMRCoeffs_.lookup("angleFormat");
00196 
00197     if (angleFormat == "degrees" || angleFormat == "degree")
00198     {
00199         convertToDegrees_ = true;
00200     }
00201     else if (angleFormat == "radians" || angleFormat == "radian")
00202     {
00203         convertToDegrees_ = false;
00204     }
00205     else
00206     {
00207         FatalErrorIn
00208         (
00209             "Foam::sixDoFRigidBodyMotionRestraints::"
00210             "tabulatedAxialAngularSpring::read"
00211             "("
00212                 "const dictionary& sDoFRBMCDict"
00213             ")"
00214         )
00215             << "angleFormat must be degree, degrees, radian or radians"
00216             << abort(FatalError);
00217     }
00218 
00219     sDoFRBMRCoeffs_.lookup("damping") >> damping_;
00220 
00221     return true;
00222 }
00223 
00224 
00225 void Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::write
00226 (
00227     Ostream& os
00228 ) const
00229 {
00230     os.writeKeyword("referenceOrientation")
00231         << refQ_ << token::END_STATEMENT << nl;
00232 
00233     os.writeKeyword("axis")
00234         << axis_ << token::END_STATEMENT << nl;
00235 
00236     moment_.write(os);
00237 
00238     os.writeKeyword("angleFormat");
00239 
00240     if (convertToDegrees_)
00241     {
00242         os  << "degrees" << token::END_STATEMENT << nl;
00243     }
00244     else
00245     {
00246         os  << "radians" << token::END_STATEMENT << nl;
00247     }
00248 
00249     os.writeKeyword("damping")
00250         << damping_ << token::END_STATEMENT << nl;
00251 }
00252 
00253 
00254 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines