Skip to content

Compute initial states for u0 if u0 is parametric #2103

Closed
@MarcBerliner

Description

@MarcBerliner

If u0 is known to be a parametric function, changing the parameters will affect the initial values (e.g., for ODEs) and/or the initial guess for algebraic equations (e.g., DAEs). This problem can be avoided if MTK detects any parametric initial states (when declaring @variables u(t) = p or ODEProblem(sys, [u => p])) and generates a function to recompute the initial states upon declaring new parameters.

It would be helpful if this is included in remake (e.g., when calling remake(prob; p=...)) and as an internal function (e.g., generate_initial_states!(prob) or something).

MWE:

using ModelingToolkit, OrdinaryDiffEq
@parameters p = 1
@variables t u(t)

eqs = [Differential(t)(u) ~ 1]

@named sys = ODESystem(eqs,t,[u],[p],tspan=(0, 10))

prob = ODEProblem(sys, [u => p])

sol = solve(prob, Tsit5())
# sol.u[end] ≈ 11

# remake the problem with new parameters
prob_new = remake(prob; p=[p => 2])
# however, u0 is still 1
# prob_new.u0[1] == 1

sol_new = solve(prob_new, Tsit5())
# sol_new.u[end] ≈ 11, and not 12

An ideal workflow where I can define u(t) = p:

using ModelingToolkit, OrdinaryDiffEq
@parameters p = 1
@variables t u(t) = p

eqs = [Differential(t)(u) ~ 1]

@named sys = ODESystem(eqs,t,[u],[p],tspan=(0, 10))

prob = ODEProblem(sys)

sol = solve(prob, Tsit5())
# sol.u[end] ≈ 11

# remake the problem with new parameters
prob_new = remake(prob; p=[p => 2])
# now, u0 is 2
# prob_new.u0[1] == 2

sol_new = solve(prob_new, Tsit5())
# sol_new.u[end] ≈ 12

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions