Repository navigation
Construct SCCSteadyStateProblem from a System; drop the deferred SCC lowering - #5276
ChrisRackauckas wants to merge 11 commits into
Conversation
…lowering
SCCSteadyStateProblem(sys, op) compiles the steady-state residual of the
uncompiled model into SCCs and returns the SCC problem directly, so its
solutions stay in the compressed layout with symbolic indexing through the
compiled residual system. SteadyStateProblem(sys, op) no longer records a
lowered_problem and solves in its own state layout (SteadyStateDiffEq#171).
Also strips Nothing from the tunable buffer eltype in
calculate_resid_prototype, which threw zero(Union{Nothing, Float64}) when
remaking a steady-state problem whose initialization buffers hold
placeholders.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Devin <noreply@cognition.ai>
Agent-Harness: Devin CLI 3000.11.3
Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/log.txt
An all-placeholder tunable buffer (eltype Nothing or a union containing
Nothing) now maps to Union{} instead of erroring, so promote_type picks up
the u0 eltype.
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Devin <noreply@cognition.ai>
Agent-Harness: Devin CLI 3000.11.3
Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu1/log.txt
Removing steady_state_sccprob and the SteadyStateProblem -> SCCNonlinearProblem conversion is breaking, so MTKBase is now 2.0.0. ModelingToolkit requires ModelingToolkitBase 2; SciCompDSL (1.0.6) allows 1 and 2. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu1/log.txt
SCCSteadyStateProblem gains p_constructor and forwards every non-initialization
keyword to the residual SCCNonlinearProblem, so function options (jac, sparse,
u0_eltype) reach every block and problem keywords (maxiters, abstol) are stored
on every nonlinear block. Static container types are derived from the user's
op container since the residual operating point is a Dict. expression = Val{true}
now throws an ArgumentError instead of a FieldError. Nonlinear SCC blocks
generate a symbolic jacobian when jac is requested (generate_jacobian learns
cachesyms for the SCC cache arguments).
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Devin <noreply@cognition.ai>
Agent-Harness: Devin CLI 3000.11.3
Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium
Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu1/log.txt
Capturing jac/sparse as named keywords of SCCNonlinearFunction stopped them reaching the linear branch's LinearFunction, which uses sparse for calculate_A_b. Pass both through explicitly. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu1/log.txt
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu2/log.txt
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu2/log.txt
Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu2/log.txt
…delingToolkitBase 2 Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.3 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/scc-ssprob/fu2/log.txt
…ocessing cannot determine SCCSteadyStateProblem copied the temporary SteadyStateProblem's states into the residual operating point. For unknowns without a value or guess those states are not the fallback: the steady-state initialization tears e.g. `0 ~ a - b^3` into `a = b^3`, so `MissingGuessValue.Constant(0.2)` gave a = 0.008, depending on unknown order. The temporary problem now uses a NaN sentinel and the NaN states receive the requested fallback. The multi-block SCCNonlinearProblem no longer passes `u0_constructor` to the symbolic `process_SciMLProblem` call, where it ran on unresolved symbolic entries (`v -> Float32.(v)` threw "Cannot convert Sym to Float32"); block states already apply it once numeric. Missing guesses in blocks of a static `op` are filled in a mutable copy, since `setindex!` on the static container threw. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.92 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/fu/SciML_ModelingToolkit.jl-5276-0909/log.txt
New commit 8e754d3 addresses two of the three blocking findings from the third independent review (gpt-6.1-sol):
Still open: the new compat bounds need ModelingToolkitTearing 1.20.8 and ModelingToolkitStandardLibrary 2.29.9 releases. That is waiting on @ChrisRackauckas. A fourth review is queued. 🤖 Posted by an AI agent — harness: Claude Code 2.1.285 · model: claude-opus-5-5 |
…eProblem guess The temporary SteadyStateProblem used a NaN missing-guess sentinel, so a state that a user initialization equation determines from a fallback-filled state (`a + b ~ 1` gives `a = 1 - b`) became NaN and was overwritten by the fallback, dropping the constraint and changing which root Newton reaches. The temporary problem now gets the real `missing_guess_value` and a NaN guess for every derivative without a user or system guess, in place of the zero guess the steady-state initialization gives such derivatives. Only states that the differential equations alone determine are NaN and receive the fallback; states fixed by `op`, guesses or initialization equations keep the values `SteadyStateProblem` gives. This also removes the non-public `Moshi.Data.isa_variant` access that failed root QA; `MissingGuessValue.Error` now throws for undetermined states through `fallback_guess`, as in `SCCNonlinearProblem`. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Devin <noreply@cognition.ai> Agent-Harness: Devin CLI 3000.11.92 Agent-Model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium Agent-Session: local headless run, log /Users/chrisrackauckas/sandbox/master/green/fu/SciML_ModelingToolkit.jl-5276-1100/log.txt
New commit c518e1c addresses two of the three blocking findings from the fourth independent review (gpt-6.1-sol):
Still open: the ModelingToolkitTearing 1.20.8 and ModelingToolkitStandardLibrary 2.29.9 releases, which are waiting on @ChrisRackauckas. A fifth review is queued. 🤖 Posted by an AI agent — harness: Claude Code 2.1.285 · model: claude-opus-5-5 |
This fixes a failure on the default branch's CI. The diagnosis and the evidence below come from the investigating agent's report; "confirmed by running" and "read in logs" are kept apart there.
Part of a three-PR stack implementing Chris's direction (2026-10-14) to replace the post-solve SCC reversal with an SCC form of SteadyStateProblem stored in the compressed layout: SciMLBase (new type) → ModelingToolkit (constructs it) → SteadyStateDiffEq (solves it). Supersedes SciML/SteadyStateDiffEq.jl#175 and #177; fixes SciML/SteadyStateDiffEq.jl#171. CI on the downstream PRs cannot pass until the upstream ones are released.
ModelingToolkit.jl
Branch
scc-steadystate(on master)a89fdd8f2Construct SCCSteadyStateProblem from a System; drop the deferred SCC loweringsrc/problems/sccnonlinearproblem.jl(SCCSteadyStateProblem(sys, op)with the{iip}and{iip, specialize}forms, docstring; deletessteady_state_sccprobandis_structurally_unbalanced_error),src/ModelingToolkit.jl(import),lib/ModelingToolkitBase/src/problems/odeproblem.jl(removes the stub, bothSCCNonlinearProblem(::SteadyStateProblem/AbstractSciMLProblem)accessors and thelowered_problemkwarg),lib/ModelingToolkitBase/src/systems/problem_utils.jl(resid-prototype fix, below),
lib/ModelingToolkitBase/test/qa/aqua.jl,test/qa/qa.jl,docs/src/API/problems.md,test/scc_nonlinear_problem.jl, and bothProject.tomls(MTK 11.45.4 → 11.46.0, MTKBase 1.77.4 → 1.78.0, SciMLBase
3.59, MTKBase compat1.78,test SteadyStateDiffEq
2.19).Fix
solve(::SteadyStateProblem)regressions from the deferred SCC lowering #5163 andSteadyStateProblem SCC lowering throws ExtraEquationsSystemException inside solve (also for DynamicSS) on structurally singular residuals #5177 (parents,
initialization_eqs,bindings, hierarchy, multi-SCC, empty schedule, connectors, arrays,
Initial/Γ) throughboth
SteadyStateProblemandSCCSteadyStateProblem. For conservation systems,SCCSteadyStateProblemthrowsModelingToolkit.StateSelection.ExtraEquationsSystemException.mtk_scc_nonlinear_r2.log(test/scc_nonlinear_problem.jl, env-stack): all green, includingcalculate_resid_prototypethrewzero(Union{Nothing, Float64})when a plainSteadyStateProblemwithInitialplaceholders was
remaked (Γ case,remake(prob; p = [k2 => 4.0])withSSRootfind()).On master the SCC lowering bypassed this path. The fix is a local
tunable_real_eltypehelper (
Base.nonnothingtypeis not public).resid_prototype_before.log:solve2 ERRORED: MethodErrorresid_prototype_after.log:solve2 ok: [2.4]test/qa/qa.jl, MTKBaseaqua.jl; onlyedited, not run) and the docs build. After the last test run I moved the 3-line helper
above the
calculate_resid_prototypedocstring so the docstring stays attached; Runic wasre-checked, but the tests were not re-run after that move.
Open design questions for Chris
SteadyStateProblem+ nonlinear alg. WithNewtonRaphson()the solution'ssol.probis the convertedNonlinearProblem, as before the lowering existed (onlySSRootfind/DynamicSS/SICNMgivesol.prob isa SteadyStateProblem). The testsencode this. Should SSDE rewrap it? I left it alone because it changes the dispatch
surface that SciMLSensitivity uses.
lowered_problemgo now as SciMLBase4.0 (
scc-steadystate-remove-lowered), or stay deprecated-but-unused in 3.x? The 4.0path needs
SciMLBase = "3.59, 4"compat in MTK/SSDE and in every package that capsSciMLBase below 4.
SCCNonlinearProblem(::SteadyStateProblem)method was a public-ish extension in MTKBase 1.77. I released its removal as a minor
(1.78.0), on the grounds that it was only meaningful with the lowering. A strict reading
makes it a major.
SCCSteadyStateProblem(sys, op)builds a fullSteadyStateProblem(including its initialization problem) only to processop, thencompiles the residual system.
build_initializeprob = falsebreaks hierarchicalinitialization_eqs. Is a lighter op-processing path worth adding?DynamicSS(Tsit5())withthe default
tspan = Infruns out of maxiters before the termination callback fires,even though the ODE is globally stable. A hand-written
SteadyStateProblembehaves thesame, so this is not caused by this change. The tests use
tspan = 100. Worth an SSDEissue?
SteadyStateSolution(=NonlinearSolution) on anSCCSteadyStateProblemcarries the compressed layout throughsol.prob.f.sys, and nodedicated SCC solution type was added. Is that the intended end state?
🤖 Posted by an AI agent — harness: Devin CLI 3000.11.3 (fix), Claude Code 2.1.285 (PR) · model: fusion-claude-opus-5-5-high-sidekick-swe-2-medium / claude-opus-5-5
Conversation: local Claude session 3c311569-dda6-4687-bc9f-65febb212c33 (fleet master)
🤖 Generated with Claude Code
Independent review (Codex CLI 0.162.1 gpt-6.1-sol, head c518e1c)
VERDICT: CHANGES
Read the full diff, supplied discussion, and intended linked issue (the supplied issue-171.json is unrelated). The explicit SCC problem has substantial analytic regression coverage. I reproduced the original layout bug on the base, but this head cannot resolve its dependencies. Risk is high (H1): documented SCCNonlinearProblem(::SteadyStateProblem) and fallback constructor methods are removed; ModelingToolkitBase is bumped to 2.0. Other matched criteria include L1/L2 (docs/tests), L5/ML4 (compat changes), and M1 (methods on SciMLBase constructors). The removed API requires a human release decision.
Not verified: head regression tests, full InterfaceII group, QA, docs build, downstream suites, and passing-after runtime behavior, because registered dependencies cannot resolve. Base aea9c2e resolved and reproduced the linked issue using SteadyStateDiffEq 2.18.1: solve returned Success, length(prob.u0) = 3, sol.u = Float64[], and both layout/time-dependence assertions failed (tmp/base-regression-rerun.log:9; standalone reproducer tmp/layout_regression.jl). No tracked repository files were modified and nothing was posted.
🤖 Posted by an AI agent — harness: Codex CLI 0.162.1 · model: gpt-6.1-sol
Conversation: Codex exec session 01a14b0e-4957-7330-8477-b8f8b86dd818 (no public URL)
Codex CLI gpt-6.1-sol rated it high (H1) at head c518e1c