Skip to content

Phase 2a: emit strain-coupled implicit-residual materials (Mode B) - #100

Merged
petlenz merged 3 commits into
mainfrom
phase-2a-strain-coupled-residual-emit
Jul 8, 2026
Merged

Phase 2a: emit strain-coupled implicit-residual materials (Mode B)#100
petlenz merged 3 commits into
mainfrom
phase-2a-strain-coupled-residual-emit

Conversation

@petlenz

@petlenz petlenz commented Jun 18, 2026

Copy link
Copy Markdown
Member

What

Teaches NumSimMaterialTarget to emit strain-coupled implicit-residual materials — a recipe whose scalar state is defined by an implicit R(x, ε)=0 (via add_scalar_residual_equation, landed in #99) is lowered to a numsim-materials material that holds a material_ref<backward_euler> and drives the Newton loop itself in one compute() (Mode B, the robust pattern small_strain_plasticity uses — no Local-edge ordering fragility). The consistent tangent dσ/dε is deferred to PR 2b and rejected loudly here.

Commits

  1. 90f98d9 — Finding A guard. Before this PR, a residual recipe was mishandled on main: NumSimMaterialTarget threw a misleading rate/rk_integrator error, and the self-contained path (emit_compute_function, standalone/MOOSE) silently emitted a function dropping the state. Now both reject loudly with an accurate message (the self-contained guard is permanent; the target one is replaced by emission in commit 2).
  2. f6edc2a — Mode-B emitter. emit_residual_material(): material_ref<backward_euler> + solve(eval) returning {residual, jacobian} (∂R/∂x via cas::diff), state-apply, stress. emit() routes residual recipes here. Unit tests + a gcc-gated cross-repo e2e against the real backward_euler (z=c·tr(ε), σ=z·ε).
  3. df9fb8e — review fixes (3-lens critical review folded in). See below.

Verification

  • 294/294 tests pass (g++-14), including the gcc-gated cross-repo e2e driving the real solver.
  • The emitted material was instantiated & run end-to-end; multi-output headers template-instantiate against real numsim-materials.
  • The nonlinear-residual e2e validates the emitted jacobian (sabotage-checked: forcing jacobian=1.0 makes it fail).

Review fixes (commit df9fb8e)

Four HIGH emitted-code-correctness bugs the single-output test recipe never exercised: multi-output CSE temp collision (t0 redeclared), <state>_old → unbound identifier, solver/eval/residual/jacobian name collisions, and an e2e that couldn't catch a wrong jacobian (linear ∂R/∂z≡1). All fixed + pinned by tests.

Deferred (tracked): backward_euler::solve() clamps std::max(x,0) (plasticity convention — documented in the emitted header; upstream issue for an unclamped mode to follow); ~445-line duplication vs the rate path (extract detail:: helpers after PR 2b).

🤖 Generated with Claude Code

@petlenz
petlenz merged commit 4aa8eda into main Jul 8, 2026
4 checks passed
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