Dynamic lower/upper bound of Pyomo Variable for every iteration

99 Views Asked by At

I want to adjust the lower and upper bound of three pyo.Var() depending on the outcome of another variable. the variable model.inverter_power should be in the i-th iteration bigger than model.inverter_power[i].lb + model.fcr_power[i] but also smaller than model.inverter_power[i].ub - model.fcr_power[i]) How can i implement this? Unfortuntately my idea is not working....

        def fcr_inverter_reduction(model, i):
                return (model.inverter_power[i] >= model.inverter_power[i].lb + model.fcr_power[i],
                        model.inverter_power[i] <= model.inverter_power[i].ub - model.fcr_power[i])

        model.fcr_inverter_rule = pyo.Constraint(model.i, rule = fcr_inverter_reduction)

I tried various versions of this code, not only is this code not linear anymore, so I used ipopt as a solver but no solution can be found, i got this error message:

  File "D:\.conda\envs\PythonEnviromentV2\lib\site-packages\pyomo\opt\base\solvers.py", line 596, in solve
    raise ApplicationError(
pyomo.common.errors.ApplicationError: Solver (ipopt) did not exit normally
1

There are 1 best solutions below

0
On

This is very doable if you reformulate just a bit. Also, I don't think it is possible to return a tuple of 2 constraints like you are doing with that function, so you should break it up... it is clearer as well.

You probably could access the upper/lower bound and use that within the constraint because they are fixed/constant with respect to the solver, but I think it is probably clearer to break out your min/max values as parameters. Some variation of this works.

(also, in the future, you are more likely to get better help/results if you post a fully minimal-reproducible example instead of just 1-line.)

Code:

import pyomo.environ as pyo

model = pyo.ConcreteModel()

model.I = pyo.Set(initialize=[1,2,3])

# power parameters...
model.min_inverter = pyo.Param(model.I, initialize={1:10, 2:15, 3:22})
model.max_inverter = pyo.Param(model.I, initialize={1:55, 2:45, 3:80})

# vars...
model.inverter_power = pyo.Var(model.I)
model.fcr_power = pyo.Var(model.I)

def fcr_inverter_min(model, i):
    return model.inverter_power[i] >= model.min_inverter[i] + model.fcr_power[i]
model.fcr_inverter_rule_min = pyo.Constraint(model.I, rule=fcr_inverter_min)

def fcr_inverter_max(model, i):
    return model.inverter_power[i] <= model.max_inverter[i] - model.fcr_power[i]
model.fcr_inverter_rule_max = pyo.Constraint(model.I, rule=fcr_inverter_max)

model.pprint()

Output:

1 Set Declarations
    I : Size=1, Index=None, Ordered=Insertion
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :    3 : {1, 2, 3}

2 Param Declarations
    max_inverter : Size=3, Index=I, Domain=Any, Default=None, Mutable=False
        Key : Value
          1 :    55
          2 :    45
          3 :    80
    min_inverter : Size=3, Index=I, Domain=Any, Default=None, Mutable=False
        Key : Value
          1 :    10
          2 :    15
          3 :    22

2 Var Declarations
    fcr_power : Size=3, Index=I
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          1 :  None :  None :  None : False :  True :  Reals
          2 :  None :  None :  None : False :  True :  Reals
          3 :  None :  None :  None : False :  True :  Reals
    inverter_power : Size=3, Index=I
        Key : Lower : Value : Upper : Fixed : Stale : Domain
          1 :  None :  None :  None : False :  True :  Reals
          2 :  None :  None :  None : False :  True :  Reals
          3 :  None :  None :  None : False :  True :  Reals

2 Constraint Declarations
    fcr_inverter_rule_max : Size=3, Index=I, Active=True
        Key : Lower : Body                                    : Upper : Active
          1 :  -Inf : inverter_power[1] - (55 - fcr_power[1]) :   0.0 :   True
          2 :  -Inf : inverter_power[2] - (45 - fcr_power[2]) :   0.0 :   True
          3 :  -Inf : inverter_power[3] - (80 - fcr_power[3]) :   0.0 :   True
    fcr_inverter_rule_min : Size=3, Index=I, Active=True
        Key : Lower : Body                                  : Upper : Active
          1 :  -Inf : 10 + fcr_power[1] - inverter_power[1] :   0.0 :   True
          2 :  -Inf : 15 + fcr_power[2] - inverter_power[2] :   0.0 :   True
          3 :  -Inf : 22 + fcr_power[3] - inverter_power[3] :   0.0 :   True