From 9ed70d7453e968f8f3156804a7cc44f2c65aca22 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <github@naumov.de>
Date: Wed, 14 Apr 2021 11:18:05 +0200
Subject: [PATCH] [MPL] Access and reset to internal state variables

For storage as ip-data in the output and simulation restart.
---
 MaterialLib/SolidModels/Ehlers.cpp        | 47 +++++++++++++++++++++++
 MaterialLib/SolidModels/Ehlers.h          |  2 +
 MaterialLib/SolidModels/MFront/MFront.cpp | 11 ++++++
 MaterialLib/SolidModels/MechanicsBase.h   | 10 ++++-
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/MaterialLib/SolidModels/Ehlers.cpp b/MaterialLib/SolidModels/Ehlers.cpp
index efbc6a5d9f4..ee7c261af64 100644
--- a/MaterialLib/SolidModels/Ehlers.cpp
+++ b/MaterialLib/SolidModels/Ehlers.cpp
@@ -720,6 +720,15 @@ SolidEhlers<DisplacementDim>::getInternalVariables() const
                  cache.resize(1);
                  cache.front() = ehlers_state.damage.kappa_d();
                  return cache;
+             },
+             [](typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                 assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+                            &state) != nullptr);
+                 auto& ehlers_state =
+                     static_cast<StateVariables<DisplacementDim>&>(state);
+
+                 return {&ehlers_state.damage.kappa_d(), 1};
              }},
             {"damage.value", 1,
              [](typename MechanicsBase<
@@ -733,6 +742,15 @@ SolidEhlers<DisplacementDim>::getInternalVariables() const
                  cache.resize(1);
                  cache.front() = ehlers_state.damage.value();
                  return cache;
+             },
+             [](typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                 assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+                            &state) != nullptr);
+                 auto& ehlers_state =
+                     static_cast<StateVariables<DisplacementDim>&>(state);
+
+                 return {&ehlers_state.damage.value(), 1};
              }},
             {"eps_p.D", KelvinVector::RowsAtCompileTime,
              [](typename MechanicsBase<
@@ -750,6 +768,17 @@ SolidEhlers<DisplacementDim>::getInternalVariables() const
                          ehlers_state.eps_p.D);
 
                  return cache;
+             },
+             [](typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                 assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+                            &state) != nullptr);
+                 auto& ehlers_state =
+                     static_cast<StateVariables<DisplacementDim>&>(state);
+
+                 return {
+                     ehlers_state.eps_p.D.data(),
+                     static_cast<std::size_t>(KelvinVector::RowsAtCompileTime)};
              }},
             {"eps_p.V", 1,
              [](typename MechanicsBase<
@@ -763,6 +792,15 @@ SolidEhlers<DisplacementDim>::getInternalVariables() const
                  cache.resize(1);
                  cache.front() = ehlers_state.eps_p.V;
                  return cache;
+             },
+             [](typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                 assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+                            &state) != nullptr);
+                 auto& ehlers_state =
+                     static_cast<StateVariables<DisplacementDim>&>(state);
+
+                 return {&ehlers_state.eps_p.V, 1};
              }},
             {"eps_p.eff", 1,
              [](typename MechanicsBase<
@@ -776,6 +814,15 @@ SolidEhlers<DisplacementDim>::getInternalVariables() const
                  cache.resize(1);
                  cache.front() = ehlers_state.eps_p.eff;
                  return cache;
+             },
+             [](typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                 assert(dynamic_cast<StateVariables<DisplacementDim> const*>(
+                            &state) != nullptr);
+                 auto& ehlers_state =
+                     static_cast<StateVariables<DisplacementDim>&>(state);
+
+                 return {&ehlers_state.eps_p.eff, 1};
              }}};
 }
 
diff --git a/MaterialLib/SolidModels/Ehlers.h b/MaterialLib/SolidModels/Ehlers.h
index cddd1c104f5..1ff8c3ed1bd 100644
--- a/MaterialLib/SolidModels/Ehlers.h
+++ b/MaterialLib/SolidModels/Ehlers.h
@@ -209,7 +209,9 @@ public:
     }
 
     double kappa_d() const { return _kappa_d; }
+    double& kappa_d() { return _kappa_d; }
     double value() const { return _value; }
+    double& value() { return _value; }
 
 private:
     double _kappa_d = 0;  ///< damage driving variable
diff --git a/MaterialLib/SolidModels/MFront/MFront.cpp b/MaterialLib/SolidModels/MFront/MFront.cpp
index 08a6d03445e..e6cb2b3f01b 100644
--- a/MaterialLib/SolidModels/MFront/MFront.cpp
+++ b/MaterialLib/SolidModels/MFront/MFront.cpp
@@ -431,6 +431,17 @@ MFront<DisplacementDim>::getInternalVariables() const
                             size,
                             begin(cache));
                 return cache;
+            },
+            [offset, size](
+                typename MechanicsBase<DisplacementDim>::MaterialStateVariables&
+                    state) -> BaseLib::DynamicSpan<double> {
+                assert(dynamic_cast<MaterialStateVariables const*>(&state) !=
+                       nullptr);
+                auto& internal_state_variables =
+                    static_cast<MaterialStateVariables&>(state)
+                        ._behaviour_data.s1.internal_state_variables;
+
+                return {internal_state_variables.data() + offset, size};
             }};
         internal_variables.push_back(new_variable);
     }
diff --git a/MaterialLib/SolidModels/MechanicsBase.h b/MaterialLib/SolidModels/MechanicsBase.h
index 936a372be4b..684509c0da7 100644
--- a/MaterialLib/SolidModels/MechanicsBase.h
+++ b/MaterialLib/SolidModels/MechanicsBase.h
@@ -9,15 +9,16 @@
 
 #pragma once
 
-#include <optional>
 #include <functional>
 #include <memory>
+#include <optional>
 #include <tuple>
 #include <vector>
 
+#include "BaseLib/DynamicSpan.h"
 #include "BaseLib/Error.h"
-#include "MathLib/KelvinVector.h"
 #include "MaterialLib/MPL/VariableType.h"
+#include "MathLib/KelvinVector.h"
 
 namespace ParameterLib
 {
@@ -96,6 +97,8 @@ struct MechanicsBase
     {
         using Getter = std::function<std::vector<double> const&(
             MaterialStateVariables const&, std::vector<double>& /*cache*/)>;
+        using WriteAccess = std::function<BaseLib::DynamicSpan<double>(
+            MaterialStateVariables&)>;
 
         /// name of the internal variable
         std::string const name;
@@ -105,6 +108,9 @@ struct MechanicsBase
 
         /// function accessing the internal variable
         Getter const getter;
+
+        /// function accessing the internal variable
+        WriteAccess const reference;
     };
 
     /// Returns internal variables defined by the specific material model, if
-- 
GitLab