pyomo
pyomo copied to clipboard
Add support for blocks with Pyomo.dae simulator
Per the Pyomo 5.1 documentation
The Simulator does not support multi-indexed inputs (i.e. if m.b in the above example was indexed by another set besides m.t)
Feature request: support multi-indexed inputs.
Example application: distillation column (indexed over tray number) were heat added to each tray is an input (control variable).
@pwensing and I are interested in digging into the Pyomo code and working on a PR. Where should we start?
@adowling2 and @pwensing the challenge here is coming up with a consistent and clear format for passing in the input values. The challenge with supporting multi-indexed inputs is that you have to do a lot of book-keeping to keep track of how many indices there are and the order they are in. I think the first step would be to propose a design for how the information would be passed to the simulator. What would you use instead of the b_profile and c_profile dictionaries in the example?
@blnicho That is an excellent point. Here is code from the example:
Time-varying inputs
>>> m.b = Var(m.t)
>>> m.c = Param(m.t, default=5.0)
...
Specifying the piecewise constant inputs
>>> b_profile = {0: 0.25, 15: 0.025}
>>> c_profile = {0: 5.0, 7: 50}
Declaring a Pyomo Suffix to pass the time-varying inputs to the Simulator
>>> m.var_input = Suffix(direction=Suffix.LOCAL)
>>> m.var_input[m.b] = b_profile
>>> m.var_input[m.c] = c_profile
I like the using dictionaries such as {0: 0.25, 15: 0.025} to represent step changes in time (which is a continous set). Building on this:
Idea 1: Allow b_profile to nested dictionaries. For example, let's say
>>> m.I = Set(initialize=("a","b"))
>>> m.J = Set(initialize=(1,2))
Time-varying inputs
>>> m.b = Var(m.t, m.I, m.J)
>>> b_profile = {("a",1):{0: 0.25, 15: 0.025}, ("a",2):{0: 0.3}, ("b",1):{0:0.4},("b",2):{0: 0.25, 15: 0.025}}
Declaring a Pyomo Suffix to pass the time-varying inputs to the Simulator
>>> m.var_input = Suffix(direction=Suffix.LOCAL)
>>> m.var_input[m.b] = b_profile
This would require keeping track of the order of the sets used to declare m.b.
Idea 2: Allow for time-varying profile to be specified for all combinations of sets m.I and m.J. Something like:
>>> m.var_input[m.b,"a",1] = {0: 0.25, 15: 0.025}
>>> m.var_input[m.b,"a",2] = {0: 0.3}
>>> m.var_input[m.b,"b",1] = {0:0.4}
>>> m.var_input[m.b,"b",2] = {0: 0.25, 15: 0.025}
Again, this requires bookkeeping.
These behaviours are inspired from how Param() can be initialized from a dictonary.
@pwensing. Would either of these cover the use case we discussed?
@blnicho Let's say I defined my dynamic model using a block in Pyomo such that:
- each block uses the same general dynamic model
- each block has a control variable
Would it be possible to specify a unique time-series for each control value separately to integrate with Pyomo.DAE? If so, that should address our anticipated use case.
@adowling2 do you mean something like this?
m.t = ContinuousSet(bounds=(0,1))
m.s = Set(initialize=[1,2,3])
def _block_rule(b, i):
b.x = Var(m.t)
b.dx = DerivativeVar(m.t)
b.u = Var(m.t)
m.trays = Block(m.s, rule=_block_rule)
m.var_input = Suffix(direction=Suffix.LOCAL)
m.var_input[m.trays[1].u] = u_profile
As of today this is not supported by the Simulator but should be supported in the very near future once I finish up some changes to support IDAES models. The main issue is that the Simulator does not currently support Block hierarchical models.
@blnicho Does the Pyomo simulator now support Block hierarchical models? If so, I think we can close this issue. @lxhowl
@blnicho Any update?
Also, is it possible to define a different time set for each block? We have an application were were would like to use a different time discretization for each block (multiperiod problem). @lxhowl
@adowling2 no update on this issue.
Also, is it possible to define a different time set for each block? We have an application were were would like to use a different time discretization for each block (multiperiod problem)
I think you should be able to declare different ContinuouSets on different blocks and then discretize each block independently but I've never tried this myself so I don't have an example to point you to.
Pyomo version 6.0.1
-
Pyomo.dae Simulator still deosn't support models using blocks.
-
Different discretizations were applied to each block successfully.
@jsiirola Discussed this today.
@blnicho Any update on this? @lxhowl @jialuw96 both want to use the Pyomo.DAE simulator with blocks.
@adowling2 I have a 95% complete solution for supporting Block and Expression components in the Simulator on my fork (branch name: simulator_v2). There is still an edge case I'm working on that comes up with IDAES models.