Problem when generating constraints

1,041 views
Skip to first unread message

Enquiring Mind

unread,
Oct 29, 2017, 1:38:59 PM10/29/17
to Pyomo Forum
Hello,

Pyomo is having trouble generating constraints that contain summations over empty sets.

For example, when trying the following  (note that this is a ConcreteModel where I am using list of objects as sets):


def _p_balance_EQ(m, op, bus):
return op.demand[bus.name] * (bus.pf) == \
sum(m.gen_p[op, gen] for gen in m.IDX_gen if gen.bus == bus.name) + \
sum(m.flow_p_r[op, line] for line in m.IDX_lin if line.toBus == bus.name) - \
sum(m.flow_p_s[op, line] for line in m.IDX_lin if line.fromBus == bus.name)

model.p_balance_EQ = pyo.Constraint(model.IDX_op,
model.IDX_bus,
rule=_p_balance_EQ)


I get the following error:

ValueError: Constraint 'q_balance_EQ[OperatingPoint(T4),Bus(B39)]' does not have a proper value. Found 'True'
Expecting a tuple or equation. Examples:
   summation(model.costs) == model.income
   (0, model.price[item], 50)

Instead, if I write it like this (i.e. explicitly forcing summation terms that could be over empty sets to be equal to 0) no error is raised and the optimiser works fine.


def _p_balance_EQ(m, op, bus):
local_gen = [gen for gen in m.IDX_gen if gen.bus == bus.name]
incoming_lines = [line for line in m.IDX_lin if line.tomBus == bus.name]
outgoing_lines = [line for line in m.IDX_lin if line.fromBus == bus.name]
if len(local_gen) == 0:
local_gen_p = 0
else:
local_gen_p = sum(m.gen_p[op, gen] for gen in local_gen)
if len(incoming_lines) == 0:
incoming_flows = 0
else:
incoming_flows = sum(m.flow_p[op, line] for line in incoming_lines)
if len(outgoing_lines) == 0:
outgoing_flows = 0
else:
outgoing_flows = sum(m.flow_p[op, line] for line in outgoing_lines)

return local_gen_p + incoming_flows - outgoing_flows + \
m.p_slack_up[op, bus] - m.p_slack_dn[op, bus] == op.demand[bus.name] * bus.pf

model.p_balance_EQ = pyo.Constraint(model.IDX_op,
model.IDX_bus,
rule=_p_balance_EQ)


My question are: 
1. is there a way to make the first approach work? am i missing something?
2. does the pyomo team plan to include such capability in the future (i.e. internal checking to see if some terms of the constraints are summations over empty sets and replace them with 0). this will greatly simplify code-writing and make our lives easier.

Note that this issue has already been raised in at least one previous thread on this forum: https://groups.google.com/forum/#!searchin/pyomo-forum/true$20variable$20infeasible%7Csort:date/pyomo-forum/Cp8faz5GbZg/f7j_flw_CwAJ

thanks in advance

Siirola, John D

unread,
Oct 29, 2017, 2:32:31 PM10/29/17
to pyomo...@googlegroups.com
The short answer is that your two approaches are not equivalent. In your first example, you have no slack variables.   The error you are getting is exactly what it says: your rule is returning “True” instead of a Pyomo expression. This can happen when the expression simplification logic can trivially eliminate all variables - usually by multiplication by 0 or by summing over an empty set (so there were never any variables to begin with and sum() returns 0). Your second example introduces a slack variable, so the constraint is never trivial. 

We used to silently ignore these trivial constraints, but had too many cases where the trivial constraint was either due to a modeling error or a problem with invalid data, so we now complain loudly [so to answer your #2, no: there are no plans at the moment to change this behavior]. In your case, while I do not know your data, I suspect that you have busses with no demand and no lines - or a bus with no unfixed lines and a power factor of 0. 

How to work around this:
  1) double check your model/data. 
  2) if after (1) you are still convinced that things are right, you can either 
      2a) detect the trivial constraint within your rule and return Constraint.Skip (or Constraint.Feasible).
      2b) “wrap” your rule with the “@simple_constraint_rule” decorator, which will implement that mapping for you. 

John
--
You received this message because you are subscribed to the Google Groups "Pyomo Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyomo-forum...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Enquiring Mind

unread,
Nov 6, 2017, 10:22:33 AM11/6/17
to pyomo...@googlegroups.com
Hi John,

thanks a lot for your answer; indeed the slack variables resolve this issue (should have been more observant).
When you have some time I would like to know more about the option (2b) you posted above; is this a Pyomo built-in capability and where can I learn more about such features?

Thanks & keep up the great work

Reply all
Reply to author
Forward
0 new messages