Skip to content

Derivatives w.r.t. symmetric tensors: fold P_sym contractions to sym()/dev() and tag results Symmetric / MinorMajor #493

Description

@petlenz

Use case

Every constitutive tangent: S = 2 ∂ψ/∂C, ℂ = 2 ∂S/∂C with C symmetric, or σ = ∂W/∂ε, ℂ = ∂σ/∂ε with ε symmetric. Codegen needs to know the result is symmetric (rank 2) / minor-and-major symmetric (rank 4) to emit Voigt/Mandel storage and skip redundant components, and the expression should be small enough to emit.

What happens today (probed on main, dim 3)

The derivative w.r.t. a symmetric tensor IS symmetrized (a P_sym{4} projector is inserted), and the numbers are right — but the result is neither simplified nor annotated:

Expression, C/Eps assumed Symmetric{} Result is_symmetric
diff(dot_product(C,{1,2},B,{1,2}), C) inner(P_sym{4}{1, 2}, B, {1, 2}) — this is sym(B) 0
diff(trace(C*B), C) I:permute_indices(inner(P_sym{4}{2}, B, {1}), {1, 3, 4, 2}) 0
diff(trace(C*C), C) I:(outer(I,{1,3},C,{4,2}):P_sym{4}+outer(C,{1,3},I,{4,2}):P_sym{4}) — this is 2C 0
diff(norm(dev(sg)), sg) pow(norm(dev(sg)),-1)*dev(sg):dev(P_sym{4}) 0 (and is_deviatoric 0)
diff(C4:Eps, Eps), C4 MinorMajor C4:P_sym{4} is_minor_major 0
Neo-Hooke ℂ = 2 ∂S/∂C 1036 chars minor/major/minor_major all 0, numerically both symmetries hold to 1e-16

Compare diff(dot(C), C)2*Cs with is_symmetric = 1: the dot path has a dedicated rule; the general path does not.

Two gaps, one root: the projector contractions the differentiator emits are written with explicit index sequences (inner(P_sym,{1,2},X,{1,2}), X:P_sym, C4:P_sym, dev(P_sym)), which the projector algebra does not recognise as the canonical sym(X) / dev(X) forms it already knows how to fold and tag.

Proposal

  1. Normalize projector contractions: inner(P{1,2}, X, {1,2}), X:P (contract on P's leading pair; by major symmetry equal), P:X, and permute-wrapped variants → the canonical inner_product(P, {3,4}, X, {1,2}) form, so projector_algebra.h's existing rules (P_sym : sym-space → X, P:P, dev(P_sym)P_dev, tags) fire. inner(P_sym{4}{1,2}, B, {1,2}) then becomes sym(B); dev(sg):dev(P_sym{4}) becomes dev(sg).
  2. Tag derivative results: a rank-2 derivative w.r.t. a Symmetric argument carries Symmetric; a rank-4 derivative of a symmetric-valued expression w.r.t. a symmetric argument carries MinorMajor (minor from the symmetrization on both index pairs, major when it is a second derivative of a scalar — ℂ = ∂²ψ/∂C²). This falls out of (1) for the folded forms; for the unfolded remainder it needs the rule "X : P_sym on the argument's pair ⇒ minor-symmetric on that pair".
  3. Lock-in: the six probes above, asserting both the folded print and the tag; numeric symmetry check on the Neo-Hooke tangent.

Scope

Medium. (1) is a simplifier rule set in projector_algebra.h / the inner-product factory; (2) touches tensor_differentiation result annotation. Depends on #455 for a mechanical rank guard (rank-4 nodes carrying rank-2 tags is what P_sym{4} already does by design), related to #396 (annotation derivations) and #276 (rank-4 inverse index pair — needs the same MinorMajor tag on tangents).

Signed-off-by: petlenz [email protected]

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions