version 0.4.8
feresulttypes.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2021-2026 The Ikarus Developers ikarus@ibb.uni-stuttgart.de
2// SPDX-License-Identifier: LGPL-3.0-or-later
3
4#pragma once
5
6#include <type_traits>
7
8#include <Eigen/Core>
9
11
18namespace Ikarus {
19namespace Impl {
20
21 template <bool strainlike = false>
22 struct VectorizeWithVoigt
23 {
24 template <typename Derived>
25 static auto transform(const Eigen::DenseBase<Derived>& mat) {
26 return toVoigt(mat.derived(), strainlike);
27 }
28 };
29
30 struct VectorizeGeneric
31 {
32 template <typename Derived>
33 static auto transform(const Eigen::DenseBase<Derived>& mat) {
34 return mat.derived().reshaped().eval();
35 }
36 };
37
38 template <bool strainlike = false>
39 struct MatricizeWithVoigt
40 {
41 template <typename Derived, int RowsAtCompileTime, int ColsAtCompileTime>
42 static auto transform(const Eigen::DenseBase<Derived>& vec, int rows = RowsAtCompileTime,
43 int cols = ColsAtCompileTime) {
44 assert(rows == RowsAtCompileTime && cols == ColsAtCompileTime &&
45 "Only the fixed size values work for voigt matrices and vectors");
46 static_assert(RowsAtCompileTime != Eigen::Dynamic and ColsAtCompileTime != Eigen::Dynamic,
47 "Voigt notation only available for fixed size vectors and matrices");
48 return fromVoigt(vec.derived(), strainlike);
49 }
50 };
51
52 struct MatricizeGeneric
53 {
54 template <typename Derived, int RowsAtCompileTime, int ColsAtCompileTime>
55 static auto transform(const Eigen::DenseBase<Derived>& vec, int rows = RowsAtCompileTime,
56 int cols = ColsAtCompileTime) {
57 return vec.derived().reshaped(Eigen::fix<RowsAtCompileTime>(rows), Eigen::fix<ColsAtCompileTime>(cols)).eval();
58 }
59 };
60
61} // namespace Impl
62
63namespace ResultTypes {
64#define REGISTER_RESULTTYPE_IMPL(resultTypeName, rowsExpr, colsExpr, MaxRowsExpr, MaxColsExpr, VectorizeStruct, \
65 MatricizeStruct) \
66 template <typename ScalarType, int gridDim, int worldDim> \
67 struct resultTypeName \
68 { \
69 friend std::string toString(resultTypeName) { return #resultTypeName; } \
70 \
71 using type = Eigen::Matrix<ScalarType, rowsExpr, colsExpr, 0, MaxRowsExpr, MaxColsExpr>; \
72 using Vectorizer = VectorizeStruct; \
73 using Matricizer = MatricizeStruct; \
74 \
75 template <typename ScalarType_, int gridDim_, int worldDim_> \
76 using Rebind = resultTypeName<ScalarType_, gridDim_, worldDim_>; \
77 }
78
86#define REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(resultTypeName, rowsExpr, colsExpr, strainlike) \
87 REGISTER_RESULTTYPE_IMPL(resultTypeName, rowsExpr, colsExpr, rowsExpr, colsExpr, \
88 Ikarus::Impl::VectorizeWithVoigt<strainlike>, Ikarus::Impl::MatricizeWithVoigt<strainlike>)
89
97#define REGISTER_RESULTTYPE(resultTypeName, rowsExpr, colsExpr) \
98 REGISTER_RESULTTYPE_IMPL(resultTypeName, rowsExpr, colsExpr, Ikarus::Impl::VectorizeGeneric, \
99 Ikarus::Impl::MatricizeGeneric)
109#define REGISTER_RESERVED_RESULTTYPE(resultTypeName, rowsExpr, colsExpr, MaxRowsExpr, MaxColsExpr) \
110 REGISTER_RESULTTYPE_IMPL(resultTypeName, rowsExpr, colsExpr, MaxRowsExpr, MaxColsExpr, \
111 Ikarus::Impl::VectorizeGeneric, Ikarus::Impl::MatricizeGeneric)
119#define REGISTER_SIMPLE_RESULTTYPE(resultTypeName, rowsExpr, colsExpr) \
120 REGISTER_RESERVED_RESULTTYPE(resultTypeName, rowsExpr, colsExpr, rowsExpr, colsExpr)
121
124
125 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(linearStress, worldDim, worldDim, false);
126 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(PK2Stress, worldDim, worldDim, false);
127 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(kirchhoffStress, worldDim, worldDim, false);
128 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(cauchyStress, worldDim, worldDim, false);
129
130 // The following resulttypes are for reduced materials to obtain the full 3D stress state
131 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(linearStressFull, 3, 3, false);
132 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(PK2StressFull, 3, 3, false);
133 REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(cauchyStressFull, 3, 3, false);
134
135 REGISTER_SIMPLE_RESULTTYPE(director, worldDim, 1);
136 REGISTER_SIMPLE_RESULTTYPE(magnetization, worldDim, 1);
137 REGISTER_SIMPLE_RESULTTYPE(gradientNormOfMagnetization, 1, 1);
138 REGISTER_SIMPLE_RESULTTYPE(vectorPotential, worldDim, 1);
139 REGISTER_SIMPLE_RESULTTYPE(divergenceOfVectorPotential, 1, 1);
140
141 REGISTER_SIMPLE_RESULTTYPE(BField, worldDim, 1);
142 REGISTER_SIMPLE_RESULTTYPE(HField, worldDim, 1);
143
144 REGISTER_SIMPLE_RESULTTYPE(cauchyAxialForce, 1, 1);
145 REGISTER_SIMPLE_RESULTTYPE(PK2AxialForce, 1, 1);
146 REGISTER_SIMPLE_RESULTTYPE(linearAxialForce, 1, 1);
147
148 REGISTER_SIMPLE_RESULTTYPE(customType, Eigen::Dynamic, Eigen::Dynamic);
149} // namespace ResultTypes
150
151enum class ResultShape
152{
153 Vector,
154 Matrix
155};
156
163template <typename RT, ResultShape storedResultShape = ResultShape::Vector>
164struct ResultWrapper : RT
165{
166private:
167 using ResultTypeValueType = typename RT::type;
168 static constexpr Eigen::Index rowsAtCompileTime = ResultTypeValueType::RowsAtCompileTime;
169 static constexpr Eigen::Index colsAtCompileTime = ResultTypeValueType::ColsAtCompileTime;
170 static constexpr bool storedValueIsVector = storedResultShape == ResultShape::Vector;
171
172public:
173 using VecType = std::invoke_result_t<decltype(&RT::Vectorizer::template transform<ResultTypeValueType>),
174 const ResultTypeValueType&>;
175 using MatType =
176 std::invoke_result_t<decltype(&RT::Matricizer::template transform<VecType, rowsAtCompileTime, colsAtCompileTime>),
177 const VecType&, int, int>;
178 using StoredType = std::conditional_t<storedValueIsVector, VecType, MatType>;
179 using ResultType = RT;
180
185 auto asVec() const {
186 if constexpr (storedValueIsVector)
187 return value_;
188 else
189 return RT::Vectorizer::transform(value_);
190 }
191
198 auto asMat(Eigen::Index rows = rowsAtCompileTime, Eigen::Index cols = colsAtCompileTime) const {
199 if constexpr (storedValueIsVector) {
200 if constexpr (rowsAtCompileTime == Eigen::Dynamic)
201 assert(rows != rowsAtCompileTime &&
202 "For dynamic size result types you have to pass rows by hand, since it is not clear how the result "
203 "should be reshaped");
204 if constexpr (colsAtCompileTime == Eigen::Dynamic)
205 assert(cols != colsAtCompileTime &&
206 "For dynamic size result types you have to pass cols by hand, since it is not clear how the result "
207 "should be reshaped");
208 return RT::Matricizer::template transform<VecType, rowsAtCompileTime, colsAtCompileTime>(value_, rows, cols);
209 } else
210 return value_;
211 }
212 explicit ResultWrapper() = default;
213 explicit ResultWrapper(StoredType&& value) { this->value_ = std::move(value); }
214 explicit ResultWrapper(const StoredType& value) { this->value_ = value; }
216 this->value_ = value;
217 return *this;
218 }
220 this->value_ = std::move(value);
221 return *this;
222 }
223
224private:
225 StoredType value_{};
226};
227
228namespace Impl {
229 template <template <typename, int, int> class RT>
230 using DummyRT = RT<double, 1, 1>;
231}
232
238template <template <typename, int, int> class RT>
239auto makeRT() {
240 return Impl::DummyRT<RT>{};
241}
242
248template <template <typename, int, int> class RT>
249auto toString() {
250 return toString(Impl::DummyRT<RT>{});
251}
252
258template <template <typename, int, int> class RT1, template <typename, int, int> class RT2>
259constexpr static bool isSameResultType = std::is_same_v<Impl::DummyRT<RT1>, Impl::DummyRT<RT2>>;
260
261namespace Impl {
262 template <typename T, typename Tuple>
263 struct hasType;
264
265 template <typename T, typename... Us>
266 struct hasType<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...>
267 {
268 };
269} // namespace Impl
270
276template <template <typename, int, int> typename... ResultTypes>
278{
283 template <template <typename, int, int> typename RT>
284 static consteval bool supportsResultType() {
285 return Impl::hasType<decltype(makeRT<RT>()), SupportedResultTypes>::value;
286 }
287
288 using SupportedResultTypes = std::tuple<decltype(makeRT<ResultTypes>())...>;
289};
290
291} // namespace Ikarus
Helper for the Eigen::Tensor types.
auto fromVoigt(const Eigen::Matrix< ST, size, 1, Options, maxSize, 1 > &EVoigt, bool isStrain=true)
Converts a vector given in Voigt notation to a matrix.
Definition: tensorutils.hh:296
constexpr Eigen::Index toVoigt(Eigen::Index i, Eigen::Index j) noexcept
Converts 2D indices to Voigt notation index.
Definition: tensorutils.hh:182
Definition: assemblermanipulatorbuildingblocks.hh:22
auto makeRT()
Creates a dummy resultType which can be stored in a variable.
Definition: feresulttypes.hh:239
static constexpr bool isSameResultType
Meta variable to test whether two ResultType templates are the same.
Definition: feresulttypes.hh:259
ResultShape
Definition: feresulttypes.hh:152
constexpr std::string toString(DBCOption _e)
Definition: dirichletbcenforcement.hh:8
REGISTER_SIMPLE_SYMMETRIC_RESULTTYPE(linearStress, worldDim, worldDim, false)
REGISTER_SIMPLE_RESULTTYPE(director, worldDim, 1)
Container that is used for FE Results. It gives access to the stored value, but can also be used to a...
Definition: feresulttypes.hh:165
std::conditional_t< storedValueIsVector, VecType, MatType > StoredType
Definition: feresulttypes.hh:178
std::invoke_result_t< decltype(&RT::Matricizer::template transform< VecType, rowsAtCompileTime, colsAtCompileTime >), const VecType &, int, int > MatType
Definition: feresulttypes.hh:177
ResultWrapper(StoredType &&value)
Definition: feresulttypes.hh:213
ResultWrapper & operator=(StoredType &&value)
Definition: feresulttypes.hh:219
std::invoke_result_t< decltype(&RT::Vectorizer::template transform< ResultTypeValueType >), const ResultTypeValueType & > VecType
Definition: feresulttypes.hh:174
ResultWrapper & operator=(const StoredType &value)
Definition: feresulttypes.hh:215
auto asVec() const
Returns the stored value as Vector.
Definition: feresulttypes.hh:185
ResultWrapper(const StoredType &value)
Definition: feresulttypes.hh:214
auto asMat(Eigen::Index rows=rowsAtCompileTime, Eigen::Index cols=colsAtCompileTime) const
Returns the stored value as Matrix (if possible)
Definition: feresulttypes.hh:198
RT ResultType
Definition: feresulttypes.hh:179
Base class for element definitions that provides common functionality for ResultTypes.
Definition: feresulttypes.hh:278
std::tuple< decltype(makeRT< ResultTypes >())... > SupportedResultTypes
Definition: feresulttypes.hh:288
static consteval bool supportsResultType()
Returns whether a ResultType is provided by the element.
Definition: feresulttypes.hh:284