Skip to content

Draft: Add Tensor container based on mdarray and a TensorSpan based of mdspan

Simon Praetorius requested to merge feature/tensor into master

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.

Edited by Simon Praetorius

Merge request reports