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 // Bugfix: sqr. SS, 18/Apr/2016
88 const scalar c2 = sqrt(sqr(rotT.xx()) + sqr(rotT.xy()));
90 // Calculate pitch angle
91 pitchAngle = atan2(-rotT.xz(), c2);
93 const scalar s1 = sin(rollAngle);
94 const scalar c1 = cos(rollAngle);
96 // Calculate yaw angle
97 yawAngle = atan2(s1*rotT.zx() - c1*rotT.yx(), c1*rotT.yy() - s1*rotT.zy());
103 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
105 Foam::finiteRotation::finiteRotation(const HamiltonRodriguezRot& rot)
109 rotIncrementTensor_(tensor::zero)
113 Foam::finiteRotation::finiteRotation
119 eInitial_(HamiltonRodriguezRot(r, angle)),
120 rotTensor_(eInitial_.R()),
121 rotIncrementTensor_(tensor::zero)
125 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
127 Foam::finiteRotation::~finiteRotation()
131 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
133 void Foam::finiteRotation::updateRotation(const HamiltonRodriguezRot& rot)
135 tensor rotR = rot.R();
137 rotIncrementTensor_ = (rotR & (rotTensor_.T()));
142 const Foam::HamiltonRodriguezRot& Foam::finiteRotation::eInitial() const
148 Foam::HamiltonRodriguezRot Foam::finiteRotation::eCurrent() const
150 return HamiltonRodriguezRot(rotVector(), rotAngle());
154 const Foam::tensor& Foam::finiteRotation::rotTensor() const
160 Foam::vector Foam::finiteRotation::rotVector() const
162 return rotVector(rotTensor_);
166 Foam::scalar Foam::finiteRotation::rotAngle() const
168 return rotAngle(rotTensor_);
172 Foam::vector Foam::finiteRotation::eulerAngles() const
174 return eulerAngles(rotTensor_);
178 const Foam::tensor& Foam::finiteRotation::rotIncrementTensor() const
180 return rotIncrementTensor_;
184 Foam::vector Foam::finiteRotation::rotIncrementVector() const
186 return rotVector(rotIncrementTensor_);
190 Foam::scalar Foam::finiteRotation::rotIncrementAngle() const
192 return rotAngle(rotIncrementTensor_);
196 Foam::vector Foam::finiteRotation::omegaAverage(const scalar deltaT) const
198 return (rotIncrementAngle()/deltaT)*rotIncrementVector();
202 Foam::tensor Foam::finiteRotation::rotTensorAverage() const
208 rotIncrementVector(),
209 0.5*rotIncrementAngle()
216 Foam::vector Foam::finiteRotation::rotVectorAverage() const
218 return rotVector(rotTensorAverage());
222 Foam::vector Foam::finiteRotation::omegaAverageAbsolute
227 return (rotTensorAverage().T() & omegaAverage(deltaT));
231 // ************************************************************************* //