在 Pyomo 约束中定义 cyclic/periodic 边界条件
Defining cyclic/periodic boundary conditions in Pyomo constraints
我正在尝试对使用循环条件的 Pyomo 模型定义约束。以下是我认为它应该如何工作(来自 GAMS 的循环语法)。
from __future__ import division
from pyomo.environ import *
model = ConcreteModel()
## define sets
model.t = Set(initialize = [i for i in range(8760)])
## define variables
model.ESS_SOC = Var(model.t, domain = NonNegativeReals) # battery state of charge
model.ESS_c = Var(model.t, domain = NonNegativeReals) # battery charging
model.ESS_d = Var(model.t, domain = NonNegativeReals) # battery discharging
## skip obj for this example
## define constraints
#SOC constraint
model.SOC_const = ConstraintList()
for i in model.t:
model.SOC_const.add( model.ESS_SOC[i] == model.ESS_SOC[i--1] + model.ESS_c[i] - model.ESS_d[i] )
但是当我运行上面的例子时,我得到以下错误信息:
KeyError: "Index '8760' is not valid for indexed component 'ESS_SOC'"
我同意 model.t
定义的错误,但错误让我相信它几乎在做我想做的事情,那就是:
model.ESS_SOC[0] == model.ESS_SOC[8759] + model.ESS_c[0] - model.ESS_d[0]
model.ESS_SOC[1] == model.ESS_SOC[0] + model.ESS_c[1] - model.ESS_d[1]
...
model.ESS_SOC[8759] == model.ESS_SOC[8758] + model.ESS_c[8759] - model.ESS_d[8759]
有没有办法定义约束,这样我就得到了?
我建议使用索引约束而不是 ConstraintList
:
from __future__ import division
from pyomo.environ import *
model = ConcreteModel()
## define sets
model.t = Set(initialize = [i for i in range(8760)], ordered=True)
## define variables
model.ESS_SOC = Var(model.t, domain = NonNegativeReals) # battery state of charge
model.ESS_c = Var(model.t, domain = NonNegativeReals) # battery charging
model.ESS_d = Var(model.t, domain = NonNegativeReals) # battery discharging
## skip obj for this example
## define constraints
#SOC constraint
def _SOC_const(m, i):
if i == m.t.first():
return model.ESS_SOC[i] == model.ESS_SOC[m.t.last()] + model.ESS_c[i] - model.ESS_d[i]
return model.ESS_SOC[i] == model.ESS_SOC[i-1] + model.ESS_c[i] - model.ESS_d[i]
model.SOC_const = Constraint(model.t, rule=_SOC_const)
请注意,您需要在 Set
上设置 ordered=True
选项才能使 first()
和 last()
方法正常工作。
我正在尝试对使用循环条件的 Pyomo 模型定义约束。以下是我认为它应该如何工作(来自 GAMS 的循环语法)。
from __future__ import division
from pyomo.environ import *
model = ConcreteModel()
## define sets
model.t = Set(initialize = [i for i in range(8760)])
## define variables
model.ESS_SOC = Var(model.t, domain = NonNegativeReals) # battery state of charge
model.ESS_c = Var(model.t, domain = NonNegativeReals) # battery charging
model.ESS_d = Var(model.t, domain = NonNegativeReals) # battery discharging
## skip obj for this example
## define constraints
#SOC constraint
model.SOC_const = ConstraintList()
for i in model.t:
model.SOC_const.add( model.ESS_SOC[i] == model.ESS_SOC[i--1] + model.ESS_c[i] - model.ESS_d[i] )
但是当我运行上面的例子时,我得到以下错误信息:
KeyError: "Index '8760' is not valid for indexed component 'ESS_SOC'"
我同意 model.t
定义的错误,但错误让我相信它几乎在做我想做的事情,那就是:
model.ESS_SOC[0] == model.ESS_SOC[8759] + model.ESS_c[0] - model.ESS_d[0]
model.ESS_SOC[1] == model.ESS_SOC[0] + model.ESS_c[1] - model.ESS_d[1]
...
model.ESS_SOC[8759] == model.ESS_SOC[8758] + model.ESS_c[8759] - model.ESS_d[8759]
有没有办法定义约束,这样我就得到了?
我建议使用索引约束而不是 ConstraintList
:
from __future__ import division
from pyomo.environ import *
model = ConcreteModel()
## define sets
model.t = Set(initialize = [i for i in range(8760)], ordered=True)
## define variables
model.ESS_SOC = Var(model.t, domain = NonNegativeReals) # battery state of charge
model.ESS_c = Var(model.t, domain = NonNegativeReals) # battery charging
model.ESS_d = Var(model.t, domain = NonNegativeReals) # battery discharging
## skip obj for this example
## define constraints
#SOC constraint
def _SOC_const(m, i):
if i == m.t.first():
return model.ESS_SOC[i] == model.ESS_SOC[m.t.last()] + model.ESS_c[i] - model.ESS_d[i]
return model.ESS_SOC[i] == model.ESS_SOC[i-1] + model.ESS_c[i] - model.ESS_d[i]
model.SOC_const = Constraint(model.t, rule=_SOC_const)
请注意,您需要在 Set
上设置 ordered=True
选项才能使 first()
和 last()
方法正常工作。