mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: expose calculation of coordinate rotations as static methods
- improve handling of degenerate cases for the two-axes specification.
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -24,8 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "EulerCoordinateRotation.H"
|
#include "EulerCoordinateRotation.H"
|
||||||
|
#include "unitConversion.H"
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -47,6 +46,43 @@ namespace Foam
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tensor Foam::EulerCoordinateRotation::rotation
|
||||||
|
(
|
||||||
|
const vector& angles,
|
||||||
|
bool degrees
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar phi = angles.component(vector::X); // 1. Rotate about Z
|
||||||
|
scalar theta = angles.component(vector::Y); // 2. Rotate about X
|
||||||
|
scalar psi = angles.component(vector::Z); // 3. Rotate about Z
|
||||||
|
|
||||||
|
if (degrees)
|
||||||
|
{
|
||||||
|
phi *= degToRad();
|
||||||
|
theta *= degToRad();
|
||||||
|
psi *= degToRad();
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
tensor
|
||||||
|
(
|
||||||
|
cos(phi)*cos(psi) - sin(phi)*sin(psi)*cos(theta),
|
||||||
|
-sin(phi)*cos(psi)*cos(theta) - cos(phi)*sin(psi),
|
||||||
|
sin(phi)*sin(theta),
|
||||||
|
|
||||||
|
cos(phi)*sin(psi)*cos(theta) + sin(phi)*cos(psi),
|
||||||
|
cos(phi)*cos(psi)*cos(theta) - sin(phi)*sin(psi),
|
||||||
|
-cos(phi)*sin(theta),
|
||||||
|
|
||||||
|
sin(psi)*sin(theta),
|
||||||
|
cos(psi)*sin(theta),
|
||||||
|
cos(theta)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::vector Foam::EulerCoordinateRotation::transform(const vector& st) const
|
Foam::vector Foam::EulerCoordinateRotation::transform(const vector& st) const
|
||||||
@ -147,49 +183,6 @@ Foam::symmTensor Foam::EulerCoordinateRotation::transformVector
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::EulerCoordinateRotation::calcTransform
|
|
||||||
(
|
|
||||||
const scalar phiAngle,
|
|
||||||
const scalar thetaAngle,
|
|
||||||
const scalar psiAngle,
|
|
||||||
const bool inDegrees
|
|
||||||
)
|
|
||||||
{
|
|
||||||
scalar phi = phiAngle;
|
|
||||||
scalar theta = thetaAngle;
|
|
||||||
scalar psi = psiAngle;
|
|
||||||
|
|
||||||
if (inDegrees)
|
|
||||||
{
|
|
||||||
phi *= constant::mathematical::pi/180.0;
|
|
||||||
theta *= constant::mathematical::pi/180.0;
|
|
||||||
psi *= constant::mathematical::pi/180.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
R_ =
|
|
||||||
(
|
|
||||||
tensor
|
|
||||||
(
|
|
||||||
cos(phi)*cos(psi) - sin(phi)*sin(psi)*cos(theta),
|
|
||||||
-sin(phi)*cos(psi)*cos(theta) - cos(phi)*sin(psi),
|
|
||||||
sin(phi)*sin(theta),
|
|
||||||
|
|
||||||
cos(phi)*sin(psi)*cos(theta) + sin(phi)*cos(psi),
|
|
||||||
cos(phi)*cos(psi)*cos(theta) - sin(phi)*sin(psi),
|
|
||||||
-cos(phi)*sin(theta),
|
|
||||||
|
|
||||||
sin(psi)*sin(theta),
|
|
||||||
cos(psi)*sin(theta),
|
|
||||||
cos(theta)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Rtr_ = R_.T();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::EulerCoordinateRotation::EulerCoordinateRotation()
|
Foam::EulerCoordinateRotation::EulerCoordinateRotation()
|
||||||
@ -212,35 +205,25 @@ Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
|||||||
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
||||||
(
|
(
|
||||||
const vector& phiThetaPsi,
|
const vector& phiThetaPsi,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(phiThetaPsi, degrees)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
calcTransform
|
|
||||||
(
|
|
||||||
phiThetaPsi.component(vector::X),
|
|
||||||
phiThetaPsi.component(vector::Y),
|
|
||||||
phiThetaPsi.component(vector::Z),
|
|
||||||
inDegrees
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
||||||
(
|
(
|
||||||
const scalar phiAngle,
|
const scalar phi,
|
||||||
const scalar thetaAngle,
|
const scalar theta,
|
||||||
const scalar psiAngle,
|
const scalar psi,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(vector(phi, theta, psi), degrees)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
calcTransform(phiAngle, thetaAngle, psiAngle, inDegrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
||||||
@ -248,19 +231,16 @@ Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_
|
||||||
Rtr_(sphericalTensor::I)
|
|
||||||
{
|
|
||||||
const vector rotation(dict.lookup("rotation"));
|
|
||||||
|
|
||||||
calcTransform
|
|
||||||
(
|
(
|
||||||
rotation.component(vector::X),
|
rotation
|
||||||
rotation.component(vector::Y),
|
(
|
||||||
rotation.component(vector::Z),
|
dict.get<vector>("rotation"),
|
||||||
dict.lookupOrDefault("degrees", true)
|
dict.lookupOrDefault("degrees", true)
|
||||||
);
|
)
|
||||||
}
|
),
|
||||||
|
Rtr_(R_.T())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
Foam::EulerCoordinateRotation::EulerCoordinateRotation
|
||||||
|
|||||||
@ -73,7 +73,6 @@ class EulerCoordinateRotation
|
|||||||
:
|
:
|
||||||
public coordinateRotation
|
public coordinateRotation
|
||||||
{
|
{
|
||||||
|
|
||||||
// Private Member Data
|
// Private Member Data
|
||||||
|
|
||||||
//- Local-to-global transformation tensor
|
//- Local-to-global transformation tensor
|
||||||
@ -83,18 +82,6 @@ class EulerCoordinateRotation
|
|||||||
tensor Rtr_;
|
tensor Rtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Calculate transformation tensor
|
|
||||||
void calcTransform
|
|
||||||
(
|
|
||||||
const scalar phiAngle,
|
|
||||||
const scalar thetaAngle,
|
|
||||||
const scalar psiAngle,
|
|
||||||
const bool inDegrees
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -113,16 +100,16 @@ public:
|
|||||||
EulerCoordinateRotation
|
EulerCoordinateRotation
|
||||||
(
|
(
|
||||||
const vector& phiThetaPsi,
|
const vector& phiThetaPsi,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from components of rotation vector
|
//- Construct from components of rotation vector
|
||||||
EulerCoordinateRotation
|
EulerCoordinateRotation
|
||||||
(
|
(
|
||||||
const scalar phiAngle,
|
const scalar phi,
|
||||||
const scalar thetaAngle,
|
const scalar theta,
|
||||||
const scalar psiAngle,
|
const scalar psi,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from dictionary
|
//- Construct from dictionary
|
||||||
@ -144,6 +131,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Static Member Functions
|
||||||
|
|
||||||
|
//- The rotation tensor calculated for the specified Euler angles
|
||||||
|
//- interpreted as phi/theta/psi (z-x-z order)
|
||||||
|
static tensor rotation(const vector& angles, bool degrees);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Reset rotation to an identity rotation
|
//- Reset rotation to an identity rotation
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -24,8 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "STARCDCoordinateRotation.H"
|
#include "STARCDCoordinateRotation.H"
|
||||||
|
#include "unitConversion.H"
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -148,29 +147,26 @@ Foam::symmTensor Foam::STARCDCoordinateRotation::transformVector
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::STARCDCoordinateRotation::calcTransform
|
Foam::tensor Foam::STARCDCoordinateRotation::rotation
|
||||||
(
|
(
|
||||||
const scalar rotZ,
|
const vector& angles,
|
||||||
const scalar rotX,
|
const bool degrees
|
||||||
const scalar rotY,
|
|
||||||
const bool inDegrees
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalar x = rotX;
|
scalar z = angles.component(vector::X); // 1. Rotate about Z
|
||||||
scalar y = rotY;
|
scalar x = angles.component(vector::Y); // 2. Rotate about X
|
||||||
scalar z = rotZ;
|
scalar y = angles.component(vector::Z); // 3. Rotate about Y
|
||||||
|
|
||||||
if (inDegrees)
|
if (degrees)
|
||||||
{
|
{
|
||||||
x *= constant::mathematical::pi/180.0;
|
x *= degToRad();
|
||||||
y *= constant::mathematical::pi/180.0;
|
y *= degToRad();
|
||||||
z *= constant::mathematical::pi/180.0;
|
z *= degToRad();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_ =
|
return
|
||||||
(
|
|
||||||
tensor
|
tensor
|
||||||
(
|
(
|
||||||
cos(y)*cos(z) - sin(x)*sin(y)*sin(z),
|
cos(y)*cos(z) - sin(x)*sin(y)*sin(z),
|
||||||
@ -184,10 +180,7 @@ void Foam::STARCDCoordinateRotation::calcTransform
|
|||||||
-cos(x)*sin(y),
|
-cos(x)*sin(y),
|
||||||
sin(x),
|
sin(x),
|
||||||
cos(x)*cos(y)
|
cos(x)*cos(y)
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
|
||||||
Rtr_ = R_.T();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -213,20 +206,12 @@ Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
|||||||
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
||||||
(
|
(
|
||||||
const vector& rotZrotXrotY,
|
const vector& rotZrotXrotY,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(rotZrotXrotY, degrees)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
calcTransform
|
|
||||||
(
|
|
||||||
rotZrotXrotY.component(vector::X),
|
|
||||||
rotZrotXrotY.component(vector::Y),
|
|
||||||
rotZrotXrotY.component(vector::Z),
|
|
||||||
inDegrees
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
||||||
@ -234,14 +219,12 @@ Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
|||||||
const scalar rotZ,
|
const scalar rotZ,
|
||||||
const scalar rotX,
|
const scalar rotX,
|
||||||
const scalar rotY,
|
const scalar rotY,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(vector(rotZ, rotX, rotY), degrees)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
calcTransform(rotZ, rotX, rotY, inDegrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
||||||
@ -249,19 +232,16 @@ Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_
|
||||||
Rtr_(sphericalTensor::I)
|
|
||||||
{
|
|
||||||
const vector rotation(dict.lookup("rotation"));
|
|
||||||
|
|
||||||
calcTransform
|
|
||||||
(
|
(
|
||||||
rotation.component(vector::X),
|
rotation
|
||||||
rotation.component(vector::Y),
|
(
|
||||||
rotation.component(vector::Z),
|
dict.get<vector>("rotation"),
|
||||||
dict.lookupOrDefault("degrees", true)
|
dict.lookupOrDefault("degrees", true)
|
||||||
);
|
)
|
||||||
}
|
),
|
||||||
|
Rtr_(R_.T())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
Foam::STARCDCoordinateRotation::STARCDCoordinateRotation
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -65,7 +65,6 @@ class STARCDCoordinateRotation
|
|||||||
:
|
:
|
||||||
public coordinateRotation
|
public coordinateRotation
|
||||||
{
|
{
|
||||||
|
|
||||||
// Private Member Data
|
// Private Member Data
|
||||||
|
|
||||||
//- Local-to-Global transformation tensor
|
//- Local-to-Global transformation tensor
|
||||||
@ -75,18 +74,6 @@ class STARCDCoordinateRotation
|
|||||||
tensor Rtr_;
|
tensor Rtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Calculate transformation tensor
|
|
||||||
void calcTransform
|
|
||||||
(
|
|
||||||
const scalar rotZ,
|
|
||||||
const scalar rotX,
|
|
||||||
const scalar rotY,
|
|
||||||
const bool inDegrees
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -105,7 +92,7 @@ public:
|
|||||||
STARCDCoordinateRotation
|
STARCDCoordinateRotation
|
||||||
(
|
(
|
||||||
const vector& rotZrotXrotY,
|
const vector& rotZrotXrotY,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from components of rotation vector
|
//- Construct from components of rotation vector
|
||||||
@ -114,7 +101,7 @@ public:
|
|||||||
const scalar rotZ,
|
const scalar rotZ,
|
||||||
const scalar rotX,
|
const scalar rotX,
|
||||||
const scalar rotY,
|
const scalar rotY,
|
||||||
const bool inDegrees
|
const bool degrees
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct from dictionary
|
//- Construct from dictionary
|
||||||
@ -137,6 +124,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Static Member Functions
|
||||||
|
|
||||||
|
//- The rotation tensor calculated for the specified STARCD angles
|
||||||
|
//- interpreted as rotate-Z, rotate-X, rotate-Y
|
||||||
|
static tensor rotation(const vector& angles, bool degrees);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Reset rotation to an identity rotation
|
//- Reset rotation to an identity rotation
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -47,6 +47,151 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tensor Foam::axesRotation::rotation
|
||||||
|
(
|
||||||
|
const vector& axis1,
|
||||||
|
const vector& axis2,
|
||||||
|
axisOrder order
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const scalar magAxis1(mag(axis1));
|
||||||
|
scalar magAxis2(mag(axis2));
|
||||||
|
|
||||||
|
if (magAxis1 < ROOTVSMALL)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Dominant coordinate axis cannot have zero length"
|
||||||
|
<< nl << endl
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const vector ax1(axis1 / magAxis1); // normalise
|
||||||
|
vector ax2(axis2);
|
||||||
|
|
||||||
|
if (magAxis2 < ROOTVSMALL)
|
||||||
|
{
|
||||||
|
// axis2 == Zero : Use best-guess for the second axis.
|
||||||
|
ax2 = findOrthogonal(axis1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove colinear component
|
||||||
|
ax2 -= ((ax1 & ax2) * ax1);
|
||||||
|
|
||||||
|
magAxis2 = mag(ax2);
|
||||||
|
|
||||||
|
if (magAxis2 < SMALL)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "axis1, axis2 appear to be co-linear: "
|
||||||
|
<< axis1 << ", " << axis2 << " Revert to guessing axis2"
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
|
ax2 = findOrthogonal(axis1);
|
||||||
|
|
||||||
|
// Remove colinear component
|
||||||
|
ax2 -= ((ax1 & ax2) * ax1);
|
||||||
|
|
||||||
|
magAxis2 = mag(ax2);
|
||||||
|
|
||||||
|
if (magAxis2 < SMALL)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Could not find an appropriate second axis"
|
||||||
|
<< nl << endl
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ax2 /= magAxis2; // normalise
|
||||||
|
|
||||||
|
|
||||||
|
// The local axes are columns of the rotation matrix
|
||||||
|
|
||||||
|
tensor rotTensor;
|
||||||
|
|
||||||
|
switch (order)
|
||||||
|
{
|
||||||
|
case E1_E2:
|
||||||
|
{
|
||||||
|
rotTensor.col<0>(ax1);
|
||||||
|
rotTensor.col<1>(ax2);
|
||||||
|
rotTensor.col<2>(ax1^ax2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case E2_E3:
|
||||||
|
{
|
||||||
|
rotTensor.col<0>(ax1^ax2);
|
||||||
|
rotTensor.col<1>(ax1);
|
||||||
|
rotTensor.col<2>(ax2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case E3_E1:
|
||||||
|
case E3_E1_COMPAT:
|
||||||
|
{
|
||||||
|
rotTensor.col<0>(ax2);
|
||||||
|
rotTensor.col<1>(ax1^ax2);
|
||||||
|
rotTensor.col<2>(ax1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rotTensor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::axesRotation::read(const dictionary& dict)
|
||||||
|
{
|
||||||
|
vector axis1, axis2;
|
||||||
|
axisOrder order = E3_E1;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
dict.readIfPresent("e1", axis1)
|
||||||
|
&& dict.readIfPresent("e2", axis2)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
order = E1_E2;
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
dict.readIfPresent("e2", axis1)
|
||||||
|
&& dict.readIfPresent("e3", axis2)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
order = E2_E3;
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
dict.readIfPresent("e3", axis1)
|
||||||
|
&& dict.readIfPresent("e1", axis2)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
order = E3_E1;
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
dict.readIfPresent("axis", axis1)
|
||||||
|
&& dict.readIfPresent("direction", axis2)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
order = E3_E1_COMPAT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "No entries of the type (e1, e2) or (e2, e3) or (e3, e1) found"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_ = rotation(axis1, axis2, order);
|
||||||
|
Rtr_ = R_.T();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::axesRotation::axesRotation()
|
Foam::axesRotation::axesRotation()
|
||||||
@ -77,11 +222,9 @@ Foam::axesRotation::axesRotation
|
|||||||
const axisOrder& order
|
const axisOrder& order
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(axis, dir, order)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
setTransform(axis, dir, order);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::axesRotation::axesRotation
|
Foam::axesRotation::axesRotation
|
||||||
@ -89,37 +232,9 @@ Foam::axesRotation::axesRotation
|
|||||||
const vector& axis
|
const vector& axis
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
R_(sphericalTensor::I),
|
R_(rotation(axis, findOrthogonal(axis), E3_E1)),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(R_.T())
|
||||||
{
|
{}
|
||||||
direction maxCmpt = 0, dirCmpt = 1;
|
|
||||||
|
|
||||||
scalar maxVal = mag(axis[maxCmpt]);
|
|
||||||
bool negative = (axis[maxCmpt] < 0);
|
|
||||||
|
|
||||||
for (direction cmpt = 1; cmpt < vector::nComponents; ++cmpt)
|
|
||||||
{
|
|
||||||
const scalar val = mag(axis[cmpt]);
|
|
||||||
|
|
||||||
if (maxVal < val)
|
|
||||||
{
|
|
||||||
maxVal = val;
|
|
||||||
maxCmpt = cmpt;
|
|
||||||
dirCmpt = maxCmpt+1;
|
|
||||||
negative = (axis[cmpt] < 0);
|
|
||||||
|
|
||||||
if (dirCmpt >= vector::nComponents)
|
|
||||||
{
|
|
||||||
dirCmpt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vector dir = Zero;
|
|
||||||
dir.component(dirCmpt) = (negative ? -1 : 1);
|
|
||||||
|
|
||||||
setTransform(axis, dir, E3_E1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::axesRotation::axesRotation
|
Foam::axesRotation::axesRotation
|
||||||
@ -130,7 +245,7 @@ Foam::axesRotation::axesRotation
|
|||||||
R_(sphericalTensor::I),
|
R_(sphericalTensor::I),
|
||||||
Rtr_(sphericalTensor::I)
|
Rtr_(sphericalTensor::I)
|
||||||
{
|
{
|
||||||
operator=(dict);
|
read(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -146,62 +261,6 @@ Foam::axesRotation::axesRotation
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::axesRotation::setTransform
|
|
||||||
(
|
|
||||||
const vector& axis1,
|
|
||||||
const vector& axis2,
|
|
||||||
const axisOrder& order
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const vector a = axis1/mag(axis1);
|
|
||||||
vector b = axis2;
|
|
||||||
|
|
||||||
b = b - (b & a)*a;
|
|
||||||
|
|
||||||
if (mag(b) < SMALL)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "axis1, axis2 appear to be co-linear: "
|
|
||||||
<< axis1 << ", " << axis2 << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
b = b/mag(b);
|
|
||||||
const vector c = a^b;
|
|
||||||
|
|
||||||
// Global->local transformation
|
|
||||||
switch (order)
|
|
||||||
{
|
|
||||||
case E1_E2:
|
|
||||||
{
|
|
||||||
Rtr_ = tensor(a, b, c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case E2_E3:
|
|
||||||
{
|
|
||||||
Rtr_ = tensor(c, a, b);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case E3_E1:
|
|
||||||
{
|
|
||||||
Rtr_ = tensor(b, c, a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Unhandled axes specification" << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local->global transformation
|
|
||||||
R_ = Rtr_.T();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Foam::tensorField& Foam::axesRotation::Tr() const
|
const Foam::tensorField& Foam::axesRotation::Tr() const
|
||||||
{
|
{
|
||||||
NotImplemented;
|
NotImplemented;
|
||||||
@ -298,36 +357,7 @@ Foam::symmTensor Foam::axesRotation::transformVector
|
|||||||
|
|
||||||
void Foam::axesRotation::operator=(const dictionary& dict)
|
void Foam::axesRotation::operator=(const dictionary& dict)
|
||||||
{
|
{
|
||||||
vector axis1, axis2;
|
read(dict);
|
||||||
|
|
||||||
if (dict.readIfPresent("e1", axis1) && dict.readIfPresent("e2", axis2))
|
|
||||||
{
|
|
||||||
setTransform(axis1, axis2, E1_E2);
|
|
||||||
}
|
|
||||||
else if (dict.readIfPresent("e2", axis1) && dict.readIfPresent("e3", axis2))
|
|
||||||
{
|
|
||||||
setTransform(axis1, axis2, E2_E3);
|
|
||||||
}
|
|
||||||
else if (dict.readIfPresent("e3", axis1) && dict.readIfPresent("e1", axis2))
|
|
||||||
{
|
|
||||||
setTransform(axis1, axis2, E3_E1);
|
|
||||||
}
|
|
||||||
else if (dict.found("axis") || dict.found("direction"))
|
|
||||||
{
|
|
||||||
// Both "axis" and "direction" are required
|
|
||||||
// If one is missing the appropriate error message will be generated
|
|
||||||
dict.readEntry("axis", axis1);
|
|
||||||
dict.readEntry("direction", axis2);
|
|
||||||
|
|
||||||
setTransform(axis1, axis2, E3_E1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "not entry of the type (e1, e2) or (e2, e3) or (e3, e1) "
|
|
||||||
<< "found "
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -73,9 +73,10 @@ public:
|
|||||||
// Note that these follow the right-hand rule.
|
// Note that these follow the right-hand rule.
|
||||||
enum axisOrder
|
enum axisOrder
|
||||||
{
|
{
|
||||||
E1_E2, //!< The axis is X-dominant, the direction is Y-dominant
|
E1_E2, //!< The axis1 (dominant) is local X, axis2 is local Y.
|
||||||
E2_E3, //!< The axis is Y-dominant, the direction is Z-dominant
|
E2_E3, //!< The axis1 (dominant) is local Y, axis2 is local Z.
|
||||||
E3_E1 //!< The axis is Z-dominant, the direction is X-dominant
|
E3_E1, //!< The axis1 (dominant) is local Z, axis2 is local X.
|
||||||
|
E3_E1_COMPAT, //!< E3_E1 specified as axis/direction.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -90,6 +91,12 @@ private:
|
|||||||
tensor Rtr_;
|
tensor Rtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Read from dictionary
|
||||||
|
void read(const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -149,14 +156,19 @@ public:
|
|||||||
Rtr_ = sphericalTensor::I;
|
Rtr_ = sphericalTensor::I;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Set the transformation tensors from two axes (axis and direction)
|
|
||||||
void setTransform
|
// Static Member Functions
|
||||||
|
|
||||||
|
//- The rotation tensor calculated from two axes and their order.
|
||||||
|
// The input axes will be normalised.
|
||||||
|
static tensor rotation
|
||||||
(
|
(
|
||||||
const vector& axis1,
|
const vector& axis1,
|
||||||
const vector& axis2,
|
const vector& axis2,
|
||||||
const axisOrder& order = E3_E1
|
axisOrder order = E3_E1
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Update the rotation for a list of cells
|
//- Update the rotation for a list of cells
|
||||||
virtual void updateCells(const polyMesh&, const labelList&)
|
virtual void updateCells(const polyMesh&, const labelList&)
|
||||||
{}
|
{}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -37,41 +37,65 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::vector Foam::coordinateRotation::findOrthogonal(const vector& axis)
|
||||||
|
{
|
||||||
|
direction maxCmpt = 0;
|
||||||
|
scalar maxVal = mag(axis[maxCmpt]);
|
||||||
|
|
||||||
|
for (direction cmpt=1; cmpt < vector::nComponents; ++cmpt)
|
||||||
|
{
|
||||||
|
const scalar val = mag(axis[cmpt]);
|
||||||
|
|
||||||
|
if (maxVal < val)
|
||||||
|
{
|
||||||
|
maxVal = val;
|
||||||
|
maxCmpt = cmpt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
direction cmpt = ((maxCmpt == vector::nComponents-1) ? 0 : (maxCmpt+1));
|
||||||
|
|
||||||
|
vector dirn(Zero);
|
||||||
|
dirn.component(cmpt) = ((axis[maxCmpt] < 0) ? -1 : 1);
|
||||||
|
|
||||||
|
return dirn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::symmTensor Foam::coordinateRotation::transformPrincipal
|
Foam::symmTensor Foam::coordinateRotation::transformPrincipal
|
||||||
(
|
(
|
||||||
const tensor& tt,
|
const tensor& tt,
|
||||||
const vector& st
|
const vector& v
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
return symmTensor
|
return symmTensor
|
||||||
(
|
(
|
||||||
tt.xx()*st.x()*tt.xx()
|
tt.xx()*v.x()*tt.xx()
|
||||||
+ tt.xy()*st.y()*tt.xy()
|
+ tt.xy()*v.y()*tt.xy()
|
||||||
+ tt.xz()*st.z()*tt.xz(),
|
+ tt.xz()*v.z()*tt.xz(),
|
||||||
|
|
||||||
tt.xx()*st.x()*tt.yx()
|
tt.xx()*v.x()*tt.yx()
|
||||||
+ tt.xy()*st.y()*tt.yy()
|
+ tt.xy()*v.y()*tt.yy()
|
||||||
+ tt.xz()*st.z()*tt.yz(),
|
+ tt.xz()*v.z()*tt.yz(),
|
||||||
|
|
||||||
tt.xx()*st.x()*tt.zx()
|
tt.xx()*v.x()*tt.zx()
|
||||||
+ tt.xy()*st.y()*tt.zy()
|
+ tt.xy()*v.y()*tt.zy()
|
||||||
+ tt.xz()*st.z()*tt.zz(),
|
+ tt.xz()*v.z()*tt.zz(),
|
||||||
|
|
||||||
tt.yx()*st.x()*tt.yx()
|
tt.yx()*v.x()*tt.yx()
|
||||||
+ tt.yy()*st.y()*tt.yy()
|
+ tt.yy()*v.y()*tt.yy()
|
||||||
+ tt.yz()*st.z()*tt.yz(),
|
+ tt.yz()*v.z()*tt.yz(),
|
||||||
|
|
||||||
tt.yx()*st.x()*tt.zx()
|
tt.yx()*v.x()*tt.zx()
|
||||||
+ tt.yy()*st.y()*tt.zy()
|
+ tt.yy()*v.y()*tt.zy()
|
||||||
+ tt.yz()*st.z()*tt.zz(),
|
+ tt.yz()*v.z()*tt.zz(),
|
||||||
|
|
||||||
tt.zx()*st.x()*tt.zx()
|
tt.zx()*v.x()*tt.zx()
|
||||||
+ tt.zy()*st.y()*tt.zy()
|
+ tt.zy()*v.y()*tt.zy()
|
||||||
+ tt.zz()*st.z()*tt.zz()
|
+ tt.zz()*v.z()*tt.zz()
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -75,12 +75,14 @@ protected:
|
|||||||
// Protected member functions
|
// Protected member functions
|
||||||
|
|
||||||
//- Transform principal
|
//- Transform principal
|
||||||
symmTensor transformPrincipal(const tensor&, const vector&) const;
|
static symmTensor transformPrincipal(const tensor&, const vector&);
|
||||||
|
|
||||||
|
//- Determine best-guess for an orthogonal axis
|
||||||
|
static vector findOrthogonal(const vector& axis);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("coordinateRotation");
|
TypeName("coordinateRotation");
|
||||||
|
|
||||||
@ -135,8 +137,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~coordinateRotation()
|
virtual ~coordinateRotation() = default;
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|||||||
Reference in New Issue
Block a user