Repository navigation
Params indexed by ContinuousSets are not initialized when the set is discretized. #4009
Description
Summary
When a Param is indexed by a ContinuousSet and that ContinuousSet is discretize, the Param is not initialized on the new indices created. If the Param is mutable and initialized at some value, I would expect the new ParamData to be initialized at the same value. If it's not mutable, then I'd expect either indexing it by a ContinuousSet or discretizing that ContinuousSet to fail.
Steps to reproduce the issue
import pyomo.environ as pyo
from pyomo.dae import DerivativeVar, ContinuousSet
m = pyo.ConcreteModel()
m.time = ContinuousSet(initialize=[0,1])
m.x = pyo.Var(m.time, initialize=0)
m.y = pyo.Param(m.time, mutable=True, initialize=0)
discretizer = pyo.TransformationFactory("dae.finite_difference")
discretizer.apply_to(m, nfe=4, wrt=m.time, scheme="BACKWARD")
print(f"x[0.25] = {m.x[0.25].value}")
print(f"y[0.25] = {m.y[0.25].value}")Error Message
x[0.25] = 0
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[2], line 13
10 discretizer.apply_to(m, nfe=4, wrt=m.time, scheme="BACKWARD")
12 print(f"x[0.25] = {m.x[0.25].value}")
---> 13 print(f"y[0.25] = {m.y[0.25].value}")
File ~\miniforge3\envs\idaes-fresh\Lib\site-packages\pyomo\core\base\param.py:230, in ParamData.value(self)
227 @property
228 def value(self):
229 """Return the value for this variable."""
--> 230 return self()
File ~\miniforge3\envs\idaes-fresh\Lib\site-packages\pyomo\core\base\param.py:217, in ParamData.__call__(self, exception)
215 if self._value is Param.NoValue:
216 if exception:
--> 217 raise ValueError(
218 "Error evaluating Param value (%s):\n\tThe Param value is "
219 "currently set to an invalid value. This is\n\ttypically "
220 "from a scalar Param or mutable Indexed Param without\n"
221 "\tan initial or default value." % (self.name,)
222 )
223 else:
224 return None
ValueError: Error evaluating Param value (y[0.25]):
The Param value is currently set to an invalid value. This is
typically from a scalar Param or mutable Indexed Param without
an initial or default valueApplication and Workaround
As part of a larger IDAES model, I want a time-derivative term to exist regardless of whether the system is steady-state or dynamic. If it's steady-state, I want it to be a Param set to 0:
if self.config.dynamic is True:
self.dTdt = DerivativeVar(
self.drum_wall_temperature, wrt=self.flowsheet().time
)
else:
self.dTdt = Param(
self.flowsheet().time,
self.dimensionless_radial_domain,
initialize=0,
mutable=True
)A workaround is to use an Expression instead of a Param:
if self.config.dynamic is True:
self.dTdt = DerivativeVar(
self.drum_wall_temperature, wrt=self.flowsheet().time
)
else:
@self.Expression(self.flowsheet().time, self.dimensionless_radial_domain)
def dTdt(b, t, r):
return 0 Information on your system
Pyomo version: 6.10.1
Python version: 3.13.14
Operating system: Windows 11
How Pyomo was installed (PyPI, conda, source): IDAES developer installation
Solver (if applicable): n/a
Activity