Skip to content

Commit

Permalink
Fixed hierarchical/block model bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
smartin71 committed Aug 20, 2024
1 parent d432500 commit 577aea3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
16 changes: 16 additions & 0 deletions pyomo/contrib/parmest/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ def label_model(self):
self.assertEqual(pyo.value(iv), pyo.value(iv_old))
self.assertTrue(c in m_vars.unknown_parameters)

# test hierarchical model
#########################

m = pyo.ConcreteModel()
m.p1 = pyo.Param(initialize=1, mutable=True)
m.b = pyo.Block()
m.b.p2 = pyo.Param(initialize=2, mutable=True)

param_CUIDs = [pyo.ComponentUID(m.p1), pyo.ComponentUID(m.b.p2)]
m_vars = parmest.utils.convert_params_to_vars(m, param_CUIDs)

for v in [str(CUID) for CUID in param_CUIDs]:
c = m_vars.find_component(v)
self.assertIsInstance(c, pyo.Var)
c_old = m.find_component(v)
self.assertEqual(pyo.value(c), pyo.value(c_old))

if __name__ == "__main__":
unittest.main()
23 changes: 13 additions & 10 deletions pyomo/contrib/parmest/utils/model_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pyomo.core.base.var import IndexedVar
from pyomo.core.base.param import IndexedParam
from pyomo.common.collections import ComponentMap
from pyomo.core.base import Model

from pyomo.environ import ComponentUID

Expand Down Expand Up @@ -62,14 +63,15 @@ def convert_params_to_vars(model, param_CUIDs=None, fix_vars=False):
# Param
if theta_object.is_parameter_type():

# Delete Param, add Var
# change from Param to Var
vals = theta_object.extract_values()
model.del_component(theta_object)
model.add_component(theta_object.name, pyo.Var(initialize=vals[None]))
parent = theta_object.parent_block()
parent.del_component(theta_object)
parent.add_component(theta_object.name, pyo.Var(initialize=vals[None]))

# Update substitution map
theta_var_cuid = ComponentUID(theta_object.name)
theta_var_object = theta_var_cuid.find_component_on(model)
theta_var_cuid = ComponentUID(theta_object.local_name)
theta_var_object = theta_var_cuid.find_component_on(parent)
substitution_map[id(theta_object)] = theta_var_object
comp_map[theta_object] = theta_var_object

Expand All @@ -88,19 +90,20 @@ def convert_params_to_vars(model, param_CUIDs=None, fix_vars=False):
)

# delete Param
model.del_component(theta_object)
parent = theta_object.parent_block()
parent.del_component(theta_object)

# add Var w/ previous Param values
index_name = theta_object.index_set().name
index_cuid = ComponentUID(index_name)
index_object = index_cuid.find_component_on(model)
model.add_component(
index_object = index_cuid.find_component_on(parent)
parent.add_component(
theta_object.name, pyo.Var(index_object, initialize=vals)
)

# Update substitution map (map each indexed param to indexed var)
theta_var_cuid = ComponentUID(theta_object.name)
theta_var_object = theta_var_cuid.find_component_on(model)
theta_var_object = theta_var_cuid.find_component_on(parent)
comp_map[theta_object] = theta_var_object
var_theta_objects = list(theta_var_object.values())
for param_theta_obj, var_theta_obj in zip(
Expand All @@ -114,7 +117,7 @@ def convert_params_to_vars(model, param_CUIDs=None, fix_vars=False):
theta_var_object = theta_object

else:
logger.warning("%s is not a Param or Var on the model", (param_name))
logger.warning("%s is not a Param or Var on the model", (theta_object))
return model

if fix_vars:
Expand Down

0 comments on commit 577aea3

Please sign in to comment.