[forms] Implement gradient of TransformedOperator
Since a transformation is linear, applied pointwise, and independent of the position, we can in principle exchange the order of transformation and derivative. However, we do in general not now an appropriate type for the jacobian. E.g. for matrix valued functions we would need a third order tensor.
However, when viewing the gradient as the transposed
of the jacobian, it is a vector of partial derivatives,
where the outer most index corresponds to the partial
derivative direction while each entry has the same type
as the range of the original function. Hence we can
generically use std::array<Range,dim>
as range for the
gradient of a function with range of type Range
.
This e.g. allows to transform a power function space
to matrix valued finite elements using a local isomorphism
and then to compute gradients of this space.
To make this usable, this also adds an overload of dot(x,y)
for two std::array
arguments. To make this more general, one
may want to implement more overloads for different combinations
of types or more generic ones later.