version 0.4.1
autodiffmat.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
10#pragma once
11
12#include <autodiff/forward/dual.hpp>
13#include <autodiff/forward/dual/dual.hpp>
14#include <autodiff/forward/dual/eigen.hpp>
15#include <autodiff/forward/utils/derivative.hpp>
16
20
22
33template <typename RealMAT, bool forceAutoDiffV = false, bool forceAutoDiffS = false>
34struct AutoDiffMAT : public RealMAT
35{
36 using ScalarType = typename RealMAT::ScalarType;
37 using StrainMatrix = typename RealMAT::StrainMatrix;
38 using StressMatrix = typename RealMAT::StressMatrix;
39 using MaterialTensor = typename RealMAT::MaterialTensor;
40
41 using MaterialParameters = typename RealMAT::MaterialParameters;
42
43 static constexpr int dim = RealMAT::dim;
44 static constexpr int nVoigtIndices = dim * (dim + 1) / 2;
45
46 static constexpr auto strainTag = RealMAT::strainTag;
47 static constexpr auto stressTag = RealMAT::stressTag;
48 static constexpr auto tangentModuliTag = RealMAT::tangentModuliTag;
49 static constexpr bool energyAcceptsVoigt = RealMAT::energyAcceptsVoigt;
50 static constexpr bool stressToVoigt = RealMAT::stressToVoigt;
51 static constexpr bool stressAcceptsVoigt = RealMAT::stressAcceptsVoigt;
52 static constexpr bool moduliToVoigt = RealMAT::moduliToVoigt;
53 static constexpr bool moduliAcceptsVoigt = RealMAT::moduliAcceptsVoigt;
54 static constexpr double derivativeFactorImpl = RealMAT::derivativeFactorImpl;
55
63 template <typename... Args>
64 explicit AutoDiffMAT(Args&&... args)
65 : RealMAT{std::forward<Args>(args)...} {}
66
67 [[nodiscard]] constexpr static std::string nameImpl() noexcept { return "AutoDiff: " + RealMAT::name(); }
68
72 MaterialParameters materialParametersImpl() const { return realMAT().materialParametersImpl(); }
73
80 template <StrainTags tag, typename Derived>
81 auto storedEnergy(const Eigen::MatrixBase<Derived>& E) const {
82 if constexpr (requires { realMAT().template storedEnergy<tag>(E); }) {
83 auto mat_ad = realMAT().template rebind<autodiff::dual>();
84 return mat_ad.template storedEnergy<tag>(E);
85 } else {
86 static_assert(Dune::AlwaysFalse<AutoDiffMAT>::value,
87 "Appropriate storedEnergy function not is implemented for the chosen material model.");
88 }
89 }
90
98 template <StrainTags tag, bool voigt = true, typename Derived>
99 auto stresses(const Eigen::MatrixBase<Derived>& E) const {
100 if constexpr (requires { realMAT().template stresses<tag>(E); } and not(forceAutoDiffV or forceAutoDiffS)) {
101 return realMAT().template stresses<tag>(E);
102 } else if constexpr (requires { realMAT().template storedEnergy<tag>(E); }) {
103 static_assert(!Concepts::EigenVector<Derived>,
104 "The strain measure used for autodiff has to be in matrix notation.");
105 auto mat_ad = realMAT().template rebind<autodiff::dual>();
106
107 auto f = [&](const auto& x) { return mat_ad.template storedEnergy<tag>(x); };
108
109 Eigen::Vector<autodiff::dual, nVoigtIndices> dx = toVoigt(E.derived());
110 autodiff::dual e;
111 Eigen::Vector<double, nVoigtIndices> g;
112
113 gradient(f, autodiff::wrt(dx), autodiff::at(dx), e, g);
114
115 return (derivativeFactorImpl * g).eval();
116 } else {
117 static_assert(Dune::AlwaysFalse<AutoDiffMAT>::value,
118 "Appropriate storedEnergy function not is implemented for the chosen material model.");
119 }
120 }
121
129 template <StrainTags tag, bool voigt = true, typename Derived>
130 auto tangentModuli(const Eigen::MatrixBase<Derived>& E) const {
131 if constexpr (requires { realMAT().template tangentModuli<tag>(E); } and not(forceAutoDiffV or forceAutoDiffS)) {
132 return realMAT().template tangentModuli<tag>(E);
133 } else if constexpr (requires { realMAT().template stresses<tag>(E); } and forceAutoDiffV and not forceAutoDiffS) {
134 static_assert(!Concepts::EigenVector<Derived>,
135 "The strain measure used for autodiff has to be in matrix notation.");
136 auto mat_ad = realMAT().template rebind<autodiff::dual>();
137
138 auto f = [&](const auto& x) { return mat_ad.template stresses<tag>(x); };
139
140 auto dx = Eigen::Vector<autodiff::dual, nVoigtIndices>{};
141
142 dx = toVoigt(E.derived());
143 Eigen::VectorXdual g(nVoigtIndices);
144
145 auto h = Eigen::Matrix<double, nVoigtIndices, nVoigtIndices>{};
146 jacobian(f, autodiff::wrt(dx), autodiff::at(dx), g, h);
147
148 return (derivativeFactorImpl * h).eval();
149 } else if constexpr (requires { realMAT().template storedEnergy<tag>(E); }) {
150 static_assert(!Concepts::EigenVector<Derived>,
151 "The strain measure used for autodiff has to be in matrix notation.");
152 auto mat_ad = realMAT().template rebind<autodiff::dual2nd>();
153
154 auto f = [&](const auto& x) { return mat_ad.template storedEnergy<tag>(x); };
155
156 Eigen::Matrix<autodiff::dual2nd, nVoigtIndices, 1> dx = toVoigt(E.derived());
157
158 autodiff::dual2nd e;
159 Eigen::Matrix<double, nVoigtIndices, 1> g;
160 Eigen::Matrix<double, nVoigtIndices, nVoigtIndices> h;
161
162 h = autodiff::hessian(f, autodiff::wrt(dx), autodiff::at(dx), e, g);
163
164 return (derivativeFactorImpl * derivativeFactorImpl * h).eval();
165 } else {
166 static_assert(
167 Dune::AlwaysFalse<AutoDiffMAT>::value,
168 "Appropriate storedEnergy and stresses functions are not implemented for the chosen material model.");
169 }
170 }
171
177 const RealMAT& realMAT() const { return *this; }
178
179private:
180 MaterialParameters materialParameter_;
181};
182
183} // namespace Ikarus::Experimental
Helper for the Eigen::Tensor types.
helper functions used by material model implementations.
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:179
STL namespace.
Definition: autodiffmat.hh:21
Implementation of a AutoDiff-based material model.
Definition: autodiffmat.hh:35
static constexpr bool moduliToVoigt
Definition: autodiffmat.hh:52
typename RealMAT::StrainMatrix StrainMatrix
Definition: autodiffmat.hh:37
static constexpr auto strainTag
Definition: autodiffmat.hh:46
static constexpr double derivativeFactorImpl
Definition: autodiffmat.hh:54
MaterialParameters materialParametersImpl() const
Returns the material parameters stored in the material.
Definition: autodiffmat.hh:72
typename RealMAT::StressMatrix StressMatrix
Definition: autodiffmat.hh:38
static constexpr std::string nameImpl() noexcept
Definition: autodiffmat.hh:67
typename RealMAT::MaterialTensor MaterialTensor
Definition: autodiffmat.hh:39
static constexpr int dim
Definition: autodiffmat.hh:43
auto storedEnergy(const Eigen::MatrixBase< Derived > &E) const
Computes the stored energy in the underlying material model.
Definition: autodiffmat.hh:81
static constexpr bool energyAcceptsVoigt
Definition: autodiffmat.hh:49
const RealMAT & realMAT() const
Get the reference to the base material.
Definition: autodiffmat.hh:177
static constexpr auto stressTag
Definition: autodiffmat.hh:47
static constexpr bool moduliAcceptsVoigt
Definition: autodiffmat.hh:53
static constexpr int nVoigtIndices
Definition: autodiffmat.hh:44
typename RealMAT::MaterialParameters MaterialParameters
Definition: autodiffmat.hh:41
static constexpr bool stressToVoigt
Definition: autodiffmat.hh:50
auto stresses(const Eigen::MatrixBase< Derived > &E) const
Computes the stresses in the underlying material model.
Definition: autodiffmat.hh:99
static constexpr auto tangentModuliTag
Definition: autodiffmat.hh:48
typename RealMAT::ScalarType ScalarType
Definition: autodiffmat.hh:36
auto tangentModuli(const Eigen::MatrixBase< Derived > &E) const
Computes the tangent moduli in the underlying material model.
Definition: autodiffmat.hh:130
AutoDiffMAT(Args &&... args)
Constructor for the AutoDiffMAT class. Forward the construction to the underlying element.
Definition: autodiffmat.hh:64
static constexpr bool stressAcceptsVoigt
Definition: autodiffmat.hh:51
Concept defining the requirements for Eigen vectors.
Definition: utils/concepts.hh:353
Contains the Material interface class and related template functions for material properties.