version 0.4.1
mixin.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#include <dune/common/tuplevector.hh>
13
15
16namespace Ikarus {
26template <typename PreFE, template <typename, typename> class... Skills>
27struct FEMixin : Skills<PreFE, typename PreFE::template FE<Skills...>>...
28{
34 explicit FEMixin(typename Skills<PreFE, typename PreFE::template FE<Skills...>>::Pre&&... skillsArgs)
35 : Skills<PreFE, typename PreFE::template FE<Skills...>>(
36 std::forward<typename Skills<PreFE, typename PreFE::template FE<Skills...>>::Pre>(skillsArgs))... {}
37
44 template <template <typename, typename> class Skill>
45 static consteval bool hasSkill() {
46 return Ikarus::traits::hasType<Skill<PreFE, typename PreFE::template FE<Skills...>>,
47 std::tuple<Skills<PreFE, typename PreFE::template FE<Skills...>>...>>::value;
48 }
49
50private:
51 template <typename T>
52 consteval static auto computeSupportedResultTypes() {
53 if constexpr (requires { typename T::SupportedResultTypes; })
54 return typename T::SupportedResultTypes();
55 else
56 return std::tuple();
57 }
58
59public:
64 decltype(std::tuple_cat(computeSupportedResultTypes<Skills<PreFE, typename PreFE::template FE<Skills...>>>()...));
65
68 using LocalView = typename Traits::LocalView;
69 static constexpr int worldDim = Traits::worlddim;
70
78 friend auto calculateScalar(const FEMixin& self, const FERequirementType& par) {
79 return self.template calculateScalarImpl<double>(par);
80 }
81
89 friend void calculateVector(const FEMixin& self, const FERequirementType& par,
90 typename Traits::template VectorType<> force) {
91 self.template calculateVectorImpl<double>(par, force);
92 }
93
101 friend void calculateMatrix(const FEMixin& self, const FERequirementType& par,
102 typename Traits::template MatrixType<> K) {
103 self.template calculateMatrixImpl<double>(par, K);
104 }
105
106 using Skills<PreFE, typename PreFE::template FE<Skills...>>::calculateAtImpl...;
107
116 template <template <typename, int, int> class RT>
117 requires requires(FEMixin m, const FERequirementType& req, const Dune::FieldVector<double, Traits::mydim>& local) {
118 m.template calculateAtImpl<RT>(req, local, Dune::PriorityTag<10>());
119 }
121 return this->template calculateAtImpl<RT>(req, local, Dune::PriorityTag<10>());
122 }
123
124private:
125 template <typename Sk>
126 auto invokeBind() {
127 if constexpr (requires { this->Sk::bindImpl(); })
128 Sk::bindImpl();
129 }
130
131 static constexpr bool implementsCalculateScalarImpl =
132 (requires(FEMixin m, const FERequirementType& par,
133 const std::optional<std::reference_wrapper<const Eigen::VectorX<double>>>& dx) {
134 m.Skills<PreFE, typename PreFE::template FE<Skills...>>::calculateScalarImpl(par, dx);
135 } ||
136 ...);
137
138public:
142 void bind() { (invokeBind<Skills<PreFE, typename PreFE::template FE<Skills...>>>(), ...); }
143
152 template <typename ScalarType = double>
153 requires implementsCalculateScalarImpl
155 const FERequirementType& par,
156 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
157 return (Skills<PreFE, typename PreFE::template FE<Skills...>>::template calculateScalarImpl<ScalarType>(par, dx) +
158 ... + ScalarType{0});
159 }
160
161private:
162 static constexpr bool implementsCalculateVectorImpl =
163 (requires(FEMixin m, const FERequirementType& par, typename Traits::template VectorType<double> force,
164 const std::optional<std::reference_wrapper<const Eigen::VectorX<double>>>& dx) {
165 m.Skills<PreFE, typename PreFE::template FE<Skills...>>::calculateVectorImpl(par, force, dx);
166 } ||
167 ...);
168
169public:
178 template <typename ScalarType>
179 requires implementsCalculateVectorImpl
181 const FERequirementType& par, typename Traits::template VectorType<ScalarType> force,
182 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
183 (Skills<PreFE, typename PreFE::template FE<Skills...>>::template calculateVectorImpl<ScalarType>(par, force, dx),
184 ...);
185 }
186
187private:
188 static constexpr bool implementsCalculateMatrixImpl =
189 (requires(FEMixin m, const FERequirementType& par, typename Traits::template MatrixType<double> K,
190 const std::optional<std::reference_wrapper<const Eigen::VectorX<double>>>& dx) {
191 m.Skills<PreFE, typename PreFE::template FE<Skills...>>::calculateMatrixImpl(par, K, dx);
192 } ||
193 ...);
194
195public:
204 template <typename ScalarType>
205 requires implementsCalculateMatrixImpl
207 const FERequirementType& par, typename Traits::template MatrixType<ScalarType> K,
208 const std::optional<std::reference_wrapper<const Eigen::VectorX<ScalarType>>>& dx = std::nullopt) const {
209 (Skills<PreFE, typename PreFE::template FE<Skills...>>::template calculateMatrixImpl<ScalarType>(par, K, dx), ...);
210 }
211
212protected:
218 const auto& underlying() const { return static_cast<const typename PreFE::template FE<Skills...>&>(*this); }
224 auto& underlying() { return static_cast<typename PreFE::template FE<Skills...>&>(*this); }
225};
226
232template <typename... ARGS>
233struct Skills
234{
235 using Args = std::tuple<ARGS...>;
237};
238
246template <typename... Args>
247auto skills(const Args&... args) {
248 return Skills<std::remove_cvref_t<Args>...>{std::forward_as_tuple(std::remove_cvref_t<Args>(args)...)};
249}
250
260template <typename... Args1, typename... Args2>
261auto merge(const Skills<Args1...>& sk1, const Skills<Args2...>& sk2) {
262 return Skills<std::remove_cvref_t<Args1>..., std::remove_cvref_t<Args2>...>{std::tuple_cat(sk1.args, sk2.args)};
263}
264
265} // namespace Ikarus
FETraits template structure for finite element traits.
Definition: simpleassemblers.hh:22
auto merge(const Skills< Args1... > &sk1, const Skills< Args2... > &sk2)
Function to merge two Skills instances.
Definition: mixin.hh:261
auto skills(const Args &... args)
Function to create a Skills instance with the given skills.
Definition: mixin.hh:247
FE class is a base class for all finite elements.
Definition: febase.hh:81
PreFE struct acts as a convenient wrapper for the FE class to access different type traits.
Definition: febase.hh:34
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
static constexpr int worlddim
Dimension of the world space.
Definition: fetraits.hh:64
CRTP mixin class for finite elements with additional skills.
Definition: mixin.hh:28
FEMixin(typename Skills< PreFE, typename PreFE::template FE< Skills... > >::Pre &&... skillsArgs)
Constructor for the FEMixin class.
Definition: mixin.hh:34
static constexpr int worldDim
Definition: mixin.hh:69
friend auto calculateScalar(const FEMixin &self, const FERequirementType &par)
Calculate the scalar value associated with the given FERequirementType.
Definition: mixin.hh:78
friend void calculateMatrix(const FEMixin &self, const FERequirementType &par, typename Traits::template MatrixType<> K)
Calculate the matrix associated with the given FERequirementType.
Definition: mixin.hh:101
auto calculateAt(const FERequirementType &req, const Dune::FieldVector< double, Traits::mydim > &local) const
Calculate the element values at a specific location for a given ResultType.
Definition: mixin.hh:120
void calculateVectorImpl(const FERequirementType &par, typename Traits::template VectorType< ScalarType > force, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Calculate the vector for each skill.
Definition: mixin.hh:180
auto & underlying()
Get a reference to the underlying finite element object.
Definition: mixin.hh:224
void calculateMatrixImpl(const FERequirementType &par, typename Traits::template MatrixType< ScalarType > K, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Calculate the matrix for each skill.
Definition: mixin.hh:206
const auto & underlying() const
Get a reference to the underlying finite element object.
Definition: mixin.hh:218
typename Traits::FERequirementType FERequirementType
Definition: mixin.hh:67
static consteval bool hasSkill()
Checks if the mixin class has a specific skill.
Definition: mixin.hh:45
void bind()
Call all bind functions if the skill implements it.
Definition: mixin.hh:142
decltype(std::tuple_cat(computeSupportedResultTypes< Skills< PreFE, typename PreFE::template FE< Skills... > > >()...)) SupportedResultTypes
Type alias for the supported result types by the mixin.
Definition: mixin.hh:64
typename Traits::LocalView LocalView
Definition: mixin.hh:68
auto calculateScalarImpl(const FERequirementType &par, const std::optional< std::reference_wrapper< const Eigen::VectorX< ScalarType > > > &dx=std::nullopt) const
Calculate the scalar value in each skill and joins them by +.
Definition: mixin.hh:154
friend void calculateVector(const FEMixin &self, const FERequirementType &par, typename Traits::template VectorType<> force)
Calculate the vector associated with the given FERequirementType.
Definition: mixin.hh:89
Struct representing a collection of skills.
Definition: mixin.hh:234
std::tuple< ARGS... > Args
Definition: mixin.hh:235
Args args
Definition: mixin.hh:236
Definition: utils/dirichletvalues.hh:30
Type trait to check if a specified type is present in a tuple.
Definition: traits.hh:81