e2nIEE / pandapower

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

broken lightsim2grid integration for contingency analysis #2361

Closed awarsewa closed 2 months ago

awarsewa commented 2 months ago

Feature Checklist

Issue

The integration of lightsim2grid into pandapower for contingency analysis seems to be outdated and has several issues. It would be nice if this can be fixed for faster contingency analysis. I offer to work on a PR, but some support would be appreciated :)

@BDonnot would you be interested in working on a PR together?

Label

BDonnot commented 2 months ago

Hello,

I'll be on holiday starting Friday and getting back Monday, 26th August.

I can help if course but probably not during on holiday.

I think also that adding some basic pandapower integration tests in lightsim2grid would be a nice idea so that this kind of issues does not appear anymore.

More concretely I think that the cpp API allows to do most of the things done in pandapower. So lightsim2grid side it's mainly python (probably easier to do).

rbolgaryn commented 2 months ago

Thank you!

We already fixed it in the following pull request:

https://github.com/e2nIEE/pandapower/issues/2361

BDonnot commented 2 months ago

Hello,

Sorry to bother here but I think the way you import things can be a bit "optimized" to recognize both earlier lightsim2grid version (<=0.8.2) and new one (>=0.9.0) if you do something like this:


try:
    # lightsim2grid version >= 0.9.0
    from lightsim2grid.gridmodel import init_from_pandapower as init_ls2g
    lightsim2grid_installed = True
except ImportError:
    try: 
        # lightsim2grid <= 0.8.2
        from lightsim2grid.gridmodel import init as int_ls2g
        lightsim2grid_installed = True
    except ImportError:
        # lightsim2grid is most likely not installed
        lightsim2grid_installed = False

if lightsim2grid_installed:
    try:
        # ligthsim2grid >= 0.8.0
        from lightsim2grid.contingencyAnalysis import ContingencyAnalysisCPP
    except ImportError:
        try:
            # ligthsim2grid < 0.8.0
            from lightsim2igrd.securityAnalysis import SecurityAnalysisCPP as ContingencyAnalysisCPP
        except ImportError:
            # issue a warning here maybe ? Most likely lightsim2grid version is too old
           lightsim2grid_installed = False
    try:
        from lightsim2grid.solver import SolverType
    except ImportError:
        # issue a warning here maybe ? Most likely lightsim2grid version is too old
        lightsim2grid_installed = False

This way should work if lightsim2grid is not installed and also if an oldest version of lightsim2grid with different import is installed.

It's a bit more verbose I totally agree, but really more difficult to understand what's going on (no readability issue)

awarsewa commented 2 months ago

Thanks @rbolgaryn, I missed these PRs. I'm having more issues though than just the import statement having to be adapted. So I'll try creating a minimal example that reproduces my issues and file a separate bug report. With larger networks I'm having the issue that these lines:

v_init = net._ppc["internal"]["V"]
s.compute(v_init, net._options["max_iteration"], net._options["tolerance_mva"])

throw an error because the size of V is not equal to the number of buses, in case there are redundant buses, which can be fixed using the mapping:

v_init = net._ppc["internal"]["V"][net._pd2ppc_lookups["bus"]]

And I'm also confused about these lines of code:

max_loading_limit_all = np.r_[net.line["max_loading_percent_nminus1"]
    if "max_loading_percent_nminus1" in net.line.columns
    else net.line["max_loading_percent"] if n_lines > 0 else [],
    net.trafo["max_loading_percent_nminus1"]
    if "max_loading_percent_nminus1" in net.trafo.columns
    else net.trafo["max_loading_percent"] if n_trafos > 0 else []]

The columns "max_loading_percent" or "max_loading_percent_nminus1" are not initialised before as far as I can see. So if you don't run pp.run_contingency before running pp.run_contingency_ls2g, this won't work. But I'll look into it some more - maybe I missed something or I'm not using it correctly.

rbolgaryn commented 2 months ago

Thanks @rbolgaryn, I missed these PRs. I'm having more issues though than just the import statement having to be adapted. So I'll try creating a minimal example that reproduces my issues and file a separate bug report. With larger networks I'm having the issue that these lines:

v_init = net._ppc["internal"]["V"]
s.compute(v_init, net._options["max_iteration"], net._options["tolerance_mva"])

throw an error because the size of V is not equal to the number of buses, in case there are redundant buses, which can be fixed using the mapping:

v_init = net._ppc["internal"]["V"][net._pd2ppc_lookups["bus"]]

And I'm also confused about these lines of code:

max_loading_limit_all = np.r_[net.line["max_loading_percent_nminus1"]
    if "max_loading_percent_nminus1" in net.line.columns
    else net.line["max_loading_percent"] if n_lines > 0 else [],
    net.trafo["max_loading_percent_nminus1"]
    if "max_loading_percent_nminus1" in net.trafo.columns
    else net.trafo["max_loading_percent"] if n_trafos > 0 else []]

The columns "max_loading_percent" or "max_loading_percent_nminus1" are not initialised before as far as I can see. So if you don't run pp.run_contingency before running pp.run_contingency_ls2g, this won't work. But I'll look into it some more - maybe I missed something or I'm not using it correctly.

Thank you!

Can you please write a small failing test that provides a minimal example for this?

rbolgaryn commented 2 months ago

Hello,

Sorry to bother here but I think the way you import things can be a bit "optimized" to recognize both earlier lightsim2grid version (<=0.8.2) and new one (>=0.9.0) if you do something like this:

try:
    # lightsim2grid version >= 0.9.0
    from lightsim2grid.gridmodel import init_from_pandapower as init_ls2g
    lightsim2grid_installed = True
except ImportError:
    try: 
        # lightsim2grid <= 0.8.2
        from lightsim2grid.gridmodel import init as int_ls2g
        lightsim2grid_installed = True
    except ImportError:
        # lightsim2grid is most likely not installed
        lightsim2grid_installed = False

if lightsim2grid_installed:
    try:
        # ligthsim2grid >= 0.8.0
        from lightsim2grid.contingencyAnalysis import ContingencyAnalysisCPP
    except ImportError:
        try:
            # ligthsim2grid < 0.8.0
            from lightsim2igrd.securityAnalysis import SecurityAnalysisCPP as ContingencyAnalysisCPP
        except ImportError:
            # issue a warning here maybe ? Most likely lightsim2grid version is too old
           lightsim2grid_installed = False
    try:
        from lightsim2grid.solver import SolverType
    except ImportError:
        # issue a warning here maybe ? Most likely lightsim2grid version is too old
        lightsim2grid_installed = False

This way should work if lightsim2grid is not installed and also if an oldest version of lightsim2grid with different import is installed.

It's a bit more verbose I totally agree, but really more difficult to understand what's going on (no readability issue)

Thank you for the suggestion, I think we will just limit the version to 0.9.0 or above and issue a warning to update lightsim2grid:

try:
    import lightsim2grid
    v = Version(lightsim2grid.__version__)
    if v < Version("0.9.0"):
        logger.warning("Only lightsim2grid version 0.9.0 or newer is supported - please update ligtsim2grid")
        raise ImportError

    from lightsim2grid.gridmodel.from_pandapower import init as init_ls2g
    from lightsim2grid.contingencyAnalysis import ContingencyAnalysisCPP
    from lightsim2grid_cpp import SolverType

    lightsim2grid_installed = True
except ImportError:
    lightsim2grid_installed = False