电池存储的线性优化

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)

您可以尝试一些方法:

  1. 限制放电到可用存储能量:

    您可以限制 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)
    
  2. 修复首充:

    正如您评论的那样,您可以只说在初始时间步长中不允许放电,这将在初始时间步长期间将 model.discharge 设置为零:

     model.initial_discharge_fixed = pyo.Constraint(expr=model.discharge[model.t.first()]==0)
    
  3. 未固定初始 soe:

    您也可以不固定初始充电状态,而是计算它。在这个场景中,model.chargemodel.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