Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
00069
00070 Foam::sixDoFRigidBodyMotionRestraints::tabulatedAxialAngularSpring::
00071 ~tabulatedAxialAngularSpring()
00072 {}
00073
00074
00075
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
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
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
00113
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
00128 restraintMoment = moment*axis_ - damping_*(motion.omega() & axis_)*axis_;
00129
00130 restraintForce = vector::zero;
00131
00132
00133
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