version 0.4.1
traction.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
4#pragma once
5
6#include <dune/fufem/boundarypatch.hh>
7#include <dune/localfefunctions/derivativetransformators.hh>
8#include <dune/localfefunctions/meta.hh>
9
11
12namespace Ikarus {
13
14template <typename PreFE, typename FE>
15class Traction;
16
21template <typename GV>
23{
24 using GridView = GV;
25 static constexpr int worldDim = GridView::dimensionworld;
26 const BoundaryPatch<GridView>* neumannBoundary;
27
28 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)> load;
29 using BoundaryPatchType = BoundaryPatch<GridView>;
30
31 template <typename PreFE, typename FE>
33};
34
43template <typename PreFE, typename FE>
45{
46public:
49 using LocalView = typename Traits::LocalView;
50 using GridView = typename Traits::GridView;
51 static constexpr int myDim = Traits::mydim;
52 static constexpr int worldDim = Traits::worlddim;
54
60 explicit Traction(const Pre& pre)
61 : neumannBoundaryLoad_{pre.load},
62 neumannBoundary_{pre.neumannBoundary} {}
63
64protected:
65 template <template <typename, int, int> class RT>
66 requires Dune::AlwaysFalse<RT<double, 1, 1>>::value
68 Dune::PriorityTag<0>) const {}
69
70 template <typename ST>
72 const FERequirementType& par,
73 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const -> ST {
74 if (not neumannBoundary_ and not neumannBoundaryLoad_)
75 return 0.0;
76 ST energy = 0.0;
77 const auto uFunction = underlying().displacementFunction(par, dx);
78 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
79 auto& element = underlying().localView().element();
80
81 for (auto&& intersection : intersections(neumannBoundary_->gridView(), element)) {
82 if (not neumannBoundary_->contains(intersection))
83 continue;
84
85 const auto& quadLine = Dune::QuadratureRules<double, myDim - 1>::rule(intersection.type(), underlying().order());
86
87 for (const auto& curQuad : quadLine) {
88 // Local position of the quadrature point
89 const Dune::FieldVector<double, myDim>& quadPos = intersection.geometryInInside().global(curQuad.position());
90
91 const double integrationElement = intersection.geometry().integrationElement(curQuad.position());
92
93 // The value of the local function
94 const auto uVal = uFunction.evaluate(quadPos);
95
96 // Value of the Neumann data at the current position
97 auto neumannValue = neumannBoundaryLoad_(intersection.geometry().global(curQuad.position()), lambda);
98
99 energy -= neumannValue.dot(uVal) * curQuad.weight() * integrationElement;
100 }
101 }
102 return energy;
103 }
104
105 template <typename ST>
107 const FERequirementType& par, typename Traits::template VectorType<ST> force,
108 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
109 if (not neumannBoundary_ and not neumannBoundaryLoad_)
110 return;
111 using namespace Dune::DerivativeDirections;
112 using namespace Dune;
113 const auto uFunction = underlying().displacementFunction(par, dx);
114 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
115 auto& element = underlying().localView().element();
116
117 for (auto&& intersection : intersections(neumannBoundary_->gridView(), element)) {
118 if (not neumannBoundary_->contains(intersection))
119 continue;
120
122 const auto& quadLine = Dune::QuadratureRules<double, myDim - 1>::rule(intersection.type(), underlying().order());
123
124 for (const auto& curQuad : quadLine) {
125 const Dune::FieldVector<double, myDim>& quadPos = intersection.geometryInInside().global(curQuad.position());
126 const double intElement = intersection.geometry().integrationElement(curQuad.position());
127
129 for (size_t i = 0; i < underlying().numberOfNodes(); ++i) {
130 const auto udCi = uFunction.evaluateDerivative(quadPos, wrt(coeff(i)));
131
133 auto neumannValue = neumannBoundaryLoad_(intersection.geometry().global(curQuad.position()), lambda);
134 force.template segment<worldDim>(worldDim * i) -= udCi * neumannValue * curQuad.weight() * intElement;
135 }
136 }
137 }
138 }
139
140 template <typename ST>
142 const FERequirementType&, typename Traits::template MatrixType<>,
143 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& = std::nullopt) const {}
144
145private:
146 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)>
147 neumannBoundaryLoad_;
148 const BoundaryPatch<GridView>* neumannBoundary_;
149
150 //> CRTP
151 const auto& underlying() const { return static_cast<const FE&>(*this); }
152 auto& underlying() { return static_cast<FE&>(*this); }
153};
154
163template <typename GV, typename F>
164auto neumannBoundaryLoad(const BoundaryPatch<GV>* patch, F&& load) {
165 NeumannBoundaryLoadPre<GV> pre(patch, std::forward<F>(load));
166
167 return pre;
168}
169
170} // namespace Ikarus
Definition of the LinearElastic class for finite element mechanics computations.
Definition: simpleassemblers.hh:22
auto neumannBoundaryLoad(const BoundaryPatch< GV > *patch, F &&load)
A helper function to create a Neumann boundary load skill.
Definition: traction.hh:164
Definition: utils/dirichletvalues.hh:28
FE class is a base class for all finite elements.
Definition: febase.hh:81
FETraits< BH, FER, useEigenRef, useFlat > Traits
Definition: febase.hh:40
Traits for handling finite elements.
Definition: fetraits.hh:26
FER FERequirementType
Type of the requirements for the finite element.
Definition: fetraits.hh:31
typename Basis::LocalView LocalView
Type of the local view.
Definition: fetraits.hh:46
typename Basis::GridView GridView
Type of the grid view.
Definition: fetraits.hh:49
static constexpr int worlddim
Dimension of the world space.
Definition: fetraits.hh:64
static constexpr int mydim
Dimension of the geometry.
Definition: fetraits.hh:67
Traction class represents distributed traction load that can be applied.
Definition: traction.hh:45
::value auto calculateAtImpl(const FERequirementType &req, const Dune::FieldVector< double, Traits::mydim > &local, Dune::PriorityTag< 0 >) const
Definition: traction.hh:67
auto calculateScalarImpl(const FERequirementType &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const -> ST
Definition: traction.hh:71
typename Traits::LocalView LocalView
Definition: traction.hh:49
typename Traits::GridView GridView
Definition: traction.hh:50
void calculateMatrixImpl(const FERequirementType &, typename Traits::template MatrixType<>, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &=std::nullopt) const
Definition: traction.hh:141
typename Traits::FERequirementType FERequirementType
Definition: traction.hh:48
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ST > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: traction.hh:106
static constexpr int myDim
Definition: traction.hh:51
static constexpr int worldDim
Definition: traction.hh:52
Traction(const Pre &pre)
Constructor for the traction class.
Definition: traction.hh:60
A PreFE struct for Neumann boundary load skill.
Definition: traction.hh:23
static constexpr int worldDim
Definition: traction.hh:25
GV GridView
Definition: traction.hh:24
const BoundaryPatch< GridView > * neumannBoundary
Definition: traction.hh:26
BoundaryPatch< GridView > BoundaryPatchType
Definition: traction.hh:29
std::function< Eigen::Vector< double, worldDim >(const Dune::FieldVector< double, worldDim > &, const double &)> load
Definition: traction.hh:28
Definition: utils/dirichletvalues.hh:30