From a0dc19282a91ff857a6b4896742b5ba2ecacf83b Mon Sep 17 00:00:00 2001
From: Manuel Weberndorfer <manuel.weberndorfer@id.ethz.ch>
Date: Tue, 31 Aug 2021 09:08:39 +0000
Subject: [PATCH] allow parametrization of value- and real_type

- permits complex displacement gradients, stresses, strains, tangents
---
 .../ae108/elements/materialmodels/Hookean.h   | 49 ++++++++++---------
 .../materialmodels/MaterialModelBase.h        |  5 +-
 .../ae108/elements/materialmodels/Minimal.h   |  3 +-
 3 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/elements/src/include/ae108/elements/materialmodels/Hookean.h b/elements/src/include/ae108/elements/materialmodels/Hookean.h
index b140a8e3..3834b078 100644
--- a/elements/src/include/ae108/elements/materialmodels/Hookean.h
+++ b/elements/src/include/ae108/elements/materialmodels/Hookean.h
@@ -31,43 +31,44 @@ namespace materialmodels {
  * @brief A material model for linear elastic isotropic materials.
  * @remark See https://en.wikipedia.org/wiki/Hooke%27s_law
  */
-template <std::size_t Dimension_>
+template <std::size_t Dimension_, class ValueType_ = double,
+          class RealType_ = double>
 class Hookean final
-    : public MaterialModelBase<std::size_t, double, Dimension_> {
+    : public MaterialModelBase<std::size_t, ValueType_, RealType_, Dimension_> {
 public:
   /**
    * @brief Constructs the material model using Young's modulus E and the
    * Poisson ratio nu.
    */
   explicit constexpr Hookean(
-      const typename Hookean::value_type &youngs_modulus,
-      const typename Hookean::value_type &poisson_ratio) noexcept
+      const typename Hookean::real_type &youngs_modulus,
+      const typename Hookean::real_type &poisson_ratio) noexcept
       : lambda_(youngs_modulus * poisson_ratio /
-                (typename Hookean::value_type{1.} -
-                 typename Hookean::value_type{2.} * poisson_ratio) /
-                (typename Hookean::value_type{1.} + poisson_ratio)),
-        mu_(youngs_modulus / typename Hookean::value_type{2.} /
-            (typename Hookean::value_type{1.} + poisson_ratio)) {}
+                (typename Hookean::real_type{1.} -
+                 typename Hookean::real_type{2.} * poisson_ratio) /
+                (typename Hookean::real_type{1.} + poisson_ratio)),
+        mu_(youngs_modulus / typename Hookean::real_type{2.} /
+            (typename Hookean::real_type{1.} + poisson_ratio)) {}
 
   /**
    * @brief Returns the first Lame constant.
    */
-  constexpr typename Hookean::value_type lambda() const noexcept {
+  constexpr typename Hookean::real_type lambda() const noexcept {
     return lambda_;
   }
 
   /**
    * @brief Returns the second Lame constant.
    */
-  constexpr typename Hookean::value_type mu() const noexcept { return mu_; }
+  constexpr typename Hookean::real_type mu() const noexcept { return mu_; }
 
 private:
-  typename Hookean::value_type lambda_;
-  typename Hookean::value_type mu_;
+  typename Hookean::real_type lambda_;
+  typename Hookean::real_type mu_;
 };
 
-template <std::size_t Dimension_>
-struct ComputeEnergyTrait<Hookean<Dimension_>> {
+template <std::size_t Dimension_, class ValueType_, class RealType_>
+struct ComputeEnergyTrait<Hookean<Dimension_, ValueType_, RealType_>> {
   template <class MaterialModel>
   typename MaterialModel::Energy
   operator()(const MaterialModel &model,
@@ -76,15 +77,15 @@ struct ComputeEnergyTrait<Hookean<Dimension_>> {
              const typename MaterialModel::Time time) noexcept {
     const auto strain = compute_strain(model, id, gradient, time);
     const auto stress = compute_stress(model, id, gradient, time);
-    return typename MaterialModel::value_type{0.5} *
+    return typename MaterialModel::real_type{0.5} *
            tensor::as_matrix_of_rows(&strain)
                .cwiseProduct(tensor::as_matrix_of_rows(&stress))
                .sum();
   }
 };
 
-template <std::size_t Dimension_>
-struct ComputeStrainTrait<Hookean<Dimension_>> {
+template <std::size_t Dimension_, class ValueType_, class RealType_>
+struct ComputeStrainTrait<Hookean<Dimension_, ValueType_, RealType_>> {
   template <class MaterialModel>
   typename MaterialModel::Strain
   operator()(const MaterialModel &, const typename MaterialModel::size_type,
@@ -94,14 +95,14 @@ struct ComputeStrainTrait<Hookean<Dimension_>> {
 
     typename MaterialModel::Strain result;
     tensor::as_matrix_of_rows(&result) =
-        typename MaterialModel::value_type{.5} *
+        typename MaterialModel::real_type{.5} *
         (gradient_matrix + gradient_matrix.transpose());
     return result;
   }
 };
 
-template <std::size_t Dimension_>
-struct ComputeStressTrait<Hookean<Dimension_>> {
+template <std::size_t Dimension_, class ValueType_, class RealType_>
+struct ComputeStressTrait<Hookean<Dimension_, ValueType_, RealType_>> {
   template <class MaterialModel>
   typename MaterialModel::Stress
   operator()(const MaterialModel &model,
@@ -114,13 +115,13 @@ struct ComputeStressTrait<Hookean<Dimension_>> {
     typename MaterialModel::Stress result;
     tensor::as_matrix_of_rows(&result) =
         model.lambda() * strain_matrix.trace() * strain_matrix.Identity() +
-        typename MaterialModel::value_type{2.} * model.mu() * strain_matrix;
+        typename MaterialModel::real_type{2.} * model.mu() * strain_matrix;
     return result;
   }
 };
 
-template <std::size_t Dimension_>
-struct ComputeTangentMatrixTrait<Hookean<Dimension_>> {
+template <std::size_t Dimension_, class ValueType_, class RealType_>
+struct ComputeTangentMatrixTrait<Hookean<Dimension_, ValueType_, RealType_>> {
   template <class MaterialModel>
   typename MaterialModel::TangentMatrix
   operator()(const MaterialModel &model,
diff --git a/elements/src/include/ae108/elements/materialmodels/MaterialModelBase.h b/elements/src/include/ae108/elements/materialmodels/MaterialModelBase.h
index 7a900dca..5f84d977 100644
--- a/elements/src/include/ae108/elements/materialmodels/MaterialModelBase.h
+++ b/elements/src/include/ae108/elements/materialmodels/MaterialModelBase.h
@@ -21,11 +21,12 @@ namespace ae108 {
 namespace elements {
 namespace materialmodels {
 
-template <class SizeType_, class ValueType_, SizeType_ Dimension_,
-          SizeType_ DegreesOfFreedom_ = Dimension_>
+template <class SizeType_, class ValueType_, class RealType_,
+          SizeType_ Dimension_, SizeType_ DegreesOfFreedom_ = Dimension_>
 struct MaterialModelBase {
   using size_type = SizeType_;
   using value_type = ValueType_;
+  using real_type = RealType_;
 
   using Energy = value_type;
   using Time = value_type;
diff --git a/elements/src/include/ae108/elements/materialmodels/Minimal.h b/elements/src/include/ae108/elements/materialmodels/Minimal.h
index 081e7a80..4a49f470 100644
--- a/elements/src/include/ae108/elements/materialmodels/Minimal.h
+++ b/elements/src/include/ae108/elements/materialmodels/Minimal.h
@@ -30,7 +30,8 @@ namespace materialmodels {
  * defined.
  */
 template <std::size_t Dimension_>
-struct Minimal final : MaterialModelBase<std::size_t, double, Dimension_> {};
+struct Minimal final
+    : MaterialModelBase<std::size_t, double, double, Dimension_> {};
 
 /**
  * @brief Always returns 0.
-- 
GitLab