From b98a01b28c2bb5f84fae3d5b2cfdf3137a736fc7 Mon Sep 17 00:00:00 2001 From: graham Date: Thu, 4 Feb 2010 19:51:31 +0000 Subject: [PATCH] ENH: surfaceInertia. Adding the calculation of the Q tensor, required for six DoF motion bodies that are not principal axis aligned shapes to start with. Calculates the best match axes to give the most naturl transformation from the Cartesian axes. The eigenvectors are returned in the order relating to ascending magnitude of their eigenvalues - not necessarily in a right handed triplet. --- .../surface/surfaceInertia/surfaceInertia.C | 231 +++++++++++++++++- 1 file changed, 221 insertions(+), 10 deletions(-) diff --git a/applications/utilities/surface/surfaceInertia/surfaceInertia.C b/applications/utilities/surface/surfaceInertia/surfaceInertia.C index 95edabed0c..30e91425a8 100644 --- a/applications/utilities/surface/surfaceInertia/surfaceInertia.C +++ b/applications/utilities/surface/surfaceInertia/surfaceInertia.C @@ -41,6 +41,9 @@ Description #include "OFstream.H" #include "meshTools.H" #include "Random.H" +#include "transform.H" +#include "IOmanip.H" +#include "Pair.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -355,6 +358,12 @@ int main(int argc, char *argv[]) ); } + if (m < 0) + { + WarningIn(args.executable() + "::main") + << "Negative mass detected" << endl; + } + vector eVal = eigenValues(J); tensor eVec = eigenVectors(J); @@ -380,19 +389,221 @@ int main(int argc, char *argv[]) pertI++; } - Info<< nl - << "Density = " << density << nl - << "Mass = " << m << nl - << "Centre of mass = " << cM << nl - << "Inertia tensor around centre of mass = " << J << nl - << "eigenValues (principal moments) = " << eVal << nl - << "eigenVectors (principal axes) = " - << eVec.x() << ' ' << eVec.y() << ' ' << eVec.z() - << endl; + bool showTransform = true; + + if + ( + (mag(eVec.x() ^ eVec.y()) > (1.0 - SMALL)) + && (mag(eVec.y() ^ eVec.z()) > (1.0 - SMALL)) + && (mag(eVec.z() ^ eVec.x()) > (1.0 - SMALL)) + ) + { + // Make the eigenvectors a right handed orthogonal triplet + eVec.z() *= sign((eVec.x() ^ eVec.y()) & eVec.z()); + + // Finding the most natural transformation. Using Lists + // rather than tensors to allow indexed permutation. + + // Cartesian basis vectors - right handed orthogonal triplet + List cartesian(3); + + cartesian[0] = vector(1, 0, 0); + cartesian[1] = vector(0, 1, 0); + cartesian[2] = vector(0, 0, 1); + + // Principal axis basis vectors - right handed orthogonal + // triplet + List principal(3); + + principal[0] = eVec.x(); + principal[1] = eVec.y(); + principal[2] = eVec.z(); + + scalar maxMagDotProduct = -GREAT; + + // Matching axis indices, first: cartesian, second:principal + + Pair