@@ -7,6 +7,20 @@ using NaNMath
7
7
using Setfield
8
8
const MTK = ModelingToolkit
9
9
10
+ SPECIAL_FUNCTIONS_DICT = Dict ([acos => Pyomo. py_acos,
11
+ log1p => Pyomo. py_log1p,
12
+ acosh => Pyomo. py_acosh,
13
+ log2 => Pyomo. py_log2,
14
+ asin => Pyomo. py_asin,
15
+ tan => Pyomo. py_tan,
16
+ atanh => Pyomo. py_atanh,
17
+ cos => Pyomo. py_cos,
18
+ log => Pyomo. py_log,
19
+ sin => Pyomo. py_sin,
20
+ log10 => Pyomo. py_log10,
21
+ sqrt => Pyomo. py_sqrt,
22
+ exp => Pyomo. py_exp])
23
+
10
24
struct PyomoDynamicOptModel
11
25
model:: ConcreteModel
12
26
U:: PyomoVar
@@ -17,13 +31,12 @@ struct PyomoDynamicOptModel
17
31
dU:: PyomoVar
18
32
model_sym:: Union{Num, Symbolics.BasicSymbolic}
19
33
t_sym:: Union{Num, Symbolics.BasicSymbolic}
20
- uidx_sym:: Union{Num, Symbolics.BasicSymbolic}
21
- vidx_sym:: Union{Num, Symbolics.BasicSymbolic}
34
+ dummy_sym:: Union{Num, Symbolics.BasicSymbolic}
22
35
23
36
function PyomoDynamicOptModel (model, U, V, tₛ, is_free_final)
24
- @variables MODEL_SYM:: Symbolics.symstruct (ConcreteModel) U_IDX_SYM :: Int V_IDX_SYM :: Int T_SYM
37
+ @variables MODEL_SYM:: Symbolics.symstruct (ConcreteModel) T_SYM DUMMY_SYM
25
38
model. dU = dae. DerivativeVar (U, wrt = model. t, initialize = 0 )
26
- new (model, U, V, tₛ, is_free_final, nothing , PyomoVar (model. dU), MODEL_SYM, T_SYM, U_IDX_SYM, V_IDX_SYM )
39
+ new (model, U, V, tₛ, is_free_final, nothing , PyomoVar (model. dU), MODEL_SYM, T_SYM, DUMMY_SYM )
27
40
end
28
41
end
29
42
@@ -42,7 +55,7 @@ struct PyomoDynamicOptProblem{uType, tType, isinplace, P, F, K} <:
42
55
end
43
56
end
44
57
45
- pysym_getproperty (s, name:: Symbol ) = Symbolics. wrap (SymbolicUtils. term (_getproperty, s , Val {name} (), type = Symbolics. Struct{PyomoVar}))
58
+ pysym_getproperty (s:: Union{Num, Symbolics.Symbolic} , name:: Symbol ) = Symbolics. wrap (SymbolicUtils. term (_getproperty, Symbolics . unwrap (s) , Val {name} (), type = Symbolics. Struct{PyomoVar}))
46
59
_getproperty (s, name:: Val{fieldname} ) where fieldname = getproperty (s, fieldname)
47
60
48
61
function MTK. PyomoDynamicOptProblem (sys:: ODESystem , u0map, tspan, pmap;
@@ -78,22 +91,38 @@ function MTK.generate_timescale!(m::ConcreteModel, guess, is_free_t)
78
91
end
79
92
80
93
function MTK. add_constraint! (pmodel:: PyomoDynamicOptModel , cons; n_idxs = 1 )
81
- @unpack model, model_sym, t_sym = pmodel
94
+ @unpack model, model_sym, t_sym, dummy_sym = pmodel
82
95
expr = if cons isa Equation
83
96
cons. lhs - cons. rhs == 0
84
97
elseif cons. relational_op === Symbolics. geq
85
98
cons. lhs - cons. rhs ≥ 0
86
99
else
87
100
cons. lhs - cons. rhs ≤ 0
88
101
end
89
- f_expr = Symbolics. build_function (expr, model_sym, t_sym)
102
+ expr = Symbolics. substitute (expr, SPECIAL_FUNCTIONS_DICT)
103
+ @show expr
104
+
90
105
cons_sym = Symbol (" cons" , hash (cons))
91
- constraint_f = eval (:(cons_sym = $ f_expr))
92
- setproperty! (model, cons_sym, pyomo. Constraint (model. t, rule = Pyomo. pyfunc (constraint_f)))
106
+ if occursin (Symbolics. unwrap (t_sym), expr)
107
+ f = eval (Symbolics. build_function (expr, model_sym, t_sym))
108
+ setproperty! (model, cons_sym, pyomo. Constraint (model. t, rule = Pyomo. pyfunc (f)))
109
+ else
110
+ f = eval (Symbolics. build_function (expr, model_sym, dummy_sym))
111
+ setproperty! (model, cons_sym, pyomo. Constraint (rule = Pyomo. pyfunc (f)))
112
+ end
93
113
end
94
114
95
- function MTK. set_objective! (m:: PyomoDynamicOptModel , expr)
96
- m. model. obj = pyomo. Objective (expr = expr)
115
+ function MTK. set_objective! (pmodel:: PyomoDynamicOptModel , expr)
116
+ @unpack model, model_sym, t_sym, dummy_sym = pmodel
117
+ @show expr
118
+ expr = Symbolics. substitute (expr, SPECIAL_FUNCTIONS_DICT)
119
+ if occursin (Symbolics. unwrap (t_sym), expr)
120
+ f = eval (Symbolics. build_function (expr, model_sym, t_sym))
121
+ model. obj = pyomo. Objective (model. t, rule = Pyomo. pyfunc (f))
122
+ else
123
+ f = eval (Symbolics. build_function (expr, model_sym, dummy_sym))
124
+ model. obj = pyomo. Objective (rule = Pyomo. pyfunc (f))
125
+ end
97
126
end
98
127
99
128
function MTK. add_initial_constraints! (model:: PyomoDynamicOptModel , u0, u0_idxs, ts)
104
133
105
134
function MTK. lowered_integral (m:: PyomoDynamicOptModel , arg, lo, hi)
106
135
@unpack model, model_sym, t_sym = m
107
- arg_f = Symbolics. build_function (arg, model_sym, t_sym)
108
- dae. Integral (model. t, wrt = model. t, rule= arg_f)
136
+ @show arg
137
+ @show Symbolics. build_function (arg, model_sym, t_sym)
138
+ arg_f = eval (Symbolics. build_function (arg, model_sym, t_sym))
139
+ @show arg_f
140
+ int_sym = Symbol (:int , hash (arg))
141
+ @show int_sym
142
+ setproperty! (model, int_sym, dae. Integral (model. t, wrt = model. t, rule= Pyomo. pyfunc (arg_f)))
143
+ PyomoVar (model. tₛ * model. int_sym)
109
144
end
110
145
111
146
MTK. process_integral_bounds (model, integral_span, tspan) = integral_span
@@ -135,15 +170,16 @@ function MTK.prepare_and_optimize!(prob::PyomoDynamicOptProblem, collocation; ve
135
170
ncp = Pyomo. is_finite_difference (dm) ? 1 : dm. np
136
171
discretizer. apply_to (solver_m, wrt = solver_m. t, nfe = solver_m. steps, scheme = Pyomo. scheme_string (dm))
137
172
solver = SolverFactory (string (collocation. solver))
138
- solver. solve (solver_m, tee = true )
139
- solver_m
173
+ results = solver. solve (solver_m, tee = true )
174
+ ConcreteModel ( solver_m)
140
175
end
141
176
142
- MTK. get_U_values (m:: ConcreteModel ) = [[pyomo. value (m. U[i, t]) for i in m. u_idxs] for t in m. t]
143
- MTK. get_V_values (m:: ConcreteModel ) = [[pyomo. value (m. V[i, t]) for i in m. v_idxs] for t in m. t]
144
- MTK. get_t_values (m:: ConcreteModel ) = [t for t in m. t]
177
+ MTK. get_U_values (m:: ConcreteModel ) = [[Pyomo . pyconvert (Float64, pyomo. value (m. U[i, t]) ) for i in m. u_idxs] for t in m. t]
178
+ MTK. get_V_values (m:: ConcreteModel ) = [[Pyomo . pyconvert (Float64, pyomo. value (m. V[i, t]) ) for i in m. v_idxs] for t in m. t]
179
+ MTK. get_t_values (m:: ConcreteModel ) = [Pyomo . pyconvert (Float64, t) for t in m. t]
145
180
146
181
function MTK. successful_solve (m:: ConcreteModel )
182
+ return true
147
183
ss = m. solver. status
148
184
tc = m. solver. termination_condition
149
185
if ss == opt. SolverStatus. ok && (tc == opt. TerminationStatus. optimal || tc == opt. TerminationStatus. locallyOptimal)
0 commit comments