Gekko 中的电池充电状态 (SOC) 更新

问题描述 投票:0回答:1

我正在尝试使用 Gekko 中的优化程序对电池充电/放电过程进行建模。我在模型中使用了以下能量平衡方程:

可再生电力[t] - (充电[t] + 剩余[t])+(放电[t] + 未满足[t])= 需求[t]

充电/放电状态 (SOC) 通过以下公式更新:

SOC[t]=SOC[t-1]+充电[t]-放电[t]

我在 Gekko 中制定了上述方程,但在放电阶段遇到了问题。例如,我没有收到下图所示数据集的第二行(图中的黄色部分)的解决方案。我预计 SOC[第二行]=196400,但我没有在 Gekko 模型中收到解决方案。对于这个问题,我感谢您的建议。

from gekko import GEKKO
import sys

Battery_capacity=589200 #kW-h
Battery_Initial_capacity=589200

max_discharge=Battery_capacity/3
max_charge=Battery_capacity

Big_M=1000000000000
epsilon=sys.float_info.epsilon

m = GEKKO(remote=False)

m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 10000',\
                    'minlp_max_iter_with_int_sol 500',\
                    'minlp_branch_method 1',\
                    'minlp_integer_tol 1e-100', \
                    'minlp_integer_leaves 2']

Demand_total=[5629940,5327262,4669939]
RE_total=[5204098,4410247,3694715]
Price_total=[15,17,17]

row=1
finish=0
counter=0

for r in range(3):
    start=finish
    finish=(r+1)*row

    Demand = [Demand_total[r]]
    RE = [RE_total[r]]
    Price = [Price_total[r]]

    # Objective function
    c = [None] * row
    for t in range(row):
        c[t] = (Demand[t] * Price[t])

    B_ch_over = [m.Var(lb=0) for t in range(row)]
    B_disch_over = [m.Var(lb=0) for t in range(row)]

    B_ch = [m.Var(lb=0) for t in range(row)]
    B_disch = [m.Var(lb=0) for t in range(row)]

    Unmet = [m.Var(lb=0) for t in range(row)]
    Surplus = [m.Var(lb=0) for t in range(row)]

    B_SOC = [m.Var() for t in range(row)]

    if r==0:
        starting_point = 0
        Last_BOS=Battery_Initial_capacity
        m.Equation(B_SOC[0]==Last_BOS) # initial charge at start
    else:
        m.Equation(B_SOC[0] == Last_BOS[0])  # initial charge at start


    for t in range(starting_point,row):

        m.Equation(RE[t] - B_ch_over[t] + B_disch_over[t] == Demand[t])
        m.Equation(B_ch_over[t] * B_disch_over[t] <= 0)

        B_ch[t] = m.if3(max_charge - m.if3(B_ch_over[t] - (Battery_capacity - B_SOC[t - 1]), B_ch_over[t],Battery_capacity - B_SOC[t - 1]), max_charge,m.if3(B_ch_over[t] - (Battery_capacity - B_SOC[t - 1]), B_ch_over[t],Battery_capacity - B_SOC[t - 1]))

        B_disch[t]=m.if3(max_discharge-m.if3(B_disch_over[t]-B_SOC[t-1],B_disch_over[t],B_SOC[t-1]),max_discharge,m.if3(B_disch_over[t]-B_SOC[t-1],B_disch_over[t],B_SOC[t-1]))
        B_SOC[t]=m.if3(Battery_capacity-(B_SOC[t - 1] + B_ch[t] - B_disch[t]),Battery_capacity,B_SOC[t - 1] + B_ch[t] - B_disch[t])

        m.Equation(B_ch[t] + Surplus[t] == B_ch_over[t])
        m.Equation(B_disch[t] + Unmet[t] == B_disch_over[t])

        counter+=1

    m.Maximize(m.sum(c))

    m.options.SOLVER = 1


    # m.open_folder()
    m.solve(disp=False)

    Last_BOS=B_SOC[t].value
    if r==0:
        print('Results')
    for t in range(starting_point, row):
        print('B_ch{}={}  B_disch{}={}  B_SOC{}={} B_ch_over{}={}  B_disch_over{}={} Unmet{}={} Surplus{}={} RE{}={} Demand{}={}'.format(counter-row+t, B_ch[t].value, counter-row+t, B_disch[t].value, counter-row+t, B_SOC[t].value, counter-row+t, B_ch_over[t].value, counter-row+t,B_disch_over[t].value, counter-row+t, Unmet[t].value, counter-row+t, Surplus[t].value, counter-row+t, RE[t], counter-row+t,Demand[t]))

