@@ -42,14 +42,14 @@ struct CasADiDynamicOptProblem{uType, tType, isinplace, P, F, K} <:
42
42
end
43
43
end
44
44
45
- function (M:: MXLinearInterpolation )(τ)
45
+ function (M:: MXLinearInterpolation )(τ)
46
46
nt = (τ - M. t[1 ]) / M. dt
47
47
i = 1 + floor (Int, nt)
48
48
Δ = nt - i + 1
49
49
50
50
(i > length (M. t) || i < 1 ) && error (" Cannot extrapolate past the tspan." )
51
51
if i < length (M. t)
52
- M. u[:, i] + Δ* (M. u[:, i + 1 ] - M. u[:, i])
52
+ M. u[:, i] + Δ * (M. u[:, i + 1 ] - M. u[:, i])
53
53
else
54
54
M. u[:, i]
55
55
end
@@ -74,7 +74,7 @@ The constraints are:
74
74
function MTK. CasADiDynamicOptProblem (sys:: ODESystem , u0map, tspan, pmap;
75
75
dt = nothing ,
76
76
steps = nothing ,
77
- guesses = Dict (), kwargs... )
77
+ guesses = Dict (), kwargs... )
78
78
MTK. warn_overdetermined (sys, u0map)
79
79
_u0map = has_alg_eqs (sys) ? u0map : merge (Dict (u0map), Dict (guesses))
80
80
f, u0, p = MTK. process_SciMLProblem (ODEInputFunction, sys, _u0map, pmap;
@@ -104,21 +104,21 @@ function init_model(sys, tspan, steps, u0map, pmap, u0; is_free_t = false)
104
104
subject_to! (opti, tₛ >= lo)
105
105
subject_to! (opti, tₛ >= hi)
106
106
end
107
- pmap[te_sym] = tₛ
107
+ pmap[te_sym] = tₛ
108
108
tsteps = LinRange (0 , 1 , steps)
109
109
else
110
110
tₛ = MX (1 )
111
111
tsteps = LinRange (tspan[1 ], tspan[2 ], steps)
112
112
end
113
-
113
+
114
114
U = CasADi. variable! (opti, length (states), steps)
115
115
V = CasADi. variable! (opti, length (ctrls), steps)
116
116
set_initial! (opti, U, DM (repeat (u0, 1 , steps)))
117
117
c0 = MTK. value .([pmap[c] for c in ctrls])
118
118
! isempty (c0) && set_initial! (opti, V, DM (repeat (c0, 1 , steps)))
119
119
120
- U_interp = MXLinearInterpolation (U, tsteps, tsteps[2 ]- tsteps[1 ])
121
- V_interp = MXLinearInterpolation (V, tsteps, tsteps[2 ]- tsteps[1 ])
120
+ U_interp = MXLinearInterpolation (U, tsteps, tsteps[2 ] - tsteps[1 ])
121
+ V_interp = MXLinearInterpolation (V, tsteps, tsteps[2 ] - tsteps[1 ])
122
122
for (i, ct) in enumerate (ctrls)
123
123
pmap[ct] = V[i, :]
124
124
end
@@ -185,8 +185,8 @@ function add_user_constraints!(model::CasADiModel, sys, tspan, pmap; is_free_t)
185
185
x = MTK. operation (st)
186
186
t = only (MTK. arguments (st))
187
187
MTK. symbolic_type (t) === MTK. NotSymbolic () || continue
188
- if haskey (stidxmap, x (iv))
189
- idx = stidxmap[x (iv)]
188
+ if haskey (stidxmap, x (iv))
189
+ idx = stidxmap[x (iv)]
190
190
cv = U
191
191
else
192
192
idx = ctidxmap[x (iv)]
@@ -196,11 +196,11 @@ function add_user_constraints!(model::CasADiModel, sys, tspan, pmap; is_free_t)
196
196
end
197
197
198
198
if cons isa Equation
199
- subject_to! (opti, cons. lhs - cons. rhs== 0 )
199
+ subject_to! (opti, cons. lhs - cons. rhs == 0 )
200
200
elseif cons. relational_op === Symbolics. geq
201
- subject_to! (opti, cons. lhs - cons. rhs≥ 0 )
201
+ subject_to! (opti, cons. lhs - cons. rhs ≥ 0 )
202
202
else
203
- subject_to! (opti, cons. lhs - cons. rhs≤ 0 )
203
+ subject_to! (opti, cons. lhs - cons. rhs ≤ 0 )
204
204
end
205
205
end
206
206
end
@@ -227,8 +227,8 @@ function add_cost_function!(model::CasADiModel, sys, tspan, pmap; is_free_t)
227
227
x = operation (st)
228
228
t = only (arguments (st))
229
229
MTK. symbolic_type (t) === MTK. NotSymbolic () || continue
230
- if haskey (stidxmap, x (iv))
231
- idx = stidxmap[x (iv)]
230
+ if haskey (stidxmap, x (iv))
231
+ idx = stidxmap[x (iv)]
232
232
cv = U
233
233
else
234
234
idx = ctidxmap[x (iv)]
@@ -244,7 +244,8 @@ function add_cost_function!(model::CasADiModel, sys, tspan, pmap; is_free_t)
244
244
op = MTK. operation (int)
245
245
arg = only (arguments (MTK. value (int)))
246
246
lo, hi = (op. domain. domain. left, op. domain. domain. right)
247
- ! isequal ((lo, hi), tspan) && error (" Non-whole interval bounds for integrals are not currently supported for CasADiDynamicOptProblem." )
247
+ ! isequal ((lo, hi), tspan) &&
248
+ error (" Non-whole interval bounds for integrals are not currently supported for CasADiDynamicOptProblem." )
248
249
# Approximate integral as sum.
249
250
intmap[int] = dt * tₛ * sum (arg)
250
251
end
@@ -253,7 +254,8 @@ function add_cost_function!(model::CasADiModel, sys, tspan, pmap; is_free_t)
253
254
minimize! (opti, MX (MTK. value (consolidate (jcosts))))
254
255
end
255
256
256
- function substitute_casadi_vars (model:: CasADiModel , sys, pmap, exprs; auxmap:: Dict = Dict (), is_free_t)
257
+ function substitute_casadi_vars (
258
+ model:: CasADiModel , sys, pmap, exprs; auxmap:: Dict = Dict (), is_free_t)
257
259
@unpack opti, U, V, tₛ = model
258
260
iv = MTK. get_iv (sys)
259
261
sts = unknowns (sys)
@@ -281,44 +283,44 @@ end
281
283
282
284
function add_solve_constraints (prob, tableau)
283
285
@unpack A, α, c = tableau
284
- @unpack model, f, p = prob
286
+ @unpack model, f, p = prob
285
287
@unpack opti, U, V, tₛ = model
286
288
solver_opti = copy (opti)
287
289
288
- tsteps = U. t
290
+ tsteps = U. t
289
291
dt = tsteps[2 ] - tsteps[1 ]
290
292
291
293
nᵤ = size (U. u, 1 )
292
294
nᵥ = size (V. u, 1 )
293
295
294
296
if MTK. is_explicit (tableau)
295
297
K = MX[]
296
- for k in 1 : length (tsteps)- 1
298
+ for k in 1 : ( length (tsteps) - 1 )
297
299
τ = tsteps[k]
298
300
for (i, h) in enumerate (c)
299
301
ΔU = sum ([A[i, j] * K[j] for j in 1 : (i - 1 )], init = MX (zeros (nᵤ)))
300
- Uₙ = U. u[:, k] + ΔU* dt
302
+ Uₙ = U. u[:, k] + ΔU * dt
301
303
Vₙ = V. u[:, k]
302
304
Kₙ = tₛ * f (Uₙ, Vₙ, p, τ + h * dt) # scale the time
303
305
push! (K, Kₙ)
304
306
end
305
307
ΔU = dt * sum ([α[i] * K[i] for i in 1 : length (α)])
306
- subject_to! (solver_opti, U. u[:, k] + ΔU == U. u[:, k+ 1 ])
308
+ subject_to! (solver_opti, U. u[:, k] + ΔU == U. u[:, k + 1 ])
307
309
empty! (K)
308
310
end
309
311
else
310
- for k in 1 : length (tsteps)- 1
312
+ for k in 1 : ( length (tsteps) - 1 )
311
313
τ = tsteps[k]
312
314
Kᵢ = variable! (solver_opti, nᵤ, length (α))
313
315
ΔUs = A * Kᵢ' # the stepsize at each stage of the implicit method
314
316
for (i, h) in enumerate (c)
315
- ΔU = ΔUs[i,:]'
316
- Uₙ = U. u[:,k] + ΔU* dt
317
- Vₙ = V. u[:,k]
318
- subject_to! (solver_opti, Kᵢ[:,i] == tₛ * f (Uₙ, Vₙ, p, τ + h* dt))
317
+ ΔU = ΔUs[i, :]'
318
+ Uₙ = U. u[:, k] + ΔU * dt
319
+ Vₙ = V. u[:, k]
320
+ subject_to! (solver_opti, Kᵢ[:, i] == tₛ * f (Uₙ, Vₙ, p, τ + h * dt))
319
321
end
320
- ΔU_tot = dt* (Kᵢ* α)
321
- subject_to! (solver_opti, U. u[:, k] + ΔU_tot == U. u[:,k + 1 ])
322
+ ΔU_tot = dt * (Kᵢ * α)
323
+ subject_to! (solver_opti, U. u[:, k] + ΔU_tot == U. u[:, k + 1 ])
322
324
end
323
325
end
324
326
solver_opti
331
333
332
334
NOTE: the solver should be passed in as a string to CasADi. "ipopt"
333
335
"""
334
- function DiffEqBase. solve (prob:: CasADiDynamicOptProblem , solver:: Union{String, Symbol} = " ipopt" , tableau_getter = MTK. constructDefault; plugin_options:: Dict = Dict (), solver_options:: Dict = Dict (), silent = false )
336
+ function DiffEqBase. solve (
337
+ prob:: CasADiDynamicOptProblem , solver:: Union{String, Symbol} = " ipopt" ,
338
+ tableau_getter = MTK. constructDefault; plugin_options:: Dict = Dict (),
339
+ solver_options:: Dict = Dict (), silent = false )
335
340
@unpack model, u0, p, tspan, f = prob
336
341
tableau = tableau_getter ()
337
342
@unpack opti, U, V, tₛ = model
@@ -366,7 +371,8 @@ function DiffEqBase.solve(prob::CasADiDynamicOptProblem, solver::Union{String, S
366
371
end
367
372
368
373
if failed
369
- ode_sol = SciMLBase. solution_new_retcode (ode_sol, SciMLBase. ReturnCode. ConvergenceFailure)
374
+ ode_sol = SciMLBase. solution_new_retcode (
375
+ ode_sol, SciMLBase. ReturnCode. ConvergenceFailure)
370
376
! isnothing (input_sol) && (input_sol = SciMLBase. solution_new_retcode (
371
377
input_sol, SciMLBase. ReturnCode. ConvergenceFailure))
372
378
end
0 commit comments