Skip to content

Commit fb26f21

Browse files
committed
fix: update ext/tests to v10
1 parent e4c3e91 commit fb26f21

File tree

5 files changed

+84
-79
lines changed

5 files changed

+84
-79
lines changed

ext/MTKCasADiDynamicOptExt.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ function (M::MXLinearInterpolation)(τ)
6161
end
6262
end
6363

64-
function MTK.CasADiDynamicOptProblem(sys::ODESystem, u0map, tspan, pmap;
64+
function MTK.CasADiDynamicOptProblem(sys::System, op, tspan;
6565
dt = nothing,
6666
steps = nothing,
6767
guesses = Dict(), kwargs...)
68-
MTK.process_DynamicOptProblem(CasADiDynamicOptProblem, CasADiModel, sys, u0map, tspan, pmap; dt, steps, guesses, kwargs...)
68+
prob, _ = MTK.process_DynamicOptProblem(CasADiDynamicOptProblem, CasADiModel, sys, op, tspan; dt, steps, guesses, kwargs...)
69+
prob
6970
end
7071

7172
MTK.generate_internal_model(::Type{CasADiModel}) = CasADi.Opti()

ext/MTKInfiniteOptExt.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,19 @@ function MTK.add_constraint!(m::InfiniteOptModel, expr::Union{Equation, Inequali
7272
end
7373
MTK.set_objective!(m::InfiniteOptModel, expr) = @objective(m.model, Min, expr)
7474

75-
function MTK.JuMPDynamicOptProblem(sys::ODESystem, u0map, tspan, pmap;
75+
function MTK.JuMPDynamicOptProblem(sys::System, op, tspan;
7676
dt = nothing,
7777
steps = nothing,
7878
guesses = Dict(), kwargs...)
79-
MTK.process_DynamicOptProblem(JuMPDynamicOptProblem, InfiniteOptModel, sys, u0map, tspan, pmap; dt, steps, guesses, kwargs...)
79+
prob, _ = MTK.process_DynamicOptProblem(JuMPDynamicOptProblem, InfiniteOptModel, sys, op, tspan; dt, steps, guesses, kwargs...)
80+
prob
8081
end
8182

82-
function MTK.InfiniteOptDynamicOptProblem(sys::ODESystem, u0map, tspan, pmap;
83+
function MTK.InfiniteOptDynamicOptProblem(sys::System, op, tspan;
8384
dt = nothing,
8485
steps = nothing,
8586
guesses = Dict(), kwargs...)
86-
prob = MTK.process_DynamicOptProblem(InfiniteOptDynamicOptProblem, InfiniteOptModel, sys, u0map, tspan, pmap; dt, steps, guesses, kwargs...)
87+
prob, pmap = MTK.process_DynamicOptProblem(InfiniteOptDynamicOptProblem, InfiniteOptModel, sys, op, tspan; dt, steps, guesses, kwargs...)
8788
MTK.add_equational_constraints!(prob.wrapped_model, sys, pmap, tspan)
8889
prob
8990
end

ext/MTKPyomoDynamicOptExt.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ end
6666
pysym_getproperty(s::Union{Num, Symbolics.Symbolic}, name::Symbol) = Symbolics.wrap(SymbolicUtils.term(_getproperty, Symbolics.unwrap(s), Val{name}(), type = Symbolics.Struct{PyomoVar}))
6767
_getproperty(s, name::Val{fieldname}) where fieldname = getproperty(s, fieldname)
6868

69-
function MTK.PyomoDynamicOptProblem(sys::ODESystem, u0map, tspan, pmap;
69+
function MTK.PyomoDynamicOptProblem(sys::System, op, tspan;
7070
dt = nothing, steps = nothing,
7171
guesses = Dict(), kwargs...)
72-
prob = MTK.process_DynamicOptProblem(PyomoDynamicOptProblem, PyomoDynamicOptModel, sys, u0map, tspan, pmap; dt, steps, guesses, kwargs...)
72+
prob, pmap = MTK.process_DynamicOptProblem(PyomoDynamicOptProblem, PyomoDynamicOptModel, sys, op, tspan; dt, steps, guesses, kwargs...)
7373
conc_model = prob.wrapped_model.model
7474
MTK.add_equational_constraints!(prob.wrapped_model, sys, pmap, tspan)
7575
prob

src/systems/optimal_control_interface.jl

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ function Base.show(io::IO, sol::DynamicOptSolution)
1919
end
2020

2121
"""
22-
JuMPDynamicOptProblem(sys::ODESystem, u0, tspan, p; dt, steps, guesses, kwargs...)
22+
JuMPDynamicOptProblem(sys::System, u0, tspan, p; dt, steps, guesses, kwargs...)
2323
24-
Convert an ODESystem representing an optimal control system into a JuMP model
24+
Convert an System representing an optimal control system into a JuMP model
2525
for solving using optimization. Must provide either `dt`, the timestep between collocation
2626
points (which, along with the timespan, determines the number of points), or directly
2727
provide the number of points as `steps`.
@@ -30,9 +30,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
3030
"""
3131
function JuMPDynamicOptProblem end
3232
"""
33-
InfiniteOptDynamicOptProblem(sys::ODESystem, u0map, tspan, pmap; dt)
33+
InfiniteOptDynamicOptProblem(sys::System, op, tspan; dt)
3434
35-
Convert an ODESystem representing an optimal control system into a InfiniteOpt model
35+
Convert an System representing an optimal control system into a InfiniteOpt model
3636
for solving using optimization. Must provide `dt` for determining the length
3737
of the interpolation arrays.
3838
@@ -43,9 +43,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
4343
"""
4444
function InfiniteOptDynamicOptProblem end
4545
"""
46-
CasADiDynamicOptProblem(sys::ODESystem, u0, tspan, p; dt, steps, guesses, kwargs...)
46+
CasADiDynamicOptProblem(sys::System, u0, tspan, p; dt, steps, guesses, kwargs...)
4747
48-
Convert an ODESystem representing an optimal control system into a CasADi model
48+
Convert an System representing an optimal control system into a CasADi model
4949
for solving using optimization. Must provide either `dt`, the timestep between collocation
5050
points (which, along with the timespan, determines the number of points), or directly
5151
provide the number of points as `steps`.
@@ -54,9 +54,9 @@ To construct the problem, please load CasADi along with ModelingToolkit.
5454
"""
5555
function CasADiDynamicOptProblem end
5656
"""
57-
PyomoDynamicOptProblem(sys::ODESystem, u0, tspan, p; dt, steps)
57+
PyomoDynamicOptProblem(sys::System, u0, tspan, p; dt, steps)
5858
59-
Convert an ODESystem representing an optimal control system into a Pyomo model
59+
Convert an System representing an optimal control system into a Pyomo model
6060
for solving using optimization. Must provide either `dt`, the timestep between collocation
6161
points (which, along with the timespan, determines the number of points), or directly
6262
provide the number of points as `steps`.
@@ -91,11 +91,12 @@ Pyomo Collocation solver.
9191
"""
9292
function PyomoCollocation end
9393

94-
function warn_overdetermined(sys, u0map)
94+
function warn_overdetermined(sys, op)
9595
cstrs = constraints(sys)
96+
init_conds = filter(x -> value(x) Set(unknowns(sys)), [k for (k,v) in op])
9697
if !isempty(cstrs)
97-
(length(cstrs) + length(u0map) > length(unknowns(sys))) &&
98-
@warn "The control problem is overdetermined. The total number of conditions (# constraints + # fixed initial values given by u0map) exceeds the total number of states. The solvers will default to doing a nonlinear least-squares optimization."
98+
(length(cstrs) + length(init_conds) > length(unknowns(sys))) &&
99+
@warn "The control problem is overdetermined. The total number of conditions (# constraints + # fixed initial values given by op) exceeds the total number of states. The solvers will default to doing a nonlinear least-squares optimization."
99100
end
100101
end
101102

@@ -226,24 +227,27 @@ end
226227
##########################
227228
### MODEL CONSTRUCTION ###
228229
##########################
229-
function process_DynamicOptProblem(prob_type::Type{<:AbstractDynamicOptProblem}, model_type, sys::ODESystem, u0map, tspan, pmap;
230+
function process_DynamicOptProblem(prob_type::Type{<:AbstractDynamicOptProblem}, model_type, sys::System, op, tspan;
230231
dt = nothing,
231232
steps = nothing,
232233
guesses = Dict(), kwargs...)
233-
warn_overdetermined(sys, u0map)
234+
235+
warn_overdetermined(sys, op)
234236
ctrls = unbound_inputs(sys)
235237
states = unknowns(sys)
236238

237-
_u0map = has_alg_eqs(sys) ? u0map : merge(Dict(u0map), Dict(guesses))
238239
stidxmap = Dict([v => i for (i, v) in enumerate(states)])
239-
u0map = Dict([default_toterm(value(k)) => v for (k, v) in u0map])
240+
op = Dict([default_toterm(value(k)) => v for (k, v) in op])
240241
u0_idxs = has_alg_eqs(sys) ? collect(1:length(states)) :
241-
[stidxmap[default_toterm(k)] for (k, v) in u0map]
242+
[stidxmap[default_toterm(k)] for (k, v) in op if haskey(stidxmap, k)]
242243

243-
f, u0, p = process_SciMLProblem(ODEInputFunction, sys, _u0map, pmap;
244+
_op = has_alg_eqs(sys) ? op : merge(Dict(op), Dict(guesses))
245+
f, u0, p = process_SciMLProblem(ODEInputFunction, sys, _op;
244246
t = tspan !== nothing ? tspan[1] : tspan, kwargs...)
245247
model_tspan, steps, is_free_t = process_tspan(tspan, dt, steps)
248+
warn_overdetermined(sys, op)
246249

250+
pmap = filter(p -> (first(p) Set(unknowns(sys))), op)
247251
pmap = recursive_unwrap(AnyDict(pmap))
248252
evaluate_varmap!(pmap, keys(pmap))
249253
c0 = value.([pmap[c] for c in ctrls])
@@ -261,7 +265,7 @@ function process_DynamicOptProblem(prob_type::Type{<:AbstractDynamicOptProblem},
261265
add_user_constraints!(fullmodel, sys, tspan, pmap)
262266
add_initial_constraints!(fullmodel, u0, u0_idxs, model_tspan[1])
263267

264-
prob_type(f, u0, tspan, p, fullmodel, kwargs...)
268+
prob_type(f, u0, tspan, p, fullmodel, kwargs...), pmap
265269
end
266270

267271
function generate_time_variable! end
@@ -301,16 +305,16 @@ end
301305
is_free_final(model) = model.is_free_final
302306

303307
function add_cost_function!(model, sys, tspan, pmap)
304-
jcosts = copy(get_costs(sys))
305-
consolidate = get_consolidate(sys)
306-
if isnothing(jcosts) || isempty(jcosts)
308+
jcosts = cost(sys)
309+
if Symbolics._iszero(jcosts)
307310
set_objective!(model, 0)
308311
return
309312
end
310-
jcosts = substitute_model_vars(model, sys, jcosts, tspan)
313+
314+
jcosts = substitute_model_vars(model, sys, [jcosts], tspan)
311315
jcosts = substitute_params(pmap, jcosts)
312-
jcosts = substitute_integral(model, jcosts, tspan)
313-
set_objective!(model, consolidate(jcosts))
316+
jcosts = substitute_integral(model, only(jcosts), tspan)
317+
set_objective!(model, value(jcosts))
314318
end
315319

316320
"""
@@ -319,16 +323,16 @@ Substitute integrals. For an integral from (ts, te):
319323
- CasADi cannot handle partial timespans, even for non-free-final time problems.
320324
time problems and unchanged otherwise.
321325
"""
322-
function substitute_integral(model, exprs, tspan)
326+
function substitute_integral(model, expr, tspan)
323327
intmap = Dict()
324-
for int in collect_applied_operators(exprs, Symbolics.Integral)
328+
for int in collect_applied_operators(expr, Symbolics.Integral)
325329
op = operation(int)
326330
arg = only(arguments(value(int)))
327331
lo, hi = value.((op.domain.domain.left, op.domain.domain.right))
328332
lo, hi = process_integral_bounds(model, (lo, hi), tspan)
329333
intmap[int] = lowered_integral(model, arg, lo, hi)
330334
end
331-
exprs = map(c -> Symbolics.substitute(c, intmap), value.(exprs))
335+
Symbolics.substitute(expr, intmap)
332336
end
333337

334338
function process_integral_bounds(model, integral_span, tspan)
@@ -386,13 +390,13 @@ function lowered_var end
386390
function fixed_t_map end
387391

388392
function add_user_constraints!(model, sys, tspan, pmap)
389-
conssys = get_constraintsystem(sys)
390-
jconstraints = isnothing(conssys) ? nothing : get_constraints(conssys)
393+
jconstraints = get_constraints(sys)
391394
(isnothing(jconstraints) || isempty(jconstraints)) && return nothing
392-
consvars = get_unknowns(conssys)
393-
is_free_final(model) && check_constraint_vars(consvars)
395+
cons_dvs, cons_ps = process_constraint_system(jconstraints, Set(unknowns(sys)), parameters(sys), get_iv(sys); validate = false)
396+
397+
is_free_final(model) && check_constraint_vars(cons_dvs)
394398

395-
jconstraints = substitute_toterm(consvars, jconstraints)
399+
jconstraints = substitute_toterm(cons_dvs, jconstraints)
396400
jconstraints = substitute_model_vars(model, sys, jconstraints, tspan)
397401
jconstraints = substitute_params(pmap, jconstraints)
398402

0 commit comments

Comments
 (0)