Draft: Add Tensor container based on mdarray and a TensorSpan based of mdspan
Summary
This MR brings the dune interface to mdarray and mdspan, by providing a mixin base class TensorMixin
(similar to DenseMatrix
and DenseVector
) and a derived class Tensor
. Additionally, the MR provides a TensorSpan
, i.e. an mdspan-like class with TensorMixin
interface.
Motivation
The Std::mdarray
and Std::mdspan
classes are based on the corresponding std c++ library proposals and implementations. Those are pure container-adapters and container-views. They can be used like they are, but do not provide the usual Dune interfaces as found in DynamicMatrix
and FieldMatrix
, for example. This MR provides these datastructures in the regular Dune::
namespace, to be used by Dune algorithms.
Limitations and Design Decisions
The TensorMixin
is not (yet) a replacement for DynamicMatrix
and DynamicVector
, but goes in this direction. Currently the interface provided by TensorMixin
is very minimal. It essentially just provides for rank-2 tensors the rows()
and cols()
member functions and the exists(i0,i1...)
method. Especially, there are no arithmetic operators yet implemented.
A rank-0 tensor behaves like a scalar, i.e., it can be compared against a scalar, and it can be converted implicitly into a scalar. The other dune-ish scalar-specialization is not implemented (i.e. tensors with all extents 1 are not considered a scalar).
Tensor
The Tensor
is a multi-dimensional container with dynamic or static extents:
template <class Value, int... extents>
class Tensor;
The extents are given either as template parameter (in case of static extents) or the value Dune::dynamic
(a special value denoting a dynamic extent). In the constructor any non-static extent must be provided (or all extents) - in form of a list of integers, or a shape container, e.g., a std::array
- plus an optional default value for the entries or an initializer list:
Tensor<double,2,2> matrix1(42.0); // with initial value 42.0 for all entries
Tensor<double,Dune::dynamic,Dune::dynamic> matrix2(2,2, 42.0);
Tensor<double,2,2> matrix3{{1.0, 2.0}, {3.0,4.0}}; // with initializer lists
Tensor<double,Dune::dynamic,Dune::dynamic> matrix4(std::array{2,2}, {{1.0, 2.0}, {3.0,4.0}});
Discussion
This MR is an alternative to !1385. Both try to solve the same problem. It needs to be decided which design should be followed in Dune if we want to have tensor data strcutures.