DUNE-ACFEM (unstable)

fieldtensor.hh
1#ifndef __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_FIELDTENSOR_HH__
2#define __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_FIELDTENSOR_HH__
3
4#include <dune/common/fvector.hh>
5#include <dune/common/fmatrix.hh>
6#include <dune/common/hybridutilities.hh>
7
8#include "../../../expressions/terminal.hh"
9#include "../../tensorbase.hh"
10#include "../../operations/assign.hh"
11#include "../../optimization/policy.hh"
12#include "fieldvectortraits.hh"
13#include "densevectorview.hh"
14
15namespace Dune {
16
17 namespace ACFem {
18
19 namespace Tensor {
20
21 template<class FV>
22 class FieldVectorTensor
23 : public TensorBase<typename FieldTraits<std::decay_t<FV> >::field_type,
24 FieldVectorSignature<FV>,
25 FieldVectorTensor<FV> >
26 , public Expressions::SelfExpression<FieldVectorTensor<FV> >
27 , public MPL::UniqueTags<ConditionalType<
28 !std::is_reference<FV>::value,
29 IndependentExpression,
30 void> >
31 {
32 using ThisType = FieldVectorTensor;
33 using DataType = FV;
34 using ArrayType = std::decay_t<FV>;
35 using BaseType = TensorBase<typename FieldTraits<ArrayType>::field_type,
36 FieldVectorSignature<ArrayType>,
37 FieldVectorTensor<FV> >;
38 public:
39 using typename BaseType::Signature;
40 using typename BaseType::FieldType;
41 using BaseType::rank;
42
46 FieldVectorTensor()
47 {}
48
49 template<class T, std::enable_if_t<SameDecay<T, ArrayType>::value, int> = 0>
50 FieldVectorTensor(T&& t)
51 : data_(std::forward<T>(t))
52 {}
53
54 template<class T,
55 std::enable_if_t<(std::is_constructible<DataType, T>::value
56 && !SameDecay<T, ArrayType>::value
57 ), int> = 0>
58 explicit FieldVectorTensor(T&& t)
59 : data_(std::forward<T>(t))
60 {}
61
63 template<class Tensor,
64 std::enable_if_t<(IsTensor<Tensor>::value
65 && !Expressions::IsClosure<Tensor>::value
66 && !std::is_const<DataType>::value
67 && !std::is_same<Tensor, FieldVectorTensor>::value
68 && std::is_same<typename Tensor::Signature, Signature>::value
69 ), int> = 0>
70 explicit FieldVectorTensor(const Tensor& other)
71 : data_(DenseVectorView<const Tensor&>(other))
72 {}
73
75 template<class T,
76 std::enable_if_t<(IsTensor<T>::value
77 && !RefersConst<DataType>::value
78 && std::is_same<Signature, typename TensorTraits<T>::Signature>::value),
79 int> = 0>
80 FieldVectorTensor& operator=(T&& other)
81 {
82 //std::clog << "Assign from " << typeString(other) << std::endl;
83 return assign(*this, std::forward<T>(other), [](auto& dst, auto&& src) { dst = src; });
84 }
85
86 FieldVectorTensor& operator=(const ArrayType& other)
87 {
88 data_ = other;
89 return *this;
90 }
91
92 template<class... Dims,
93 std::enable_if_t<(sizeof...(Dims) == rank
94 &&
95 IsIntegralPack<Dims...>::value), int> = 0>
96 decltype(auto) operator()(Dims... indices)
97 {
98 return value(data_, indices...);
99 }
100
101 template<class... Dims,
102 std::enable_if_t<(sizeof...(Dims) == rank
103 &&
104 IsIntegralPack<Dims...>::value), int> = 0>
105 const FieldType& operator()(Dims... indices) const
106 {
107 return value(data_, indices...);
108 }
109
111 template<std::size_t... Indices, std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
112 decltype(auto) constexpr operator()(Seq<Indices...>)
113 {
114 return (*this)(Indices...);
115 }
116
118 template<std::size_t... Indices, std::enable_if_t<sizeof...(Indices) == rank, int> = 0>
119 decltype(auto) constexpr operator()(Seq<Indices...>) const
120 {
121 return (*this)(Indices...);
122 }
123
124 operator DataType () &&
125 {
126 return data_;
127 }
128
129 operator ConditionalType<RefersConst<DataType>::value, DataType, ArrayType>& () &
130 {
131 return data_;
132 }
133
134 operator const ArrayType& () const&
135 {
136 return data_;
137 }
138
139 std::string name() const
140 {
141 return "FT(" + refPrefix() + name<Signature>() + ")";
142 }
143
144 private:
145 std::string refPrefix() const
146 {
147 constexpr bool isRef = std::is_lvalue_reference<DataType>::value;
148 constexpr bool isConst = std::is_const<std::remove_reference_t<DataType> >::value;
149
150 return isRef ? (isConst ? "cref" : "ref") : "";
151 }
152
153 template<class Sig, std::enable_if_t<Sig::size() == 0, int> = 0>
154 std::string name() const
155 {
156 return toString(data_);
157 }
158
159 template<class Sig, std::enable_if_t<Sig::size() == 1, int> = 0>
160 std::string name() const
161 {
162 return "[" + toString(data_) + "]";
163 }
164
165 template<class Sig, std::enable_if_t<(Sig::size() > 1), int> = 0>
166 std::string name() const
167 {
168 return "<" + toString(Sig{}) + ">";
169 }
170
171 template<class Data>
172 FieldType& value(Data& data)
173 {
174 return data;
175 }
176 template<class Data>
177 const FieldType& value(const Data& data)
178 {
179 return data;
180 }
181 template<class Data>
182 const FieldType& value(const Data& data) const
183 {
184 return data;
185 }
186
187 template<int Dim>
188 FieldType& value(FieldVector<FieldType, Dim>& data, const std::size_t& index)
189 {
190 return data[index];
191 }
192 template<int Dim>
193 const FieldType& value(const FieldVector<FieldType, Dim>& data, const std::size_t& index)
194 {
195 return data[index];
196 }
197 template<int Dim>
198 const FieldType& value(const FieldVector<FieldType, Dim>& data, const std::size_t& index) const
199 {
200 return data[index];
201 }
202
203 template<int rows, int cols>
204 FieldType& value(FieldMatrix<FieldType, rows, cols>& data, const std::size_t& i, const std::size_t& j)
205 {
206 return data[i][j];
207 }
208 template<int rows, int cols>
209 const FieldType& value(const FieldMatrix<FieldType, rows, cols>& data, const std::size_t& i, const std::size_t& j)
210 {
211 return data[i][j];
212 }
213 template<int rows, int cols>
214 const FieldType& value(const FieldMatrix<FieldType, rows, cols>& data, const std::size_t& i, const std::size_t& j) const
215 {
216 return data[i][j];
217 }
218
219 template<class Data, class... Dims>
220 FieldType& value(Data& data, const std::size_t& index0, Dims... rest)
221 {
222 return value(data[index0], rest...);
223 }
224 template<class Data, class... Dims>
225 const FieldType& value(const Data& data, const std::size_t& index0, Dims... rest)
226 {
227 return value(data[index0], rest...);
228 }
229 template<class Data, class... Dims>
230 const FieldType& value(const Data& data, const std::size_t& index0, Dims... rest) const
231 {
232 return value(data[index0], rest...);
233 }
234
235 DataType data_;
236 };
237
238 template<class Field, std::size_t... Dimensions>
239 using FieldTensor = FieldVectorTensor<FieldVectorType<Field, Dimensions...> >;
240
241 namespace {
242
243 template<class Field, class Seq>
244 struct MatchingFieldTensorHelper;
245
246 template<class Field, std::size_t... Dimensions>
247 struct MatchingFieldTensorHelper<Field, Seq<Dimensions...> >
248 {
249 using Type = FieldTensor<Field, Dimensions...>;
250 };
251 }
252
253 template<class T>
254 using MatchingFieldTensor = typename MatchingFieldTensorHelper<FloatingPointClosure<typename TensorTraits<T>::FieldType>, typename TensorTraits<T>::Signature>::Type;
255
256 namespace {
257
258 template<class FV>
259 struct ScalarDecayFieldTensorHelper
260 {
261 using Type = FieldVectorTensor<FV>;
262 };
263
264 template<class Data>
265 struct ScalarDecayFieldTensorHelper<FieldVector<Data, 1> >
266 {
267 using Type = FieldVectorTensor<Data>;
268 };
269
270 template<class Data>
271 struct ScalarDecayFieldTensorHelper<Fem::ExplicitFieldVector<Data, 1> >
272 {
273 using Type = FieldVectorTensor<Data>;
274 };
275
276 template<int NCols, class Data>
277 struct ScalarDecayFieldTensorHelper<FieldMatrix<Data, 1, NCols> >
278 {
279 using Type = FieldVectorTensor<FieldVector<Data, NCols> >;
280 };
281
282 }
283
285 template<class FV>
286 using ScalarDecayFieldTensor = typename ScalarDecayFieldTensorHelper<FV>::Type;
287
288 template<class T, class SFINAE = void>
289 struct IsFieldVectorTensor
290 : FalseType
291 {};
292
293 template<class T>
294 struct IsFieldVectorTensor<T, std::enable_if_t<!IsDecay<T>::value> >
295 : IsFieldVectorTensor<std::decay_t<T> >
296 {};
297
298 template<class FV>
299 struct IsFieldVectorTensor<FieldVectorTensor<FV> >
300 : TrueType
301 {};
302
303 template<class T>
304 using IsFieldTensor = IsFieldVectorTensor<T>;
305
306 template<class FV>
307 struct TensorTraits<FV, std::enable_if_t<(IsFieldObject<FV>::value && IsDecay<FV>::value)> >
308 : public TensorTraits<FieldVectorTensor<FV> >
309 {
310 template<class T>
311 static constexpr auto toTensor(T&& t)
312 {
313 return FieldVectorTensor<T>(std::forward<T>(t));
314 }
315 };
316
317 template<class FV>
318 struct IsTensorOperand<FV, std::enable_if_t<(IsFieldObject<FV>::value && IsDecay<FV>::value)> >
319 : TrueType
320 {};
321
322 template<class T>
323 struct IsUnaryTensorOperand;
324
325 template<class T1, class T2, class SFINAE>
326 struct AreBinaryTensorOperands;
327
332 template<class T1, class T2>
334 T1, T2,
335 std::enable_if_t<(IsFieldObject<T1>::value
336 && IsFieldObject<T2>::value
337 && IsUnaryTensorOperand<T1>::value
338 && IsUnaryTensorOperand<T2>::value
339 )> >
340 : TrueType
341 {};
342
343 } // NS Tensor
344
345 } // NS ACFem
346
347 template<class FV>
348 struct FieldTraits<ACFem::Tensor::FieldVectorTensor<FV> >
349 : FieldTraits<std::decay_t<FV> >
350 {};
351
352} // NS Dune
353
354#endif // __DUNE_ACFEM_TENSORS_BINDINGS_DUNE_FIELDTENSOR_HH__
auto & assign(T1 &t1, T2 &&t2)
Assign one tuple-alike to another by looping over the elements.
Definition: assign.hh:40
auto toString(Sequence< T, I0 >)
Generate a compact string representation as a comma separated list of the values, without spaces.
Definition: tostring.hh:28
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
STL namespace.
Definition: expressiontraits.hh:67
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 4, 22:38, 2025)