From 941eed6625b36d89033d0d3cca1b6648df2834e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Mon, 17 Oct 2016 15:14:45 +0200 Subject: [PATCH] #914 Created stress tensor rotation method, including tests --- .../UnitTests/ScalarMapper-Test.cpp | 115 ++++++++++++++++++ Fwk/AppFwk/cafTensor/cafTensor3.h | 7 +- Fwk/AppFwk/cafTensor/cafTensor3.inl | 23 +++- 3 files changed, 140 insertions(+), 5 deletions(-) diff --git a/ApplicationCode/UnitTests/ScalarMapper-Test.cpp b/ApplicationCode/UnitTests/ScalarMapper-Test.cpp index a3a1c85c5e..1ca13b57c4 100644 --- a/ApplicationCode/UnitTests/ScalarMapper-Test.cpp +++ b/ApplicationCode/UnitTests/ScalarMapper-Test.cpp @@ -121,3 +121,118 @@ TEST(OffshoreSphericalCoords, OffshoreSphericalCoords) } +#include "../cafTensor/cafTensor3.h" +#include "cvfMath.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST(TensorRotation, TensorRotation) +{ + + { + caf::Ten3f orgT(1.0f, 0.5f, 0.2f, 0, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(1, 0, 0), cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(1.0f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.5f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(1.0f, 0.5f, 0.2f, 0, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(1, 0, 0), 0.5*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(1.0f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.5f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(1.0f, 0.5f, 0.2f, 0, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(0, 0, 1), 0.5*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(0.5f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(1.0f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(1.0f, 0.5f, 0.2f, 0, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(0, 0, 1), 0.25*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(0.75f,rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.75f,rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.25f,rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(0.75f, 0.75f, 0.2f, 0.25, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(0, 0, 1), -0.25*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(1.0f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.5f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(1.0f, 0.5f, 0.2f, 0, 0, 0); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(1, 1, 1), 0.2*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(0.8320561f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.5584094f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.3095343f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.2091861f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(-0.2258091f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0166228f, rotT[caf::Ten3f::SYZ], 1e-4); + } + + { + caf::Ten3f orgT(0.8320561f, 0.5584094f, 0.3095343f, 0.2091861f, 0.0166228f, -0.2258091f); + + cvf::Mat3f rotMx = cvf::Mat3f::fromRotation(cvf::Vec3f(1, 1, 1), -0.2*cvf::PI_F); + + caf::Ten3f rotT = orgT.rotate(rotMx); + + EXPECT_NEAR(1.0f, rotT[caf::Ten3f::SXX], 1e-4); + EXPECT_NEAR(0.5f, rotT[caf::Ten3f::SYY], 1e-4); + EXPECT_NEAR(0.2f, rotT[caf::Ten3f::SZZ], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SXY], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SZX], 1e-4); + EXPECT_NEAR(0.0f, rotT[caf::Ten3f::SYZ], 1e-4); + } + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.h b/Fwk/AppFwk/cafTensor/cafTensor3.h index e06357450d..753e19c856 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.h +++ b/Fwk/AppFwk/cafTensor/cafTensor3.h @@ -46,10 +46,11 @@ public: void setFromInternalLayout(S* tensorData); void setFromAbaqusLayout(S* tensorData); - cvf::Vec3f calculatePrincipals(cvf::Vec3f principalDirections[3]); - float calculateVonMises(); -}; + cvf::Vec3f calculatePrincipals(cvf::Vec3f principalDirections[3]) const; + float calculateVonMises() const; + Tensor3 rotate(const cvf::Matrix3& rotMx) const; +}; typedef Tensor3 Ten3f; diff --git a/Fwk/AppFwk/cafTensor/cafTensor3.inl b/Fwk/AppFwk/cafTensor/cafTensor3.inl index a7b107d26f..c228fa9700 100644 --- a/Fwk/AppFwk/cafTensor/cafTensor3.inl +++ b/Fwk/AppFwk/cafTensor/cafTensor3.inl @@ -168,7 +168,7 @@ cvf::Vec3d eigenVector3(const cvf::Mat3d& mx, double eigenValue, bool* computedO /// The tensor must be laid out as follows: SXX, SYY, SZZ, SXY, SYZ, SZX //-------------------------------------------------------------------------------------------------- template -cvf::Vec3f Tensor3::calculatePrincipals( cvf::Vec3f principalDirections[3]) +cvf::Vec3f Tensor3::calculatePrincipals( cvf::Vec3f principalDirections[3]) const { CVF_TIGHT_ASSERT(m_tensor); @@ -314,12 +314,31 @@ cvf::Vec3f Tensor3::calculatePrincipals( cvf::Vec3f principalDirections[3]) /// //-------------------------------------------------------------------------------------------------- template< typename S> -float caf::Tensor3::calculateVonMises() +float caf::Tensor3::calculateVonMises() const { return (float) sqrt( ( (m_tensor[0]*m_tensor[0] + m_tensor[1]*m_tensor[1] + m_tensor[2]*m_tensor[2]) ) + ( -(m_tensor[0]*m_tensor[1] + m_tensor[1]*m_tensor[2] + m_tensor[0]*m_tensor[2]) ) + ( 3*(m_tensor[3]*m_tensor[3] + m_tensor[4]*m_tensor[4] + m_tensor[5]*m_tensor[5]) ) ); } +//-------------------------------------------------------------------------------------------------- +/// Calculates Trot = rotMx*T*transpose(rotMx) +//-------------------------------------------------------------------------------------------------- +template< typename S> +Tensor3 caf::Tensor3::rotate(const cvf::Matrix3& rotMx) const +{ + cvf::Matrix3 tensor(m_tensor[SXX], m_tensor[SXY], m_tensor[SZX], + m_tensor[SXY], m_tensor[SYY], m_tensor[SYZ], + m_tensor[SZX], m_tensor[SYZ], m_tensor[SZZ]); + + cvf::Matrix3 transposedRotMx = rotMx; + transposedRotMx.transpose(); + cvf::Matrix3 rotatedTensor = rotMx * tensor * transposedRotMx; + + return Tensor3(rotatedTensor(0,0), rotatedTensor(1,1), rotatedTensor(2,2), + rotatedTensor(1,0), rotatedTensor(1,2), rotatedTensor(0,2)); +} + + }