@@ -19,11 +19,11 @@ const SPECIAL_FUNCTIONS_DICT = Dict([acos => Pyomo.py_acos,
1919 exp => Pyomo. py_exp,
2020 abs2 => (x -> x^ 2 )])
2121
22- struct PyomoDynamicOptModel
22+ struct PyomoDynamicOptModel{T}
2323 model:: ConcreteModel
2424 U:: PyomoVar
2525 V:: PyomoVar
26- P:: PyomoVar
26+ P:: T
2727 tₛ:: PyomoVar
2828 is_free_final:: Bool
2929 solver_model:: Union{Nothing, ConcreteModel}
@@ -35,7 +35,7 @@ struct PyomoDynamicOptModel
3535 function PyomoDynamicOptModel (model, U, V, P, tₛ, is_free_final)
3636 @variables MODEL_SYM:: Symbolics.symstruct (ConcreteModel) T_SYM DUMMY_SYM
3737 model. dU = dae. DerivativeVar (U, wrt = model. t, initialize = 0 )
38- new (model, U, V, P, tₛ, is_free_final, nothing ,
38+ new {typeof(P)} (model, U, V, P, tₛ, is_free_final, nothing ,
3939 PyomoVar (model. dU), MODEL_SYM, T_SYM, DUMMY_SYM)
4040 end
4141end
@@ -178,15 +178,17 @@ function MTK.lowered_var(m::PyomoDynamicOptModel, uv, i, t)
178178 Symbolics. unwrap (var)
179179end
180180
181- function MTK. lowered_param (m:: PyomoDynamicOptModel , i)
182- P = Symbolics. value (pysym_getproperty (m. model_sym, :P ))
183- Symbolics. unwrap (P[i])
181+ # For Pyomo, we need to create symbolic representations for pmap
182+ # This is needed because Pyomo uses symbolic building for constraints
183+ function MTK. get_param_for_pmap (m:: ConcreteModel , P:: PyomoVar , i)
184+ # Create a symbolic variable that will be used in the pmap
185+ # The actual PyomoVar will be accessed via the symbolic representation
186+ @variables MODEL_SYM:: Symbolics.symstruct (ConcreteModel)
187+ P_sym = Symbolics. value (pysym_getproperty (MODEL_SYM, :P ))
188+ Symbolics. unwrap (P_sym[i])
184189end
185190
186- # For Pyomo, return symbolic accessors instead of raw PyomoVar
187- function MTK. get_param_for_pmap (m:: PyomoDynamicOptModel , P, i)
188- MTK. lowered_param (m, i)
189- end
191+ MTK. needs_individual_tunables (m:: ConcreteModel ) = true
190192
191193struct PyomoCollocation <: AbstractCollocation
192194 solver:: Union{String, Symbol}
0 commit comments