e2nIEE / pandapower

Convenient Power System Modelling and Analysis based on PYPOWER and pandas
https://www.pandapower.org
Other
848 stars 478 forks source link

OPF not converged #2064

Closed Yiwen233 closed 1 year ago

Yiwen233 commented 1 year ago

Running OPF with pandapower do not convege!

I implement ieee15bus, and add two distributed generator and one pv on three different buses, and several storages as well. I found that the opf just not convege regardless of load tuning. Then I try to cut the storages and remain only one generator in the system, the result is still the same. I run PF in all conditions and it works, except OPF. So any one can help me what I should do ?

        b1 = pp.create_bus(net, vn_kv=110, name="Bus 1")
        b2 = pp.create_bus(net, vn_kv=10, name="Bus 2")
        b3 = pp.create_bus(net, vn_kv=10, name="Bus 3")
        b4 = pp.create_bus(net, vn_kv=10, name="Bus 4")
        b5 = pp.create_bus(net, vn_kv=10, name="Bus 5")
        b6 = pp.create_bus(net, vn_kv=10, name="Bus 6")
        b7 = pp.create_bus(net, vn_kv=10, name="Bus 7")
        b8 = pp.create_bus(net, vn_kv=10, name="Bus 8")
        b9 = pp.create_bus(net, vn_kv=10, name="Bus 9")
        b10 = pp.create_bus(net, vn_kv=10, name="Bus 10")
        b11 = pp.create_bus(net, vn_kv=10, name="Bus 11")
        b12 = pp.create_bus(net, vn_kv=10, name="Bus 12")
        b13 = pp.create_bus(net, vn_kv=10, name="Bus 13")
        b14 = pp.create_bus(net, vn_kv=10, name="Bus 14")
        b15 = pp.create_bus(net, vn_kv=10, name="Bus 15")

        line1 = pp.create_line(net, b2, b3, length_km=1.,
                               std_type="149-AL1/24-ST1A 10.0") 
        line2 = pp.create_line(net, b3, b4, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line3 = pp.create_line(net, b4, b5, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line4 = pp.create_line(net, b2, b9, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line5 = pp.create_line(net, b9, b10, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line6 = pp.create_line(net, b2, b6, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line7 = pp.create_line(net, b6, b7, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line8 = pp.create_line(net, b6, b8, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line9 = pp.create_line(net, b3, b11, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line10 = pp.create_line(net, b11, b12, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line11 = pp.create_line(net, b12, b13, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line12 = pp.create_line(net, b4, b14, length_km=1., std_type="149-AL1/24-ST1A 10.0")
        line13 = pp.create_line(net, b4, b15, length_km=1., std_type="149-AL1/24-ST1A 10.0")

        eg = pp.create_ext_grid(net, bus=b1, name="Main Grid", max_p_mw=200, min_p_mw=-200, slack=True)
        cost_eg = pp.create_poly_cost(net, eg, 'ext_grid', cp1_eur_per_mw=15)
        pp.create_transformer(net, hv_bus=b1, lv_bus=b2, std_type="25 MVA 110/10 kV", name="Trafo",
                              max_loading_percent=100) 
        dg1 = pp.create_gen(net, bus=b3, p_mw=20, name="DG 1", max_p_mw=20, min_p_mw=0,
                            vm_pu=1.01, controllable=True)
        cost_dg1 = pp.create_poly_cost(net, dg1, "DG 1", cp1_eur_per_mw=15)

The load are modified manually in the following:

       pp.create_load(net, bus=b4, p_mw=0.5, name="Load 4", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b5, p_mw=0.441, name="Load 5", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b7, p_mw=0.30, name="Load 7", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b8, p_mw=0.70, name="Load 8", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b10, p_mw=1.441, name="Load 10", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b11, p_mw=0.480, name="Load 11", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b12, p_mw=1.70, name="Load 12", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b13, p_mw=0.441, name="Load 13", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b14, p_mw=0.70, name="Load 14", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)
        pp.create_load(net, bus=b15, p_mw=0.140, name="Load 15", max_p_mw=5, min_p_mw=0, max_q_mvar=5, min_q_mvar=0,
                       controllable=True)

runpp():

This pandapower network includes the following parameter tables:
   - bus (15 elements)
   - load (10 elements)
   - gen (1 element)
   - ext_grid (1 element)
   - line (13 elements)
   - trafo (1 element)
   - poly_cost (2 elements)
============================================

Process finished with exit code 0

runopp():

    pp.runopp(net, numba=False)
  File "D:\Anaconda3\envs\pytorch_1.9.0\lib\site-packages\pandapower\run.py", line 366, in runopp
    _optimal_powerflow(net, verbose, suppress_warnings, **kwargs)
  File "D:\Anaconda3\envs\pytorch_1.9.0\lib\site-packages\pandapower\optimal_powerflow.py", line 86, in _optimal_powerflow
    raise OPFNotConverged("Optimal Power Flow did not converge!")
pandapower.optimal_powerflow.OPFNotConverged: Optimal Power Flow did not converge!
jwiemer112 commented 1 year ago

Hey,

maybe the OPF tutorial helps you with that problem.

https://github.com/e2nIEE/pandapower/blob/master/tutorials/opf_basic.ipynb

Also you specified only costs for the ext_grid and the gen but not for the loads (which are controllable).

https://pandapower.readthedocs.io/en/v2.13.1/opf/formulation.html#cost-functions

Best regards Jan

Yiwen233 commented 1 year ago

I already read the tutorials about opf calculation. I add min_vm_pu and max_vm_pu to buses, max_loading_percent to lines, and set load controllable=False, but runopp() still does not work.

jwiemer112 commented 1 year ago

Seems like the defined optimization problem is then not solvable with your parameter set up. Try to play arround with the parameters. Run a normal power flow and check the results / loadings and then adapt the constraints or parameters and run an opf again.

The convergence of the pypower OPF isn't that good.

Yiwen233 commented 1 year ago

I found that if p_mw of all gens and sgens are determined, then runopf() is not necessary, and actully it will not converge, runpp() is needed only and compute the cost manually.

jwiemer112 commented 1 year ago

I just tried it: set all the needed constraints as mentioned in the documentation and the tutorial and set calculate_voltage_angles=True then the OPF converges. :)

See https://github.com/e2nIEE/pandapower/issues/489

Yiwen233 commented 1 year ago

I just tried it: set all the needed constraints as mentioned in the documentation and the tutorial and set calculate_voltage_angles=True then the OPF converges. :)

See #489

alright, I found the problem. Thanks