@@ -7,6 +7,20 @@ using NaNMath
77using Setfield
88const MTK = ModelingToolkit
99
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+
1024struct PyomoDynamicOptModel
1125 model:: ConcreteModel
1226 U:: PyomoVar
@@ -17,13 +31,12 @@ struct PyomoDynamicOptModel
1731 dU:: PyomoVar
1832 model_sym:: Union{Num, Symbolics.BasicSymbolic}
1933 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}
2235
2336 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
2538 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 )
2740 end
2841end
2942
@@ -42,7 +55,7 @@ struct PyomoDynamicOptProblem{uType, tType, isinplace, P, F, K} <:
4255 end
4356end
4457
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}))
4659_getproperty (s, name:: Val{fieldname} ) where fieldname = getproperty (s, fieldname)
4760
4861function MTK. PyomoDynamicOptProblem (sys:: ODESystem , u0map, tspan, pmap;
@@ -78,22 +91,38 @@ function MTK.generate_timescale!(m::ConcreteModel, guess, is_free_t)
7891end
7992
8093function 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
8295 expr = if cons isa Equation
8396 cons. lhs - cons. rhs == 0
8497 elseif cons. relational_op === Symbolics. geq
8598 cons. lhs - cons. rhs ≥ 0
8699 else
87100 cons. lhs - cons. rhs ≤ 0
88101 end
89- f_expr = Symbolics. build_function (expr, model_sym, t_sym)
102+ expr = Symbolics. substitute (expr, SPECIAL_FUNCTIONS_DICT)
103+ @show expr
104+
90105 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
93113end
94114
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
97126end
98127
99128function MTK. add_initial_constraints! (model:: PyomoDynamicOptModel , u0, u0_idxs, ts)
104133
105134function MTK. lowered_integral (m:: PyomoDynamicOptModel , arg, lo, hi)
106135 @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)
109144end
110145
111146MTK. process_integral_bounds (model, integral_span, tspan) = integral_span
@@ -135,15 +170,16 @@ function MTK.prepare_and_optimize!(prob::PyomoDynamicOptProblem, collocation; ve
135170 ncp = Pyomo. is_finite_difference (dm) ? 1 : dm. np
136171 discretizer. apply_to (solver_m, wrt = solver_m. t, nfe = solver_m. steps, scheme = Pyomo. scheme_string (dm))
137172 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)
140175end
141176
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]
145180
146181function MTK. successful_solve (m:: ConcreteModel )
182+ return true
147183 ss = m. solver. status
148184 tc = m. solver. termination_condition
149185 if ss == opt. SolverStatus. ok && (tc == opt. TerminationStatus. optimal || tc == opt. TerminationStatus. locallyOptimal)
0 commit comments