[forms] Add helper class for lazy dense tensor blocks
When assembling a local linear or bilinear form on a grid element, each evaluation of the integrand corresponds to a vector or matrix (i.e. a tensor of rank k=1 or k=2) whose dimensions corresponds to the dimensions of the local test and trial space. The full local assembled tensor (vector or matrix) is simply a weighted sum of these tensors.
For nested spaces, each of these tensors is in general
only a block whose indices correspond to the test and
trial nodes of the local ansatz tree. The translation
of an index i
within the block associated to a node
to a local index within the full tensor is done via node.localIndex(i)
.
Conceptually, this pattern is already implemented in the
forms assemblers. However, evaluation at quadrature points
so far simply returns a k-variate callback which has
to be interpreted by the local assembler using the
additional node
information.
This patch adds a utility class Impl::LazyTensorBlock
which encodes the full tensor block information. While
the data is still stored as a callback, the class additionally
contains the size of the block and its offset within the
full tensor. An additional utility function axpy
then
allows to add the tensor block to the full tensor
(with quadrature weight as factor) without needing
the additional node
information.
As a result this allows for a looser coupling of local assembler and k-linear operators. In later stages one may even extend the tensor classes to exploit the product structure and implement sum factorization.