e2nIEE / pandapower

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

PP does not check for feasibility in (O)PF? #1600

Open kevin-kruse opened 2 years ago

kevin-kruse commented 2 years ago

Hi,

I'm performing a basic OPF on basic grids (e.g. the 118 bus grid network), using this code:

net = pn.case118()
#net.line["in_service"] = False
pp.rundcopp(net)
net.res_cost 

This basically works (with PyPower). However, my overall goal is to identify lines to turn off in order to optimise the overall cost. But for this, the DC-OPF also "works", if i put all lines out of service. Why does PP not return an infeasible model? Instead, it just returns a resulting load table indicating that almost all load requirements are not fulfilled.

How can I enforce that all load requirements have to be fulfilled? (And yes, I set controllable=False for all loads)

Best, Kevin

rbolgaryn commented 2 years ago

Hi @kevin-kruse ,

sorry I couldn't understand the issue from your description. Can you elaborate?

Roman

kevin-kruse commented 2 years ago

Okay. First of all; my overall goal is to reduce the costs given by the OPF by switching transmission lines. I do that by modifying the vector net.line["in_service"] (e.g. setting some lines out of service).

However, if i basically disconnect loads completely from the grid, the OPF returns a solution where the load demand is just not met. My expectation would be an infeasible power flow instead. Since my objective is to reduce the overall costs, I'm currently validating that the load specified before (net.load) equals the resulting, calculated load (net.res_load). Otherwise, even a greedy model would just switch off all transmission lines and obtain 0 costs (whats not useful).

Hope that helps, Best, Kevin

rbolgaryn commented 2 years ago

It sounds like what you need is not implemented in pandapower.

rbolgaryn commented 2 years ago

I think you need a different approach, maybe you will have to implement the feature you need yourself

kevin-kruse commented 2 years ago

Okay, thanks. But actually, one implementation with the same goal does already exist (https://docs.juliahub.com/PandaModels/lPFae/0.3.1/ots/).

And, in addition, why does the OPF calculation modify the given load properties although it is forbidden (controllable=False) and does not return an infeasible flow?

Best, Kevin

rbolgaryn commented 2 years ago

I don't know but you can provide a failing test

rbolgaryn commented 2 years ago

If controllable = False, it should not be adjusted by OPF. If you are observing the opposite, please provide a failing test

kevin-kruse commented 2 years ago

You can verify it with this small code snippet:

import pandapower as pp
import pandapower.networks as pn
import pandas as pd

print("Scenario A - Everything works fine")
net = pn.case118()
pp.rundcopp(net)
print(f"Total operating costs are {net.res_cost}")
if not (net.load["p_mw"].equals(net.res_load["p_mw"])):
    print("Resulting load is not matched with requirements")
else:
    print("Everything is fine")

print("Scenario B - Load Demands are ignored, though controllable=False")
net = pn.case118()
net.line["in_service"] = False
net.load["controllable"] = False
pp.rundcopp(net)
print(f"Total operating costs are {net.res_cost}")
if not (net.load["p_mw"].equals(net.res_load["p_mw"].values)):
    print("Resulting load is not matched with requirements")
else:
    print("Everything is fine")
rbolgaryn commented 2 years ago

I think if you can use PandaModels you should do it. The OPF in pandapower is not as good as with PandaModels.

AnkurArohi commented 2 years ago

Okay. First of all; my overall goal is to reduce the costs given by the OPF by switching transmission lines. I do that by modifying the vector net.line["in_service"] (e.g. setting some lines out of service).

However, if i basically disconnect loads completely from the grid, the OPF returns a solution where the load demand is just not met. My expectation would be an infeasible power flow instead. Since my objective is to reduce the overall costs, I'm currently validating that the load specified before (net.load) equals the resulting, calculated load (net.res_load). Otherwise, even a greedy model would just switch off all transmission lines and obtain 0 costs (whats not useful).

Hope that helps, Best, Kevin

Hey @kevin-kruse you need to add constraints for you greedy model to not switch off non controllable and critical loads. So your resulting loads will atleast be not curtailed. This should be an additional constraint for the opf model.

kevin-kruse commented 2 years ago

Hi @AnkurArohi, thank you. What constraints are you referring to (except the regular net.load["controllable"] = False)?

In addition, i tried using the PowerModels implementation of the OPF. But this does not work at all: I'm using this tutorial notebook as a starting point: pandapower/tutorials/opf_powermodels.ipynb. This - in principle - works. But if i now use a different network, e.g. the above-mentioned 118-bus network, it does not converge anymore: You should be able to reproduce the error just using the following code snippet:

import pandapower.networks as pn
import pandapower as pp

net = pn.case118()
pp.runopp(net) # PyPower, works: res_cost = 129695.10150252422
pp.runpm_ac_opf(net) # PowerModels - error: OPF did not converge!
pp.runpm_dc_opf(net) # PowerModels - error. OPF did not converge!

To trace the error, I did the following:

In addition (and what is really interesting for me), the following tutorial notebook does not work at all for me: https://github.com/e2nIEE/pandapower/blob/develop/tutorials/ost_powermodels.ipynb Can you confirm that this is an general error? Or do I have a broken/wrong installation?