KASKADE 7 development version
tensor.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2019-2023 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12#ifndef TENSOR_HH
13#define TENSOR_HH
14
15
16#include "dune/common/fvector.hh"
17#include "dune/common/fmatrix.hh"
18
19#include "utilities/scalar.hh"
20
21namespace Kaskade
22{
23
28 template <int first, int last>
30
31 // forward declaration
32 template <class Entry, int Size0, int ... Sizes>
33 class Tensor;
34
38 namespace TensorDetail
39 {
40 template <class Entry, int Size>
41 struct Prepend { using type = Tensor<Entry,Size>; };
42
43 template <class Entry, int SizePre, int Size0, int ... Sizes>
44 struct Prepend<Tensor<Entry,Size0,Sizes...>,SizePre> { using type = Tensor<Entry,SizePre,Size0,Sizes...>; };
45 }
46
47 // Provide the rank of tensors with the same interface as for vectors and matrices.
48 namespace ScalarDetail
49 {
50 template <class K, int Size0, int ... Sizes>
51 struct Rank<Tensor<K,Size0,Sizes...>>
52 {
53 static constexpr int value = Tensor<K,Size0,Sizes...>::rank;
54 };
55 }
60 namespace TensorAccess
61 {
75 }
76
84 template <class Entry, int Size0, int ... Sizes>
85 class Tensor: public Dune::FieldVector<Tensor<Entry,Sizes...>,Size0>
86 {
87 using Base = Dune::FieldVector<Tensor<Entry,Sizes...>,Size0>;
88 static_assert(Size0>0);
89 static constexpr int Size1 = Tensor<Entry,Sizes...>::dimension;
90 public:
91
95 static constexpr int rank = Tensor<Entry,Sizes...>::rank + 1;
96
101 Tensor() = default;
102
103 Tensor(Entry const& e)
104 {
105 (*this) = e;
106 }
107
119 Tensor& operator=(Entry const& e)
120 {
121 for (auto& t: *this)
122 t = e;
123 return *this;
124 }
125
127 {
128 static_assert(rank==2);
129 if constexpr (rank==2)
130 for (int i=0; i<Size0; ++i)
131 (*this)[i] = a[i];
132 return *this;
133 }
162 template <class ... Access>
163 auto operator()(int i0, Access... is) const
164 {
165 return (*this)[i0](is...);
166 }
167
168 template <int first, int last, class ... Access>
169 auto operator()(StaticIndexRange<first,last> , Access... is) const
170 {
171 constexpr int s = std::min(Size0,last-first);
172 using SubT = decltype( (*this)[0](is...) );
173 using R = typename TensorDetail::Prepend<SubT,s>::type;
174 R r;
175 for (int i=0; i<s; ++i)
176 r[i] = (*this)[i+first](is...);
177 return r;
178 }
179
187 operator std::conditional_t<rank==2,
189 Base&> () const
190 {
191 if constexpr(rank==2)
192 {
194 // We want that A[i][j] = (*this)[i][j]. A[i] are the rows of A (of type FieldVector),
195 // and (*this)[i] are Tensors of rank 1, and thus derived from FieldVector. So we can
196 // assign the matrix row by row.
197 for (int i=0; i<Size0; ++i)
198 A[i] = (*this)[i];
199 return A;
200 }
201 else
202 return *this;
203 }
204
205 };
206
207 // ----------------------------------------------------------------------------------------------
208
209 // Terminal of parameter pack recursion
210 template <class Entry, int Size0>
211 class Tensor<Entry,Size0>: public Dune::FieldVector<Entry,Size0>
212 {
214 public:
215
217
218 static constexpr int rank = 1;
219
220 Tensor() = default;
221
222 Tensor(Entry const& e)
223 {
224 (*this) = e;
225 }
226
227 Tensor& operator=(Entry const& e)
228 {
229 for (auto& t: *this)
230 t = e;
231 return *this;
232 }
233
235 {
236 static_cast<Base&>(*this) = v;
237 return *this;
238 }
239
240 Entry operator()(int i) const
241 {
242 return (*this)[i];
243 }
244
245 template <int first, int last>
247 {
248 constexpr int s = std::min(Size0,last-first);
249
251 for (int i=0; i<s; ++i)
252 r[i] = (*this)[i+first];
253 return r;
254 }
255
257 {
258 static_cast<Base&>(*this) *= x;
259 return *this;
260 }
261 };
262
263
264 // Template specialization for accessing type information.
265 template <class Entry, int ... Sizes>
266 struct EntryTraits<Tensor<Entry,Sizes...>>
267 {
270 static int const lapackLayout = false;
271 };
272
273 // ----------------------------------------------------------------------------------------------
274
280 template <class Entry, int Size0, int ...Sizes>
282 {
283 A *= a;
284 return A;
285 }
286
287 // ----------------------------------------------------------------------------------------------
288
294 template <class Entry, int n>
295 Entry trace(Tensor<Entry,n,n> const& A)
296 {
297 Entry t = 0;
298 for (int i=0; i<n; ++i)
299 t += A[i][i];
300 return t;
301 }
302
303 // ----------------------------------------------------------------------------------------------
304
305 // Tensor output
306 template <class Entry, int ... Sizes>
307 std::ostream& operator<<(std::ostream& out, Tensor<Entry,Sizes...> const& t)
308 {
309 out << "[" << t[0];
310 for (int i=1; i<std::size(t); ++i)
311 out << "," << t[i];
312 out << "]";
313 return out;
314 }
315
316}
317
318// ------------------------------------------------------------------------------------------------
319
320// ------------------------------------------------------------------------------------------------
321
325namespace Dune
326{
327 // For interoperability with Dune (and as we put Tensors as entries into FieldVectors,
328 // we need to specify the underlying field type.
329 template <class K, int Size0, int ... Sizes>
330 struct FieldTraits<Kaskade::Tensor<K,Size0,Sizes...>>
331 {
332 using field_type = typename FieldTraits<K>::field_type;
333 using real_type = typename FieldTraits<K>::real_type;
334 };
335}
340#endif
Scalar Real
The real type on which the scalar field is based.
Definition: scalar.hh:49
Tensor & operator=(Base const &v)
Definition: tensor.hh:234
Tensor()=default
auto operator()(StaticIndexRange< first, last >) const
Definition: tensor.hh:246
Entry operator()(int i) const
Definition: tensor.hh:240
Tensor & operator*=(field_type const &x)
Definition: tensor.hh:256
Tensor & operator=(Entry const &e)
Definition: tensor.hh:227
Tensor(Entry const &e)
Definition: tensor.hh:222
typename EntryTraits< Entry >::field_type field_type
Definition: tensor.hh:216
A class for representing tensors of arbitrary static rank and extents.
Definition: tensor.hh:86
auto operator()(int i0, Access... is) const
Definition: tensor.hh:163
Tensor(Entry const &e)
Definition: tensor.hh:103
Tensor()=default
static constexpr int rank
The rank of the tensor.
Definition: tensor.hh:95
Tensor & operator=(Entry const &e)
Assignment from a scalar.
Definition: tensor.hh:119
Tensor & operator=(Dune::FieldMatrix< Entry, Size0, Size1 > const &a)
Definition: tensor.hh:126
auto operator()(StaticIndexRange< first, last >, Access... is) const
Definition: tensor.hh:169
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
Entry trace(Tensor< Entry, n, n > const &A)
Trace of a square matrix-shaped tensor.
Definition: tensor.hh:295
constexpr int rank
Reports the rank of vector, matrix, and tensor types of static size.
Definition: scalar.hh:150
constexpr StaticIndexRange< 0, std::numeric_limits< int >::max()> _
Convenience static range denoting the full available range, analogous to Matlab's :.
Definition: tensor.hh:74
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
Dune::BlockVector< FieldType > operator*(Dune::Matrix< FieldType > const &A, Dune::BlockVector< FieldType > const &x)
std::ostream & operator<<(std::ostream &s, std::vector< Scalar > const &vec)
Definition: dune_bridge.hh:47
typename EntryTraits< Entry >::field_type field_type
Definition: tensor.hh:268
typename ScalarTraits< field_type >::Real real_type
Definition: tensor.hh:269
Definition: scalar.hh:73
Entry field_type
Definition: scalar.hh:77
static int const lapackLayout
Definition: scalar.hh:79
A compile-time index range.
Definition: tensor.hh:29