1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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
29 6-DOF solver using quaternions
32 Dubravko Matijasevic, FSB Zagreb. All rights reserved.
34 \*---------------------------------------------------------------------------*/
36 #include "sixDOFqODE.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40 // Runtime type information
41 // Not possible because of I/O error: incorrect type, expecting dictionary
45 // defineTypeNameAndDebug(sixDOFqODE, 0);
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 void Foam::sixDOFqODE::setCoeffs()
53 // Set ODE coefficients from position and rotation
55 // Linear displacement relative to spring equilibrium
56 const vector& Xval = Xrel_.value();
57 coeffs_[0] = Xval.x();
58 coeffs_[1] = Xval.y();
59 coeffs_[2] = Xval.z();
62 const vector& Uval = U_.value();
63 coeffs_[3] = Uval.x();
64 coeffs_[4] = Uval.y();
65 coeffs_[5] = Uval.z();
67 // Rotational velocity in non - inertial coordinate system
68 const vector& omegaVal = omega_.value();
69 coeffs_[6] = omegaVal.x();
70 coeffs_[7] = omegaVal.y();
71 coeffs_[8] = omegaVal.z();
74 coeffs_[9] = rotation_.eInitial().e0();
75 coeffs_[10] = rotation_.eInitial().e1();
76 coeffs_[11] = rotation_.eInitial().e2();
77 coeffs_[12] = rotation_.eInitial().e3();
81 Foam::dimensionedVector Foam::sixDOFqODE::A
83 const dimensionedVector& xR,
84 const dimensionedVector& uR,
85 const HamiltonRodriguezRot& rotation
90 - (linSpringCoeffs_ & xR) // spring
91 - (linDampingCoeffs_ & uR) // damping
94 + (rotation.invR() & forceRelative())
99 Foam::dimensionedVector Foam::sixDOFqODE::OmegaDot
101 const HamiltonRodriguezRot& rotation,
102 const dimensionedVector& omega
106 inv(momentOfInertia_)
110 + (rotation.R() & moment())
116 Foam::dimensionedVector Foam::sixDOFqODE::E
118 const dimensionedVector& omega
121 return (*(momentOfInertia_ & omega) & omega);
126 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
128 // Construct from components
129 Foam::sixDOFqODE::sixDOFqODE(const IOobject& io)
132 mass_(lookup("mass")),
133 momentOfInertia_(lookup("momentOfInertia")),
134 Xequilibrium_(lookup("equilibriumPosition")),
135 linSpringCoeffs_(lookup("linearSpring")),
136 linDampingCoeffs_(lookup("linearDamping")),
137 Xrel_(lookup("Xrel")),
142 vector(lookup("rotationVector")),
143 dimensionedScalar(lookup("rotationAngle")).value()
145 omega_(lookup("omega")),
146 omegaAverage_(omega_),
147 omegaAverageAbsolute_(omega_),
148 force_(lookup("force")),
149 moment_(lookup("moment")),
150 forceRelative_(lookup("forceRelative")),
151 momentRelative_(lookup("momentRelative")),
158 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
160 Foam::sixDOFqODE::~sixDOFqODE()
164 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
166 void Foam::sixDOFqODE::derivatives
169 const scalarField& y,
173 // Set the derivatives for displacement
178 dimensionedVector curX("curX", dimLength, vector(y[0], y[1], y[2]));
179 dimensionedVector curU("curU", dimVelocity, vector(y[3], y[4], y[5]));
180 const HamiltonRodriguezRot curRotation
188 const vector accel = A(curX, curU, curRotation).value();
194 // Set the derivatives for rotation
195 dimensionedVector curOmega
199 vector(y[6], y[7], y[8])
202 const vector omegaDot = OmegaDot(curRotation, curOmega).value();
204 dydx[6] = omegaDot.x();
205 dydx[7] = omegaDot.y();
206 dydx[8] = omegaDot.z();
208 dydx[9] = curRotation.eDot(curOmega.value(), 0);
209 dydx[10] = curRotation.eDot(curOmega.value(), 1);
210 dydx[11] = curRotation.eDot(curOmega.value(), 2);
211 dydx[12] = curRotation.eDot(curOmega.value(), 3);
215 void Foam::sixDOFqODE::jacobian
218 const scalarField& y,
220 scalarSquareMatrix& dfdy
223 Info << "jacobian(...)" << endl;
224 notImplemented("sixDOFqODE::jacobian(...) const");
228 void Foam::sixDOFqODE::update(const scalar delta)
231 vector Xold = Xrel_.value();
233 vector& Xval = Xrel_.value();
235 Xval.x() = coeffs_[0];
236 Xval.y() = coeffs_[1];
237 Xval.z() = coeffs_[2];
240 Uaverage_.value() = (Xval - Xold)/delta;
242 vector& Uval = U_.value();
244 Uval.x() = coeffs_[3];
245 Uval.y() = coeffs_[4];
246 Uval.z() = coeffs_[5];
249 vector& omegaVal = omega_.value();
251 omegaVal.x() = coeffs_[6];
252 omegaVal.y() = coeffs_[7];
253 omegaVal.z() = coeffs_[8];
255 rotation_.updateRotation
266 omegaAverage_.value() = rotation_.omegaAverage(delta);
267 omegaAverageAbsolute_.value() = rotation_.omegaAverageAbsolute(delta);
271 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
273 bool Foam::sixDOFqODE::writeData(Ostream& os) const
280 // * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * * //
282 Foam::Ostream& Foam::operator<<(Ostream& os, const sixDOFqODE& sds)
284 os.writeKeyword("mass") << tab << sds.mass_ << token::END_STATEMENT << nl;
285 os.writeKeyword("momentOfInertia") << tab << sds.momentOfInertia_
286 << token::END_STATEMENT << nl << nl;
288 os.writeKeyword("equilibriumPosition") << tab << sds.Xequilibrium_
289 << token::END_STATEMENT << nl;
290 os.writeKeyword("linearSpring") << tab << sds.linSpringCoeffs_
291 << token::END_STATEMENT << nl;
292 os.writeKeyword("linearDamping") << tab << sds.linDampingCoeffs_
293 << token::END_STATEMENT << nl << nl;
295 os.writeKeyword("Xrel") << tab << sds.Xrel() << token::END_STATEMENT << nl;
296 os.writeKeyword("U") << tab << sds.U() << token::END_STATEMENT << nl;
297 os.writeKeyword("rotationVector") << tab << sds.rotVector()
298 << token::END_STATEMENT << nl;
299 os.writeKeyword("rotationAngle") << tab << sds.rotAngle()
300 << token::END_STATEMENT << nl;
301 os.writeKeyword("omega") << tab << sds.omega()
302 << token::END_STATEMENT << nl << nl;
304 os.writeKeyword("force") << tab << sds.force()
305 << token::END_STATEMENT << nl;
306 os.writeKeyword("moment") << tab << sds.moment()
307 << token::END_STATEMENT << nl;
308 os.writeKeyword("forceRelative") << tab << sds.forceRelative()
309 << token::END_STATEMENT << nl;
310 os.writeKeyword("momentRelative") << tab << sds.momentRelative()
311 << token::END_STATEMENT << endl;
317 // ************************************************************************* //