Open
Description
Summary
I can use the return from create_using
to create a Block on a model, but I lose the mappings between primal and dual components when I do so. I'm not sure why, but it seems that somehow the private_data
data structure is empty in this case?
Steps to reproduce the issue
This script looks like it should work:
from pyomo.environ import *
m = ConcreteModel()
m.outer1 = Var(domain=Binary)
m.outer = Var([2, 3], domain=Binary)
m.x = Var(domain=NonNegativeReals)
m.y = Var(domain=NonPositiveReals)
m.z = Var(domain=Reals)
m.obj = Objective(expr=m.outer1 + m.outer[2] + m.outer[3])
m.inner = Block()
m.inner.obj = Objective(expr=m.x + 2 * m.y - 3 * m.outer[3] * m.z)
m.inner.c1 = Constraint(expr=-4 * m.x - 2 * m.y - m.z <= -5 * m.outer1)
m.inner.c2 = Constraint(expr=m.x + m.outer[2] * m.y >= 3)
m.inner.c3 = Constraint(expr=-m.y - m.z == -4.2)
m.inner.c4 = Constraint(expr=m.z <= 42)
lp_dual = TransformationFactory('core.lp_dual')
m.dualblk = Block(
rule=lambda blk: lp_dual.create_using(
m.inner, parameterize_wrt=[m.outer1, m.outer])
)
dualvar = lp_dual.get_dual_var(m.dualblk, m.inner.c1)
dualvar.pprint()
Error Message
But the transformation can't find the mapping:
Traceback (most recent call last):
File "/home/esjohn/src/pyomo/pyomo/core/tests/im_confused.py", line 31, in <module>
dualvar = lp_dual.get_dual_var(m.dualblk, m.inner.c1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/esjohn/src/pyomo/pyomo/core/plugins/transform/lp_dual.py", line 259, in get_dual_var
raise ValueError(
ValueError: It does not appear that Constraint 'inner.c1' is a primal constraint on model 'dualblk'
Information on your system
Pyomo version: main branch
Python version: 3.11
Operating system: linux
How Pyomo was installed (PyPI, conda, source): source
Solver (if applicable):
Additional information
Replacing the m.dualblk = Block(...)
line with
thing = lp_dual.create_using(m.inner, parameterize_wrt=[m.outer1, m.outer])
m.add_component('dualblk', thing)
works as expected. So the rule construction is at fault.