Skip to content

Commit 910ce55

Browse files
feat: use LinearProblem for linear SCCs in SCCNonlinearProblem
1 parent 5273028 commit 910ce55

File tree

1 file changed

+27
-13
lines changed

1 file changed

+27
-13
lines changed

src/problems/sccnonlinearproblem.jl

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ end
1010

1111
function CacheWriter(sys::AbstractSystem, buffer_types::Vector{TypeT},
1212
exprs::Dict{TypeT, Vector{Any}}, solsyms, obseqs::Vector{Equation};
13-
eval_expression = false, eval_module = @__MODULE__, cse = true)
13+
eval_expression = false, eval_module = @__MODULE__, cse = true, sparse = false)
1414
ps = parameters(sys; initial_parameters = true)
1515
rps = reorder_parameters(sys, ps)
1616
obs_assigns = [eq.lhs eq.rhs for eq in obseqs]
@@ -39,9 +39,22 @@ end
3939
struct SCCNonlinearFunction{iip} end
4040

4141
function SCCNonlinearFunction{iip}(
42-
sys::System, _eqs, _dvs, _obs, cachesyms; eval_expression = false,
42+
sys::System, _eqs, _dvs, _obs, cachesyms, op; eval_expression = false,
4343
eval_module = @__MODULE__, cse = true, kwargs...) where {iip}
4444
ps = parameters(sys; initial_parameters = true)
45+
subsys = System(
46+
_eqs, _dvs, ps; observed = _obs, name = nameof(sys), defaults = defaults(sys))
47+
@set! subsys.parameter_dependencies = parameter_dependencies(sys)
48+
if get_index_cache(sys) !== nothing
49+
@set! subsys.index_cache = subset_unknowns_observed(
50+
get_index_cache(sys), sys, _dvs, getproperty.(_obs, (:lhs,)))
51+
@set! subsys.complete = true
52+
end
53+
# generate linear problem instead
54+
if isaffine(subsys)
55+
return LinearFunction{iip}(
56+
subsys; eval_expression, eval_module, cse, cachesyms, kwargs...)
57+
end
4558
rps = reorder_parameters(sys, ps)
4659

4760
obs_assignments = [eq.lhs eq.rhs for eq in _obs]
@@ -54,14 +67,6 @@ function SCCNonlinearFunction{iip}(
5467
f_oop, f_iip = eval_or_rgf.(f_gen; eval_expression, eval_module)
5568
f = GeneratedFunctionWrapper{(2, 2, is_split(sys))}(f_oop, f_iip)
5669

57-
subsys = System(_eqs, _dvs, ps; observed = _obs,
58-
parameter_dependencies = parameter_dependencies(sys), name = nameof(sys))
59-
if get_index_cache(sys) !== nothing
60-
@set! subsys.index_cache = subset_unknowns_observed(
61-
get_index_cache(sys), sys, _dvs, getproperty.(_obs, (:lhs,)))
62-
@set! subsys.complete = true
63-
end
64-
6570
return NonlinearFunction{iip}(f; sys = subsys)
6671
end
6772

@@ -70,7 +75,7 @@ function SciMLBase.SCCNonlinearProblem(sys::System, args...; kwargs...)
7075
end
7176

7277
function SciMLBase.SCCNonlinearProblem{iip}(sys::System, op; eval_expression = false,
73-
eval_module = @__MODULE__, cse = true, kwargs...) where {iip}
78+
eval_module = @__MODULE__, cse = true, u0_constructor = identity, kwargs...) where {iip}
7479
if !iscomplete(sys) || get_tearing_state(sys) === nothing
7580
error("A simplified `System` is required. Call `mtkcompile` on the system before creating an `SCCNonlinearProblem`.")
7681
end
@@ -224,7 +229,8 @@ function SciMLBase.SCCNonlinearProblem{iip}(sys::System, op; eval_expression = f
224229
get(cachevars, T, [])
225230
end)
226231
f = SCCNonlinearFunction{iip}(
227-
sys, _eqs, _dvs, _obs, cachebufsyms; eval_expression, eval_module, cse, kwargs...)
232+
sys, _eqs, _dvs, _obs, cachebufsyms, op;
233+
eval_expression, eval_module, cse, kwargs...)
228234
push!(nlfuns, f)
229235
end
230236

@@ -245,7 +251,15 @@ function SciMLBase.SCCNonlinearProblem{iip}(sys::System, op; eval_expression = f
245251
for (f, vscc) in zip(nlfuns, var_sccs)
246252
_u0 = SymbolicUtils.Code.create_array(
247253
typeof(u0), eltype(u0), Val(1), Val(length(vscc)), u0[vscc]...)
248-
prob = NonlinearProblem(f, _u0, p)
254+
if f isa LinearFunction
255+
symbolic_interface = f.interface
256+
A,
257+
b = get_A_b_from_LinearFunction(
258+
sys, f, p; eval_expression, eval_module, u0_constructor)
259+
prob = LinearProblem(A, b, p; u0 = _u0, f = symbolic_interface)
260+
else
261+
prob = NonlinearProblem(f, _u0, p)
262+
end
249263
push!(subprobs, prob)
250264
end
251265

0 commit comments

Comments
 (0)