version 0.4.1
linearelastic.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#if HAVE_DUNE_LOCALFEFUNCTIONS
13
14 #include <optional>
15 #include <type_traits>
16
17 #include <dune/geometry/quadraturerules.hh>
18 #include <dune/localfefunctions/expressions/linearStrainsExpr.hh>
19 #include <dune/localfefunctions/impl/standardLocalFunction.hh>
20
26
27namespace Ikarus {
28
29template <typename PreFE, typename FE, typename PRE>
30class LinearElastic;
31
36template <Concepts::GeometricallyLinearMaterial MAT>
38{
39 using Material = MAT;
41
42 template <typename PreFE, typename FE>
44};
45
54template <typename PreFE, typename FE, typename PRE>
55class LinearElastic : public ResultTypeBase<ResultTypes::linearStress, ResultTypes::linearStressFull>
56{
57public:
60 using FlatBasis = typename Traits::FlatBasis;
63 using LocalView = typename Traits::LocalView;
64 using Geometry = typename Traits::Geometry;
65 using GridView = typename Traits::GridView;
66 using Element = typename Traits::Element;
67 using Material = PRE::Material;
68 using Pre = PRE;
69
70 static constexpr int myDim = Traits::mydim;
71 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
72
77 explicit LinearElastic(const Pre& pre)
78 : mat_{pre.material} {}
79
80protected:
84 void bindImpl() {
85 const auto& localView = underlying().localView();
86 const auto& element = localView.element();
87 auto& firstChild = localView.tree().child(0);
88 const auto& fe = firstChild.finiteElement();
89 geo_ = std::make_shared<const Geometry>(element.geometry());
90 numberOfNodes_ = fe.size();
91 order_ = 2 * (fe.localBasis().order());
92 localBasis_ = Dune::CachedLocalBasis(fe.localBasis());
93 if constexpr (requires { element.impl().getQuadratureRule(order_); })
94 if (element.impl().isTrimmed())
95 localBasis_.bind(element.impl().getQuadratureRule(order_), Dune::bindDerivatives(0, 1));
96 else
97 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_),
98 Dune::bindDerivatives(0, 1));
99 else
100 localBasis_.bind(Dune::QuadratureRules<double, myDim>::rule(element.type(), order_), Dune::bindDerivatives(0, 1));
101 }
102
103public:
112 template <typename ScalarType = double>
114 const Requirement& par,
115 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
116 const auto& d = par.globalSolution();
117 auto disp = Ikarus::FEHelper::localSolutionBlockVector<Traits>(d, underlying().localView(), dx);
118 Dune::StandardLocalFunction uFunction(localBasis_, disp, geo_);
119 return uFunction;
120 }
130 template <class ScalarType = double>
132 const Requirement& par,
133 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
134 return Dune::linearStrains(displacementFunction(par, dx));
135 }
136
142 auto materialTangent() const {
143 // Since that material is independent of the strains, a zero strain is passed here
144 return mat_.template tangentModuli<StrainTags::linear, true>(Eigen::Vector<double, 6>::Zero());
145 }
146
153 auto materialTangentFunction([[maybe_unused]] const Requirement& par) const {
154 return [&]([[maybe_unused]] auto gp) { return materialTangent(); };
155 }
156
157 const Geometry& geometry() const { return *geo_; }
158 [[nodiscard]] size_t numberOfNodes() const { return numberOfNodes_; }
159 [[nodiscard]] int order() const { return order_; }
160
161 template <typename ScalarType = double>
162 decltype(auto) material() const {
164 return mat_.template rebind<ScalarType>();
165 else
166 return mat_;
167 }
168
169public:
180 template <template <typename, int, int> class RT>
181 requires(supportsResultType<RT>())
183 Dune::PriorityTag<1>) const {
185
186 if constexpr (isSameResultType<RT, ResultTypes::linearStress> or
187 isSameResultType<RT, ResultTypes::linearStressFull>) {
188 const auto eps = strainFunction(req);
189 auto epsVoigt = eps.evaluate(local, Dune::on(Dune::DerivativeDirections::gridElement));
190 decltype(auto) mat = [&]() {
191 if constexpr (isSameResultType<RT, ResultTypes::linearStressFull> and requires { mat_.underlying(); })
192 return mat_.underlying();
193 else
194 return mat_;
195 }();
196 return RTWrapper{mat.template stresses<StrainTags::linear>(enlargeIfReduced<Material>(epsVoigt))};
197 }
198 }
199
200private:
201 //> CRTP
202 const auto& underlying() const { return static_cast<const FE&>(*this); }
203 auto& underlying() { return static_cast<FE&>(*this); }
204
205 std::shared_ptr<const Geometry> geo_;
206 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis_;
207 Material mat_;
208 size_t numberOfNodes_{0};
209 int order_{};
210
211protected:
212 template <typename ScalarType>
214 const Requirement& par, const MatrixAffordance& affordance, typename Traits::template MatrixType<> K,
215 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
216 const auto eps = strainFunction(par, dx);
217 using namespace Dune::DerivativeDirections;
218 using namespace Dune;
219
220 const auto C = materialTangent();
221 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
222 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
223 for (size_t i = 0; i < numberOfNodes_; ++i) {
224 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
225 for (size_t j = 0; j < numberOfNodes_; ++j) {
226 const auto bopJ = eps.evaluateDerivative(gpIndex, wrt(coeff(j)), on(gridElement));
227 K.template block<myDim, myDim>(i * myDim, j * myDim) += bopI.transpose() * C * bopJ * intElement;
228 }
229 }
230 }
231 }
232
233 template <typename ScalarType>
235 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx =
236 std::nullopt) const -> ScalarType {
237 const auto uFunction = displacementFunction(par, dx);
238 const auto eps = strainFunction(par, dx);
239 const auto& lambda = par.parameter();
240 using namespace Dune::DerivativeDirections;
241 using namespace Dune;
242
243 const auto C = materialTangent();
244
245 ScalarType energy = 0.0;
246 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
247 const auto EVoigt = eps.evaluate(gpIndex, on(gridElement));
248 energy += (0.5 * EVoigt.dot(C * EVoigt)) * geo_->integrationElement(gp.position()) * gp.weight();
249 }
250 return energy;
251 }
252
253 template <typename ScalarType>
255 const Requirement& par, VectorAffordance affordance, typename Traits::template VectorType<ScalarType> force,
256 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
257 const auto eps = strainFunction(par, dx);
258 using namespace Dune::DerivativeDirections;
259 using namespace Dune;
260
261 const auto C = materialTangent();
262
263 // Internal forces
264 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
265 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
266 auto stresses = (C * eps.evaluate(gpIndex, on(gridElement))).eval();
267 for (size_t i = 0; i < numberOfNodes_; ++i) {
268 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
269 force.template segment<myDim>(myDim * i) += bopI.transpose() * stresses * intElement;
270 }
271 }
272 }
273};
274
281template <typename MAT>
282auto linearElastic(const MAT& mat) {
283 LinearElasticPre<MAT> pre(mat);
284
285 return pre;
286}
287} // namespace Ikarus
288
289#else
290 #error LinearElastic depends on dune-localfefunctions, which is not included
291#endif
Definitions of ResultTypes used for finite element results.
Definition of the LinearElastic class for finite element mechanics computations.
Material property functions and conversion utilities.
Definition: assemblermanipulatorbuildingblocks.hh:22
MatrixAffordance
A strongly typed enum class representing the matrix affordance.
Definition: ferequirements.hh:63
VectorAffordance
A strongly typed enum class representing the vector affordance.
Definition: ferequirements.hh:48
ScalarAffordance
A strongly typed enum class representing the scalar affordance.
Definition: ferequirements.hh:37
auto linearElastic(const MAT &mat)
A helper function to create a linear elastic pre finite element.
Definition: linearelastic.hh:282
Definition: utils/dirichletvalues.hh:30
FE class is a base class for all finite elements.
Definition: febase.hh:79
FETraits< BH, useEigenRef, useFlat > Traits
Definition: febase.hh:38
Class representing the requirements for finite element calculations.
Definition: ferequirements.hh:252
SolutionVectorReturnType globalSolution()
Get the global solution vector.
Definition: ferequirements.hh:308
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
BH BasisHandler
Type of the basis of the finite element.
Definition: fetraits.hh:27
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
LinearElastic class represents a linear elastic finite element.
Definition: linearelastic.hh:56
void bindImpl()
A helper function to bind the local view to the element.
Definition: linearelastic.hh:84
static constexpr int myDim
Definition: linearelastic.hh:70
auto materialTangent() const
Gets the material tangent matrix for the linear elastic material.
Definition: linearelastic.hh:142
typename Traits::Element Element
Definition: linearelastic.hh:66
auto materialTangentFunction(const Requirement &par) const
Gets the material tangent function for the given Requirement.
Definition: linearelastic.hh:153
PRE Pre
Definition: linearelastic.hh:68
auto calculateScalarImpl(const Requirement &par, ScalarAffordance affordance, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const -> ScalarType
Definition: linearelastic.hh:234
size_t numberOfNodes() const
Definition: linearelastic.hh:158
int order() const
Definition: linearelastic.hh:159
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: linearelastic.hh:182
void calculateVectorImpl(const Requirement &par, VectorAffordance affordance, typename Traits::template VectorType< ScalarType > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Definition: linearelastic.hh:254
typename Traits::GridView GridView
Definition: linearelastic.hh:65
typename Traits::BasisHandler BasisHandler
Definition: linearelastic.hh:59
typename Traits::LocalView LocalView
Definition: linearelastic.hh:63
typename Traits::FlatBasis FlatBasis
Definition: linearelastic.hh:60
void calculateMatrixImpl(const Requirement &par, const MatrixAffordance &affordance, typename Traits::template MatrixType<> K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Definition: linearelastic.hh:213
auto displacementFunction(const Requirement &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Gets the displacement function for the given Requirement and optional displacement vector.
Definition: linearelastic.hh:113
LinearElastic(const Pre &pre)
Constructor for the LinearElastic class.
Definition: linearelastic.hh:77
PRE::Material Material
Definition: linearelastic.hh:67
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: linearelastic.hh:71
decltype(auto) material() const
Definition: linearelastic.hh:162
typename Traits::Geometry Geometry
Definition: linearelastic.hh:64
const Geometry & geometry() const
Definition: linearelastic.hh:157
auto strainFunction(const Requirement &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Gets the strain function for the given Requirement and optional di splacement vector.
Definition: linearelastic.hh:131
A PreFE struct for linear elastic elements.
Definition: linearelastic.hh:38
MAT Material
Definition: linearelastic.hh:39
MAT material
Definition: linearelastic.hh:40
Definition: utils/dirichletvalues.hh:32
Concept to check if the underlying scalar type is a dual type.
Definition: concepts.hh:608
Header file for material models in Ikarus finite element mechanics.