mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-plus into develop
This commit is contained in:
@ -68,6 +68,21 @@ void printRotation(const quaternion& quat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool equalTensors(const tensor& rot1, const tensor& rot2)
|
||||||
|
{
|
||||||
|
for (direction cmpt=0; cmpt < tensor::nComponents; ++cmpt)
|
||||||
|
{
|
||||||
|
// Cannot be really picky, but SMALL is reasonable
|
||||||
|
if (mag(rot1[cmpt] - rot2[cmpt]) > SMALL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -108,8 +123,17 @@ int main(int argc, char *argv[])
|
|||||||
"(vector angle)",
|
"(vector angle)",
|
||||||
"Rotate about the <vector> by <angle> degrees - eg, '((1 0 0) 45)'"
|
"Rotate about the <vector> by <angle> degrees - eg, '((1 0 0) 45)'"
|
||||||
);
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"verbose",
|
||||||
|
"Additional verbosity"
|
||||||
|
);
|
||||||
|
|
||||||
argList args(argc, argv);
|
argList args(argc, argv);
|
||||||
|
|
||||||
|
const bool verbose = args.found("verbose");
|
||||||
|
|
||||||
|
|
||||||
vector rotVector;
|
vector rotVector;
|
||||||
|
|
||||||
if (args.readIfPresent("rollPitchYaw", rotVector))
|
if (args.readIfPresent("rollPitchYaw", rotVector))
|
||||||
@ -122,10 +146,18 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
rotVector *= degToRad();
|
rotVector *= degToRad();
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::XYZ, rotVector);
|
const quaternion quat(quaternion::eulerOrder::XYZ, rotVector);
|
||||||
|
|
||||||
printRotation(quat);
|
printRotation(quat);
|
||||||
|
|
||||||
|
// Euler
|
||||||
|
const tensor rot
|
||||||
|
(
|
||||||
|
euler::rotation(euler::eulerOrder::XYZ, rotVector, false)
|
||||||
|
);
|
||||||
|
printRotation(rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.readIfPresent("yawPitchRoll", rotVector))
|
if (args.readIfPresent("yawPitchRoll", rotVector))
|
||||||
{
|
{
|
||||||
Info<< nl
|
Info<< nl
|
||||||
@ -136,9 +168,16 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
rotVector *= degToRad();
|
rotVector *= degToRad();
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::ZYX, rotVector);
|
const quaternion quat(quaternion::eulerOrder::ZYX, rotVector);
|
||||||
|
|
||||||
printRotation(quat);
|
printRotation(quat);
|
||||||
|
|
||||||
|
// Euler
|
||||||
|
const tensor rot
|
||||||
|
(
|
||||||
|
euler::rotation(euler::eulerOrder::ZYX, rotVector, false)
|
||||||
|
);
|
||||||
|
printRotation(rot);
|
||||||
}
|
}
|
||||||
if (args.readIfPresent("euler", rotVector))
|
if (args.readIfPresent("euler", rotVector))
|
||||||
{
|
{
|
||||||
@ -152,7 +191,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
rotVector *= degToRad();
|
rotVector *= degToRad();
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::ZXZ, rotVector);
|
const quaternion quat(quaternion::eulerOrder::ZXZ, rotVector);
|
||||||
|
|
||||||
printRotation(quat);
|
printRotation(quat);
|
||||||
}
|
}
|
||||||
@ -266,23 +305,44 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "Test conversion from and to Euler-angles" << nl;
|
Info<< "Test conversion from and to Euler-angles" << nl;
|
||||||
vector angles(0.1, 0.2, 0.3);
|
vector angles(0.1, 0.2, 0.3);
|
||||||
for (int rs=quaternion::ZYX; rs<quaternion::XZX; ++rs)
|
|
||||||
|
for (int rs : quaternion::eulerOrderNames.values())
|
||||||
{
|
{
|
||||||
|
const quaternion::eulerOrder order = quaternion::eulerOrder(rs);
|
||||||
|
const word& orderName = quaternion::eulerOrderNames[order];
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
mag
|
mag(angles - quaternion(order, angles).eulerAngles(order))
|
||||||
(
|
|
||||||
angles
|
|
||||||
- quaternion(quaternion::rotationSequence(rs), angles)
|
|
||||||
.eulerAngles(quaternion::rotationSequence(rs))
|
|
||||||
)
|
|
||||||
> SMALL
|
> SMALL
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Inconsistent conversion for rotation sequence "
|
<< "Inconsistent conversion for euler rotation order "
|
||||||
<< rs << exit(FatalError)
|
<< orderName << nl << exit(FatalError);
|
||||||
<< nl;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tensor rotQ(quaternion(order, angles).R());
|
||||||
|
tensor rotE(euler::rotation(order, angles, false));
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "euler " << orderName << angles << nl;
|
||||||
|
printRotation(rotE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!equalTensors(rotQ, rotE))
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Inconsistent quaternion/euler rotation matrices for "
|
||||||
|
<< orderName << nl;
|
||||||
|
|
||||||
|
printRotation(rotQ);
|
||||||
|
printRotation(rotE);
|
||||||
|
|
||||||
|
FatalError
|
||||||
|
<< nl << exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +1,5 @@
|
|||||||
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
/* EXE_LIBS = -lfiniteVolume */
|
/* EXE_LIBS = -lfiniteVolume */
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
|
-lmeshTools \
|
||||||
-lgenericPatchFields
|
-lgenericPatchFields
|
||||||
|
|||||||
@ -2,7 +2,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) 2017 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
@ -57,7 +57,7 @@ Usage
|
|||||||
With -rotateFields (in combination with -rotate/yawPitchRoll/rollPitchYaw)
|
With -rotateFields (in combination with -rotate/yawPitchRoll/rollPitchYaw)
|
||||||
it will also read & transform vector & tensor fields.
|
it will also read & transform vector & tensor fields.
|
||||||
|
|
||||||
Note:
|
Note
|
||||||
roll (rotation about x)
|
roll (rotation about x)
|
||||||
pitch (rotation about y)
|
pitch (rotation about y)
|
||||||
yaw (rotation about z)
|
yaw (rotation about z)
|
||||||
@ -73,9 +73,11 @@ Usage
|
|||||||
#include "pointFields.H"
|
#include "pointFields.H"
|
||||||
#include "transformField.H"
|
#include "transformField.H"
|
||||||
#include "transformGeometricField.H"
|
#include "transformGeometricField.H"
|
||||||
#include "unitConversion.H"
|
#include "axisAngleRotation.H"
|
||||||
|
#include "EulerCoordinateRotation.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
using namespace Foam::coordinateRotations;
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -284,40 +286,38 @@ int main(int argc, char *argv[])
|
|||||||
n1n2[0].normalise();
|
n1n2[0].normalise();
|
||||||
n1n2[1].normalise();
|
n1n2[1].normalise();
|
||||||
|
|
||||||
const tensor rotT = rotationTensor(n1n2[0], n1n2[1]);
|
const tensor rot(rotationTensor(n1n2[0], n1n2[1]));
|
||||||
|
|
||||||
Info<< "Rotating points by " << rotT << endl;
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
points = transform(rotT, points);
|
|
||||||
|
|
||||||
if (doRotateFields)
|
if (doRotateFields)
|
||||||
{
|
{
|
||||||
rotateFields(args, runTime, rotT);
|
rotateFields(args, runTime, rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args.found("rotate-angle"))
|
else if (args.found("rotate-angle"))
|
||||||
{
|
{
|
||||||
const Tuple2<vector, scalar> axisAngle
|
const Tuple2<vector, scalar> rotAxisAngle
|
||||||
(
|
(
|
||||||
args.lookup("rotate-angle")()
|
args.lookup("rotate-angle")()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const vector& axis = rotAxisAngle.first();
|
||||||
|
const scalar& angle = rotAxisAngle.second();
|
||||||
|
|
||||||
Info<< "Rotating points " << nl
|
Info<< "Rotating points " << nl
|
||||||
<< " about " << axisAngle.first() << nl
|
<< " about " << axis << nl
|
||||||
<< " angle " << axisAngle.second() << nl;
|
<< " angle " << angle << nl;
|
||||||
|
|
||||||
const quaternion quat
|
const tensor rot(axisAngle::rotation(axis, angle, true));
|
||||||
(
|
|
||||||
axisAngle.first(),
|
|
||||||
degToRad(axisAngle.second())
|
|
||||||
);
|
|
||||||
|
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
Info<< "Rotating points by " << rot << endl;
|
||||||
points = transform(quat, points);
|
points = transform(rot, points);
|
||||||
|
|
||||||
if (doRotateFields)
|
if (doRotateFields)
|
||||||
{
|
{
|
||||||
rotateFields(args, runTime, quat.R());
|
rotateFields(args, runTime, rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args.readIfPresent("rollPitchYaw", v))
|
else if (args.readIfPresent("rollPitchYaw", v))
|
||||||
@ -327,16 +327,14 @@ int main(int argc, char *argv[])
|
|||||||
<< " pitch " << v.y() << nl
|
<< " pitch " << v.y() << nl
|
||||||
<< " yaw " << v.z() << nl;
|
<< " yaw " << v.z() << nl;
|
||||||
|
|
||||||
v *= degToRad();
|
const tensor rot(euler::rotation(euler::eulerOrder::XYZ, v, true));
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::XYZ, v);
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
|
||||||
points = transform(quat, points);
|
|
||||||
|
|
||||||
if (doRotateFields)
|
if (doRotateFields)
|
||||||
{
|
{
|
||||||
rotateFields(args, runTime, quat.R());
|
rotateFields(args, runTime, rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (args.readIfPresent("yawPitchRoll", v))
|
else if (args.readIfPresent("yawPitchRoll", v))
|
||||||
@ -346,16 +344,14 @@ int main(int argc, char *argv[])
|
|||||||
<< " pitch " << v.y() << nl
|
<< " pitch " << v.y() << nl
|
||||||
<< " roll " << v.z() << nl;
|
<< " roll " << v.z() << nl;
|
||||||
|
|
||||||
v *= degToRad();
|
const tensor rot(euler::rotation(euler::eulerOrder::ZYX, v, true));
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::ZYX, v);
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
|
||||||
points = transform(quat, points);
|
|
||||||
|
|
||||||
if (doRotateFields)
|
if (doRotateFields)
|
||||||
{
|
{
|
||||||
rotateFields(args, runTime, quat.R());
|
rotateFields(args, runTime, rot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,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) 2017-2018 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
| Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
@ -24,7 +24,7 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Application
|
Application
|
||||||
surfaceMeshTriangulate
|
surfaceMeshExtract
|
||||||
|
|
||||||
Group
|
Group
|
||||||
grpSurfaceUtilities
|
grpSurfaceUtilities
|
||||||
@ -47,6 +47,7 @@ Description
|
|||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
|
#include "emptyPolyPatch.H"
|
||||||
#include "processorPolyPatch.H"
|
#include "processorPolyPatch.H"
|
||||||
#include "ListListOps.H"
|
#include "ListListOps.H"
|
||||||
#include "uindirectPrimitivePatch.H"
|
#include "uindirectPrimitivePatch.H"
|
||||||
@ -58,6 +59,57 @@ using namespace Foam;
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
labelList getSelectedPatches
|
||||||
|
(
|
||||||
|
const polyBoundaryMesh& patches,
|
||||||
|
const wordRes& whitelist,
|
||||||
|
const wordRes& blacklist
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DynamicList<label> patchIDs(patches.size());
|
||||||
|
|
||||||
|
for (const polyPatch& pp : patches)
|
||||||
|
{
|
||||||
|
if (isType<emptyPolyPatch>(pp))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (Pstream::parRun() && bool(isA<processorPolyPatch>(pp)))
|
||||||
|
{
|
||||||
|
break; // No processor patches for parallel output
|
||||||
|
}
|
||||||
|
|
||||||
|
const word& patchName = pp.name();
|
||||||
|
|
||||||
|
bool accept = false;
|
||||||
|
|
||||||
|
if (whitelist.size())
|
||||||
|
{
|
||||||
|
const auto matched = whitelist.matched(patchName);
|
||||||
|
|
||||||
|
accept =
|
||||||
|
(
|
||||||
|
matched == wordRe::LITERAL
|
||||||
|
? true
|
||||||
|
: (matched == wordRe::REGEX && !blacklist.match(patchName))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accept = !blacklist.match(patchName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accept)
|
||||||
|
{
|
||||||
|
patchIDs.append(pp.index());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return patchIDs.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -69,6 +121,10 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
timeSelector::addOptions();
|
timeSelector::addOptions();
|
||||||
|
|
||||||
|
// Less frequently used - reduce some clutter
|
||||||
|
argList::setAdvanced("decomposeParDict");
|
||||||
|
argList::setAdvanced("noFunctionObjects");
|
||||||
|
|
||||||
argList::addArgument("output", "The output surface file");
|
argList::addArgument("output", "The output surface file");
|
||||||
|
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
@ -78,18 +134,26 @@ int main(int argc, char *argv[])
|
|||||||
"Exclude processor patches"
|
"Exclude processor patches"
|
||||||
);
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
|
(
|
||||||
|
"faceZones",
|
||||||
|
"wordRes",
|
||||||
|
"Specify single or multiple faceZones to extract\n"
|
||||||
|
"Eg, 'cells' or '( slice \"mfp-.*\" )'"
|
||||||
|
);
|
||||||
|
argList::addOption
|
||||||
(
|
(
|
||||||
"patches",
|
"patches",
|
||||||
"wordRes"
|
"wordRes",
|
||||||
"Specify single patch or multiple patches to extract.\n"
|
"Specify single patch or multiple patches to extract.\n"
|
||||||
"Eg, 'top' or '( front \".*back\" )'"
|
"Eg, 'top' or '( front \".*back\" )'"
|
||||||
);
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
"faceZones",
|
"excludePatches",
|
||||||
"wordRes",
|
"wordRes",
|
||||||
"Specify single or multiple faceZones to extract\n"
|
"Specify single patch or multiple patches to exclude from writing."
|
||||||
"Eg, 'cells' or '( slice \"mfp-.*\" )'"
|
" Eg, 'outlet' or '( inlet \".*Wall\" )'",
|
||||||
|
true // mark as an advanced option
|
||||||
);
|
);
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
@ -121,6 +185,25 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Excluding all processor patches." << nl << endl;
|
Info<< "Excluding all processor patches." << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wordRes includePatches, excludePatches;
|
||||||
|
if (args.readListIfPresent<wordRe>("patches", includePatches))
|
||||||
|
{
|
||||||
|
Info<< "Including patches " << flatOutput(includePatches)
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
if (args.readListIfPresent<wordRe>("excludePatches", excludePatches))
|
||||||
|
{
|
||||||
|
Info<< "Excluding patches " << flatOutput(excludePatches)
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-mandatory
|
||||||
|
const wordRes selectedFaceZones(args.getList<wordRe>("faceZones", false));
|
||||||
|
if (selectedFaceZones.size())
|
||||||
|
{
|
||||||
|
Info<< "Including faceZones " << flatOutput(selectedFaceZones)
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
Info<< "Reading mesh from time " << runTime.value() << endl;
|
Info<< "Reading mesh from time " << runTime.value() << endl;
|
||||||
|
|
||||||
@ -171,53 +254,25 @@ int main(int argc, char *argv[])
|
|||||||
// Construct table of patches to include.
|
// Construct table of patches to include.
|
||||||
const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
|
const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
|
||||||
|
|
||||||
labelList includePatches;
|
labelList patchIds =
|
||||||
|
(
|
||||||
|
(includePatches.size() || excludePatches.size())
|
||||||
|
? getSelectedPatches(bMesh, includePatches, excludePatches)
|
||||||
|
: includeProcPatches
|
||||||
|
? identity(bMesh.size())
|
||||||
|
: identity(bMesh.nNonProcessor())
|
||||||
|
);
|
||||||
|
|
||||||
if (args.found("patches"))
|
labelList faceZoneIds;
|
||||||
{
|
|
||||||
includePatches =
|
|
||||||
bMesh.patchSet(args.getList<wordRe>("patches")).sortedToc();
|
|
||||||
}
|
|
||||||
else if (includeProcPatches)
|
|
||||||
{
|
|
||||||
includePatches = identity(bMesh.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
includePatches = identity(bMesh.nNonProcessor());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
labelList includeFaceZones;
|
|
||||||
|
|
||||||
const faceZoneMesh& fzm = mesh.faceZones();
|
const faceZoneMesh& fzm = mesh.faceZones();
|
||||||
|
|
||||||
if (args.found("faceZones"))
|
if (selectedFaceZones.size())
|
||||||
{
|
{
|
||||||
const wordList allZoneNames(fzm.names());
|
faceZoneIds = fzm.indices(selectedFaceZones);
|
||||||
|
|
||||||
const wordRes zoneNames(args.getList<wordRe>("faceZones"));
|
|
||||||
|
|
||||||
labelHashSet hashed(2*fzm.size());
|
|
||||||
|
|
||||||
for (const wordRe& zoneName : zoneNames)
|
|
||||||
{
|
|
||||||
labelList zoneIDs = findStrings(zoneName, allZoneNames);
|
|
||||||
hashed.insert(zoneIDs);
|
|
||||||
|
|
||||||
if (zoneIDs.empty())
|
|
||||||
{
|
|
||||||
WarningInFunction
|
|
||||||
<< "Cannot find any faceZone name matching "
|
|
||||||
<< zoneName << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
includeFaceZones = hashed.sortedToc();
|
|
||||||
|
|
||||||
Info<< "Additionally extracting faceZones "
|
Info<< "Additionally extracting faceZones "
|
||||||
<< UIndirectList<word>(allZoneNames, includeFaceZones)
|
<< fzm.names(selectedFaceZones) << nl;
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -232,7 +287,7 @@ int main(int argc, char *argv[])
|
|||||||
// processor patches)
|
// processor patches)
|
||||||
HashTable<label> patchSize(1024);
|
HashTable<label> patchSize(1024);
|
||||||
label nFaces = 0;
|
label nFaces = 0;
|
||||||
for (const label patchi : includePatches)
|
for (const label patchi : patchIds)
|
||||||
{
|
{
|
||||||
const polyPatch& pp = bMesh[patchi];
|
const polyPatch& pp = bMesh[patchi];
|
||||||
patchSize.insert(pp.name(), pp.size());
|
patchSize.insert(pp.name(), pp.size());
|
||||||
@ -240,7 +295,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
HashTable<label> zoneSize(1024);
|
HashTable<label> zoneSize(1024);
|
||||||
for (const label zonei : includeFaceZones)
|
for (const label zonei : faceZoneIds)
|
||||||
{
|
{
|
||||||
const faceZone& pp = fzm[zonei];
|
const faceZone& pp = fzm[zonei];
|
||||||
zoneSize.insert(pp.name(), pp.size());
|
zoneSize.insert(pp.name(), pp.size());
|
||||||
@ -289,7 +344,7 @@ int main(int argc, char *argv[])
|
|||||||
compactZones.setCapacity(nFaces);
|
compactZones.setCapacity(nFaces);
|
||||||
|
|
||||||
// Collect faces on patches
|
// Collect faces on patches
|
||||||
for (const label patchi : includePatches)
|
for (const label patchi : patchIds)
|
||||||
{
|
{
|
||||||
const polyPatch& pp = bMesh[patchi];
|
const polyPatch& pp = bMesh[patchi];
|
||||||
forAll(pp, i)
|
forAll(pp, i)
|
||||||
@ -299,7 +354,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Collect faces on faceZones
|
// Collect faces on faceZones
|
||||||
for (const label zonei : includeFaceZones)
|
for (const label zonei : faceZoneIds)
|
||||||
{
|
{
|
||||||
const faceZone& pp = fzm[zonei];
|
const faceZone& pp = fzm[zonei];
|
||||||
forAll(pp, i)
|
forAll(pp, i)
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/surfMesh/lnInclude
|
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lsurfMesh
|
-lsurfMesh \
|
||||||
|
-lmeshTools
|
||||||
|
|||||||
@ -33,12 +33,18 @@ Description
|
|||||||
Transform (scale/rotate) a surface.
|
Transform (scale/rotate) a surface.
|
||||||
Like transformPoints but for surfaces.
|
Like transformPoints but for surfaces.
|
||||||
|
|
||||||
The rollPitchYaw option takes three angles (degrees):
|
The rollPitchYaw and yawPitchRoll options take three angles (degrees)
|
||||||
- roll (rotation about x) followed by
|
that describe the intrinsic Euler rotation.
|
||||||
- pitch (rotation about y) followed by
|
|
||||||
- yaw (rotation about z)
|
|
||||||
|
|
||||||
The yawPitchRoll does yaw followed by pitch followed by roll.
|
rollPitchYaw
|
||||||
|
- roll (rotation about X) followed by
|
||||||
|
- pitch (rotation about Y) followed by
|
||||||
|
- yaw (rotation about Z)
|
||||||
|
|
||||||
|
yawPitchRoll
|
||||||
|
- yaw (rotation about Z) followed by
|
||||||
|
- pitch (rotation about Y) followed by
|
||||||
|
- roll (rotation about X)
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -48,12 +54,12 @@ Description
|
|||||||
#include "transformField.H"
|
#include "transformField.H"
|
||||||
#include "Pair.H"
|
#include "Pair.H"
|
||||||
#include "Tuple2.H"
|
#include "Tuple2.H"
|
||||||
#include "quaternion.H"
|
#include "axisAngleRotation.H"
|
||||||
#include "unitConversion.H"
|
#include "EulerCoordinateRotation.H"
|
||||||
|
|
||||||
#include "MeshedSurfaces.H"
|
#include "MeshedSurfaces.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
using namespace Foam::coordinateRotations;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -179,31 +185,29 @@ int main(int argc, char *argv[])
|
|||||||
n1n2[0].normalise();
|
n1n2[0].normalise();
|
||||||
n1n2[1].normalise();
|
n1n2[1].normalise();
|
||||||
|
|
||||||
const tensor rotT = rotationTensor(n1n2[0], n1n2[1]);
|
const tensor rot(rotationTensor(n1n2[0], n1n2[1]));
|
||||||
|
|
||||||
Info<< "Rotating points by " << rotT << endl;
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
points = transform(rotT, points);
|
|
||||||
}
|
}
|
||||||
else if (args.found("rotate-angle"))
|
else if (args.found("rotate-angle"))
|
||||||
{
|
{
|
||||||
const Tuple2<vector, scalar> axisAngle
|
const Tuple2<vector, scalar> rotAxisAngle
|
||||||
(
|
(
|
||||||
args.lookup("rotate-angle")()
|
args.lookup("rotate-angle")()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const vector& axis = rotAxisAngle.first();
|
||||||
|
const scalar& angle = rotAxisAngle.second();
|
||||||
|
|
||||||
Info<< "Rotating points " << nl
|
Info<< "Rotating points " << nl
|
||||||
<< " about " << axisAngle.first() << nl
|
<< " about " << axis << nl
|
||||||
<< " angle " << axisAngle.second() << nl;
|
<< " angle " << angle << nl;
|
||||||
|
|
||||||
const quaternion quat
|
const tensor rot(axisAngle::rotation(axis, angle, true));
|
||||||
(
|
|
||||||
axisAngle.first(),
|
|
||||||
degToRad(axisAngle.second())
|
|
||||||
);
|
|
||||||
|
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
Info<< "Rotating points by " << rot << endl;
|
||||||
points = transform(quat, points);
|
points = transform(rot, points);
|
||||||
}
|
}
|
||||||
else if (args.readIfPresent("rollPitchYaw", v))
|
else if (args.readIfPresent("rollPitchYaw", v))
|
||||||
{
|
{
|
||||||
@ -212,12 +216,10 @@ int main(int argc, char *argv[])
|
|||||||
<< " pitch " << v.y() << nl
|
<< " pitch " << v.y() << nl
|
||||||
<< " yaw " << v.z() << nl;
|
<< " yaw " << v.z() << nl;
|
||||||
|
|
||||||
v *= degToRad();
|
const tensor rot(euler::rotation(euler::eulerOrder::XYZ, v, true));
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::XYZ, v);
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
|
||||||
points = transform(quat, points);
|
|
||||||
}
|
}
|
||||||
else if (args.readIfPresent("yawPitchRoll", v))
|
else if (args.readIfPresent("yawPitchRoll", v))
|
||||||
{
|
{
|
||||||
@ -226,12 +228,10 @@ int main(int argc, char *argv[])
|
|||||||
<< " pitch " << v.y() << nl
|
<< " pitch " << v.y() << nl
|
||||||
<< " roll " << v.z() << nl;
|
<< " roll " << v.z() << nl;
|
||||||
|
|
||||||
v *= degToRad();
|
const tensor rot(euler::rotation(euler::eulerOrder::ZYX, v, true));
|
||||||
|
|
||||||
const quaternion quat(quaternion::rotationSequence::ZYX, v);
|
Info<< "Rotating points by " << rot << endl;
|
||||||
|
points = transform(rot, points);
|
||||||
Info<< "Rotating points by quaternion " << quat << endl;
|
|
||||||
points = transform(quat, points);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<scalar> scaling;
|
List<scalar> scaling;
|
||||||
|
|||||||
@ -31,10 +31,30 @@ License
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const char* const Foam::quaternion::typeName = "quaternion";
|
|
||||||
const Foam::quaternion Foam::quaternion::zero(0, vector(0, 0, 0));
|
const Foam::quaternion Foam::quaternion::zero(0, vector(0, 0, 0));
|
||||||
const Foam::quaternion Foam::quaternion::I(1, vector(0, 0, 0));
|
const Foam::quaternion Foam::quaternion::I(1, vector(0, 0, 0));
|
||||||
|
|
||||||
|
const Foam::Enum<Foam::quaternion::eulerOrder>
|
||||||
|
Foam::quaternion::eulerOrderNames
|
||||||
|
({
|
||||||
|
// Proper Euler angles
|
||||||
|
{ eulerOrder::XZX, "xzx" },
|
||||||
|
{ eulerOrder::XYX, "xyx" },
|
||||||
|
{ eulerOrder::YXY, "yxy" },
|
||||||
|
{ eulerOrder::YZY, "yzy" },
|
||||||
|
{ eulerOrder::ZYZ, "zyz" },
|
||||||
|
{ eulerOrder::ZXZ, "zxz" },
|
||||||
|
|
||||||
|
// Tait-Bryan angles
|
||||||
|
{ eulerOrder::XZY, "xzy" },
|
||||||
|
{ eulerOrder::XYZ, "xyz" },
|
||||||
|
{ eulerOrder::YXZ, "yxz" },
|
||||||
|
{ eulerOrder::YZX, "yzx" },
|
||||||
|
{ eulerOrder::ZYX, "zyx" },
|
||||||
|
{ eulerOrder::ZXY, "zxy" },
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::quaternion::quaternion(Istream& is)
|
Foam::quaternion::quaternion(Istream& is)
|
||||||
|
|||||||
@ -43,6 +43,7 @@ SourceFiles
|
|||||||
#include "tensor.H"
|
#include "tensor.H"
|
||||||
#include "word.H"
|
#include "word.H"
|
||||||
#include "contiguous.H"
|
#include "contiguous.H"
|
||||||
|
#include "Enum.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -90,15 +91,24 @@ class quaternion
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Public Types
|
||||||
|
|
||||||
//- Component type
|
//- Component type
|
||||||
typedef scalar cmptType;
|
typedef scalar cmptType;
|
||||||
|
|
||||||
//- Euler-angle rotation sequence
|
//- Euler-angle rotation order
|
||||||
enum rotationSequence
|
enum eulerOrder : unsigned char
|
||||||
{
|
{
|
||||||
ZYX, ZYZ, ZXY, ZXZ, YXZ, YXY, YZX, YZY, XYZ, XYX, XZY, XZX
|
// Proper Euler angles
|
||||||
|
XZX, XYX, YXY, YZY, ZYZ, ZXZ,
|
||||||
|
|
||||||
|
// Tait-Bryan angles
|
||||||
|
XZY, XYZ, YXZ, YZX, ZYX, ZXY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//- The names for Euler-angle rotation order
|
||||||
|
static const Enum<eulerOrder> eulerOrderNames;
|
||||||
|
|
||||||
|
|
||||||
// Member Constants
|
// Member Constants
|
||||||
|
|
||||||
@ -108,7 +118,7 @@ public:
|
|||||||
|
|
||||||
// Static Data Members
|
// Static Data Members
|
||||||
|
|
||||||
static const char* const typeName;
|
static constexpr const char* const typeName = "quaternion";
|
||||||
|
|
||||||
static const quaternion zero;
|
static const quaternion zero;
|
||||||
static const quaternion I;
|
static const quaternion I;
|
||||||
@ -119,15 +129,17 @@ public:
|
|||||||
//- Construct null
|
//- Construct null
|
||||||
inline quaternion();
|
inline quaternion();
|
||||||
|
|
||||||
|
//- Construct zero initialized
|
||||||
|
inline quaternion(const Foam::zero);
|
||||||
|
|
||||||
//- Construct given scalar and vector parts
|
//- Construct given scalar and vector parts
|
||||||
inline quaternion(const scalar w, const vector& v);
|
inline quaternion(const scalar w, const vector& v);
|
||||||
|
|
||||||
//- Construct a rotation quaternion given the direction d
|
//- Construct rotation quaternion given direction d and angle theta
|
||||||
// and angle theta
|
|
||||||
inline quaternion(const vector& d, const scalar theta);
|
inline quaternion(const vector& d, const scalar theta);
|
||||||
|
|
||||||
//- Construct a rotation quaternion given the direction d
|
//- Construct a rotation quaternion given direction d
|
||||||
//- and cosine angle cosTheta and a if d is normalized
|
//- and cosine angle cosTheta and flag if d is normalized
|
||||||
inline quaternion
|
inline quaternion
|
||||||
(
|
(
|
||||||
const vector& d,
|
const vector& d,
|
||||||
@ -135,7 +147,8 @@ public:
|
|||||||
const bool normalized
|
const bool normalized
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct a real from the given scalar part, the vector part = zero
|
//- Construct a real quaternion from the given scalar part,
|
||||||
|
//- the vector part = zero
|
||||||
inline explicit quaternion(const scalar w);
|
inline explicit quaternion(const scalar w);
|
||||||
|
|
||||||
//- Construct a pure imaginary quaternion given the vector part,
|
//- Construct a pure imaginary quaternion given the vector part,
|
||||||
@ -146,8 +159,8 @@ public:
|
|||||||
//- (w = sqrt(1 - |sqr(v)|))
|
//- (w = sqrt(1 - |sqr(v)|))
|
||||||
static inline quaternion unit(const vector& v);
|
static inline quaternion unit(const vector& v);
|
||||||
|
|
||||||
//- Construct from three Euler angles
|
//- Construct from three Euler rotation angles
|
||||||
inline quaternion(const rotationSequence rs, const vector& angles);
|
inline quaternion(const eulerOrder order, const vector& angles);
|
||||||
|
|
||||||
//- Construct from a rotation tensor
|
//- Construct from a rotation tensor
|
||||||
inline explicit quaternion(const tensor& rotationTensor);
|
inline explicit quaternion(const tensor& rotationTensor);
|
||||||
@ -169,9 +182,9 @@ public:
|
|||||||
//- The rotation tensor corresponding the quaternion
|
//- The rotation tensor corresponding the quaternion
|
||||||
inline tensor R() const;
|
inline tensor R() const;
|
||||||
|
|
||||||
//- Return a vector of euler angles corresponding to the
|
//- Return the Euler rotation angles corresponding to the
|
||||||
//- specified rotation sequence
|
//- specified rotation order
|
||||||
inline vector eulerAngles(const rotationSequence rs) const;
|
inline vector eulerAngles(const eulerOrder order) const;
|
||||||
|
|
||||||
//- Return the quaternion normalized by its magnitude
|
//- Return the quaternion normalized by its magnitude
|
||||||
inline quaternion normalized() const;
|
inline quaternion normalized() const;
|
||||||
@ -238,7 +251,7 @@ inline quaternion normalize(const quaternion& q);
|
|||||||
inline quaternion inv(const quaternion& q);
|
inline quaternion inv(const quaternion& q);
|
||||||
|
|
||||||
//- Return a string representation of a quaternion
|
//- Return a string representation of a quaternion
|
||||||
word name(const quaternion&);
|
word name(const quaternion& q);
|
||||||
|
|
||||||
//- Spherical linear interpolation of quaternions
|
//- Spherical linear interpolation of quaternions
|
||||||
quaternion slerp
|
quaternion slerp
|
||||||
|
|||||||
@ -31,6 +31,13 @@ inline Foam::quaternion::quaternion()
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::quaternion::quaternion(const Foam::zero)
|
||||||
|
:
|
||||||
|
w_(Zero),
|
||||||
|
v_(Zero)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::quaternion::quaternion(const scalar w, const vector& v)
|
inline Foam::quaternion::quaternion(const scalar w, const vector& v)
|
||||||
:
|
:
|
||||||
w_(w),
|
w_(w),
|
||||||
@ -88,87 +95,112 @@ inline Foam::quaternion Foam::quaternion::unit(const vector& v)
|
|||||||
|
|
||||||
inline Foam::quaternion::quaternion
|
inline Foam::quaternion::quaternion
|
||||||
(
|
(
|
||||||
const rotationSequence rs,
|
const eulerOrder order,
|
||||||
const vector& angles
|
const vector& angles
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch(rs)
|
switch (order)
|
||||||
{
|
{
|
||||||
case ZYX:
|
case ZYX:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZYZ:
|
case ZYZ:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZXY:
|
case ZXY:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZXZ:
|
case ZXZ:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
operator=(quaternion(vector(0, 0, 1), angles.x()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YXZ:
|
case YXZ:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YXY:
|
case YXY:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
operator*=(quaternion(vector(1, 0, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YZX:
|
case YZX:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YZY:
|
case YZY:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
operator=(quaternion(vector(0, 1, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XYZ:
|
case XYZ:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
operator*=(quaternion(vector(0, 0, 1), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XYX:
|
case XYX:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
operator*=(quaternion(vector(0, 1, 0), angles.y()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XZY:
|
case XZY:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
||||||
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
operator*=(quaternion(vector(0, 1, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XZX:
|
case XZX:
|
||||||
|
{
|
||||||
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
operator=(quaternion(vector(1, 0, 0), angles.x()));
|
||||||
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
operator*=(quaternion(vector(0, 0, 1), angles.y()));
|
||||||
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
operator*=(quaternion(vector(1, 0, 0), angles.z()));
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Unknown rotation sequence " << rs << abort(FatalError);
|
<< "Unknown euler rotation order "
|
||||||
|
<< int(order) << abort(FatalError);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +233,7 @@ inline Foam::quaternion::quaternion
|
|||||||
&& rotationTensor.xx() > rotationTensor.zz()
|
&& rotationTensor.xx() > rotationTensor.zz()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalar s = 2.0*Foam::sqrt
|
const scalar s = 2.0*Foam::sqrt
|
||||||
(
|
(
|
||||||
1.0
|
1.0
|
||||||
+ rotationTensor.xx()
|
+ rotationTensor.xx()
|
||||||
@ -219,7 +251,7 @@ inline Foam::quaternion::quaternion
|
|||||||
rotationTensor.yy() > rotationTensor.zz()
|
rotationTensor.yy() > rotationTensor.zz()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalar s = 2.0*Foam::sqrt
|
const scalar s = 2.0*Foam::sqrt
|
||||||
(
|
(
|
||||||
1.0
|
1.0
|
||||||
+ rotationTensor.yy()
|
+ rotationTensor.yy()
|
||||||
@ -234,7 +266,7 @@ inline Foam::quaternion::quaternion
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scalar s = 2.0*Foam::sqrt
|
const scalar s = 2.0*Foam::sqrt
|
||||||
(
|
(
|
||||||
1.0
|
1.0
|
||||||
+ rotationTensor.zz()
|
+ rotationTensor.zz()
|
||||||
@ -373,7 +405,7 @@ inline Foam::vector Foam::quaternion::threeAxes
|
|||||||
|
|
||||||
inline Foam::vector Foam::quaternion::eulerAngles
|
inline Foam::vector Foam::quaternion::eulerAngles
|
||||||
(
|
(
|
||||||
const rotationSequence rs
|
const eulerOrder order
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const scalar w2 = sqr(w());
|
const scalar w2 = sqr(w());
|
||||||
@ -381,9 +413,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
const scalar y2 = sqr(v().y());
|
const scalar y2 = sqr(v().y());
|
||||||
const scalar z2 = sqr(v().z());
|
const scalar z2 = sqr(v().z());
|
||||||
|
|
||||||
switch(rs)
|
switch (order)
|
||||||
{
|
{
|
||||||
case ZYX:
|
case ZYX:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().y() + w()*v().z()),
|
2*(v().x()*v().y() + w()*v().z()),
|
||||||
@ -393,8 +426,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 - x2 - y2 + z2
|
w2 - x2 - y2 + z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZYZ:
|
case ZYZ:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().y()*v().z() - w()*v().x()),
|
2*(v().y()*v().z() - w()*v().x()),
|
||||||
@ -404,8 +439,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(w()*v().y() - v().x()*v().z())
|
2*(w()*v().y() - v().x()*v().z())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZXY:
|
case ZXY:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(w()*v().z() - v().x()*v().y()),
|
2*(w()*v().z() - v().x()*v().y()),
|
||||||
@ -415,8 +452,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 - x2 - y2 + z2
|
w2 - x2 - y2 + z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ZXZ:
|
case ZXZ:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().z() + w()*v().y()),
|
2*(v().x()*v().z() + w()*v().y()),
|
||||||
@ -426,8 +465,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(v().y()*v().z() + w()*v().x())
|
2*(v().y()*v().z() + w()*v().x())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YXZ:
|
case YXZ:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().z() + w()*v().y()),
|
2*(v().x()*v().z() + w()*v().y()),
|
||||||
@ -437,8 +478,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 - x2 + y2 - z2
|
w2 - x2 + y2 - z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YXY:
|
case YXY:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().y() - w()*v().z()),
|
2*(v().x()*v().y() - w()*v().z()),
|
||||||
@ -448,8 +491,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(w()*v().x() - v().y()*v().z())
|
2*(w()*v().x() - v().y()*v().z())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YZX:
|
case YZX:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(w()*v().y() - v().x()*v().z()),
|
2*(w()*v().y() - v().x()*v().z()),
|
||||||
@ -459,8 +504,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 - x2 + y2 - z2
|
w2 - x2 + y2 - z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case YZY:
|
case YZY:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().y()*v().z() + w()*v().x()),
|
2*(v().y()*v().z() + w()*v().x()),
|
||||||
@ -470,8 +517,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(v().x()*v().y() + w()*v().z())
|
2*(v().x()*v().y() + w()*v().z())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XYZ:
|
case XYZ:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(w()*v().x() - v().y()*v().z()),
|
2*(w()*v().x() - v().y()*v().z()),
|
||||||
@ -481,8 +530,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 + x2 - y2 - z2
|
w2 + x2 - y2 - z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XYX:
|
case XYX:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().y() + w()*v().z()),
|
2*(v().x()*v().y() + w()*v().z()),
|
||||||
@ -492,8 +543,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(v().x()*v().z() + w()*v().y())
|
2*(v().x()*v().z() + w()*v().y())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XZY:
|
case XZY:
|
||||||
|
{
|
||||||
return threeAxes
|
return threeAxes
|
||||||
(
|
(
|
||||||
2*(v().y()*v().z() + w()*v().x()),
|
2*(v().y()*v().z() + w()*v().x()),
|
||||||
@ -503,8 +556,10 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
w2 + x2 - y2 - z2
|
w2 + x2 - y2 - z2
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case XZX:
|
case XZX:
|
||||||
|
{
|
||||||
return twoAxes
|
return twoAxes
|
||||||
(
|
(
|
||||||
2*(v().x()*v().z() - w()*v().y()),
|
2*(v().x()*v().z() - w()*v().y()),
|
||||||
@ -514,12 +569,16 @@ inline Foam::vector Foam::quaternion::eulerAngles
|
|||||||
2*(w()*v().z() - v().x()*v().y())
|
2*(w()*v().z() - v().x()*v().y())
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Unknown rotation sequence " << rs << abort(FatalError);
|
<< "Unknown euler rotation order "
|
||||||
return Zero;
|
<< int(order) << abort(FatalError);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,7 @@ namespace Foam
|
|||||||
|
|
||||||
Foam::tensor Foam::coordinateRotations::euler::rotation
|
Foam::tensor Foam::coordinateRotations::euler::rotation
|
||||||
(
|
(
|
||||||
|
const eulerOrder order,
|
||||||
const vector& angles,
|
const vector& angles,
|
||||||
bool degrees
|
bool degrees
|
||||||
)
|
)
|
||||||
@ -83,14 +84,163 @@ Foam::tensor Foam::coordinateRotations::euler::rotation
|
|||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
|
// https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
|
||||||
|
|
||||||
// Z1-X2-Z3 rotation
|
switch (order)
|
||||||
return
|
{
|
||||||
tensor
|
// Proper Euler angles
|
||||||
|
|
||||||
|
case eulerOrder::XZX: // X1-Z2-X3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
(
|
(
|
||||||
c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1, s1*s2,
|
( c2 ), ( -c3*s2 ), ( s2*s3 ),
|
||||||
c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3, -c1*s2,
|
( c1*s2 ), ( c1*c2*c3 - s1*s3 ), ( -c3*s1 - c1*c2*s3 ),
|
||||||
s2*s3, c3*s2, c2
|
( s1*s2 ), ( c1*s3 + c2*c3*s1 ), ( c1*c3 - c2*s1*s3 )
|
||||||
);
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::XYX: // X1-Y2-X3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c2 ), ( s2*s3 ), ( c3*s2 ),
|
||||||
|
( s1*s2 ), ( c1*c3 - c2*s1*s3 ), ( -c1*s3 - c2*c3*s1 ),
|
||||||
|
( -c1*s2 ), ( c3*s1 + c1*c2*s3 ), ( c1*c2*c3 - s1*s3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::YXY: // Y1-X2-Y3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c3 - c2*s1*s3 ), ( s1*s2 ), ( c1*s3 + c2*c3*s1 ),
|
||||||
|
( s2*s3 ), ( c2 ), ( -c3*s2 ),
|
||||||
|
( -c3*s1 -c1*c2*s3 ), ( c1*s2 ), ( c1*c2*c3 - s1*s3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::YZY: // Y1-Z2-Y3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c2*c3 - s1*s3 ), ( -c1*s2 ), ( c3*s1 + c1*c2*s3 ),
|
||||||
|
( c3*s2 ), ( c2 ), ( s2*s3 ),
|
||||||
|
(-c1*s3 - c2*c3*s1 ), ( s1*s2 ), ( c1*c3 - c2*s1*s3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::ZYZ: // Z1-Y2-Z3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c2*c3 - s1*s3 ), ( -c3*s1 - c1*c2*s3 ), ( c1*s2 ),
|
||||||
|
( c1*s3 + c2*c3*s1 ), ( c1*c3 - c2*s1*s3 ), ( s1*s2 ),
|
||||||
|
( -c3*s2 ), ( s2*s3 ), ( c2 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::ZXZ: // Z1-X2-Z3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c3 - c2*s1*s3 ), ( -c1*s3 - c2*c3*s1 ), ( s1*s2 ),
|
||||||
|
( c3*s1 + c1*c2*s3 ), ( c1*c2*c3 - s1*s3 ), ( -c1*s2 ),
|
||||||
|
( s2*s3 ), ( c3*s2 ), ( c2 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tait-Bryan angles
|
||||||
|
|
||||||
|
case eulerOrder::XZY: // X1-Z2-Y3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c2*c3 ), ( -s2 ), ( c2*s3 ),
|
||||||
|
( s1*s3 + c1*c3*s2 ), ( c1*c2 ), ( c1*s2*s3 - c3*s1 ),
|
||||||
|
( c3*s1*s2 - c1*s3 ), ( c2*s1 ), ( c1*c3 + s1*s2*s3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::XYZ: // X1-Y2-Z3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c2*c3 ), ( -c2*s3 ), ( s2 ),
|
||||||
|
( c1*s3 + c3*s1*s2 ), ( c1*c3 - s1*s2*s3 ), ( -c2*s1 ),
|
||||||
|
( s1*s3 - c1*c3*s2 ), ( c3*s1 + c1*s2*s3 ), ( c1*c2 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::YXZ: // Y1-X2-Z3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c3 + s1*s2*s3 ), ( c3*s1*s2 - c1*s3 ), ( c2*s1 ),
|
||||||
|
( c2*s3 ), ( c2*c3 ), ( -s2 ),
|
||||||
|
( c1*s2*s3 - c3*s1 ), ( c1*c3*s2 + s1*s3 ), ( c1*c2 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::YZX: // Y1-Z2-X3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c2 ), ( s1*s3 - c1*c3*s2 ), ( c3*s1 + c1*s2*s3 ),
|
||||||
|
( s2 ), ( c2*c3 ), ( -c2*s3 ),
|
||||||
|
( -c2*s1 ), ( c1*s3 + c3*s1*s2 ), ( c1*c3 - s1*s2*s3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::ZYX: // Z1-Y2-X3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c2 ), ( c1*s2*s3 - c3*s1 ), ( s1*s3 + c1*c3*s2 ),
|
||||||
|
( c2*s1 ), ( c1*c3 + s1*s2*s3 ), ( c3*s1*s2 - c1*s3 ),
|
||||||
|
( -s2 ), ( c2*s3 ), ( c2*c3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case eulerOrder::ZXY: // Z1-X2-Y3 rotation
|
||||||
|
{
|
||||||
|
return tensor
|
||||||
|
(
|
||||||
|
( c1*c3 - s1*s2*s3 ), ( -c2*s1 ), ( c1*s3 + c3*s1*s2 ),
|
||||||
|
( c3*s1 + c1*s2*s3 ), ( c1*c2 ), ( s1*s3 - c1*c3*s2 ),
|
||||||
|
( -c2*s3 ), ( s2 ), ( c2*c3 )
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unknown euler rotation order "
|
||||||
|
<< int(order) << abort(FatalError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tensor::I;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tensor Foam::coordinateRotations::euler::rotation
|
||||||
|
(
|
||||||
|
const vector& angles,
|
||||||
|
bool degrees
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rotation(eulerOrder::ZXZ, angles, degrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,7 +250,8 @@ Foam::coordinateRotations::euler::euler()
|
|||||||
:
|
:
|
||||||
coordinateRotation(),
|
coordinateRotation(),
|
||||||
angles_(Zero),
|
angles_(Zero),
|
||||||
degrees_(true)
|
degrees_(true),
|
||||||
|
order_(eulerOrder::ZXZ)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +259,8 @@ Foam::coordinateRotations::euler::euler(const euler& crot)
|
|||||||
:
|
:
|
||||||
coordinateRotation(crot),
|
coordinateRotation(crot),
|
||||||
angles_(crot.angles_),
|
angles_(crot.angles_),
|
||||||
degrees_(crot.degrees_)
|
degrees_(crot.degrees_),
|
||||||
|
order_(crot.order_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +272,8 @@ Foam::coordinateRotations::euler::euler
|
|||||||
:
|
:
|
||||||
coordinateRotation(),
|
coordinateRotation(),
|
||||||
angles_(angles),
|
angles_(angles),
|
||||||
degrees_(degrees)
|
degrees_(degrees),
|
||||||
|
order_(eulerOrder::ZXZ)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +287,8 @@ Foam::coordinateRotations::euler::euler
|
|||||||
:
|
:
|
||||||
coordinateRotation(),
|
coordinateRotation(),
|
||||||
angles_(angle1, angle2, angle3),
|
angles_(angle1, angle2, angle3),
|
||||||
degrees_(degrees)
|
degrees_(degrees),
|
||||||
|
order_(eulerOrder::ZXZ)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -142,7 +296,16 @@ Foam::coordinateRotations::euler::euler(const dictionary& dict)
|
|||||||
:
|
:
|
||||||
coordinateRotation(),
|
coordinateRotation(),
|
||||||
angles_(dict.getCompat<vector>("angles", {{"rotation", 1806}})),
|
angles_(dict.getCompat<vector>("angles", {{"rotation", 1806}})),
|
||||||
degrees_(dict.lookupOrDefault("degrees", true))
|
degrees_(dict.lookupOrDefault("degrees", true)),
|
||||||
|
order_
|
||||||
|
(
|
||||||
|
quaternion::eulerOrderNames.lookupOrDefault
|
||||||
|
(
|
||||||
|
"order",
|
||||||
|
dict,
|
||||||
|
quaternion::eulerOrder::ZXZ
|
||||||
|
)
|
||||||
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -182,6 +345,12 @@ void Foam::coordinateRotations::euler::writeEntry
|
|||||||
os.writeEntry("degrees", "false");
|
os.writeEntry("degrees", "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeEntryIfDifferent, but with enumerated name
|
||||||
|
if (order_ != eulerOrder::ZXZ)
|
||||||
|
{
|
||||||
|
os.writeEntry("order", quaternion::eulerOrderNames[order_]);
|
||||||
|
}
|
||||||
|
|
||||||
os.endBlock();
|
os.endBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ SourceFiles
|
|||||||
#define coordinateRotations_euler_H
|
#define coordinateRotations_euler_H
|
||||||
|
|
||||||
#include "coordinateRotation.H"
|
#include "coordinateRotation.H"
|
||||||
|
#include "quaternion.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -77,6 +78,16 @@ class euler
|
|||||||
:
|
:
|
||||||
public coordinateRotation
|
public coordinateRotation
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public Types
|
||||||
|
|
||||||
|
//- Euler-angle rotation order
|
||||||
|
using eulerOrder = quaternion::eulerOrder;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
//- The rotation angles
|
//- The rotation angles
|
||||||
@ -85,6 +96,9 @@ class euler
|
|||||||
//- Angles measured in degrees
|
//- Angles measured in degrees
|
||||||
bool degrees_;
|
bool degrees_;
|
||||||
|
|
||||||
|
//- The Euler-angle rotation order (default: zxz)
|
||||||
|
eulerOrder order_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -126,7 +140,15 @@ public:
|
|||||||
|
|
||||||
//- The rotation tensor calculated for the intrinsic Euler
|
//- The rotation tensor calculated for the intrinsic Euler
|
||||||
//- angles in z-x-z order
|
//- angles in z-x-z order
|
||||||
static tensor rotation(const vector& angles, bool degrees);
|
static tensor rotation(const vector& angles, bool degrees=false);
|
||||||
|
|
||||||
|
//- The rotation tensor calculated for given angles and order
|
||||||
|
static tensor rotation
|
||||||
|
(
|
||||||
|
const eulerOrder order,
|
||||||
|
const vector& angles,
|
||||||
|
bool degrees=false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|||||||
@ -57,6 +57,24 @@ void Foam::coordinateRotations::axisAngle::checkSpec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tensor Foam::coordinateRotations::axisAngle::rotation
|
||||||
|
(
|
||||||
|
const vector& axis,
|
||||||
|
const scalar angle,
|
||||||
|
bool degrees
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (mag(angle) < VSMALL || mag(axis) < SMALL)
|
||||||
|
{
|
||||||
|
return sphericalTensor::I; // identity rotation
|
||||||
|
}
|
||||||
|
|
||||||
|
return quaternion(axis, (degrees ? degToRad(angle) : angle)).R();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::coordinateRotations::axisAngle::axisAngle()
|
Foam::coordinateRotations::axisAngle::axisAngle()
|
||||||
@ -144,12 +162,7 @@ void Foam::coordinateRotations::axisAngle::clear()
|
|||||||
|
|
||||||
Foam::tensor Foam::coordinateRotations::axisAngle::R() const
|
Foam::tensor Foam::coordinateRotations::axisAngle::R() const
|
||||||
{
|
{
|
||||||
if (mag(angle_) < VSMALL || mag(axis_) < SMALL)
|
return rotation(axis_, angle_, degrees_);
|
||||||
{
|
|
||||||
return sphericalTensor::I; // identity rotation
|
|
||||||
}
|
|
||||||
|
|
||||||
return quaternion(axis_, (degrees_ ? degToRad(angle_) : angle_)).R();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -130,6 +130,17 @@ public:
|
|||||||
virtual ~axisAngle() = default;
|
virtual ~axisAngle() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Member Functions
|
||||||
|
|
||||||
|
//- The rotation tensor for given axis/angle
|
||||||
|
static tensor rotation
|
||||||
|
(
|
||||||
|
const vector& axis,
|
||||||
|
const scalar angle,
|
||||||
|
bool degrees=false
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Reset specification
|
//- Reset specification
|
||||||
|
|||||||
@ -14,7 +14,12 @@ FoamFile
|
|||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
libs ("libmeshTools.so" "liblumpedPointMotion.so");
|
libs
|
||||||
|
(
|
||||||
|
"libmeshTools.so"
|
||||||
|
"liblumpedPointMotion.so"
|
||||||
|
"libfvMotionSolvers.so"
|
||||||
|
);
|
||||||
|
|
||||||
application simpleFoam; // Change to pimpleFoam for transient
|
application simpleFoam; // Change to pimpleFoam for transient
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user