version 0.4
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// SPDX-License-Identifier: LGPL-3.0-or-later
11
12#pragma once
13
17
18namespace Ikarus {
19
20 namespace Impl {
21
25 struct StressIndexPair {
26 Eigen::Index row;
27 Eigen::Index col;
28 };
29
36 template <size_t size>
37 consteval auto createfreeVoigtIndices(const std::array<StressIndexPair, size>& fixed) {
38 std::array<size_t, 6 - size> res{};
39 std::array<size_t, size> voigtFixedIndices;
40 std::ranges::transform(fixed, voigtFixedIndices.begin(), [](auto pair) { return toVoigt(pair.row, pair.col); });
41 std::ranges::sort(voigtFixedIndices);
42 std::ranges::set_difference(std::ranges::iota_view(size_t(0), size_t(6)), voigtFixedIndices, res.begin());
43 std::ranges::sort(res);
44 return res;
45 }
46
53 template <size_t size>
54 consteval auto createFixedVoigtIndices(const std::array<StressIndexPair, size>& fixed) {
55 std::array<size_t, size> fixedIndices;
56 std::ranges::transform(fixed, fixedIndices.begin(), [](auto pair) { return toVoigt(pair.row, pair.col); });
57 std::ranges::sort(fixedIndices);
58 return fixedIndices;
59 }
60
67 template <size_t size>
68 constexpr size_t countDiagonalIndices(const std::array<StressIndexPair, size>& fixed) {
69 size_t count = 0;
70 for (auto v : fixed) {
71 if (v.col == v.row) ++count;
72 }
73 return count;
74 }
75
76 } // namespace Impl
77
84 template <auto stressIndexPair, typename MaterialImpl>
85 struct VanishingStress : public Material<VanishingStress<stressIndexPair, MaterialImpl>> {
91 explicit VanishingStress(MaterialImpl mat, typename MaterialImpl::ScalarType p_tol = 1e-12)
92 : matImpl{mat}, tol{p_tol} {}
93
94 using Underlying = MaterialImpl;
95
96 static constexpr auto fixedPairs = stressIndexPair;
97 static constexpr auto freeVoigtIndices = createfreeVoigtIndices(fixedPairs);
98 static constexpr auto fixedVoigtIndices = createFixedVoigtIndices(fixedPairs);
99 static constexpr auto fixedDiagonalVoigtIndicesSize
100 = countDiagonalIndices(fixedPairs);
101 static constexpr auto freeStrains = freeVoigtIndices.size();
102 using ScalarType = typename MaterialImpl::ScalarType;
103
104 [[nodiscard]] constexpr std::string nameImpl() const noexcept {
105 auto matName = matImpl.name() + "_Vanishing(";
106 for (auto p : fixedPairs)
107 matName += "(" + std::to_string(p.row) + std::to_string(p.col) + ")";
108 matName += ")";
109 return matName;
110 }
111
112 static constexpr auto strainTag = MaterialImpl::strainTag;
113 static constexpr auto stressTag = MaterialImpl::stressTag;
114 static constexpr auto tangentModuliTag = MaterialImpl::tangentModuliTag;
115 static constexpr bool energyAcceptsVoigt = MaterialImpl::energyAcceptsVoigt;
116 static constexpr bool stressToVoigt = true;
117 static constexpr bool stressAcceptsVoigt = true;
118 static constexpr bool moduliToVoigt = true;
119 static constexpr bool moduliAcceptsVoigt = true;
120 static constexpr double derivativeFactor = 1;
121
128 template <typename Derived>
129 ScalarType storedEnergyImpl(const Eigen::MatrixBase<Derived>& E) const {
130 const auto [nonOp, Esol] = reduceStress(E);
131 return matImpl.storedEnergyImpl(Esol);
132 }
133
141 template <bool voigt, typename Derived>
142 auto stressesImpl(const Eigen::MatrixBase<Derived>& E) const {
143 const auto [nonOp, Esol] = reduceStress(E);
144 auto stressesRed = matImpl.template stresses<MaterialImpl::strainTag, true>(Esol);
145
146 if constexpr (voigt) {
147 return removeCol(stressesRed, fixedVoigtIndices);
148 } else
149 return fromVoigt(stressesRed, false);
150 }
151
159 template <bool voigt, typename Derived>
160 auto tangentModuliImpl(const Eigen::MatrixBase<Derived>& E) const {
161 const auto [nonOp, Esol] = reduceStress(E);
162 auto C = matImpl.template tangentModuli<MaterialImpl::strainTag, true>(Esol);
163 if constexpr (voigt)
165 else
166 return fromVoigt(C);
167 }
168
174 template <typename ScalarTypeOther>
175 auto rebind() const {
176 auto reboundMatImpl = matImpl.template rebind<ScalarTypeOther>();
178 }
179
180 private:
187 template <typename Derived>
188 decltype(auto) maybeFromVoigt(const Eigen::MatrixBase<Derived>& E) const {
189 if constexpr (Concepts::EigenVector<Derived>) { // receiving vector means Voigt notation
190 return fromVoigt(E.derived(), true);
191 } else
192 return E.derived();
193 }
194
200 template <typename Derived>
201 void initUnknownStrains(Eigen::MatrixBase<Derived>& E) const {
202 for (size_t i = 0; i < fixedPairs.size(); ++i) {
203 ScalarType initialVal = E(fixedPairs[i].row, fixedPairs[i].col);
205 if (Dune::FloatCmp::eq(initialVal, ScalarType(0.0)) and (fixedPairs[i].row == fixedPairs[i].col))
206 initialVal = ScalarType(1.0);
207 }
208 if (fixedPairs[i].row != fixedPairs[i].col) initialVal = ScalarType(0.0);
209 E(fixedPairs[i].row, fixedPairs[i].col) = E(fixedPairs[i].col, fixedPairs[i].row) = initialVal;
210 }
211 }
212
219 template <typename Derived>
220 auto reduceStress(const Eigen::MatrixBase<Derived>& p_Eraw) const {
221 auto E = maybeFromVoigt(p_Eraw);
222 initUnknownStrains(E);
223
224 std::array<size_t, fixedDiagonalVoigtIndicesSize> fixedDiagonalVoigtIndices;
225 for (size_t ri = 0; auto i : fixedVoigtIndices) {
226 auto indexPair = fromVoigt(i);
227 if (indexPair[0] == indexPair[1]) fixedDiagonalVoigtIndices[ri++] = i;
228 }
229
230 auto f = [&](auto&) {
231 auto S = matImpl.template stresses<MaterialImpl::strainTag, true>(E);
232 return S(fixedDiagonalVoigtIndices).eval();
233 };
234 auto df = [&](auto&) {
235 auto moduli = (matImpl.template tangentModuli<MaterialImpl::strainTag, true>(E)).eval();
236 return (moduli(fixedDiagonalVoigtIndices, fixedDiagonalVoigtIndices) / MaterialImpl::derivativeFactor).eval();
237 };
238
239 auto Er = E(fixedDiagonalVoigtIndices, fixedDiagonalVoigtIndices).eval().template cast<ScalarType>();
240 auto nonOp = Ikarus::NonLinearOperator(functions(f, df), parameter(Er));
242 nonOp, [&](auto& r, auto& A) { return (A.inverse() * r).eval(); },
243 [&](auto& /* Ex33 */, auto& Ecomps) {
244 for (int ri = 0; auto i : fixedDiagonalVoigtIndices) {
245 auto indexPair = fromVoigt(i);
246 E(indexPair[0], indexPair[1]) += Ecomps(ri++);
247 }
248 });
249 nr->setup({.tol = tol, .maxIter = 100});
250 if (!static_cast<bool>(nr->solve()))
251 DUNE_THROW(Dune::MathError, "The stress reduction of material " << nameImpl() << " was unsuccessful\n"
252 << "The strains are\n"
253 << E << "\n The stresses are\n"
254 << f(Er));
255 return std::make_pair(nonOp, E);
256 }
257
258 MaterialImpl matImpl;
259 double tol{};
260 };
261
270 template <Impl::StressIndexPair... stressIndexPair, typename MaterialImpl>
271 auto makeVanishingStress(MaterialImpl mat, typename MaterialImpl::ScalarType p_tol = 1e-12) {
272 return VanishingStress<std::to_array({stressIndexPair...}), MaterialImpl>(mat, p_tol);
273 }
274
282 template <typename MaterialImpl>
283 auto planeStress(const MaterialImpl& mat, typename MaterialImpl::ScalarType p_tol = 1e-8) {
284 return makeVanishingStress<Impl::StressIndexPair{2, 1}, Impl::StressIndexPair{2, 0}, Impl::StressIndexPair{2, 2}>(
285 mat, p_tol);
286 }
287
296 template <typename MaterialImpl>
297 auto shellMaterial(const MaterialImpl& mat, typename MaterialImpl::ScalarType p_tol = 1e-8) {
298 return makeVanishingStress<Impl::StressIndexPair{2, 2}>(mat, p_tol);
299 }
300
309 template <typename MaterialImpl>
310 auto beamMaterial(const MaterialImpl& mat, typename MaterialImpl::ScalarType p_tol = 1e-8) {
311 return makeVanishingStress<Impl::StressIndexPair{1, 1}, Impl::StressIndexPair{2, 2}>(mat, p_tol);
312 }
313} // namespace Ikarus
Provides a NonLinearOperator class for handling nonlinear operators.
Contains the Material interface class and related template functions for material properties.
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:495
auto removeCol(const Eigen::MatrixBase< Derived > &E, const std::array< size_t, sizeOfRemovedCols > &indices)
Removes specified columns from a matrix.
Definition: linearalgebrahelper.hh:523
auto fromVoigt(const Eigen::Vector< ST, size > &EVoigt, bool isStrain=true)
Converts a vector given in Voigt notation to a matrix.
Definition: tensorutils.hh:256
Definition: simpleassemblers.hh:21
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:271
auto makeNewtonRaphson(const NonLinearOperatorImpl &p_nonLinearOperator, LinearSolver &&p_linearSolver={}, UpdateFunctionType &&p_updateFunction={})
Function to create a NewtonRaphson solver instance.
Definition: newtonraphson.hh:156
auto shellMaterial(const MaterialImpl &mat, typename MaterialImpl::ScalarType p_tol=1e-8)
Factory function to create a VanishingStress material for a shell material with zero normal stress co...
Definition: vanishingstress.hh:297
auto planeStress(const MaterialImpl &mat, typename MaterialImpl::ScalarType p_tol=1e-8)
Factory function to create a VanishingStress material for plane stress conditions.
Definition: vanishingstress.hh:283
auto beamMaterial(const MaterialImpl &mat, typename MaterialImpl::ScalarType p_tol=1e-8)
Factory function to create a VanishingStress material for a beam material with two zero normal stress...
Definition: vanishingstress.hh:310
auto functions(Args &&... args)
Creates a Functions object.
Definition: nonlinearoperator.hh:126
auto parameter(Args &&... args)
Creates a Parameter object.
Definition: nonlinearoperator.hh:114
Interface classf or materials.
Definition: interface.hh:75
VanishingStress material model that enforces stress components to be zero.
Definition: vanishingstress.hh:85
typename MaterialImpl::ScalarType ScalarType
Scalar type.
Definition: vanishingstress.hh:102
auto stressesImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the stresses for the VanishingStress material.
Definition: vanishingstress.hh:142
static constexpr auto strainTag
Strain tag.
Definition: vanishingstress.hh:112
static constexpr auto fixedVoigtIndices
Fixed Voigt indices.
Definition: vanishingstress.hh:98
static constexpr auto stressTag
Stress tag.
Definition: vanishingstress.hh:113
static constexpr bool stressToVoigt
Stress to Voigt notation.
Definition: vanishingstress.hh:116
static constexpr auto freeVoigtIndices
Free Voigt indices.
Definition: vanishingstress.hh:97
constexpr std::string nameImpl() const noexcept
Definition: vanishingstress.hh:104
static constexpr auto freeStrains
Number of free strains.
Definition: vanishingstress.hh:101
static constexpr auto fixedDiagonalVoigtIndicesSize
Number of fixed diagonal indices.
Definition: vanishingstress.hh:100
auto tangentModuliImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the tangent moduli for the VanishingStress material.
Definition: vanishingstress.hh:160
static constexpr bool moduliAcceptsVoigt
Moduli accepts Voigt notation.
Definition: vanishingstress.hh:119
static constexpr bool energyAcceptsVoigt
Energy accepts Voigt notation.
Definition: vanishingstress.hh:115
static constexpr auto fixedPairs
Array of fixed stress components.
Definition: vanishingstress.hh:96
static constexpr double derivativeFactor
Derivative factor.
Definition: vanishingstress.hh:120
VanishingStress(MaterialImpl mat, typename MaterialImpl::ScalarType p_tol=1e-12)
Constructor for VanishingStress.
Definition: vanishingstress.hh:91
ScalarType storedEnergyImpl(const Eigen::MatrixBase< Derived > &E) const
Computes the stored energy for the VanishingStress material.
Definition: vanishingstress.hh:129
static constexpr bool moduliToVoigt
Moduli to Voigt notation.
Definition: vanishingstress.hh:118
auto rebind() const
Rebinds the material to a different scalar type.
Definition: vanishingstress.hh:175
static constexpr auto tangentModuliTag
Tangent moduli tag.
Definition: vanishingstress.hh:114
static constexpr bool stressAcceptsVoigt
Stress accepts Voigt notation.
Definition: vanishingstress.hh:117
MaterialImpl Underlying
The underlying material type.
Definition: vanishingstress.hh:94
Represents a NonLinearOperator class for handling nonlinear operators.
Definition: nonlinearoperator.hh:154
Concept defining the requirements for Eigen vectors.
Definition: concepts.hh:381