Skip to content

Commit 31f260d

Browse files
feat: preserve the u0map passed to ODEProblem and use it in remake_initializeprob
1 parent a16ea8c commit 31f260d

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/systems/nonlinear/initializesystem.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,22 @@ function generate_initializesystem(sys::ODESystem;
153153
for k in keys(defs)
154154
defs[k] = substitute(defs[k], paramsubs)
155155
end
156+
meta = InitializationSystemMetadata(Dict{Any, Any}(u0map), Dict{Any, Any}(pmap))
156157
return NonlinearSystem(eqs_ics,
157158
vars,
158159
pars;
159160
defaults = defs,
160161
checks = check_units,
161162
name,
163+
metadata = meta,
162164
kwargs...)
163165
end
164166

167+
struct InitializationSystemMetadata
168+
u0map::Dict{Any, Any}
169+
pmap::Dict{Any, Any}
170+
end
171+
165172
function is_parameter_solvable(p, pmap, defs, guesses)
166173
_val1 = pmap isa AbstractDict ? get(pmap, p, nothing) : nothing
167174
_val2 = get(defs, p, nothing)
@@ -249,6 +256,15 @@ function SciMLBase.remake_initializeprob(sys::ODESystem, odefn, u0, t0, p)
249256
!isempty(setobserved) || !isempty(setparobserved)) &&
250257
ModelingToolkit.get_tearing_state(sys) !== nothing) ||
251258
!isempty(initialization_equations(sys)))
259+
if SciMLBase.has_initializeprob(odefn)
260+
oldsys = odefn.initializeprob.f.sys
261+
meta = get_metadata(oldsys)
262+
if meta isa InitializationSystemMetadata
263+
u0 = merge(meta.u0map, u0)
264+
p = merge(meta.pmap, p)
265+
end
266+
end
267+
252268
initprob = InitializationProblem(sys, t0, u0, p)
253269
initprobmap = getu(initprob, unknowns(sys))
254270
punknowns = [p for p in all_variable_symbols(initprob) if is_parameter(sys, p)]

test/initializationsystem.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,19 @@ end
779779
@test eltype(prob2.f.initializeprob.p.tunable) <: ForwardDiff.Dual
780780
@test prob2.f.initializeprob.u0 prob.f.initializeprob.u0
781781
end
782+
783+
@testset "`remake` preserves old u0map and pmap" begin
784+
@variables x(t) y(t)
785+
@parameters p
786+
@mtkbuild sys = ODESystem(
787+
[D(x) ~ x + p * y, y^2 + 4y * p^2 ~ x], t; guesses = [y => 1.0, p => 1.0])
788+
prob = ODEProblem(sys, [x => 1.0], (0.0, 1.0), [p => 1.0])
789+
@test is_variable(prob.f.initializeprob, y)
790+
prob2 = @test_nowarn remake(prob; p = [p => 3.0]) # ensure no over/under-determined warning
791+
@test is_variable(prob.f.initializeprob, y)
792+
793+
prob = ODEProblem(sys, [y => 1.0, x => 2.0], (0.0, 1.0), [p => missing])
794+
@test is_variable(prob.f.initializeprob, p)
795+
prob2 = @test_nowarn remake(prob; u0 = [y => 0.5])
796+
@test is_variable(prob.f.initializeprob, p)
797+
end

0 commit comments

Comments
 (0)