Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / ODE / sixDOF / finiteRotation / finiteRotation.C
blob05e236083e516d6e421d02950c411d82b8cd734e
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     |
5     \\  /    A nd           | For copyright notice see file Copyright
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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/>.
24 Class
25     finiteRotation
27 Author
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
43     // HJ, 4/Aug/2008
45     if (mag(ur) > SMALL)
46     {
47         return ur/(mag(ur) + SMALL);
48     }
49     else
50     {
51         // Rotation vector is undertermined at zero rotation
52         // Returning arbitrary unit vector
53         // HJ, 4/Mar/2015
54         return vector(0, 0, 1);
55     }
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));
67     scalar t = tr(rotT);
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)
76     vector eulerAngles;
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
86     // HJ, 24/Feb/2016
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());
99     return eulerAngles;
103 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
105 Foam::finiteRotation::finiteRotation(const HamiltonRodriguezRot& rot)
107     eInitial_(rot),
108     rotTensor_(rot.R()),
109     rotIncrementTensor_(tensor::zero)
113 Foam::finiteRotation::finiteRotation
115     const vector& r,
116     const scalar& angle
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()));
138     rotTensor_ = rotR;
142 const Foam::HamiltonRodriguezRot& Foam::finiteRotation::eInitial() const
144     return eInitial_;
148 Foam::HamiltonRodriguezRot Foam::finiteRotation::eCurrent() const
150     return HamiltonRodriguezRot(rotVector(), rotAngle());
154 const Foam::tensor& Foam::finiteRotation::rotTensor() const
156     return rotTensor_;
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
204     return
205     (
206         HamiltonRodriguezRot
207         (
208             rotIncrementVector(),
209             0.5*rotIncrementAngle()
210         ).R().T()
211       & rotTensor_
212     );
216 Foam::vector Foam::finiteRotation::rotVectorAverage() const
218     return rotVector(rotTensorAverage());
222 Foam::vector Foam::finiteRotation::omegaAverageAbsolute
224     const scalar deltaT
225 ) const
227     return (rotTensorAverage().T() & omegaAverage(deltaT));
231 // ************************************************************************* //