@@ -78,28 +78,25 @@ function run_simulate(ode_prob,
7878 # Redirect all library log output (including Symbolics/MTK warnings)
7979 # to the log file so they don't clutter stdout.
8080 sol = Logging. with_logger (logger) do
81- # Overwrite saveat, always use dense output.
82- # For stateless models (no unknowns) the adaptive solver takes no
83- # internal steps and sol.t would be empty with saveat=[].
84- # Supply explicit time points so observed variables can be evaluated.
81+ # Special handling for systems without states
8582 sys = ode_prob. f. sys
8683 n_unknowns = length (ModelingToolkit. unknowns (sys))
87-
88- kwargs = if n_unknowns == 0
89- # No unknowns at all (e.g. BusUsage):
90- # Supply explicit time points so observed variables can be evaluated.
84+ eqs = ModelingToolkit. equations (sys)
85+ n_states = count (ModelingToolkitBase. isdiffeq, eqs)
86+ kwargs, active_solver = if n_states == 0
87+ # No state variables (e.g. BusUsage, Modelica.Electrical.Analog.Examples.OpAmps.Subtracter):
88+ # Use Rodas5Pr on a fixed grid so observed variables can be evaluated at each step.
89+ dt_s = (ode_prob. tspan[end ] - ode_prob. tspan[1 ]) / (settings. saveat_n - 1 )
9190 saveat_s = collect (range (ode_prob. tspan[1 ], ode_prob. tspan[end ]; length = settings. saveat_n))
92- (saveat = saveat_s, dense = true )
91+ (saveat = saveat_s, dt = dt_s, adaptive = false , dense = false ),
92+ DifferentialEquations. Rodas5Pr ()
9393 else
94- (saveat = Float64[], dense = true )
94+ saveat_s = Float64[]
95+ (saveat = saveat_s, dense = true ), solver
9596 end
9697
97- # Log solver settings — init returns NullODEIntegrator (no .opts)
98- # when the problem has no unknowns (u::Nothing), so only inspect
99- # opts when a real integrator is returned.
100- # Use our own `saveat` vector for the log: integ.opts.saveat is a
101- # BinaryHeap which does not support iterate/minimum/maximum.
102- integ = DifferentialEquations. init (ode_prob, solver; kwargs... )
98+ # Log solver settings
99+ integ = DifferentialEquations. init (ode_prob, active_solver; kwargs... )
103100 saveat_s = kwargs. saveat
104101 solver_settings_string = if hasproperty (integ, :opts )
105102 sv_str = isempty (saveat_s) ? " []" : " $(length (saveat_s)) points in [$(first (saveat_s)) , $(last (saveat_s)) ]"
@@ -119,7 +116,7 @@ function run_simulate(ode_prob,
119116 end
120117
121118 # Solve
122- DifferentialEquations. solve (ode_prob, solver ; kwargs... )
119+ DifferentialEquations. solve (ode_prob, active_solver ; kwargs... )
123120 end
124121 sim_time = time () - t0
125122 if sol. retcode == DifferentialEquations. ReturnCode. Success
0 commit comments