version 0.4.7
nonlinearelastic.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
12#if HAVE_DUNE_LOCALFEFUNCTIONS
13 #include <dune/fufem/boundarypatch.hh>
14 #include <dune/geometry/quadraturerules.hh>
15 #include <dune/geometry/type.hh>
16 #include <dune/localfefunctions/cachedlocalBasis/cachedlocalBasis.hh>
17 #include <dune/localfefunctions/expressions/greenLagrangeStrains.hh>
18 #include <dune/localfefunctions/impl/standardLocalFunction.hh>
19 #include <dune/localfefunctions/manifolds/realTuple.hh>
20
32
33namespace Ikarus {
34
35template <typename PreFE, typename FE, typename PRE>
36class NonLinearElastic;
37
42template <Concepts::Material MAT>
44{
45 using Material = MAT;
47
48 template <typename PreFE, typename FE>
50};
51
61template <typename PreFE, typename FE, typename PRE>
62class NonLinearElastic : public ResultTypeBase<ResultTypes::PK2Stress, ResultTypes::PK2StressFull>
63{
64public:
66 using Basis = typename Traits::Basis;
67 using FlatBasis = typename Traits::FlatBasis;
69 using LocalView = typename Traits::LocalView;
70 using Geometry = typename Traits::Geometry;
71 using GridView = typename Traits::GridView;
72 using Element = typename Traits::Element;
73 using Material = PRE::Material;
74 using Pre = PRE;
75
76 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
77
78 template <typename ST>
79 using VectorXOptRef = std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>;
80
81 static constexpr int myDim = Traits::mydim;
82 static constexpr int strainDim = myDim * (myDim + 1) / 2;
83 static constexpr auto strainType = StrainTags::greenLagrangian;
84 static constexpr auto stressType = StressTags::PK2;
85
86 template <template <typename, int, int> class RT>
88
89 template <typename ST = double>
90 using StrainType = Eigen::Vector<ST, strainDim>;
91
92 template <typename ST = double>
93 using BopType = Eigen::Matrix<ST, strainDim, myDim>;
94
95 template <typename ST = double>
96 using KgType = Eigen::Matrix<ST, myDim, myDim>;
97
102 explicit NonLinearElastic(const Pre& pre)
103 : mat_{pre.material} {}
104
105protected:
109 void bindImpl() {
110 const auto& localView = underlying().localView();
111 const auto& element = localView.element();
112 auto& firstChild = localView.tree().child(0);
113 const auto& fe = firstChild.finiteElement();
114 geo_ = std::make_shared<const Geometry>(element.geometry());
115 numberOfNodes_ = fe.size();
116 order_ = fe.localBasis().order();
117 localBasis_ = Dune::CachedLocalBasis(fe.localBasis());
118 if (underlying().quadratureRule())
119 localBasis_.bind(underlying().quadratureRule().value(), Dune::bindDerivatives(0, 1));
120 else
121 localBasis_.bind(defaultQuadratureRule<myDim>(element, 2 * order_), Dune::bindDerivatives(0, 1));
122 }
123
124public:
133 template <typename ScalarType = double>
134 auto displacementFunction(const Requirement& par, const VectorXOptRef<ScalarType>& dx = std::nullopt) const {
135 const auto& d = par.globalSolution();
136 auto disp = Ikarus::FEHelper::localSolutionBlockVector<Traits>(d, underlying().localView(), dx);
137 Dune::StandardLocalFunction uFunction(localBasis_, disp, geo_);
138 return uFunction;
139 }
140
149 template <typename ScalarType = double>
150 inline auto strainFunction(const Requirement& par, const VectorXOptRef<ScalarType>& dx = std::nullopt) const {
151 return Dune::greenLagrangeStrains(displacementFunction(par, dx));
152 }
153
162 template <typename ScalarType, int strainDim>
163 auto internalEnergy(const Eigen::Vector<ScalarType, strainDim>& strain) const {
164 return material<ScalarType>().template storedEnergy<strainType>(strain);
165 }
166
176 template <typename ScalarType, int strainDim, bool voigt = true>
177 auto stress(const Eigen::Vector<ScalarType, strainDim>& strain) const {
178 return material<ScalarType>().template stresses<strainType, voigt>(strain);
179 }
180
190 template <typename ScalarType, int strainDim, bool voigt = true>
191 auto materialTangent(const Eigen::Vector<ScalarType, strainDim>& strain) const {
192 return material<ScalarType>().template tangentModuli<strainType, voigt>(strain);
193 }
194
195 const Geometry& geometry() const { return *geo_; }
196 [[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
197 [[nodiscard]] int order() const { return order_; }
198 const Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>>& localBasis() const { return localBasis_; }
199
200 template <typename ScalarType = double>
201 decltype(auto) material() const {
203 return mat_.template rebind<ScalarType>();
204 else
205 return mat_;
206 }
207
208public:
214 template <template <typename, int, int> class RT>
215 requires(supportsResultType<RT>())
216 auto resultFunction() const {
217 return [&](const Eigen::Vector<double, strainDim>& strainInVoigt) {
218 if constexpr (isSameResultType<RT, ResultTypes::PK2Stress> or isSameResultType<RT, ResultTypes::PK2StressFull>) {
219 decltype(auto) mat = [&]() {
220 if constexpr (isSameResultType<RT, ResultTypes::PK2StressFull> and Material::isReduced)
221 return mat_.underlying();
222 else
223 return mat_;
224 }();
225 return RTWrapperType<RT>{mat.template stresses<strainType>(enlargeIfReduced<Material>(strainInVoigt))};
226 }
227 };
228 }
229
239 template <template <typename, int, int> class RT>
240 requires(supportsResultType<RT>())
242 Dune::PriorityTag<1>) const {
243 using namespace Dune::DerivativeDirections;
244
245 if constexpr (FE::isMixed())
246 return RTWrapperType<RT>{};
247 if constexpr (isSameResultType<RT, ResultTypes::PK2Stress> or isSameResultType<RT, ResultTypes::PK2StressFull>) {
248 const auto uFunction = displacementFunction(req);
249 const auto rFunction = resultFunction<RT>();
250 const auto H = uFunction.evaluateDerivative(local, Dune::wrt(spatialAll), Dune::on(gridElement));
251 const auto E = (0.5 * (H.transpose() + H + H.transpose() * H)).eval();
252
253 return rFunction(toVoigt(E));
254 }
255 }
256
257private:
258 //> CRTP
259 const auto& underlying() const { return static_cast<const FE&>(*this); }
260 auto& underlying() { return static_cast<FE&>(*this); }
261 std::shared_ptr<const Geometry> geo_;
262 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis_;
263 Material mat_;
264 size_t numberOfNodes_{0};
265 int order_{};
266
267public:
278 template <typename ST>
279 auto geometricStiffnessMatrixFunction(const Requirement& par, typename Traits::template MatrixType<ST>& K,
280 const VectorXOptRef<ST>& dx = std::nullopt) const {
281 return [&](const FE::template KgType<ST>& kgIJ, const int I, const int J, const auto& gp) {
282 const auto geo = underlying().localView().element().geometry();
283 const double intElement = geo.integrationElement(gp.position()) * gp.weight();
284 K.template block<FE::myDim, FE::myDim>(I * FE::myDim, J * FE::myDim) += kgIJ * intElement;
285 };
286 }
297 template <typename ST>
298 auto materialStiffnessMatrixFunction(const Requirement& par, typename Traits::template MatrixType<ST>& K,
299 const VectorXOptRef<ST>& dx = std::nullopt) const {
300 return [&](const StrainType<ST>& strain, const BopType<ST>& bopI, const BopType<ST>& bopJ, const int I, const int J,
301 const auto& gp) {
302 const auto C = materialTangent(strain);
303 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
304 K.template block<myDim, myDim>(I * myDim, J * myDim) += (bopI.transpose() * C * bopJ) * intElement;
305 };
306 }
307
319 template <typename ST>
320 auto internalForcesFunction(const Requirement& par, typename Traits::template VectorType<ST>& force,
321 const VectorXOptRef<ST>& dx = std::nullopt) const {
322 return [&](const StrainType<ST>& stresses, const BopType<ST>& bopI, const int I, const auto& gp) {
323 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
324 force.template segment<myDim>(myDim * I) += bopI.transpose() * stresses * intElement;
325 };
326 }
327
336 template <typename ST>
337 auto energyFunction(const Requirement& par, const VectorXOptRef<ST>& dx = std::nullopt) const {
338 return [&]() -> ST {
339 using namespace Dune::DerivativeDirections;
340 using namespace Dune;
341 ST energy = 0.0;
342 const auto eps = strainFunction(par, dx);
343 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
344 const auto EVoigt = eps.evaluate(gpIndex, on(gridElement));
345 energy += internalEnergy(EVoigt) * geo_->integrationElement(gp.position()) * gp.weight();
346 }
347 return energy;
348 };
349 }
350
351protected:
359 template <typename ScalarType>
360 void calculateMatrixImpl(const Requirement& par, const MatrixAffordance& affordance,
361 typename Traits::template MatrixType<> K,
362 const VectorXOptRef<ScalarType>& dx = std::nullopt) const {
363 if constexpr (FE::isMixed())
364 return;
365 using namespace Dune::DerivativeDirections;
366 using namespace Dune;
367 const auto uFunction = displacementFunction(par, dx);
368 const auto eps = strainFunction(par, dx);
369 const auto kMFunction = materialStiffnessMatrixFunction<ScalarType>(par, K, dx);
370 const auto kGFunction = geometricStiffnessMatrixFunction<ScalarType>(par, K, dx);
371 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
372 const auto EVoigt = (eps.evaluate(gpIndex, on(gridElement))).eval();
373 const auto stresses = stress(EVoigt);
374 for (size_t i = 0; i < numberOfNodes_; ++i) {
375 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
376 for (size_t j = 0; j < numberOfNodes_; ++j) {
377 const auto bopJ = eps.evaluateDerivative(gpIndex, wrt(coeff(j)), on(gridElement));
378 const auto kgIJ = eps.evaluateDerivative(gpIndex, wrt(coeff(i, j)), along(stresses), on(gridElement));
379 kMFunction(EVoigt, bopI, bopJ, i, j, gp);
380 kGFunction(kgIJ, i, j, gp);
381 }
382 }
383 }
384 }
385
386 template <typename ScalarType>
388 const VectorXOptRef<ScalarType>& dx = std::nullopt) const -> ScalarType {
389 if constexpr (FE::isMixed())
390 return ScalarType{0.0};
391 return energyFunction(par, dx)();
392 }
393
394 template <typename ScalarType>
396 typename Traits::template VectorType<ScalarType> force,
397 const VectorXOptRef<ScalarType>& dx = std::nullopt) const {
398 if constexpr (FE::isMixed())
399 return;
400 using namespace Dune::DerivativeDirections;
401 using namespace Dune;
402 const auto eps = strainFunction(par, dx);
403 const auto fIntFunction = internalForcesFunction<ScalarType>(par, force, dx);
404
405 // Internal forces
406 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
407 const auto EVoigt = (eps.evaluate(gpIndex, on(gridElement))).eval();
408 const auto stresses = stress(EVoigt);
409 for (size_t i = 0; i < numberOfNodes_; ++i) {
410 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
411 fIntFunction(stresses, bopI, i, gp);
412 }
413 }
414 }
415};
416
423template <Concepts::Material MAT>
424auto nonLinearElastic(const MAT& mat) {
426
427 return pre;
428}
429
430} // namespace Ikarus
431
432#else
433 #error NonLinearElastic depends on dune-localfefunctions, which is not included
434#endif
Free function for creating a tensor product quadrature rule and other Dune::Quadrature rule utils.
Collection of fallback default functions.
Helper for transform between Dune linear algebra types and Eigen.
Helper for the autodiff library.
Header file for various EAS functions.
Definition of several material related enums.
Header file for types of loads in Ikarus finite element mechanics.
Material property functions and conversion utilities.
Contains the FE class, which is used as a base class for all finite elements. It provides information...
Definition of the LinearElastic class for finite element mechanics computations.
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:182
Definition: assemblermanipulatorbuildingblocks.hh:22
MatrixAffordance
A strongly typed enum class representing the matrix affordance.
Definition: ferequirements.hh:65
auto nonLinearElastic(const MAT &mat)
A helper function to create a non-linear elastic pre finite element.
Definition: nonlinearelastic.hh:424
VectorAffordance
A strongly typed enum class representing the vector affordance.
Definition: ferequirements.hh:50
ScalarAffordance
A strongly typed enum class representing the scalar affordance.
Definition: ferequirements.hh:39
Definition: utils/dirichletvalues.hh:35
FE class is a base class for all finite elements.
Definition: febase.hh:79
static constexpr int myDim
Definition: febase.hh:95
FETraits< BH, useEigenRef, useFlat > Traits
Definition: febase.hh:38
Class representing the requirements for finite element calculations.
Definition: ferequirements.hh:224
const SolutionVectorType & globalSolution() const
Get the global solution vector.
Definition: ferequirements.hh:314
Container that is used for FE Results. It gives access to the stored value, but can also be used to a...
Definition: feresulttypes.hh:164
Base class for element definitions that provides common functionality for ResultTypes.
Definition: feresulttypes.hh:277
Traits for handling finite elements.
Definition: fetraits.hh:25
typename Basis::LocalView LocalView
Type of the local view.
Definition: fetraits.hh:42
typename Element::Geometry Geometry
Type of the element geometry.
Definition: fetraits.hh:51
std::conditional_t< useFlat, FlatBasis, UntouchedBasis > Basis
Type of the basis version.
Definition: fetraits.hh:39
typename Basis::GridView GridView
Type of the grid view.
Definition: fetraits.hh:45
typename BasisHandler::FlatBasis FlatBasis
Type of the flat basis.
Definition: fetraits.hh:33
typename LocalView::Element Element
Type of the grid element.
Definition: fetraits.hh:48
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:63
NonLinearElastic class represents a non-linear elastic finite element.
Definition: nonlinearelastic.hh:63
auto strainFunction(const Requirement &par, const VectorXOptRef< ScalarType > &dx=std::nullopt) const
The strain function for the given Requirement.
Definition: nonlinearelastic.hh:150
typename Traits::Basis Basis
Definition: nonlinearelastic.hh:66
typename Traits::Geometry Geometry
Definition: nonlinearelastic.hh:70
typename Traits::FlatBasis FlatBasis
Definition: nonlinearelastic.hh:67
Eigen::Matrix< ST, strainDim, myDim > BopType
Definition: nonlinearelastic.hh:93
auto energyFunction(const Requirement &par, const VectorXOptRef< ST > &dx=std::nullopt) const
Get a lambda function that evaluates the internal energy at a given integration point and its index.
Definition: nonlinearelastic.hh:337
PRE::Material Material
Definition: nonlinearelastic.hh:73
const Dune::CachedLocalBasis< std::remove_cvref_t< LocalBasisType > > & localBasis() const
Definition: nonlinearelastic.hh:198
std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > VectorXOptRef
Definition: nonlinearelastic.hh:79
typename Traits::GridView GridView
Definition: nonlinearelastic.hh:71
void bindImpl()
A helper function to bind the local view to the element.
Definition: nonlinearelastic.hh:109
void calculateVectorImpl(const Requirement &par, VectorAffordance affordance, typename Traits::template VectorType< ScalarType > force, const VectorXOptRef< ScalarType > &dx=std::nullopt) const
Definition: nonlinearelastic.hh:395
const Geometry & geometry() const
Definition: nonlinearelastic.hh:195
static constexpr int myDim
Definition: nonlinearelastic.hh:81
auto calculateScalarImpl(const Requirement &par, ScalarAffordance affordance, const VectorXOptRef< ScalarType > &dx=std::nullopt) const -> ScalarType
Definition: nonlinearelastic.hh:387
auto calculateAtImpl(const Requirement &req, const Dune::FieldVector< double, Traits::mydim > &local, Dune::PriorityTag< 1 >) const
Calculates a requested result at a specific local position.
Definition: nonlinearelastic.hh:241
static constexpr auto stressType
Definition: nonlinearelastic.hh:84
decltype(auto) material() const
Definition: nonlinearelastic.hh:201
NonLinearElastic(const Pre &pre)
Constructor for the NonLinearElastic class.
Definition: nonlinearelastic.hh:102
typename Traits::Element Element
Definition: nonlinearelastic.hh:72
PRE Pre
Definition: nonlinearelastic.hh:74
Eigen::Matrix< ST, myDim, myDim > KgType
Definition: nonlinearelastic.hh:96
auto geometricStiffnessMatrixFunction(const Requirement &par, typename Traits::template MatrixType< ST > &K, const VectorXOptRef< ST > &dx=std::nullopt) const
Get a lambda function that evaluates the geometric part of the stiffness matrix (Kg) for a given inte...
Definition: nonlinearelastic.hh:279
auto resultFunction() const
Get a lambda function that evaluates the requested result type for a given strain (in Voigt notation)...
Definition: nonlinearelastic.hh:216
auto materialTangent(const Eigen::Vector< ScalarType, strainDim > &strain) const
Get the material tangent for the given strain for the given Requirement.
Definition: nonlinearelastic.hh:191
static constexpr int strainDim
Definition: nonlinearelastic.hh:82
auto materialStiffnessMatrixFunction(const Requirement &par, typename Traits::template MatrixType< ST > &K, const VectorXOptRef< ST > &dx=std::nullopt) const
Get a lambda function that evaluates the material part of the stiffness matrix (Ke + Ku) for a given ...
Definition: nonlinearelastic.hh:298
auto internalEnergy(const Eigen::Vector< ScalarType, strainDim > &strain) const
Get the internal energy for the given strain.
Definition: nonlinearelastic.hh:163
static constexpr auto strainType
Definition: nonlinearelastic.hh:83
Eigen::Vector< ST, strainDim > StrainType
Definition: nonlinearelastic.hh:90
typename Traits::LocalView LocalView
Definition: nonlinearelastic.hh:69
int order() const
Definition: nonlinearelastic.hh:197
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: nonlinearelastic.hh:76
auto internalForcesFunction(const Requirement &par, typename Traits::template VectorType< ST > &force, const VectorXOptRef< ST > &dx=std::nullopt) const
Get a lambda function that evaluates the internal force vector for a given strain,...
Definition: nonlinearelastic.hh:320
auto stress(const Eigen::Vector< ScalarType, strainDim > &strain) const
Get the stress for the given strain.
Definition: nonlinearelastic.hh:177
auto displacementFunction(const Requirement &par, const VectorXOptRef< ScalarType > &dx=std::nullopt) const
Get the displacement function for the given Requirement.
Definition: nonlinearelastic.hh:134
size_t numberOfNodes() const
Definition: nonlinearelastic.hh:196
void calculateMatrixImpl(const Requirement &par, const MatrixAffordance &affordance, typename Traits::template MatrixType<> K, const VectorXOptRef< ScalarType > &dx=std::nullopt) const
Calculate the matrix associated with the given Requirement.
Definition: nonlinearelastic.hh:360
A PreFE struct for non-linear elastic elements.
Definition: nonlinearelastic.hh:44
MAT Material
Definition: nonlinearelastic.hh:45
MAT material
Definition: nonlinearelastic.hh:46
static constexpr bool isMixed()
Definition: mixin.hh:110
Definition: utils/dirichletvalues.hh:37
Concept to check if the underlying scalar type is a dual type.
Definition: utils/concepts.hh:625