1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
5 \\ / A nd | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Dubravko Matijasevic, FSB Zagreb. All rights reserved.
29 Update by Hrvoje Jasak
31 \*---------------------------------------------------------------------------*/
33 #include "objectRegistry.H"
34 #include "finiteRotation.H"
36 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
38 Foam::vector Foam::finiteRotation::rotVector(const tensor& rotT)
40 vector ur = - *( inv(I + rotT) & (I - rotT) );
42 // Scaling to a unit vector. HJ, problems with round-off
47 return ur/(mag(ur) + SMALL);
51 // Rotation vector is undertermined at zero rotation
52 // Returning arbitrary unit vector
54 return vector(0, 0, 1);
59 Foam::scalar Foam::finiteRotation::rotAngle(const tensor& rotT)
61 // Alternative formulation: Daniel Schmode, 15/Feb/2009
62 scalar x = rotT.zy() - rotT.yz();
63 scalar y = rotT.xz() - rotT.zx();
64 scalar z = rotT.yx() - rotT.xy();
66 scalar r = hypot(x, hypot(y, z));
69 return atan2(r, t - 1);
73 Foam::vector Foam::finiteRotation::eulerAngles(const tensor& rotT)
75 // Create a vector containing euler angles (x = roll, y = pitch, z = yaw)
78 scalar& rollAngle = eulerAngles.x();
79 scalar& pitchAngle = eulerAngles.y();
80 scalar& yawAngle = eulerAngles.z();
82 // Calculate roll angle
83 rollAngle = atan2(rotT.yz(), rotT.zz());
85 // Use mag to avoid negative value due to round-off
87 const scalar c2 = sqrt(Foam::max(0, rotT.xx() + rotT.xy()));
89 // Calculate pitch angle
90 pitchAngle = atan2(-rotT.xz(), c2);
92 const scalar s1 = sin(rollAngle);
93 const scalar c1 = cos(rollAngle);
95 // Calculate yaw angle
96 yawAngle = atan2(s1*rotT.zx() - c1*rotT.yx(), c1*rotT.yy() - s1*rotT.zy());
102 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
104 Foam::finiteRotation::finiteRotation(const HamiltonRodriguezRot& rot)
108 rotIncrementTensor_(tensor::zero)
112 Foam::finiteRotation::finiteRotation
118 eInitial_(HamiltonRodriguezRot(r, angle)),
119 rotTensor_(eInitial_.R()),
120 rotIncrementTensor_(tensor::zero)
124 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
126 Foam::finiteRotation::~finiteRotation()
130 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
132 void Foam::finiteRotation::updateRotation(const HamiltonRodriguezRot& rot)
134 tensor rotR = rot.R();
136 rotIncrementTensor_ = (rotR & (rotTensor_.T()));
141 const Foam::HamiltonRodriguezRot& Foam::finiteRotation::eInitial() const
147 Foam::HamiltonRodriguezRot Foam::finiteRotation::eCurrent() const
149 return HamiltonRodriguezRot(rotVector(), rotAngle());
153 const Foam::tensor& Foam::finiteRotation::rotTensor() const
159 Foam::vector Foam::finiteRotation::rotVector() const
161 return rotVector(rotTensor_);
165 Foam::scalar Foam::finiteRotation::rotAngle() const
167 return rotAngle(rotTensor_);
171 Foam::vector Foam::finiteRotation::eulerAngles() const
173 return eulerAngles(rotTensor_);
177 const Foam::tensor& Foam::finiteRotation::rotIncrementTensor() const
179 return rotIncrementTensor_;
183 Foam::vector Foam::finiteRotation::rotIncrementVector() const
185 return rotVector(rotIncrementTensor_);
189 Foam::scalar Foam::finiteRotation::rotIncrementAngle() const
191 return rotAngle(rotIncrementTensor_);
195 Foam::vector Foam::finiteRotation::omegaAverage(const scalar deltaT) const
197 return (rotIncrementAngle()/deltaT)*rotIncrementVector();
201 Foam::tensor Foam::finiteRotation::rotTensorAverage() const
207 rotIncrementVector(),
208 0.5*rotIncrementAngle()
215 Foam::vector Foam::finiteRotation::rotVectorAverage() const
217 return rotVector(rotTensorAverage());
221 Foam::vector Foam::finiteRotation::omegaAverageAbsolute
226 return (rotTensorAverage().T() & omegaAverage(deltaT));
230 // ************************************************************************* //