Ferrite-FEM / Ferrite-FEM/Tensors.jl
`gradient` fails for `SymmetricTensor`-valued functions of a `Vec`
- Lingua principale
- Julia
- Stelle
- 182
- Fork
- 40
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
Tensors v1.17.1, Julia 1.12.6.
`Tensors.gradient` supports functions of a `Vec` returning a scalar, a `Vec`, and a
(non-symmetric) `Tensor{2}` — but a `SymmetricTensor{2}`-valued function throws a
`MethodError` in `makemixed`.
## MWE
```julia
using Tensors
# Vec-valued: works
fv(x::Vec{2}) = Vec((x[1] * x[2], x[2]^2))
Tensors.gradient(fv, Vec((0.5, 0.5))) # 2×2 Tensor{2}, OK
# Tensor{2}-valued: works (returns a third order tensor)
ft(x::Vec{2}) = Tensor{2, 2}((x[1], x[1] * x[2], x[2], x[2]^2))
Tensors.gradient(ft, Vec((0.5, 0.5))) # 2×2×2 Tensor{3}, OK
# SymmetricTensor{2}-valued: throws
fs(x::Vec{2}) = SymmetricTensor{2, 2}((x[1], x[1] * x[2], x[2]^2))
Tensors.gradient(fs, Vec((0.5, 0.5)))
```
Output of the last call:
```
ERROR: MethodError: no method matching makemixed(::SymmetricTensor{2, 2, ForwardDiff.Dual{ForwardDiff.Tag{typeof(fs), Vec{2, Float64}}, Float64, 2}, 3})
The function `makemixed` exists, but no method is defined for this combination of argument types.
Closest candidates are:
makemixed(!Matched::Tensor{1, dim}) where dim
@ Tensors ~/.julia/packages/Tensors/XcYSK/src/mixed_tensors.jl:22
...
```
## Expected behavior
Return the gradient as a full third order tensor (`Tensor{3, dim}` /
`MixedTensor3{dim, dim, rdim}`), i.e. the same result type as for the equivalent
`Tensor{2}`-valued function — there is no minor-symmetric third order tensor type,
so dropping the symmetry in the result is the natural choice (the value's symmetry
just makes `∂A[i,j]/∂x ≡ ∂A[j,i]/∂x`).
## Why it matters (context)
Ferrite PR [#1418](https://github.com/Ferrite-FEM/Ferrite.jl/pull/1418) introduces
`TensorInterpolation{TB}` for tensor-valued interpolations (e.g. Regge, HHJ,
Arnold–Winther elements with `TB = SymmetricTensor{2, dim}`). Ferrite's
`FunctionValues` precomputes reference gradients via
`reference_shape_gradient_and_value`, whose generic fallback uses
`Tensors.gradient` — which hits this error for any standalone
`SymmetricTensor`-valued interpolation. The workaround (used both by #1418 for
`TensorizedInterpolation` and by our Regge experiment in this directory) is to
define the reference gradients analytically per interpolation.
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Valutazione
Questa issue non è ancora stata valutata.