pyomo icon indicating copy to clipboard operation
pyomo copied to clipboard

Add support for blocks with Pyomo.dae simulator

Open adowling2 opened this issue 7 years ago • 11 comments

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 avatar Oct 16 '18 21:10 adowling2

@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 avatar Oct 16 '18 21:10 blnicho

@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?

adowling2 avatar Oct 17 '18 00:10 adowling2

@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 avatar Nov 29 '18 15:11 adowling2

@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 avatar Dec 10 '18 20:12 blnicho

@blnicho Does the Pyomo simulator now support Block hierarchical models? If so, I think we can close this issue. @lxhowl

adowling2 avatar Apr 20 '21 18:04 adowling2

@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 avatar Jun 16 '21 14:06 adowling2

@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.

blnicho avatar Jun 22 '21 17:06 blnicho

Pyomo version 6.0.1

  • Pyomo.dae Simulator still deosn't support models using blocks.

  • Different discretizations were applied to each block successfully.

lxhowl avatar Jun 29 '21 18:06 lxhowl

@jsiirola Discussed this today.

adowling2 avatar Aug 06 '21 18:08 adowling2

@blnicho Any update on this? @lxhowl @jialuw96 both want to use the Pyomo.DAE simulator with blocks.

adowling2 avatar May 12 '22 17:05 adowling2

@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.

blnicho avatar May 12 '22 17:05 blnicho