Phase 2b: emit the strain-coupled consistent tangent dσ/dε for Mode-B residual materials - #101
Merged
Merged
Conversation
added 4 commits
July 8, 2026 23:13
… verified in pin), seam now computes diff(tensor,scalar)
…rm vs real backward_euler
…) guard + tangent caveat, self-detect the diff seam, strengthen tangent/seam pins
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Completes the strain-coupled arc: PR #100 emitted the Mode-B residual solve; this PR emits the consistent tangent dσ/dε that makes the generated material usable in an outer FE Newton solve.
For a stress output σ and strain input ε of a material whose scalar state z solves R(z,ε)=0:
∂R/∂z is a scalar (scalar state ⇒ no matrix inverse), so the whole tangent is a rank-4 tensor expression in (z, ε, params), emitted as an extra post-solve output evaluated at the converged z (bound to
&computelike every output). ∂σ/∂z goes through thedetail::diff_tensor_wrt_scalarseam (cas#275).Commits
diff_tensor_wrt_scalarnow self-detects the cas#275 overload (diff(tensor, scalar)) via__has_includeand collapses tocas::diff. De-risked: all four diffs compile+link+produce valid exprs against the pin; the seam test now renders∂(x·ε)/∂x = ε(and∂(x²·ε)/∂x = 2x·ε).emit_residual_material()— assemble the four diffs (∂σ/∂ε,∂σ/∂z,∂R/∂ε,∂R/∂z), render the rank-4 output; full guard set (of_output must be a tensor output, wrt_input a declared tensor input, dim match, name-collision). 6 unit tests.backward_eulersolve: the off-block coupling termC_{0011}=c·ε₀₀a naive∂σ/∂εdrops.1/∂R/∂zdivision: the linear ReturnMap (∂R/∂z≡1) can't detect a dropped divisor, soReturnMapCubic(∂R/∂z=1+3z²) now carries a tangent assertingC_{0011}=c·ε₀₀/(1+3z²). Sabotage-verified (dropping the divisor fails the cubic test, passes the linear).converged()guard in generatedcompute()+ a tangent caveat: outputs are evaluated at the solved state, so a non-converged/clamped root is rejected loudly (themax(x,0)elastic-branch case needs an upstreamwas_clamped()— numsim-materials follow-up).otimesu/otimesl,z·factor) and the seam test (non-trivial coefficient).Test plan
backward_eulerin the loop). Both the coupling term and the/∂R/∂zdivision sabotage-verified.Scope notes
NCG_TENSOR_E2E): the numsim-core e2e pin (c462d9c) predates the numsim-core#16 fix (which landed on a divergentmain), so dropping the gate is entangled with pin reconciliation (Enable -Wall -Wextra -Werror: first-party baseline + gate generated code (compile_check_driver), with a cross-repo golden-compile follow-up #89) — a separate follow-up.eye<double,...>hardcoding in emitted identity tensors (pre-existing, shared with the rate path) and a full shear-component e2e index-sequence pin are noted as low-value follow-ups.