version 0.4.1
volume.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/localfefunctions/derivativetransformators.hh>
7#include <dune/localfefunctions/meta.hh>
8
12
13namespace Ikarus {
14
15template <typename PreFE, typename FE>
16class VolumeLoad;
17
22template <int wd>
24{
25 static constexpr int worldDim = wd;
26 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)> volumeLoad;
27
28 template <typename PreFE, typename FE>
30};
31
32// Deduction guide
33template <class F>
35
44template <typename PreFE, typename FE>
46{
47public:
50 static constexpr int worldDim = Traits::worlddim;
52
58 explicit VolumeLoad(const Pre& pre = {})
59 : volumeLoad_{pre.volumeLoad} {}
60
61protected:
62 template <template <typename, int, int> class RT>
63 requires Dune::AlwaysFalse<RT<double, 1, 1>>::value
65 Dune::PriorityTag<0>) const {}
66
67 template <typename ST>
69 const FERequirementType& par,
70 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const -> ST {
71 if (not volumeLoad_)
72 return 0.0;
73 ST energy = 0.0;
74 const auto uFunction = underlying().displacementFunction(par, dx);
75 const auto geo = underlying().geometry();
76 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
77
78 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
79 const auto uVal = uFunction.evaluate(gpIndex);
80 Eigen::Vector<double, worldDim> fext = volumeLoad_(geo.global(gp.position()), lambda);
81 energy -= uVal.dot(fext) * geo.integrationElement(gp.position()) * gp.weight();
82 }
83 return energy;
84 }
85
86 template <typename ST>
88 const FERequirementType& par, typename Traits::template VectorType<ST> force,
89 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {
90 if (not volumeLoad_)
91 return;
92 using namespace Dune::DerivativeDirections;
93 using namespace Dune;
94 const auto uFunction = underlying().displacementFunction(par, dx);
95 const auto geo = underlying().geometry();
96 const auto& lambda = par.getParameter(Ikarus::FEParameter::loadfactor);
97
98 for (const auto& [gpIndex, gp] : uFunction.viewOverIntegrationPoints()) {
99 const Eigen::Vector<double, worldDim> fext = volumeLoad_(geo.global(gp.position()), lambda);
100 const double intElement = geo.integrationElement(gp.position()) * gp.weight();
101 for (size_t i = 0; i < underlying().numberOfNodes(); ++i) {
102 const auto udCi = uFunction.evaluateDerivative(gpIndex, wrt(coeff(i)));
103 force.template segment<worldDim>(worldDim * i) -= udCi * fext * intElement;
104 }
105 }
106 }
107
108 template <typename ST>
110 const FERequirementType& par, typename Traits::template MatrixType<> K,
111 const std::optional<std::reference_wrapper<const Eigen::VectorX<ST>>>& dx = std::nullopt) const {}
112
113private:
114 std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&, const double&)> volumeLoad_;
115 //> CRTP
116 const auto& underlying() const { return static_cast<const FE&>(*this); }
117 auto& underlying() { return static_cast<FE&>(*this); }
118};
119
126template <int worldDim>
127auto volumeLoad(const std::function<Eigen::Vector<double, worldDim>(const Dune::FieldVector<double, worldDim>&,
128 const double&)>& f) {
129 VolumeLoadPre pre(f);
130 return pre;
131}
132
138template <typename F>
139auto volumeLoad(F&& f) {
140 VolumeLoadPre pre(f);
141 return pre;
142}
143
144} // namespace Ikarus
Several concepts.
Contains stl-like type traits.
Definition of the LinearElastic class for finite element mechanics computations.
Definition: simpleassemblers.hh:22
auto volumeLoad(const std::function< Eigen::Vector< double, worldDim >(const Dune::FieldVector< double, worldDim > &, const double &)> &f)
A helper function to create a volume load skill.
Definition: volume.hh:127
VolumeLoadPre(F f) -> VolumeLoadPre< traits::FunctionTraits< F >::return_type::RowsAtCompileTime >
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
static constexpr int worlddim
Dimension of the world space.
Definition: fetraits.hh:64
VolumeLoad class represents distributed volume load that can be applied.
Definition: volume.hh:46
auto calculateScalarImpl(const FERequirementType &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const -> ST
Definition: volume.hh:68
VolumeLoad(const Pre &pre={})
Constructor for the Loads class.
Definition: volume.hh:58
static constexpr int worldDim
Definition: volume.hh:50
void calculateMatrixImpl(const FERequirementType &par, typename Traits::template MatrixType<> K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ST > > > &dx=std::nullopt) const
Definition: volume.hh:109
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: volume.hh:87
typename Traits::FERequirementType FERequirementType
Definition: volume.hh:49
::value auto calculateAtImpl(const FERequirementType &req, const Dune::FieldVector< double, Traits::mydim > &local, Dune::PriorityTag< 0 >) const
Definition: volume.hh:64
A PreFE struct for volume load skill.
Definition: volume.hh:24
std::function< Eigen::Vector< double, worldDim >(const Dune::FieldVector< double, worldDim > &, const double &)> volumeLoad
Definition: volume.hh:26
static constexpr int worldDim
Definition: volume.hh:25
Definition: utils/dirichletvalues.hh:30