version 0.4.1
vanishingstress.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2024 The Ikarus Developers mueller@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
10#pragma once
11
12#include "vanishinghelpers.hh"
13
19
20namespace Ikarus {
21
28template <auto stressIndexPair, typename MI>
29struct VanishingStress : public Material<VanishingStress<stressIndexPair, MI>>
30{
31 using Underlying = MI;
32 using MaterialParameters = typename Underlying::MaterialParameters;
33
34 static constexpr auto fixedPairs = stressIndexPair;
35 static constexpr auto freeVoigtIndices = createfreeVoigtIndices(fixedPairs);
36 static constexpr auto fixedVoigtIndices = createFixedVoigtIndices(fixedPairs);
37 static constexpr auto fixedDiagonalVoigtIndicesSize =
38 countDiagonalIndices(fixedPairs);
39 static constexpr auto freeStrains = freeVoigtIndices.size();
40 using ScalarType = typename Underlying::ScalarType;
42
43 static constexpr auto strainTag = Underlying::strainTag;
44 static constexpr auto stressTag = Underlying::stressTag;
45 static constexpr auto tangentModuliTag = Underlying::tangentModuliTag;
46 static constexpr bool energyAcceptsVoigt = Underlying::energyAcceptsVoigt;
47 static constexpr bool stressToVoigt = true;
48 static constexpr bool stressAcceptsVoigt = true;
49 static constexpr bool moduliToVoigt = true;
50 static constexpr bool moduliAcceptsVoigt = true;
51 static constexpr double derivativeFactorImpl = Underlying::derivativeFactorImpl;
52
58 explicit VanishingStress(MI mat, typename MI::ScalarType tol = 1e-12)
59 : matImpl_{mat},
60 tol_{tol} {}
61
62 [[nodiscard]] constexpr static std::string nameImpl() noexcept {
63 auto matName = MI::name() + "_VanishingStress(";
64 for (auto p : fixedPairs)
65 matName += "(" + std::to_string(p.row) + std::to_string(p.col) + ")";
66 matName += ")";
67 return matName;
68 }
69
73 MaterialParameters materialParametersImpl() const { return matImpl_.materialParametersImpl(); }
74
81 template <typename Derived>
82 ScalarType storedEnergyImpl(const Eigen::MatrixBase<Derived>& E) const {
83 const auto [nonOp, Esol] = reduceStress(E);
84 return matImpl_.storedEnergyImpl(Esol);
85 }
86
94 template <bool voigt, typename Derived>
95 auto stressesImpl(const Eigen::MatrixBase<Derived>& E) const {
96 const auto [nonOp, Esol] = reduceStress(E);
97 auto stressesRed = matImpl_.template stresses<Underlying::strainTag, true>(Esol);
98
99 if constexpr (voigt) {
100 return removeCol(stressesRed, fixedVoigtIndices);
101 } else
102 return fromVoigt(stressesRed, false);
103 }
104
112 template <bool voigt, typename Derived>
113 auto tangentModuliImpl(const Eigen::MatrixBase<Derived>& E) const {
114 const auto [nonOp, Esol] = reduceStress(E);
115 auto C = matImpl_.template tangentModuli<Underlying::strainTag, true>(Esol);
116 if constexpr (voigt)
118 else
119 return fromVoigt(C);
120 }
121
127 template <typename ScalarTypeOther>
128 auto rebind() const {
129 auto reboundMatImpl = matImpl_.template rebind<ScalarTypeOther>();
131 }
132
133private:
139 template <typename Derived>
140 void initUnknownStrains(Eigen::MatrixBase<Derived>& E) const {
141 for (size_t i = 0; i < fixedPairs.size(); ++i) {
142 ScalarType initialVal = E(fixedPairs[i].row, fixedPairs[i].col);
144 if (Dune::FloatCmp::eq(initialVal, ScalarType(0.0)) and (fixedPairs[i].row == fixedPairs[i].col))
145 initialVal = ScalarType(1.0);
146 }
147 if (fixedPairs[i].row != fixedPairs[i].col)
148 initialVal = ScalarType(0.0);
149 E(fixedPairs[i].row, fixedPairs[i].col) = E(fixedPairs[i].col, fixedPairs[i].row) = initialVal;
150 }
151 }
152
159 template <typename Derived>
160 auto reduceStress(const Eigen::MatrixBase<Derived>& Eraw) const {
161 auto E = Impl::maybeFromVoigt(Eraw);
162 initUnknownStrains(E);
163
164 std::array<size_t, fixedDiagonalVoigtIndicesSize> fixedDiagonalVoigtIndices;
165 for (size_t ri = 0; auto i : fixedVoigtIndices) {
166 auto indexPair = fromVoigt(i);
167 if (indexPair[0] == indexPair[1])
168 fixedDiagonalVoigtIndices[ri++] = i;
169 }
170
171 auto f = [&](auto&) {
172 auto S = matImpl_.template stresses<Underlying::strainTag, true>(E);
173 return S(fixedDiagonalVoigtIndices).eval();
174 };
175 auto df = [&](auto&) {
176 auto moduli = (matImpl_.template tangentModuli<Underlying::strainTag, true>(E)).eval();
177 return (moduli(fixedDiagonalVoigtIndices, fixedDiagonalVoigtIndices) / Underlying::derivativeFactor).eval();
178 };
179
180 auto Er = E(fixedDiagonalVoigtIndices, fixedDiagonalVoigtIndices).eval().template cast<ScalarType>();
181 auto nonOp = Ikarus::NonLinearOperator(functions(f, df), parameter(Er));
182
183 auto linearSolver = [](auto& r, auto& A) { return (A.inverse() * r).eval(); };
184 auto updateFunction = [&](auto& /* Ex33 */, auto& ecomps) {
185 for (int ri = 0; auto i : fixedDiagonalVoigtIndices) {
186 auto indexPair = fromVoigt(i);
187 E(indexPair[0], indexPair[1]) += ecomps(ri++);
188 }
189 };
190
191 int minIter = isAutoDiff ? 1 : 0;
192 // THE CTAD is broken for designated initializers in clang 16, when we drop support this can be simplified
193 NewtonRaphsonConfig<decltype(linearSolver), decltype(updateFunction)> nrs{
194 .parameters = {.tol = tol_, .maxIter = 100, .minIter = minIter},
195 .linearSolver = linearSolver,
196 .updateFunction = updateFunction
197 };
198
199 auto nr = createNonlinearSolver(std::move(nrs), nonOp);
200 if (!static_cast<bool>(nr->solve()))
201 DUNE_THROW(Dune::MathError, "The stress reduction of material " << nameImpl() << " was unsuccessful\n"
202 << "The strains are\n"
203 << E << "\n The stresses are\n"
204 << f(Er));
205 return std::make_pair(nonOp, E);
206 }
207
208 Underlying matImpl_;
209 double tol_{};
210};
211
220template <Impl::MatrixIndexPair... stressIndexPair, typename MaterialImpl>
221auto makeVanishingStress(MaterialImpl mat, typename MaterialImpl::ScalarType p_tol = 1e-12) {
222 return VanishingStress<std::to_array({stressIndexPair...}), MaterialImpl>(mat, p_tol);
223}
224
232template <typename MaterialImpl>
233auto planeStress(const MaterialImpl& mat, typename MaterialImpl::ScalarType tol = 1e-8) {
234 return makeVanishingStress<Impl::MatrixIndexPair{2, 1}, Impl::MatrixIndexPair{2, 0}, Impl::MatrixIndexPair{2, 2}>(
235 mat, tol);
236}
237
246template <typename MaterialImpl>
247auto shellMaterial(const MaterialImpl& mat, typename MaterialImpl::ScalarType tol = 1e-8) {
248 return makeVanishingStress<Impl::MatrixIndexPair{2, 2}>(mat, tol);
249}
250
259template <typename MaterialImpl>
260auto beamMaterial(const MaterialImpl& mat, typename MaterialImpl::ScalarType tol = 1e-8) {
261 return makeVanishingStress<Impl::MatrixIndexPair{1, 1}, Impl::MatrixIndexPair{2, 2}>(mat, tol);
262}
263} // namespace Ikarus
Provides a NonLinearOperator class for handling nonlinear operators.
Several concepts.
Contains the generic NonlinearSolverFactory class.
Implementation of the Newton-Raphson method for solving nonlinear equations.
auto staticCondensation(const Eigen::MatrixBase< Derived > &E, const std::array< size_t, sizeOfCondensedIndices > &indices)
Performs static condensation on a square matrix.
Definition: linearalgebrahelper.hh:498
auto removeCol(const Eigen::MatrixBase< Derived > &E, const std::array< size_t, sizeOfRemovedCols > &indices)
Removes specified columns from a matrix.
Definition: linearalgebrahelper.hh:539
auto fromVoigt(const Eigen::Matrix< ST, size, 1, Options, maxSize, 1 > &EVoigt, bool isStrain=true)
Converts a vector given in Voigt notation to a matrix.
Definition: tensorutils.hh:271
Definition: assemblermanipulatorbuildingblocks.hh:22
auto makeVanishingStress(MaterialImpl mat, typename MaterialImpl::ScalarType p_tol=1e-12)
Factory function to create a VanishingStress material with specified stress indices.
Definition: vanishingstress.hh:221
::value auto createNonlinearSolver(NRConfig &&config, NLO &&nonLinearOperator)
Function to create a NewtonRaphson solver instance.
Definition: newtonraphson.hh:65
auto shellMaterial(const MaterialImpl &mat, typename MaterialImpl::ScalarType tol=1e-8)
Factory function to create a VanishingStress material for a shell material with zero normal stress co...
Definition: vanishingstress.hh:247
auto beamMaterial(const MaterialImpl &mat, typename MaterialImpl::ScalarType tol=1e-8)
Factory function to create a VanishingStress material for a beam material with two zero normal stress...
Definition: vanishingstress.hh:260
auto functions(Args &&... args)
Creates a Functions object.
Definition: nonlinearoperator.hh:127
NonLinearOperator(const Impl::Functions< DerivativeArgs &&... > &a, const Impl::Parameter< ParameterArgs... > &b) -> NonLinearOperator< Impl::Functions< DerivativeArgs... >, Impl::Parameter< ParameterArgs... > >
auto parameter(Args &&... args)
Creates a Parameter object.
Definition: nonlinearoperator.hh:115
auto planeStress(const MaterialImpl &mat, typename MaterialImpl::ScalarType tol=1e-8)
Factory function to create a VanishingStress material for plane stress conditions.
Definition: vanishingstress.hh:233
Interface classf or materials.
Definition: finiteelements/mechanics/materials/interface.hh:80
VanishingStress material model that enforces stress components to be zero.
Definition: vanishingstress.hh:30
static constexpr auto tangentModuliTag
Tangent moduli tag.
Definition: vanishingstress.hh:45
auto rebind() const
Rebinds the material to a different scalar type.
Definition: vanishingstress.hh:128
static constexpr double derivativeFactorImpl
Derivative factor.
Definition: vanishingstress.hh:51
static constexpr auto fixedPairs
Array of fixed stress components.
Definition: vanishingstress.hh:34
static constexpr std::string nameImpl() noexcept
Definition: vanishingstress.hh:62
typename Underlying::MaterialParameters MaterialParameters
Definition: vanishingstress.hh:32
VanishingStress(MI mat, typename MI::ScalarType tol=1e-12)
Constructor for VanishingStress.
Definition: vanishingstress.hh:58
static constexpr auto strainTag
Strain tag.
Definition: vanishingstress.hh:43
static constexpr auto freeVoigtIndices
Free Voigt indices.
Definition: vanishingstress.hh:35
MaterialParameters materialParametersImpl() const
Returns the material parameters stored in the material.
Definition: vanishingstress.hh:73
static constexpr bool isAutoDiff
Definition: vanishingstress.hh:41
static constexpr bool energyAcceptsVoigt
Energy accepts Voigt notation.
Definition: vanishingstress.hh:46
ScalarType storedEnergyImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the stored energy for the VanishingStress material.
Definition: vanishingstress.hh:82
MI Underlying
The underlying material type.
Definition: vanishingstress.hh:31
auto stressesImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the stresses for the VanishingStress material.
Definition: vanishingstress.hh:95
typename Underlying::ScalarType ScalarType
Scalar type.
Definition: vanishingstress.hh:40
static constexpr bool moduliToVoigt
Moduli to Voigt notation.
Definition: vanishingstress.hh:49
static constexpr bool stressToVoigt
Stress to Voigt notation.
Definition: vanishingstress.hh:47
auto tangentModuliImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the tangent moduli for the VanishingStress material.
Definition: vanishingstress.hh:113
static constexpr auto fixedDiagonalVoigtIndicesSize
Number of fixed diagonal indices.
Definition: vanishingstress.hh:37
static constexpr auto freeStrains
Number of free strains.
Definition: vanishingstress.hh:39
static constexpr auto stressTag
Stress tag.
Definition: vanishingstress.hh:44
static constexpr bool stressAcceptsVoigt
Stress accepts Voigt notation.
Definition: vanishingstress.hh:48
static constexpr auto fixedVoigtIndices
Fixed Voigt indices.
Definition: vanishingstress.hh:36
static constexpr bool moduliAcceptsVoigt
Moduli accepts Voigt notation.
Definition: vanishingstress.hh:50
Concept to check if the underlying scalar type is a dual type.
Definition: concepts.hh:608
Contains the Material interface class and related template functions for material properties.