version 0.4
finiteelements/mechanics/linearelastic.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#if HAVE_DUNE_LOCALFEFUNCTIONS
13
14# include <iosfwd>
15# include <optional>
16# include <type_traits>
17
18# include <dune/fufem/boundarypatch.hh>
19# include <dune/geometry/quadraturerules.hh>
20# include <dune/localfefunctions/expressions/linearStrainsExpr.hh>
21# include <dune/localfefunctions/impl/standardLocalFunction.hh>
22# include <dune/localfefunctions/manifolds/realTuple.hh>
23
32
33namespace Ikarus {
34
44 template <typename Basis_, typename FERequirements_ = FERequirements<>, bool useEigenRef = false>
45 class LinearElastic : public PowerBasisFE<typename Basis_::FlatBasis>,
46 public Volume<LinearElastic<Basis_, FERequirements_, useEigenRef>,
47 TraitsFromFE<Basis_, FERequirements_, useEigenRef>>,
48 public Traction<LinearElastic<Basis_, FERequirements_, useEigenRef>,
49 TraitsFromFE<Basis_, FERequirements_, useEigenRef>> {
50 public:
52 using Basis = typename Traits::Basis;
53 using FlatBasis = typename Traits::FlatBasis;
55 using LocalView = typename Traits::LocalView;
56 using Geometry = typename Traits::Geometry;
57 using GridView = typename Traits::GridView;
58 using Element = typename Traits::Element;
60 using BaseDisp = PowerBasisFE<FlatBasis>; // Handles globalIndices function
63 static constexpr int myDim = Traits::mydim;
64 using LocalBasisType = decltype(std::declval<LocalView>().tree().child(0).finiteElement().localBasis());
65
79 template <typename VolumeLoad = utils::LoadDefault, typename NeumannBoundaryLoad = utils::LoadDefault>
80 LinearElastic(const Basis& globalBasis, const typename LocalView::Element& element, double emod, double nu,
81 VolumeLoad p_volumeLoad = {}, const BoundaryPatch<GridView>* p_neumannBoundary = nullptr,
82 NeumannBoundaryLoad p_neumannBoundaryLoad = {})
83 : BaseDisp(globalBasis.flat(), element),
84 VolumeType(p_volumeLoad),
85 TractionType(p_neumannBoundary, p_neumannBoundaryLoad),
86 emod_{emod},
87 nu_{nu} {
88 this->localView().bind(element);
89 auto& first_child = this->localView().tree().child(0);
90 const auto& fe = first_child.finiteElement();
91 geo_ = std::make_shared<const Geometry>(this->localView().element().geometry());
92 numberOfNodes_ = fe.size();
93 order_ = 2 * (fe.localBasis().order());
94 localBasis = Dune::CachedLocalBasis(fe.localBasis());
95 if constexpr (requires { this->localView().element().impl().getQuadratureRule(order_); })
96 if (this->localView().element().impl().isTrimmed())
97 localBasis.bind(this->localView().element().impl().getQuadratureRule(order_), Dune::bindDerivatives(0, 1));
98 else
99 localBasis.bind(Dune::QuadratureRules<double, myDim>::rule(this->localView().element().type(), order_),
100 Dune::bindDerivatives(0, 1));
101 else
102 localBasis.bind(Dune::QuadratureRules<double, myDim>::rule(this->localView().element().type(), order_),
103 Dune::bindDerivatives(0, 1));
104 }
113 template <typename ScalarType = double>
115 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
116 const auto& d = par.getGlobalSolution(Ikarus::FESolutions::displacement);
117 auto disp = Ikarus::FEHelper::localSolutionBlockVector<Traits>(d, this->localView(), dx);
118 Dune::StandardLocalFunction uFunction(localBasis, disp, geo_);
119 return uFunction;
120 }
129 template <class ScalarType = double>
131 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
132 return Dune::linearStrains(displacementFunction(par, dx));
133 }
134
140 auto materialTangent() const {
141 if constexpr (myDim == 2)
143 else if constexpr (myDim == 3)
144 return linearElasticMaterialTangent3D(emod_, nu_);
145 }
146
153 auto materialTangentFunction([[maybe_unused]] const FERequirementType& 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
167 inline double calculateScalar(const FERequirementType& par) const { return calculateScalarImpl<double>(par); }
168
175 inline void calculateVector(const FERequirementType& par, typename Traits::template VectorType<> force) const {
176 calculateVectorImpl<double>(par, force);
177 }
178
185 void calculateMatrix(const FERequirementType& par, typename Traits::template MatrixType<> K) const {
186 const auto eps = strainFunction(par);
187 using namespace Dune::DerivativeDirections;
188 using namespace Dune;
189
190 const auto C = materialTangent();
191 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
192 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
193 for (size_t i = 0; i < numberOfNodes_; ++i) {
194 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
195 for (size_t j = 0; j < numberOfNodes_; ++j) {
196 const auto bopJ = eps.evaluateDerivative(gpIndex, wrt(coeff(j)), on(gridElement));
197 K.template block<myDim, myDim>(i * myDim, j * myDim) += bopI.transpose() * C * bopJ * intElement;
198 }
199 }
200 }
201
202 // Update due to displacement-dependent external loads, e.g., follower loads
205 }
206
215 ResultTypeMap<double>& result) const {
216 using namespace Dune::Indices;
217 using namespace Dune::DerivativeDirections;
218 using namespace Dune;
219
220 const auto eps = strainFunction(req.getFERequirements());
221 const auto C = materialTangent();
222 auto epsVoigt = eps.evaluate(local, on(gridElement));
223
224 auto linearStress = (C * epsVoigt).eval();
225
226 if (req.isResultRequested(ResultType::linearStress))
228 else
229 DUNE_THROW(Dune::NotImplemented, "The requested result type is NOT implemented.");
230 }
231
232 private:
233 std::shared_ptr<const Geometry> geo_;
234 Dune::CachedLocalBasis<std::remove_cvref_t<LocalBasisType>> localBasis;
235 double emod_;
236 double nu_;
237 size_t numberOfNodes_{0};
238 int order_{};
239
240 protected:
241 template <typename ScalarType>
242 auto calculateScalarImpl(const FERequirementType& par, const std::optional<const Eigen::VectorX<ScalarType>>& dx
243 = std::nullopt) const -> ScalarType {
244 const auto uFunction = displacementFunction(par, dx);
245 const auto eps = strainFunction(par, dx);
246 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
247 using namespace Dune::DerivativeDirections;
248 using namespace Dune;
249
250 const auto C = materialTangent();
251
252 ScalarType energy = 0.0;
253 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
254 const auto EVoigt = eps.evaluate(gpIndex, on(gridElement));
255 energy += (0.5 * EVoigt.dot(C * EVoigt)) * geo_->integrationElement(gp.position()) * gp.weight();
256 }
257
258 // External forces volume forces over the domain
259 energy += VolumeType::calculateScalarImpl(par, dx);
260
261 // line or surface loads, i.e., neumann boundary
262 energy += TractionType::calculateScalarImpl(par, dx);
263 return energy;
264 }
265
266 template <typename ScalarType>
267 void calculateVectorImpl(const FERequirementType& par, typename Traits::template VectorType<ScalarType> force,
268 const std::optional<const Eigen::VectorX<ScalarType>>& dx = std::nullopt) const {
269 const auto eps = strainFunction(par, dx);
270 using namespace Dune::DerivativeDirections;
271 using namespace Dune;
272
273 const auto C = materialTangent();
274
275 // Internal forces
276 for (const auto& [gpIndex, gp] : eps.viewOverIntegrationPoints()) {
277 const double intElement = geo_->integrationElement(gp.position()) * gp.weight();
278 auto stresses = (C * eps.evaluate(gpIndex, on(gridElement))).eval();
279 for (size_t i = 0; i < numberOfNodes_; ++i) {
280 const auto bopI = eps.evaluateDerivative(gpIndex, wrt(coeff(i)), on(gridElement));
281 force.template segment<myDim>(myDim * i) += bopI.transpose() * stresses * intElement;
282 }
283 }
284
285 // External forces volume forces over the domain
286 VolumeType::calculateVectorImpl(par, force, dx);
287
288 // External forces, boundary forces, i.e., at the Neumann boundary
289 TractionType::calculateVectorImpl(par, force, dx);
290 }
291 };
292} // namespace Ikarus
293
294#else
295# error LinearElastic depends on dune-localfefunctions, which is not included
296#endif
Collection of fallback default functions.
Helper for the autodiff library.
Contains the PowerBasisFE class, which works with a power basis in FlatInterLeaved elements.
Material property functions and conversion utilities.
Definition of the LinearElastic class for finite element mechanics computations.
Header file for material models in Ikarus finite element mechanics.
Header file for types of loads in Ikarus finite element mechanics.
Definition: simpleassemblers.hh:21
Eigen::Matrix3d planeStressLinearElasticMaterialTangent(double E, double nu)
Computes the plane stress linear elastic material tangent matrix.
Definition: physicshelper.hh:29
Eigen::Matrix< double, 6, 6 > linearElasticMaterialTangent3D(double E, double nu)
Computes the 3D linear elastic material tangent matrix.
Definition: physicshelper.hh:50
Definition: resultevaluators.hh:17
PowerBasisFE class for working with a power basis in FlatInterLeaved elements.
Definition: powerbasisfe.hh:23
const GridElement & gridElement() const
Get the grid element associated with the local view.
Definition: powerbasisfe.hh:78
const LocalView & localView() const
Get the const reference to the local view.
Definition: powerbasisfe.hh:84
Class representing a map of result types to result arrays.
Definition: ferequirements.hh:342
void insertOrAssignResult(ResultType &&resultType, const ResultArray &resultArray)
Insert or assign a result to the map.
Definition: ferequirements.hh:354
LinearElastic class represents a linear elastic finite element.
Definition: finiteelements/mechanics/linearelastic.hh:49
typename Traits::Geometry Geometry
Definition: finiteelements/mechanics/linearelastic.hh:56
decltype(std::declval< LocalView >().tree().child(0).finiteElement().localBasis()) LocalBasisType
Definition: finiteelements/mechanics/linearelastic.hh:64
static constexpr int myDim
Definition: finiteelements/mechanics/linearelastic.hh:63
auto materialTangentFunction(const FERequirementType &par) const
Gets the material tangent function for the given FERequirementType.
Definition: finiteelements/mechanics/linearelastic.hh:153
int order() const
Definition: finiteelements/mechanics/linearelastic.hh:159
auto calculateScalarImpl(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const -> ScalarType
Definition: finiteelements/mechanics/linearelastic.hh:242
typename Traits::GridView GridView
Definition: finiteelements/mechanics/linearelastic.hh:57
void calculateVector(const FERequirementType &par, typename Traits::template VectorType<> force) const
Calculates the vector force for the given FERequirementType.
Definition: finiteelements/mechanics/linearelastic.hh:175
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: finiteelements/mechanics/linearelastic.hh:267
PowerBasisFE< FlatBasis > BaseDisp
Definition: finiteelements/mechanics/linearelastic.hh:60
typename Traits::FERequirementType FERequirementType
Definition: finiteelements/mechanics/linearelastic.hh:54
void calculateAt(const ResultRequirementsType &req, const Dune::FieldVector< double, Traits::mydim > &local, ResultTypeMap< double > &result) const
Calculates results at a specific local position.
Definition: finiteelements/mechanics/linearelastic.hh:214
typename Traits::LocalView LocalView
Definition: finiteelements/mechanics/linearelastic.hh:55
Traction< LinearElastic< Basis_, FERequirements_, useEigenRef >, Traits > TractionType
Definition: finiteelements/mechanics/linearelastic.hh:62
auto displacementFunction(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Gets the displacement function for the given FERequirementType and optional displacement vector.
Definition: finiteelements/mechanics/linearelastic.hh:114
auto strainFunction(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Gets the strain function for the given FERequirementType and optional displacement vector.
Definition: finiteelements/mechanics/linearelastic.hh:130
LinearElastic(const Basis &globalBasis, const typename LocalView::Element &element, double emod, double nu, VolumeLoad p_volumeLoad={}, const BoundaryPatch< GridView > *p_neumannBoundary=nullptr, NeumannBoundaryLoad p_neumannBoundaryLoad={})
Constructor for the LinearElastic class.
Definition: finiteelements/mechanics/linearelastic.hh:80
void calculateMatrix(const FERequirementType &par, typename Traits::template MatrixType<> K) const
Calculates the matrix stiffness for the given FERequirementType.
Definition: finiteelements/mechanics/linearelastic.hh:185
const Geometry & geometry() const
Definition: finiteelements/mechanics/linearelastic.hh:157
typename Traits::ResultRequirementsType ResultRequirementsType
Definition: finiteelements/mechanics/linearelastic.hh:59
typename Traits::FlatBasis FlatBasis
Definition: finiteelements/mechanics/linearelastic.hh:53
size_t numberOfNodes() const
Definition: finiteelements/mechanics/linearelastic.hh:158
typename Traits::Basis Basis
Definition: finiteelements/mechanics/linearelastic.hh:52
auto materialTangent() const
Gets the material tangent matrix for the linear elastic material.
Definition: finiteelements/mechanics/linearelastic.hh:140
typename Traits::Element Element
Definition: finiteelements/mechanics/linearelastic.hh:58
double calculateScalar(const FERequirementType &par) const
Calculates the scalar energy for the given FERequirementType.
Definition: finiteelements/mechanics/linearelastic.hh:167
Volume< LinearElastic< Basis_, FERequirements_, useEigenRef >, Traits > VolumeType
Definition: finiteelements/mechanics/linearelastic.hh:61
Traction class represents distributed traction load that can be applied.
Definition: traction.hh:22
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< const Eigen::VectorX< ScalarType > > dx=std::nullopt) const
Definition: traction.hh:112
auto calculateScalarImpl(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const -> ScalarType
Definition: traction.hh:80
void calculateMatrix(const FERequirementType &req, typename Traits::template MatrixType<> K) const
Calculate the matrix associated with the given FERequirementType.
Definition: traction.hh:74
Volume class represents distributed volume load that can be applied.
Definition: volume.hh:20
auto calculateScalarImpl(const FERequirementType &par, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const -> ScalarType
Definition: volume.hh:71
void calculateMatrix(const FERequirementType &req, typename Traits::template MatrixType<> K) const
Calculate the matrix associated with the given FERequirementType.
Definition: volume.hh:65
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< const Eigen::VectorX< ScalarType > > &dx=std::nullopt) const
Definition: volume.hh:88
Traits for handling finite elements.see https://en.wikipedia.org/wiki/Lam%C3%A9_parameters.
Definition: physicshelper.hh:68
typename LocalView::Element Element
Type of the grid element.
Definition: physicshelper.hh:88
typename FlatBasis::LocalView LocalView
Type of the local view.
Definition: physicshelper.hh:82
typename Basis::FlatBasis FlatBasis
Type of the flat basis.
Definition: physicshelper.hh:79
ResultRequirements< FERequirementType > ResultRequirementsType
Type of the result requirements.
Definition: physicshelper.hh:76
Basis_ Basis
Type of the basis of the finite element.
Definition: physicshelper.hh:70
static constexpr int mydim
Dimension of the geometry.
Definition: physicshelper.hh:97
typename FlatBasis::GridView GridView
Type of the grid view.
Definition: physicshelper.hh:85
FERequirements_ FERequirementType
Type of the requirements for the finite element.
Definition: physicshelper.hh:73
typename Element::Geometry Geometry
Type of the element geometry.
Definition: physicshelper.hh:91
Definition: resultevaluators.hh:20