电池存储的线性优化
Linear optimization of a battery storage
我目前正在尝试使用 pyomo 优化电池存储。
我以为一切正常,但由于某种原因,存储总是在一开始就放电。这应该是不可能的,因为一开始存储是空的...
def discharge_capacity_rule(model, t):
return model.discharge[t] <= in_out_leistung
model.discharge_capacity_rule = Constraint(model.t, rule = discharge_capacity_rule)
def charge_capacity_rule(model, t):
return model.charge[t] <= in_out_leistung
model.charge_capacity_rule = Constraint(model.t, rule = charge_capacity_rule)
def max_capacity_rule(model, t):
return model.soe[t] <= battery_capacity
model.max_capacity_rule = Constraint(model.t, rule = max_capacity_rule)
def soe_start_rule(model, t):
return model.soe[0] == soe_start
model.soe_start_rule = Constraint(rule = soe_start_rule)
def soe_end_rule(model, t):
return model.soe[n] == model.soe[0]
model.soe_end_rule = Constraint(rule = soe_end_rule)
def soe_rule(model, t):
if t == 0:
return model.soe[t] == soe_start
else:
return model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
model.soe_rule = Constraint(model.t, rule = soe_rule)
这是BESS优化中的常见问题。您只是为了功率而限制 model.discharge[t]
(即,任何放电都不能超过 BESS 的标称功率输出),但没有明确限制放电超出可用能量。 model.soe
计算是避免放电超过可用存储能量的常用方法,但在初始时间步长期间,您只需避免计算 BESS 的充电状态并设置为初始值 return model.soe[t] == soe_start
,因此,在此时间步中,放电不受限于 model.soe_rule
,因为以下约束适用于所有时间步,但初始时间步除外。
model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
您可以尝试一些方法:
限制放电到可用存储能量:
您可以限制 model.discharge[t]
小于或等于任何 time.step 的可用存储能量。这等同于 SOE 计算,因为 model.soe
不能小于零,但这也适用于初始时间步长。约束将是这样的:
def discharge_leq_soe(model, t):
model.discharge[t] <= model.soe[t]
model.discharge_leq_soe = pyo.Constraint(model.t)
修复首充:
正如您评论的那样,您可以只说在初始时间步长中不允许放电,这将在初始时间步长期间将 model.discharge
设置为零:
model.initial_discharge_fixed = pyo.Constraint(expr=model.discharge[model.t.first()]==0)
未固定初始 soe:
您也可以不固定初始充电状态,而是计算它。在这个场景中,model.charge
和 model.discharge
是不固定的,model.soe[0]
是根据结果计算的。这可以为您提供一些关于改进 de BESS 调度所需的初始 SOE 的见解。在这种方法中,您只需要将 soe_rule
更改为:
def soe_rule(model, t):
if t == 0:
return model.soe[t] == (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
else:
return model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
model.soe_rule = Constraint(model.t, rule = soe_rule
我目前正在尝试使用 pyomo 优化电池存储。 我以为一切正常,但由于某种原因,存储总是在一开始就放电。这应该是不可能的,因为一开始存储是空的...
def discharge_capacity_rule(model, t):
return model.discharge[t] <= in_out_leistung
model.discharge_capacity_rule = Constraint(model.t, rule = discharge_capacity_rule)
def charge_capacity_rule(model, t):
return model.charge[t] <= in_out_leistung
model.charge_capacity_rule = Constraint(model.t, rule = charge_capacity_rule)
def max_capacity_rule(model, t):
return model.soe[t] <= battery_capacity
model.max_capacity_rule = Constraint(model.t, rule = max_capacity_rule)
def soe_start_rule(model, t):
return model.soe[0] == soe_start
model.soe_start_rule = Constraint(rule = soe_start_rule)
def soe_end_rule(model, t):
return model.soe[n] == model.soe[0]
model.soe_end_rule = Constraint(rule = soe_end_rule)
def soe_rule(model, t):
if t == 0:
return model.soe[t] == soe_start
else:
return model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
model.soe_rule = Constraint(model.t, rule = soe_rule)
这是BESS优化中的常见问题。您只是为了功率而限制 model.discharge[t]
(即,任何放电都不能超过 BESS 的标称功率输出),但没有明确限制放电超出可用能量。 model.soe
计算是避免放电超过可用存储能量的常用方法,但在初始时间步长期间,您只需避免计算 BESS 的充电状态并设置为初始值 return model.soe[t] == soe_start
,因此,在此时间步中,放电不受限于 model.soe_rule
,因为以下约束适用于所有时间步,但初始时间步除外。
model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency)
您可以尝试一些方法:
限制放电到可用存储能量:
您可以限制
model.discharge[t]
小于或等于任何 time.step 的可用存储能量。这等同于 SOE 计算,因为model.soe
不能小于零,但这也适用于初始时间步长。约束将是这样的:def discharge_leq_soe(model, t): model.discharge[t] <= model.soe[t] model.discharge_leq_soe = pyo.Constraint(model.t)
修复首充:
正如您评论的那样,您可以只说在初始时间步长中不允许放电,这将在初始时间步长期间将
model.discharge
设置为零:model.initial_discharge_fixed = pyo.Constraint(expr=model.discharge[model.t.first()]==0)
未固定初始 soe:
您也可以不固定初始充电状态,而是计算它。在这个场景中,
model.charge
和model.discharge
是不固定的,model.soe[0]
是根据结果计算的。这可以为您提供一些关于改进 de BESS 调度所需的初始 SOE 的见解。在这种方法中,您只需要将soe_rule
更改为:def soe_rule(model, t): if t == 0: return model.soe[t] == (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency) else: return model.soe[t] == model.soe[t-1] + (model.charge[t] * in_out_efficiency) - (model.discharge[t] / in_out_efficiency) model.soe_rule = Constraint(model.t, rule = soe_rule