Skip to content

Phase D: emit consistent tangent dσ/dε as a rank-4 tensor property - #98

Merged
petlenz merged 2 commits into
mainfrom
phase-d-consistent-tangent
Jun 15, 2026
Merged

Phase D: emit consistent tangent dσ/dε as a rank-4 tensor property#98
petlenz merged 2 commits into
mainfrom
phase-d-consistent-tangent

Conversation

@petlenz

@petlenz petlenz commented Jun 15, 2026

Copy link
Copy Markdown
Member

What

NumSimMaterialTarget now emits the consistent tangent dσ/dε as a rank-4 tmech::tensor property, computed via cas::diff(stress, strain).

Why this is the exact consistent tangent in scope (not just a partial): the rate-leaf guard forbids the rate from depending on strain, so the integrated state is independent of the current strain (dα/dε ≡ 0). Therefore dσ/dε = ∂σ/∂ε + ∂σ/∂α·(dα/dε) = ∂σ/∂ε — a single cas::diff, no J⁻¹ solve, no rank-4 inverse. (This mirrors the static_assert in AlgorithmicTangentPass that pins the same fact for the standalone path.)

Reuses the proven tangent machinery: cas::diff(σ,ε) → rank-4, rendered by the same tensor() emit pipeline; folded into the tensor-output path so the ctor/callback/member emission handles it uniformly.

Minor symmetry

roles::Strain carries a symmetric tensor space, so cas::diff returns the minor-symmetric rank-4 identity P_sym = ½(I⊗ᵘI + I⊗ˡI) — the emitted RHS contains both otimesu and otimesl, as a stress-strain tangent must.

Verified end-to-end (gcc)

Generated Viscoelastic (σ=α·ε) emits dstress_dstrain; driven through the real graph, dσ/dε = α·P_sym checks out component-wise: C(0,0,0,0)=α, C(0,1,0,1)=α/2 (minor-symmetric), C(0,0,1,1)=0. (Tensor e2e is GCC-gated per numsim-core#16, same as the stress path; the emit shape is verified compiler-independently by the unit test.)

Tests

  • Unit: EmitsConsistentTangent (rank-4 property + callback + minor-symmetric otimesu/otimesl), RejectsTangentOfMissingStress.
  • e2e: the tensor-stress test now also reads + verifies the rank-4 tangent property.

Scope (honest)

This covers the strain-uncoupled consistent tangent (dα/dε=0). The strain-coupled case (rate depending on ε ⇒ the residual contract + solver-assembled blocks ∂R/∂ε, ∂σ/∂x and J⁻¹) remains future work, gated on the residual contract + strain-coupling support.

274 tests pass locally; warning-gated.

🤖 Generated with Claude Code

@petlenz
petlenz merged commit 2ac5aa8 into main Jun 15, 2026
4 checks passed
@petlenz
petlenz deleted the phase-d-consistent-tangent branch June 15, 2026 20:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant