From 8d2811539ed720c2ff5c58a5346a3d5646546267 Mon Sep 17 00:00:00 2001 From: Dmitri Naumov <dmitri.naumov@ufz.de> Date: Mon, 12 Feb 2018 16:17:23 +0100 Subject: [PATCH] [T] KelvinVector; Move Test. Move tensorToKelvin. Move the test to Tests/MathLib and extract MathLib::tensorToKelvin for completness. --- MathLib/KelvinVector.cpp | 31 ++++++ MathLib/KelvinVector.h | 6 ++ .../{MaterialLib => MathLib}/KelvinVector.cpp | 95 +++++++++---------- 3 files changed, 81 insertions(+), 51 deletions(-) rename Tests/{MaterialLib => MathLib}/KelvinVector.cpp (73%) diff --git a/MathLib/KelvinVector.cpp b/MathLib/KelvinVector.cpp index 966c3fd113c..0c6718ddb8f 100644 --- a/MathLib/KelvinVector.cpp +++ b/MathLib/KelvinVector.cpp @@ -80,6 +80,37 @@ Eigen::Matrix<double, 3, 3> kelvinVectorToTensor( return m; } +template <> +KelvinVectorType<2> tensorToKelvin<2>(Eigen::Matrix<double, 3, 3> const& m) +{ + assert(std::abs(m(0, 1) - m(1, 0)) < + std::numeric_limits<double>::epsilon()); + assert(m(0, 2) == 0); + assert(m(1, 2) == 0); + assert(m(2, 0) == 0); + assert(m(2, 1) == 0); + + KelvinVectorType<2> v; + v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.); + return v; +} + +template <> +KelvinVectorType<3> tensorToKelvin<3>(Eigen::Matrix<double, 3, 3> const& m) +{ + assert(std::abs(m(0, 1) - m(1, 0)) < + std::numeric_limits<double>::epsilon()); + assert(std::abs(m(1, 2) - m(2, 1)) < + std::numeric_limits<double>::epsilon()); + assert(std::abs(m(0, 2) - m(2, 0)) < + std::numeric_limits<double>::epsilon()); + + KelvinVectorType<3> v; + v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.), + m(1, 2) * std::sqrt(2.), m(0, 2) * std::sqrt(2.); + return v; +} + template <> Eigen::Matrix<double, 4, 1> kelvinVectorToSymmetricTensor( Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> const& v) diff --git a/MathLib/KelvinVector.h b/MathLib/KelvinVector.h index 307951348d9..313e822c938 100644 --- a/MathLib/KelvinVector.h +++ b/MathLib/KelvinVector.h @@ -126,6 +126,12 @@ Eigen::Matrix<double, 3, 3> kelvinVectorToTensor(Eigen::Matrix<double, KelvinVectorSize, 1> const& v); +/// Conversion of a 3x3 matrix to a Kelvin vector. +/// Only implementations for KelvinVectorSize 4 and 6 are provided. +template <int DisplacementDim> +KelvinVectorType<DisplacementDim> tensorToKelvin( + Eigen::Matrix<double, 3, 3> const& m); + /// Conversion of a Kelvin vector to a short vector representation of a /// symmetric 3x3 matrix. /// diff --git a/Tests/MaterialLib/KelvinVector.cpp b/Tests/MathLib/KelvinVector.cpp similarity index 73% rename from Tests/MaterialLib/KelvinVector.cpp rename to Tests/MathLib/KelvinVector.cpp index b7be7b81153..8466cfe4eb8 100644 --- a/Tests/MaterialLib/KelvinVector.cpp +++ b/Tests/MathLib/KelvinVector.cpp @@ -15,39 +15,6 @@ using namespace MathLib::KelvinVector; namespace ac = autocheck; -template <int Size> -using KelvinVector = Eigen::Matrix<double, Size, 1, Eigen::ColMajor, Size, 1>; - -template <int Size> -KelvinVector<Size> tensorToKelvin(Eigen::Matrix<double, 3, 3> const& m); - -template <> -KelvinVector<4> tensorToKelvin(Eigen::Matrix<double, 3, 3> const& m) -{ - EXPECT_NEAR(m(0, 1), m(1, 0), std::numeric_limits<double>::epsilon()); - EXPECT_EQ(m(0, 2), 0); - EXPECT_EQ(m(1, 2), 0); - EXPECT_EQ(m(2, 0), 0); - EXPECT_EQ(m(2, 1), 0); - - KelvinVector<4> v; - v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.); - return v; -} - -template <> -KelvinVector<6> tensorToKelvin(Eigen::Matrix<double, 3, 3> const& m) -{ - EXPECT_NEAR(m(0, 1), m(1, 0), std::numeric_limits<double>::epsilon()); - EXPECT_NEAR(m(1, 2), m(2, 1), std::numeric_limits<double>::epsilon()); - EXPECT_NEAR(m(0, 2), m(2, 0), std::numeric_limits<double>::epsilon()); - - KelvinVector<6> v; - v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.), - m(1, 2) * std::sqrt(2.), m(0, 2) * std::sqrt(2.); - return v; -} - struct MaterialLibSolidsKelvinVector4 : public ::testing::Test { static const int size = 4; @@ -71,23 +38,49 @@ struct MaterialLibSolidsKelvinVector6 : public ::testing::Test TEST_F(MaterialLibSolidsKelvinVector4, SelfTestMappingKelvinToTensor) { - auto f = [](KelvinVector<4> const& v) { - return (v - tensorToKelvin<4>(kelvinVectorToTensor(v))).norm() <= + auto f = [](KelvinVectorType<2> const& v) { + return (v - tensorToKelvin<2>(kelvinVectorToTensor(v))).norm() <= 2 * std::numeric_limits<double>::epsilon() * v.norm(); }; - ac::check<KelvinVector<4>>( + ac::check<KelvinVectorType<2>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); } TEST_F(MaterialLibSolidsKelvinVector6, SelfTestMappingKelvinToTensor) { - auto f = [](KelvinVector<6> const& v) { - return (v - tensorToKelvin<6>(kelvinVectorToTensor(v))).norm() <= + auto f = [](KelvinVectorType<3> const& v) { + return (v - tensorToKelvin<3>(kelvinVectorToTensor(v))).norm() <= + 1.5 * std::numeric_limits<double>::epsilon() * v.norm(); + }; + + ac::check<KelvinVectorType<3>>( + f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); +} + +TEST_F(MaterialLibSolidsKelvinVector4, SelfTestMappingKelvinToSymmetricTensor) +{ + auto f = [](KelvinVectorType<2> const& v) { + return (v - + symmetricTensorToKelvinVector(kelvinVectorToSymmetricTensor(v))) + .norm() <= + 1.5 * std::numeric_limits<double>::epsilon() * v.norm(); + }; + + ac::check<KelvinVectorType<2>>( + f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); +} + +TEST_F(MaterialLibSolidsKelvinVector6, SelfTestMappingKelvinToSymmetricTensor) +{ + auto f = [](KelvinVectorType<3> const& v) { + return (v - + symmetricTensorToKelvinVector(kelvinVectorToSymmetricTensor(v))) + .norm() <= 1.5 * std::numeric_limits<double>::epsilon() * v.norm(); }; - ac::check<KelvinVector<6>>( + ac::check<KelvinVectorType<3>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); } @@ -97,27 +90,27 @@ TEST_F(MaterialLibSolidsKelvinVector6, SelfTestMappingKelvinToTensor) TEST_F(MaterialLibSolidsKelvinVector4, Determinant) { - auto f = [](KelvinVector<4> const& v) { + auto f = [](KelvinVectorType<2> const& v) { return std::abs(Invariants<4>::determinant(v) - kelvinVectorToTensor(v).determinant()) <= std::numeric_limits<double>::epsilon() * std::pow(v.norm(), 3.07); }; - ac::check<KelvinVector<4>>( + ac::check<KelvinVectorType<2>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); } TEST_F(MaterialLibSolidsKelvinVector6, Determinant) { - auto f = [](KelvinVector<6> const& v) { + auto f = [](KelvinVectorType<3> const& v) { return std::abs(Invariants<6>::determinant(v) - kelvinVectorToTensor(v).determinant()) <= std::numeric_limits<double>::epsilon() * std::pow(v.norm(), 3.07); }; - ac::check<KelvinVector<6>>( + ac::check<KelvinVectorType<3>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator), gtest_reporter); } @@ -127,18 +120,18 @@ TEST_F(MaterialLibSolidsKelvinVector6, Determinant) TEST_F(MaterialLibSolidsKelvinVector4, Inverse) { - auto f = [](KelvinVector<4> const& v) { + auto f = [](KelvinVectorType<2> const& v) { auto const error = - (inverse(v) - tensorToKelvin<4>(kelvinVectorToTensor(v).inverse())) + (inverse(v) - tensorToKelvin<2>(kelvinVectorToTensor(v).inverse())) .norm(); // The error is only weekly depending on the input vector norm. return error < 1e-6 && error < 1e-8 * std::pow(v.norm(), 1.4); }; - ac::check<KelvinVector<4>>( + ac::check<KelvinVectorType<2>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator) - .discard_if([](KelvinVector<4> const& v) { + .discard_if([](KelvinVectorType<2> const& v) { // only invertable matrices return (std::abs(kelvinVectorToTensor(v).determinant()) == 0); }), @@ -147,18 +140,18 @@ TEST_F(MaterialLibSolidsKelvinVector4, Inverse) TEST_F(MaterialLibSolidsKelvinVector6, Inverse) { - auto f = [](KelvinVector<6> const& v) { + auto f = [](KelvinVectorType<3> const& v) { auto const error = - (inverse(v) - tensorToKelvin<6>(kelvinVectorToTensor(v).inverse())) + (inverse(v) - tensorToKelvin<3>(kelvinVectorToTensor(v).inverse())) .norm(); // The error is only weekly depending on the input vector norm. return error < 1e-6 && error < 1e-8 * std::pow(v.norm(), 1.4); }; - ac::check<KelvinVector<6>>( + ac::check<KelvinVectorType<3>>( f, 1000, ac::make_arbitrary(kelvinVectorGenerator) - .discard_if([](KelvinVector<6> const& v) { + .discard_if([](KelvinVectorType<3> const& v) { // only invertable matrices return (std::abs(kelvinVectorToTensor(v).determinant()) == 0); }), -- GitLab