Part of the NumSim compiler epic: #28.
Summary
Generate algorithmic (consistent) tangents via implicit differentiation, and lower complementarity constraints (Kuhn-Tucker triples) into the LocalNewton residual via Fischer-Burmeister NCP functions. This is the highest schedule risk in the epic — de-risked by the Phase 1.3 spike.
Scope
3b.1 — AlgorithmicTangentPass
- For each output
σ(x, ε):
dx/dε = −(∂R/∂x)⁻¹ · (∂R/∂ε) via implicit differentiation
dσ/dε = ∂σ/∂ε + ∂σ/∂x · dx/dε
- The rank-4 inverse is emitted as
tmech::inv(...) per D7 — no Eigen runtime, no Voigt-flatten
3b.2 — KuhnTuckerLoweringPass
ComplementarityConstraint(λ, f) → NCP Fischer-Burmeister: φ(λ, -f) = sqrt(λ² + f²) − (λ - f) = 0 inside the LocalNewton residual
- Non-smoothness at the kink handled by CAS's existing
if_then_else-based piecewise differentiation (reuses Phase 3a's Newton solve; doesn't extend it)
- Multi-surface plasticity: multiple
ComplementarityConstraints in one LNS
Acceptance
- J2 plasticity tangent matches FD within per-region tolerance at ~100 sampled strain points:
- Tight (1e-6) in the smooth elastic + smooth plastic regimes
- Looser (1e-4) through the elastic-plastic transition (FD is noisy at discontinuities)
- Drucker-Prager multi-surface recipe lowers and verifies
- Kinematic-hardening reverse loading verifies
Files affected
- New:
include/numsim_codegen/passes/AlgorithmicTangentPass.h
- New:
include/numsim_codegen/passes/KuhnTuckerLoweringPass.h
- Test recipes:
tests/goldens/J2PlasticityFull.cpp (tangent now), tests/goldens/DruckerPrager.cpp
Dependencies
- Phase 3a —
LocalNewtonLoweringPass is the consumer of KuhnTuckerLoweringPass's output
Risk
This is the highest-risk subissue in the epic. Schedule contingency: if the Phase 1.3 spike surfaces a fundamental issue with the implicit-diff approach, this gets re-scoped.
Part of the NumSim compiler epic: #28.
Summary
Generate algorithmic (consistent) tangents via implicit differentiation, and lower complementarity constraints (Kuhn-Tucker triples) into the LocalNewton residual via Fischer-Burmeister NCP functions. This is the highest schedule risk in the epic — de-risked by the Phase 1.3 spike.
Scope
3b.1 — AlgorithmicTangentPass
σ(x, ε):dx/dε = −(∂R/∂x)⁻¹ · (∂R/∂ε)via implicit differentiationdσ/dε = ∂σ/∂ε + ∂σ/∂x · dx/dεtmech::inv(...)per D7 — no Eigen runtime, no Voigt-flatten3b.2 — KuhnTuckerLoweringPass
ComplementarityConstraint(λ, f)→ NCP Fischer-Burmeister:φ(λ, -f) = sqrt(λ² + f²) − (λ - f) = 0inside the LocalNewton residualif_then_else-based piecewise differentiation (reuses Phase 3a's Newton solve; doesn't extend it)ComplementarityConstraints in one LNSAcceptance
Files affected
include/numsim_codegen/passes/AlgorithmicTangentPass.hinclude/numsim_codegen/passes/KuhnTuckerLoweringPass.htests/goldens/J2PlasticityFull.cpp(tangent now),tests/goldens/DruckerPrager.cppDependencies
LocalNewtonLoweringPassis the consumer ofKuhnTuckerLoweringPass's outputRisk
This is the highest-risk subissue in the epic. Schedule contingency: if the Phase 1.3 spike surfaces a fundamental issue with the implicit-diff approach, this gets re-scoped.