print('Objective: ' + str(m.options.objfcnval))
battery gekko
1个回答
0
投票

我使用了两个附加变量,并分解了充电和放电时间中嵌套的 m.if3,如下面的代码所示,并收到了结果。但是,我没有注意到为什么嵌套的 m.if3 在初始代码中不起作用。

from gekko import GEKKO
import sys

Battery_capacity=589200 #kW-h
Battery_Initial_capacity=589200

max_discharge=Battery_capacity/3
max_charge=Battery_capacity

Big_M=1000000000000
epsilon=sys.float_info.epsilon

m = GEKKO(remote=False)

m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 10000',\
                    'minlp_max_iter_with_int_sol 500',\
                    'minlp_branch_method 1',\
                    'minlp_integer_tol 1e-100', \
                    'minlp_integer_leaves 2']

Demand_total=[5629940,5327262,4669939]
RE_total=[5204098,4410247,3694715]
Price_total=[15,17,17]

row=1
finish=0
counter=0

for r in range(3):
    start=finish
    finish=(r+1)*row

    Demand = [Demand_total[r]]
    RE = [RE_total[r]]
    Price = [Price_total[r]]

    # Objective function
    c = [None] * row
    for t in range(row):
        c[t] = (Demand[t] * Price[t])

    B_ch_over = [m.Var(lb=0) for t in range(row)]
    B_disch_over = [m.Var(lb=0) for t in range(row)]

    B_ch = [m.Var(lb=0) for t in range(row)]
    B_disch = [m.Var(lb=0) for t in range(row)]

    Unmet = [m.Var(lb=0) for t in range(row)]
    Surplus = [m.Var(lb=0) for t in range(row)]

    B_ch_if2 = [m.Var(lb=0) for t in range(row)]
    B_disch_if2 = [m.Var(lb=0) for t in range(row)]

    B_SOC = [m.Var() for t in range(row)]

    if r==0:
        starting_point = 0
        Last_BOS=Battery_Initial_capacity
        m.Equation(B_SOC[0]==Last_BOS) # initial charge at start
    else:
        m.Equation(B_SOC[0] == Last_BOS[0])  # initial charge at start


    for t in range(starting_point,row):

        m.Equation(RE[t] - B_ch_over[t] + B_disch_over[t] == Demand[t])
        m.Equation(B_ch_over[t] * B_disch_over[t] <= 0)

        B_ch_if2[t] = m.if3(B_ch_over[t] - (Battery_capacity - B_SOC[t - 1]), B_ch_over[t],Battery_capacity - B_SOC[t - 1])
        B_ch[t] = m.if3(max_charge - B_ch_if2[t], max_charge, B_ch_if2[t])

        B_disch_if2[t] = m.if3(B_disch_over[t] - B_SOC[t - 1], B_disch_over[t], B_SOC[t - 1])
        B_disch[t] = m.if3(max_discharge - B_disch_if2[t], max_discharge, B_disch_if2[t])

        B_SOC[t]=m.if3(Battery_capacity-(B_SOC[t - 1] + B_ch[t] - B_disch[t]),Battery_capacity,B_SOC[t - 1] + B_ch[t] - B_disch[t])

        m.Equation(B_ch[t] + Surplus[t] == B_ch_over[t])
        m.Equation(B_disch[t] + Unmet[t] == B_disch_over[t])

        counter+=1

    m.Maximize(m.sum(c))

    m.options.SOLVER = 1


    # m.open_folder()
    m.solve(disp=False)

    Last_BOS=B_SOC[t].value
    if r==0:
        print('Results')
    for t in range(starting_point, row):
        print('B_ch{}={}  B_disch{}={}  B_SOC{}={} B_ch_over{}={}  B_disch_over{}={} Unmet{}={} Surplus{}={} RE{}={} Demand{}={}'.format(counter-row+t, B_ch[t].value, counter-row+t, B_disch[t].value, counter-row+t, B_SOC[t].value, counter-row+t, B_ch_over[t].value, counter-row+t,B_disch_over[t].value, counter-row+t, Unmet[t].value, counter-row+t, Surplus[t].value, counter-row+t, RE[t], counter-row+t,Demand[t]))

print('目标:' + str(m.options.objfcnval))

© www.soinside.com 2019 - 2024. All rights reserved.