OPF成本计算公式的变化
With the new pandapower Version 1.5.1, the cost formulation for the pandapower OPF changes. Basically, you'll be good if you just multiply all your cost functions with -1 and your results will be the same as before. Maybe you already realized yourself, that there was an inconsistency with the costs.
在新的版本pandapower 1.5.1中,pandapower的OPF成本计算公式发生了变化。基本上,如果你只是用-1乘以所有的成本函数,那么你不会收到影响,你的计算结果也将和以前一样。可能你已经意识到了成本之间的矛盾。
This tutorial will explain why we made this change and how you can refactor your old code. It is based on the opf_basic tutorial.
So let's remember one convention in pandapower:
For all bus-based power values, the signing is based on the consumer viewpoint:
本教程将解释为什么要做出这一步改变和如何重构你原来的代码。本教程基于opf_basic教程。
让我们记得pandapower中的一个规定:
对所有母线上的功率值,都是从电力消费者的观点上出发的。
positive active power is power consumption, negative active power is power generation
positive reactive power is inductive consumption, negative reactive power is capacitive consumption
正值有功功率表示消耗功率值,负值有功功率表示发电功率值
正值无功功率表示感性无功,负值无功功率表示容性无功
Let's say I wan't to define linear costs of 1€ per kW for a generator, then I need to keep this in mind!
The respective cost function has a negative slope:
假设我不想定义发电机每千瓦1欧元的线性成本,那我需要牢记一点!
相应的成本函数具有负斜率:
在pandapower中,该成本函数可以采用如下的命令创建
- pp.create_polynomial_cost(net, 1, 'gen', np.array([-1, 0]))
或者
- pp.create_piecewise_linear_cost(net, 1, "gen", np.array([[p_min_kw, abs(p_min_kw)], [0,0]]))
例如:当我们拥有一台100kW的发电机时:
- pp.create_piecewise_linear_cost(net, 1, "gen", np.array([[-1000, 1000], [0,0]]))
以下面的例子说明。我们首先创建电网,与以前无异。
import pandapower as pp
import numpy as np
net = pp.create_empty_network()
#create buses
bus1 = pp.create_bus(net, vn_kv=220.)
bus2 = pp.create_bus(net, vn_kv=110.)
bus3 = pp.create_bus(net, vn_kv=110.)
bus4 = pp.create_bus(net, vn_kv=110.)
#create 220/110 kV transformer
pp.create_transformer(net, bus1, bus2, std_type="100 MVA 220/110 kV")
#create 110 kV lines
pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0')
pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0')
pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0')
#create loads
pp.create_load(net, bus2, p_kw=60e3, controllable = False)
pp.create_load(net, bus3, p_kw=70e3, controllable = False)
pp.create_load(net, bus4, p_kw=10e3, controllable = False)
#create generators
eg = pp.create_ext_grid(net, bus1)
g0 = pp.create_gen(net, bus3, p_kw=-80*1e3, min_p_kw=-80e3, max_p_kw=0,vm_pu=1.01, controllable=True)
g1 = pp.create_gen(net, bus4, p_kw=-100*1e3, min_p_kw=-100e3, max_p_kw=0, vm_pu=1.01, controllable=True)
网损最小化
We specify the same costs for the power at the external grid and all generators to minimize the overall power feed in. This equals an overall loss minimization. With the former pandapower versions, you must've specified the costs like this to get to the goal of having positive costs for high feed in:
- costeg = pp.create_polynomial_cost(net, 0, 'ext_grid', np.array([1, 0]))
- costgen1 = pp.create_polynomial_cost(net, 0, 'gen', np.array([1, 0]))
- costgen2 = pp.create_polynomial_cost(net, 1, 'gen', np.array([1, 0]))
But as we leared above, this is not right! This was due to a mix up in the signs, but from now on, the cost function signing is based on the consumer viewpoint as well.
我们指定外部电网和所有发电机的功率成本相同的情况下,最小化总的供应功率。这等同于总的网损最小化。在之前的pandapower版本中,你必须指定如下的成本以获得正的成本。
- costeg = pp.create_polynomial_cost(net, 0, 'ext_grid', np.array([1, 0]))
- costgen1 = pp.create_polynomial_cost(net, 0, 'gen', np.array([1, 0]))
- costgen2 = pp.create_polynomial_cost(net, 1, 'gen', np.array([1, 0]))
但是正如我们上面分析的,这是不对的。这是由于对于符号的混淆,但从现在起,成本函数符号都是基于电力消费者的角度。
costeg = pp.create_polynomial_cost(net, 0, 'ext_grid', np.array([-1, 0]))
costgen1 = pp.create_polynomial_cost(net, 0, 'gen', np.array([-1, 0]))
costgen2 = pp.create_polynomial_cost(net, 1, 'gen', np.array([-1, 0]))
运行OPF运算:
pp.runopp(net, verbose=True)
The OPF cost definition has changed! Please check out the tutorial 'opf_changes-may18.ipynb' or the documentation!
PYPOWER Version 5.1.4, 27-June-2018 -- AC Optimal Power Flow
Python Interior Point Solver - PIPS, Version 1.0, 07-Feb-2011
Converged!
看下计算结果:
print(net.res_ext_grid)
p_kw q_kvar
0 -56530.133524 -1974.471614
print(net.res_gen)
p_kw q_kvar va_degree vm_pu
0 -71313.545821 1969.654618 -3.712804 1.000009
1 -12299.610412 1451.160058 -3.712782 1.000010
Since all costs were specified the same, the OPF minimizes overall power generation, which is equal to a loss minimization in the network. The loads at buses 3 and 4 are supplied by generators at the same bus, the load at Bus 2 is provided by a combination of the other generators so that the power transmission leads to minimal losses.
因为指定都为相同的成本,OPF最小化总的发电功率。这等同于网损最小化。母线3和母线4上的负荷由各自母线上的发电机供应,母线2上的负荷由其他发电机联合供应,从而输电的功率损失最小。
What about the cost result? We expect costs of 1 for each kW fed into the net. So let's check the overall fed in power:
那么成本是多少呢?我们假定每1kW输入到网络中的成本为1.因此我们计算所有的输入功率:
print(net.res_gen.p_kw.sum() + net.res_ext_grid.p_kw.sum())
-140143.28975736868
因此OPF的成本为140143.29!
print(net.res_cost)
140143.28975736868
现在我们有了具有一致性的OPF成本函数了!