version 0.4.1
neohooke.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2025 The Ikarus Developers ikarus@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
10#pragma once
11
16
17namespace Ikarus::Materials {
18
37template <typename ST>
38struct NeoHookeT : public Material<NeoHookeT<ST>>
39{
40 using ScalarType = ST;
41 static constexpr int dim = 3;
42 using StrainMatrix = Eigen::Matrix<ScalarType, dim, dim>;
44 using MaterialTensor = Eigen::TensorFixedSize<ScalarType, Eigen::Sizes<dim, dim, dim, dim>>;
45
47
49 static constexpr auto stressTag = StressTags::PK2;
51 static constexpr bool energyAcceptsVoigt = false;
52 static constexpr bool stressToVoigt = false;
53 static constexpr bool stressAcceptsVoigt = false;
54 static constexpr bool moduliToVoigt = false;
55 static constexpr bool moduliAcceptsVoigt = false;
56 static constexpr double derivativeFactorImpl = 2;
57
58 [[nodiscard]] constexpr static std::string nameImpl() noexcept { return "NeoHooke"; }
59
64 explicit NeoHookeT(const MaterialParameters& mpt)
65 : materialParameter_{mpt} {}
66
70 MaterialParameters materialParametersImpl() const { return materialParameter_; }
71
78 template <typename Derived>
79 ScalarType storedEnergyImpl(const Eigen::MatrixBase<Derived>& C) const {
80 static_assert(Concepts::EigenMatrixOrVoigtNotation3<Derived>);
81 if constexpr (!Concepts::EigenVector<Derived>) {
82 const auto traceC = C.trace();
83 const auto detC = C.determinant();
84 Impl::checkPositiveOrAbort(detC);
85 const auto logdetF = log(sqrt(detC));
86 return materialParameter_.mu / 2.0 * (traceC - 3 - 2 * logdetF) +
87 materialParameter_.lambda / 2.0 * logdetF * logdetF;
88 } else
89 static_assert(!Concepts::EigenVector<Derived>,
90 "NeoHooke energy can only be called with a matrix and not a vector in Voigt notation");
91 }
92
100 template <bool voigt, typename Derived>
101 StressMatrix stressesImpl(const Eigen::MatrixBase<Derived>& C) const {
102 static_assert(Concepts::EigenMatrixOrVoigtNotation3<Derived>);
103 if constexpr (!voigt) {
104 if constexpr (!Concepts::EigenVector<Derived>) {
105 const auto detC = C.determinant();
106 Impl::checkPositiveOrAbort(detC);
107 const auto logdetF = log(sqrt(detC));
108 const auto invC = C.inverse().eval();
109 return (materialParameter_.mu * (StrainMatrix::Identity() - invC) + materialParameter_.lambda * logdetF * invC)
110 .eval();
111 } else
112 static_assert(!Concepts::EigenVector<Derived>,
113 "NeoHooke can only be called with a matrix and not a vector in Voigt notation");
114 } else
115 static_assert(voigt == false, "NeoHooke does not support returning stresses in Voigt notation");
116 }
117
125 template <bool voigt, typename Derived>
126 MaterialTensor tangentModuliImpl(const Eigen::MatrixBase<Derived>& C) const {
127 static_assert(Concepts::EigenMatrixOrVoigtNotation3<Derived>);
128 if constexpr (!voigt) {
129 const auto invC = C.inverse().eval();
130 const auto detC = C.determinant();
131 Impl::checkPositiveOrAbort(detC);
132 const auto logdetF = log(sqrt(detC));
133 const auto CTinv = tensorView(invC, std::array<Eigen::Index, 2>({3, 3}));
134
135 MaterialTensor moduli = (materialParameter_.lambda * dyadic(CTinv, CTinv) +
136 2 * (materialParameter_.mu - materialParameter_.lambda * logdetF) *
137 symTwoSlots(fourthOrderIKJL(invC, invC), {2, 3}))
138 .eval();
139 return moduli;
140 } else
141 static_assert(voigt == false, "NeoHooke does not support returning tangent moduli in Voigt notation");
142 }
143
149 template <typename STO>
150 auto rebind() const {
151 return NeoHookeT<STO>(materialParameter_);
152 }
153
164 template <typename Derived>
165 auto materialInversionImpl(const Eigen::MatrixBase<Derived>& Sraw) const {
166 decltype(auto) S = Impl::maybeFromVoigt(Sraw, false);
167 auto C = Derived::Zero().eval();
168 const auto I = Derived::Identity();
169
170 auto mu = materialParameter_.mu;
171 auto Lambda = materialParameter_.lambda;
172 if (Dune::FloatCmp::eq(Lambda, 0.0))
173 C = (I - (1.0 / mu) * S).inverse();
174 else {
175 const auto A = 1.0 / Lambda * (mu * I - S);
176 const auto a = A.determinant();
177 checkInvertabilityOrAbort(a);
178
179 const auto b = 2.0 / dim * mu / Lambda - log(static_cast<double>(dim) / 2) + 1.0 / dim * log(abs(a));
180 const auto lnJ = mu / Lambda - static_cast<double>(dim) / 2 * util::lambertW0(Dune::sign(a) * exp(b));
181 C = (mu / Lambda - lnJ) * A.inverse();
182 }
183 const auto tangentModulus = toVoigt(tangentModuliImpl<false>(C));
184 const auto D = tangentModulus.inverse().eval();
185 return std::make_pair(D, toVoigt(C));
186 }
187
188private:
189 MaterialParameters materialParameter_;
190
191 template <typename ScalarType>
192 void checkInvertabilityOrAbort(ScalarType a, ScalarType eps = 1e-10) const {
193 const bool req1 = Dune::FloatCmp::ne(a, 0.0, eps);
194 const bool req2 = [&]() {
195 if constexpr (dim == 3)
196 return Dune::FloatCmp::gt(
197 a,
198 -pow(static_cast<double>(dim) / 2, dim) * exp(-dim - 2 * materialParameter_.mu / materialParameter_.lambda),
199 eps);
200 else if (dim == 2)
201 return Dune::FloatCmp::gt(a, 0.0, eps);
202 }();
203 if (!(req1 && req2)) {
204 std::cerr << "NeoHooke: Requirements for material law inversion not met.";
205 abort();
206 }
207 }
208};
209
214
215} // namespace Ikarus::Materials
Helper for the Eigen::Tensor types.
Implementation of the zeroth branch of the lambertW function.
helper functions used by material model implementations.
Eigen::Tensor< typename Derived::Scalar, rank > tensorView(const Eigen::EigenBase< Derived > &matrix, const std::array< T, rank > &dims)
View an Eigen matrix as an Eigen Tensor with specified dimensions.
Definition: tensorutils.hh:32
auto fourthOrderIKJL(const Eigen::MatrixBase< AType > &A, const Eigen::MatrixBase< BType > &B)
Computes the IKJL product of two matrices.
Definition: tensorutils.hh:135
auto dyadic(const auto &A_ij, const auto &B_kl)
Computes the dyadic product of two Eigen tensors.
Definition: tensorutils.hh:47
auto symTwoSlots(const Eigen::TensorFixedSize< ScalarType, Eigen::Sizes< dim, dim, dim, dim > > &t, const std::array< size_t, 2 > &slots)
Creates a symmetric fourth-order tensor in the two specified slots of the input tensor.
Definition: tensorutils.hh:158
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:182
Definition: arrudaboyce.hh:27
ST lambertW0(ST z, int maxIterations=20, ST eps=std::numeric_limits< ST >::epsilon())
Implementation of the principal branch of the Lambert-W function (branch 0 in the domain ),...
Definition: lambertw.hh:42
Implementation of the Neo-Hookean material model.The energy is computed as.
Definition: neohooke.hh:39
auto materialInversionImpl(const Eigen::MatrixBase< Derived > &Sraw) const
Computes the strain measure and inverse material tangent for a given stress state.
Definition: neohooke.hh:165
auto rebind() const
Rebinds the material to a different scalar type.
Definition: neohooke.hh:150
ST ScalarType
Definition: neohooke.hh:40
StrainMatrix StressMatrix
Definition: neohooke.hh:43
MaterialParameters materialParametersImpl() const
Returns the material parameters stored in the material.
Definition: neohooke.hh:70
static constexpr bool moduliAcceptsVoigt
Definition: neohooke.hh:55
static constexpr int dim
Definition: neohooke.hh:41
static constexpr bool moduliToVoigt
Definition: neohooke.hh:54
static constexpr bool stressToVoigt
Definition: neohooke.hh:52
static constexpr bool stressAcceptsVoigt
Definition: neohooke.hh:53
Eigen::TensorFixedSize< ScalarType, Eigen::Sizes< dim, dim, dim, dim > > MaterialTensor
Definition: neohooke.hh:44
static constexpr auto stressTag
Definition: neohooke.hh:49
ScalarType storedEnergyImpl(const Eigen::MatrixBase< Derived > &C) const
Computes the stored energy in the Neo-Hookean material model.
Definition: neohooke.hh:79
MaterialTensor tangentModuliImpl(const Eigen::MatrixBase< Derived > &C) const
Computes the tangent moduli in the Neo-Hookean material model.
Definition: neohooke.hh:126
NeoHookeT(const MaterialParameters &mpt)
Constructor for NeoHookeT.
Definition: neohooke.hh:64
StressMatrix stressesImpl(const Eigen::MatrixBase< Derived > &C) const
Computes the stresses in the Neo-Hookean material model.
Definition: neohooke.hh:101
static constexpr auto strainTag
Definition: neohooke.hh:48
Eigen::Matrix< ScalarType, dim, dim > StrainMatrix
Definition: neohooke.hh:42
static constexpr std::string nameImpl() noexcept
Definition: neohooke.hh:58
static constexpr bool energyAcceptsVoigt
Definition: neohooke.hh:51
LamesFirstParameterAndShearModulus MaterialParameters
Definition: neohooke.hh:46
static constexpr double derivativeFactorImpl
Definition: neohooke.hh:56
static constexpr auto tangentModuliTag
Definition: neohooke.hh:50
Interface classf or materials.
Definition: finiteelements/mechanics/materials/interface.hh:82
Definition: physicshelper.hh:54
double lambda
Definition: physicshelper.hh:55
double mu
Definition: physicshelper.hh:56
Concept defining the requirements for Eigen vectors.
Definition: utils/concepts.hh:365
Contains the Material interface class and related template functions for material properties.