From 6c45aa23cd3c05b50dfe9850f9b75234772893c8 Mon Sep 17 00:00:00 2001
From: Florian Zill <florian.zill@ufz.de>
Date: Thu, 7 Oct 2021 11:16:24 +0200
Subject: [PATCH] [ML] LiftVectorToKelvin and ReduceKelvinToVector

---
 MathLib/KelvinVector.cpp | 57 ++++++++++++++++++++++++++++++++++++++++
 MathLib/KelvinVector.h   | 15 +++++++++++
 2 files changed, 72 insertions(+)

diff --git a/MathLib/KelvinVector.cpp b/MathLib/KelvinVector.cpp
index 6b20f6117f3..f88c618c352 100644
--- a/MathLib/KelvinVector.cpp
+++ b/MathLib/KelvinVector.cpp
@@ -180,6 +180,63 @@ kelvinVectorToSymmetricTensor(Eigen::Matrix<double,
         v.size());
 }
 
+template <>
+Eigen::Matrix<double, 2, 4> liftVectorToKelvin<2>(
+    Eigen::Matrix<double, 2, 1> const& v)
+{
+    Eigen::Matrix<double, 2, 4> m;
+    m << v[0], 0, 0, v[1] / std::sqrt(2.), 0, v[1], 0, v[0] / std::sqrt(2.);
+    return m;
+}
+
+template <>
+Eigen::Matrix<double, 3, 6> liftVectorToKelvin<3>(
+    Eigen::Matrix<double, 3, 1> const& v)
+{
+    Eigen::Matrix<double, 3, 6> m;
+    m << v[0], 0, 0, v[1] / std::sqrt(2.), 0, v[2] / std::sqrt(2.), 0, v[1], 0,
+        v[0] / std::sqrt(2.), v[2] / std::sqrt(2.), 0, 0, 0, v[2], 0,
+        v[1] / std::sqrt(2.), v[0] / std::sqrt(2.);
+    return m;
+}
+
+template <>
+Eigen::Matrix<double, 2, 1> reduceKelvinToVector<2>(
+    Eigen::Matrix<double, 2, 4> const& m)
+{
+    assert(m(0, 1) == 0);
+    assert(m(0, 2) == 0);
+    assert(m(1, 0) == 0);
+    assert(m(1, 2) == 0);
+    Eigen::Matrix<double, 2, 1> v;
+    v << m(0, 0), m(1, 1);
+    return v;
+}
+
+template <>
+Eigen::Matrix<double, 3, 1> reduceKelvinToVector<3>(
+    Eigen::Matrix<double, 3, 6> const& m)
+{
+    assert(m(0, 1) == 0);
+    assert(m(0, 2) == 0);
+    assert(m(0, 4) == 0);
+    assert(m(1, 0) == 0);
+    assert(m(1, 2) == 0);
+    assert(m(1, 5) == 0);
+    assert(m(2, 0) == 0);
+    assert(m(2, 1) == 0);
+    assert(m(2, 3) == 0);
+    assert(std::abs(m(0, 3) - m(2, 4)) <
+           std::numeric_limits<double>::epsilon());
+    assert(std::abs(m(0, 5) - m(1, 4)) <
+           std::numeric_limits<double>::epsilon());
+    assert(std::abs(m(1, 3) - m(2, 5)) <
+           std::numeric_limits<double>::epsilon());
+    Eigen::Matrix<double, 3, 1> v;
+    v << m(0, 0), m(1, 1), m(2, 2);
+    return v;
+}
+
 template <>
 KelvinMatrixType<2> fourthOrderRotationMatrix<2>(
     Eigen::Matrix<double, 2, 2, Eigen::ColMajor, 2, 2> const& transformation)
diff --git a/MathLib/KelvinVector.h b/MathLib/KelvinVector.h
index c120e74ecd4..9ffb7b452e7 100644
--- a/MathLib/KelvinVector.h
+++ b/MathLib/KelvinVector.h
@@ -228,6 +228,21 @@ KelvinVectorType<DisplacementDim> symmetricTensorToKelvinVector(
             values.data(), kelvin_vector_dimensions(DisplacementDim), 1));
 }
 
+/// Lifting of a vector to a Kelvin matrix.
+/// \f$ a -> A\f$ s.t. \f$k_{ij} a_{j} = A_[\alpha\beta} k_{\beta} \f$.
+/// Conversion for 2D -> 4D and 3D -> 6D are implemented.
+template <int DisplacementDim>
+Eigen::Matrix<double, DisplacementDim,
+              kelvin_vector_dimensions(DisplacementDim)>
+liftVectorToKelvin(Eigen::Matrix<double, DisplacementDim, 1> const& v);
+
+/// Reducing a Kelvin matrix to a vector.
+/// Conversion for 4D -> 2D and 6D -> 3D are implemented.
+template <int DisplacementDim>
+Eigen::Matrix<double, DisplacementDim, 1> reduceKelvinToVector(
+    Eigen::Matrix<double, DisplacementDim,
+                  kelvin_vector_dimensions(DisplacementDim)> const& m);
+
 /// Rotation tensor for Kelvin mapped vectors and tensors. It is meant to be
 /// used for rotation of stress/strain tensors epsilon:Q and tangent stiffness
 /// tensors Q*C*Q^t.
-- 
GitLab