Skip to content

Commit e715e28

Browse files
feat: turn parameter dependencies into initialization equations
1 parent 1a03b5a commit e715e28

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/systems/abstractsystem.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,15 @@ function has_observed_with_lhs(sys, sym)
704704
end
705705
end
706706

707+
function has_parameter_dependency_with_lhs(sys, sym)
708+
has_parameter_dependencies(sys) || return false
709+
if has_index_cache(sys) && (ic = get_index_cache(sys)) !== nothing
710+
return any(isequal(sym), ic.dependent_pars)
711+
else
712+
return any(isequal(sym), [eq.lhs for eq in parameter_dependencies(sys)])
713+
end
714+
end
715+
707716
function _all_ts_idxs!(ts_idxs, ::NotSymbolic, sys, sym)
708717
if is_variable(sys, sym) || is_independent_variable(sys, sym)
709718
push!(ts_idxs, ContinuousTimeseries())

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,13 +860,23 @@ function process_DEProblem(constructor, sys::AbstractODESystem, u0map, parammap;
860860
solvablepars = [p
861861
for p in parameters(sys)
862862
if is_parameter_solvable(p, parammap, defs, guesses)]
863+
864+
pvarmap = if parammap === nothing || parammap == SciMLBase.NullParameters() || !(eltype(parammap) <: Pair) && isempty(parammap)
865+
defs
866+
else
867+
merge(defs, todict(parammap))
868+
end
869+
setparobserved = filter(keys(pvarmap)) do var
870+
has_parameter_dependency_with_lhs(sys, var)
871+
end
863872
else
864873
solvablepars = ()
874+
setparobserved = ()
865875
end
866876
# ModelingToolkit.get_tearing_state(sys) !== nothing => Requires structural_simplify first
867877
if sys isa ODESystem && build_initializeprob &&
868878
(((implicit_dae || !isempty(missingvars) || !isempty(solvablepars) ||
869-
!isempty(setobserved)) &&
879+
!isempty(setobserved) || !isempty(setparobserved)) &&
870880
ModelingToolkit.get_tearing_state(sys) !== nothing) ||
871881
!isempty(initialization_equations(sys))) && t !== nothing
872882
if eltype(u0map) <: Number

src/systems/nonlinear/initializesystem.jl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,19 +146,34 @@ function generate_initializesystem(sys::ODESystem;
146146
end
147147
end
148148
end
149+
150+
# parameter dependencies become equations, their LHS become unknowns
151+
for eq in parameter_dependencies(sys)
152+
varp = tovar(eq.lhs)
153+
paramsubs[eq.lhs] = varp
154+
push!(eqs_ics, eq)
155+
guessval = get(guesses, eq.lhs, eq.rhs)
156+
push!(u0, varp => guessval)
157+
end
158+
159+
# handle values provided for dependent parameters
160+
for (k, v) in merge(defaults(sys), pmap)
161+
if has_parameter_dependency_with_lhs(sys, k)
162+
push!(eqs_ics, paramsubs[k] ~ v)
163+
end
164+
end
149165
pars = vcat(
150166
[get_iv(sys)],
151167
[p for p in parameters(sys) if !haskey(paramsubs, p)]
152168
)
153169
nleqs = [eqs_ics; observed(sys)]
154170
nleqs = Symbolics.substitute.(nleqs, (paramsubs,))
155171
unks = [full_states; collect(values(paramsubs))]
156-
172+
u0 = Dict(k => substitute(v, paramsubs) for (k, v) in u0)
157173
sys_nl = NonlinearSystem(nleqs,
158174
unks,
159175
pars;
160176
defaults = merge(ModelingToolkit.defaults(sys), todict(u0), dd_guess, pmap),
161-
parameter_dependencies = parameter_dependencies(sys),
162177
checks = check_units,
163178
name,
164179
kwargs...)
@@ -205,8 +220,12 @@ function SciMLBase.remake_initializeprob(sys::ODESystem, odefn, u0, t0, p)
205220
solvablepars = [par
206221
for par in parameters(sys)
207222
if is_parameter_solvable(par, p, defs, guesses)]
223+
pvarmap = merge(defs, p)
224+
setparobserved = filter(keys(pvarmap)) do var
225+
has_parameter_dependency_with_lhs(sys, var)
226+
end
208227
if (((!isempty(missingvars) || !isempty(solvablepars) ||
209-
!isempty(setobserved)) &&
228+
!isempty(setobserved) || !isempty(setparobserved)) &&
210229
ModelingToolkit.get_tearing_state(sys) !== nothing) ||
211230
!isempty(initialization_equations(sys)))
212231
initprob = InitializationProblem(sys, t0, u0, p)

0 commit comments

Comments
 (0)