Reputation: 1
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
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