You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Phase 2.6 — wire state variables through the MOOSE backend so an evolution recipe (state variable + evolution equation, with enable_local_newton()) emits a compilable, correct MOOSE Material. Today the MOOSE target is provably wrong for such recipes — pinned by the MooseBackendDoesNotYetWireStateVariables_KNOWN_GAP guard test in tests/IntegrationTest.cpp. This issue flips that guard to a positive check.
The problem (confirmed)
src/targets/moose_material.cpp iterates parameters() / inputs() / outputs() and never handles Category::StateVariableCurrent / StateVariableOld. Two concrete failures for an evolution recipe:
No member / binding for the state variable.<sv> and <sv>_old are never declared, so the generated .C references undeclared members.
Arity-mismatched compute call.emit_compute_qp_body rebuilds the argument list as parameters() → inputs() → outputs(), independently of render_compute_function's actual order (symbols() registration order → outputs → newton-owned <sv>_out). It omits the state-variable arguments entirely (observed: a 3-arg call into a 7-parameter function).
_<sv>_old(getMaterialPropertyOld<Real>("<Model>_<sv>")) — note MOOSE's getMaterialPropertyOld takes the SAME declared property name; "old" is automatic state versioning.
dt mapping. The auto-registered dt scalar parameter must map to MOOSE's built-in _dt (the framework timestep), NOT getParam<Real>("dt"). Special-case the state_time_step_name symbol in both validParams (skip — it's not an input-file param) and the compute call (pass _dt).
computeQpProperties call-site in the GENERATED order. The call must reproduce render_compute_function's argument order exactly:
symbols in registration order, with: parameters → _<name>, scalar inputs → _<name>[_qp], tensor inputs → adaptor, StateVariableOld → _<sv>_old[_qp], dt → _dt, and StateVariableCurrent SKIPPED (it's an out-param in the Newton path);
then outputs (_<name>[_qp] / adaptor);
then newton-owned <sv>_out → _<sv>[_qp] (the writable declareProperty).
State initialisation.initQpStatefulProperties() (or equivalent) sets _<sv>[_qp] to the StateVariable's initial_value at simulation start. (Scalar initial values; expression-valued initials can reuse the scalar emit.)
Architectural decision (resolve in implementation)
Argument-order coupling. The MOOSE call-site and render_compute_function independently reconstruct the argument order — a latent drift hazard (they already diverge today). Recommend extracting a single canonical_argument_order(model, newton_owned) → vector<ArgSpec> helper that BOTH the function signature and every backend's call-site iterate, so the order has one source of truth. This is the robust fix and prevents the next backend (Abaqus/ANSYS) from re-introducing the same bug.
Out of scope
Abaqus / ANSYS state-var wiring (later; the canonical-order helper makes them mechanical).
Tensor state variables (scalar only, matching Phase 3a-2).
The external-driver (non-Newton) MOOSE path — MOOSE materials solve internally, so the Newton path is the MOOSE-relevant mode; the R/J-output path is for non-MOOSE external drivers.
Acceptance
A linear-hardening + an autocatalytic-cure recipe each emit a MOOSE .h/.C pair that is self-consistent: every referenced member is declared, the compute call arity matches the generated function, dt → _dt, state var initialised.
MooseBackendDoesNotYetWireStateVariables_KNOWN_GAP rewritten to positive checks and passing.
Phase 2.6 — wire state variables through the MOOSE backend so an evolution recipe (state variable + evolution equation, with
enable_local_newton()) emits a compilable, correct MOOSEMaterial. Today the MOOSE target is provably wrong for such recipes — pinned by theMooseBackendDoesNotYetWireStateVariables_KNOWN_GAPguard test intests/IntegrationTest.cpp. This issue flips that guard to a positive check.The problem (confirmed)
src/targets/moose_material.cppiteratesparameters()/inputs()/outputs()and never handlesCategory::StateVariableCurrent/StateVariableOld. Two concrete failures for an evolution recipe:<sv>and<sv>_oldare never declared, so the generated.Creferences undeclared members.emit_compute_qp_bodyrebuilds the argument list asparameters() → inputs() → outputs(), independently ofrender_compute_function's actual order (symbols()registration order → outputs → newton-owned<sv>_out). It omits the state-variable arguments entirely (observed: a 3-arg call into a 7-parameter function).Deliverables
Materialclass):StateVariableCurrent→MaterialProperty<Real> & _<sv>;(writable,declareProperty)StateVariableOld→const MaterialProperty<Real> & _<sv>_old;(getMaterialPropertyOld)_<sv>(declareProperty<Real>("<Model>_<sv>"))_<sv>_old(getMaterialPropertyOld<Real>("<Model>_<sv>"))— note MOOSE'sgetMaterialPropertyOldtakes the SAME declared property name; "old" is automatic state versioning.dtmapping. The auto-registereddtscalar parameter must map to MOOSE's built-in_dt(the framework timestep), NOTgetParam<Real>("dt"). Special-case thestate_time_step_namesymbol in both validParams (skip — it's not an input-file param) and the compute call (pass_dt).computeQpPropertiescall-site in the GENERATED order. The call must reproducerender_compute_function's argument order exactly:_<name>, scalar inputs →_<name>[_qp], tensor inputs → adaptor,StateVariableOld→_<sv>_old[_qp],dt→_dt, andStateVariableCurrentSKIPPED (it's an out-param in the Newton path);_<name>[_qp]/ adaptor);<sv>_out→_<sv>[_qp](the writable declareProperty).initQpStatefulProperties()(or equivalent) sets_<sv>[_qp]to the StateVariable'sinitial_valueat simulation start. (Scalar initial values; expression-valued initials can reuse the scalar emit.)MooseBackendDoesNotYetWireStateVariables_KNOWN_GAP→ positive assertions:getMaterialPropertyOld<Real>("...<sv>")declared,declarePropertyfor the current, compute call has matching arity,_dtused. Closes Phase 2.2: render_compute_function Category-aware branch for StateVariable symbols #60's MOOSE half.Architectural decision (resolve in implementation)
Argument-order coupling. The MOOSE call-site and
render_compute_functionindependently reconstruct the argument order — a latent drift hazard (they already diverge today). Recommend extracting a singlecanonical_argument_order(model, newton_owned) → vector<ArgSpec>helper that BOTH the function signature and every backend's call-site iterate, so the order has one source of truth. This is the robust fix and prevents the next backend (Abaqus/ANSYS) from re-introducing the same bug.Out of scope
_Jacobian_multwiring — Phase 3b (Phase 3b — Algorithmic tangent + Kuhn-Tucker lowering #35) / Phase 5 (Phase 5 — MOOSE + Standalone state-variable + algorithmic-tangent wiring #37).Acceptance
.h/.Cpair that is self-consistent: every referenced member is declared, the compute call arity matches the generated function,dt→_dt, state var initialised.MooseBackendDoesNotYetWireStateVariables_KNOWN_GAPrewritten to positive checks and passing.Refs