stoef
stoef

Reputation: 1

Pyomo Constraint Block in Abstract Model

For a better structure of my Constraints, I want to summarize multiple constraints into a block, so that a don't have to scroll through a long list of separate functions representing my constraints.

My problem is that I'm using an Abstract model and don't know how to define that Block for a set that has not been initialized yet


M.s = pe.Set(dimen=1)

M.chp_minPower = pe.Param(within=pe.Reals,mutable=True)
M.chp_maxPower = pe.Param(within=pe.Reals,mutable=True)
M.chp_posGrad = pe.Param(within=pe.Reals,mutable=True)
M.chp_negGrad = pe.Param(within=pe.Reals,mutable=True)
M.chp_k = pe.Param(within=pe.Reals,mutable=True)
M.chp_c = pe.Param(within=pe.Reals,mutable=True)
M.chp_f1 = pe.Param(within=pe.Reals,mutable=True)
M.chp_f2 = pe.Param(within=pe.Reals,mutable=True)
M.gasCost = pe.Param(within=pe.Reals,mutable=True)

M.chpOn = pe.Var(M.s, within=pe.Binary)
M.chpSwitchON = pe.Var(M.s,within=pe.Binary)
M.chpPel = pe.Var(M.s,within=pe.NonNegativeReals)
M.chpPth = pe.Var(M.s, within=pe.NonNegativeReals)
M.chpQGas = pe.Var(M.s, within=pe.NonNegativeReals)

def chp_block_rule1(nb,i):
    #Constraints
    nb.chpPelMax = pe.Constraint(expr=M.chpPel[i] <= M.chp_maxPower * M.chpOn[i])
    nb.chpPelMin = pe.Constraint(expr=M.chpPel[i] >= M.chp_minPower * M.chpOn[i])
    #b.sellBin = pe.Constraint(expr=b.sell[i]/M.maxSell <= M.sellBin[i]
    nb.chpCogen = pe.Constraint(expr=M.chpPth[i] == M.chp_f1 * M.chpPel[i] + M.chp_f2 * M.chpOn[i])
    nb.chpConsumption = pe.Constraint(expr=M.chpQGas[i] == M.chp_c * M.chpOn[i] + M.chp_k + M.chpPel[i])
M.chp_block = pe.Block(M.s, rule=chp_block_rule1)

ValueError: Error retrieving component chpPel[1]: The component has not been constructed.

Does anybody know how to work with blocks in Abstract models?

Upvotes: 0

Views: 887

Answers (1)

Giorgio Balestrieri
Giorgio Balestrieri

Reputation: 1052

I'm not 100% sure but I guess expr tries to actually evaluate the expression, and because chpPel is a variable (thus has no value) it breaks.

In order to delay the evaluation of the expression (i.e. pass the expression into the solver as symbolic), you can use rule instead of expr. As you probably know rule takes a function. If the expression is short enough, you can use a lambda function.

nb.chpPelMax = pe.Constraint(rule=lambda M: M.chpPel[i] <= M.chp_maxPower * M.chpOn[i])

Side note: you can just use list(range(...)) instead of the list comprehension.

Upvotes: 2

Related Questions