Skip to content

Commit

Permalink
Merge pull request #90 from BDonnot/bd-dev
Browse files Browse the repository at this point in the history
Upgrade to version 0.9.1
  • Loading branch information
BDonnot authored Sep 30, 2024
2 parents df9d3c0 + d3989ea commit 275569f
Show file tree
Hide file tree
Showing 28 changed files with 1,449 additions and 291 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ TODO HVDC in Jacobian (see pandapower)
TODO: in ContingencyAnalysisCpp: add back the `if(!ac_solver_used)` inside the `remove_from_Ybus`
in order to perform the "invertibility" check
TODO: in `main.cpp` check the returned policy of pybind11 and also the `py::call_guard<py::gil_scoped_release>()` stuff
TODO: a cpp class that is able to compute (DC powerflow) ContingencyAnalysis and TimeSeries using PTDF and LODF
TODO: integration test with pandapower (see `pandapower/contingency/contingency.py` and import `lightsim2grid_installed` and check it's True)

[0.9.1] 2024-xx-yy
--------------------------
- [FIXED] a bug due to wrong type (in a numpy array) for the element name which lead in turn
to a fail assertion (equality between two numpy arrays returning a bool and not an array)
- [FIXED] a bug when init a grid from pypowsybl: the wrong value was used for trafos `h` (double)
- [FIXED] a bug when init a grid from pypowsybl: wrong values for `_ls_to_orig` and `_orig_to_ls`
was set (and later used)
- [FIXED] yet another bug when init a grid from pypowsybl: the voltage in kV (not in pu)
could be set due to "wrong" labelling of the bus ids
- [FIXED] yet another bug when init a grid from pypowsybl: the ratio of the transformers
sent in lightsim2grid did not take into account the "`rated_u1` `rated_u2`" on both side
(only used on one side)
- [FIXED] yet another bug when init a grid from pypowsybl: the ratio of the transformers
sent in lightsim2grid did not take into account the ratio in the `pypow_net.get_ratio_tap_changers()`
- [ADDED] a method for the `ContingencyAnalysisCPP` class that returns, for all contingencies
in the contingency list, which will be simulated and which causes the grid to be disconnected.
- [ADDED] it is now possible to use "one substation" (voltage level) pypowsybl side is
one substation in lightsim2grid.
- [IMPROVED] removing a weird `1j * h_` when initializing powerlines and transformers. This was
part of a pandapower "hack" which is not present anymore (see
https://github.com/BDonnot/lightsim2grid/issues/88#issue-2443299039)

[0.9.0] 2024-07-29
--------------------------
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = 'Benjamin DONNOT'

# The full version, including alpha/beta/rc tags
release = "0.9.0"
release = "0.9.1"
version = '0.9'

# -- General configuration ---------------------------------------------------
Expand Down
49 changes: 48 additions & 1 deletion docs/lightsimbackend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ For standard grid2op environment, you can use it like:
# the `LightSimBackend` will be used to carry out the powerflow computation instead
# of the default grid2op `PandaPowerBackend`
Customization of the backend
Customization of the solver
-------------------------------
.. warning::
Use grid2op > 1.7.1 for this feature to work properly. Otherwise some bugs (hard to detect) will occur.
Expand All @@ -63,6 +63,9 @@ You can customize the way the backend behaves in different ways:
- `dist_slack_non_renew`: by default in most grid2op environment, the slack bus is "centralize" / "single slack". This parameters
allows to bypass this restriction and use all non renewable generators (and turned on and with > 0.) in a distributed
slack bus setting. It might change the default `solver_type` used.
- \* `use_static_gen`: bool=False, DO NOT USE AT THE MOMENT. When it will be available, you will be able to loader_kwargs
both "static" generators (pq generators) and "regular" (pv generators) as generators in lightsim2grid. It does
not work at the moment and has no effect.
- \* `detailed_infos_for_cascading_failures`: for exhaustivity, do not modify.
- \* `can_be_copied`: for exhaustivity, do not modify.

Expand All @@ -84,12 +87,56 @@ The easiest way to customize your backend is when you create the grid2op environ
)
)
Customization of the input format
----------------------------------

For a few versions now, we try to extend the capability of lightsim2grid and make it work
with other data "reader". We started this process by allowing to initialize a
lightsim2grid `GridModel` from a pypowsybl network.

For example, if you environment contains a grid in the iidm format (native format of pypowsybl networks),
you can load it with:

.. code-block:: python
import grid2op
from lightsim2grid.LightSimBackend import LightSimBackend
from grid2op.Agent import RandomAgent
# create an environment
env_with_iidm_as_the_grid_description = ...
env = grid2op.make(env_name,
backend=LightSimBackend(loader_method="pypowsybl")
)
You can also customize the way lightsim2grid works with some extra options:


- `loader_method`: Literal["pandapower", "pypowsybl"]: from which grid "file description"
the grid will be loaded. If you use `pandapower` then pandapower needs to be installed.
If you specified `pypowsybl` then pypowsybl needs to be installed on your machine.
- `loader_kwargs` : ``dict``: some customization to use when loading the grid. It is not
not used when loading the grid from `pandapower`. Please refer to the documentation of
:attr:`LightSimBackend._loader_kwargs` for more information.

Other Customization
--------------------

Here are some other extra features you can use in lightsim2grid (but that are not yet supported by grid2op
so not really usable...) :

- stop_if_load_disco : Optional[bool] = True: whether to stop the computation (returning a `DivergingPowerflow` exception)
if a load is disconnected.
- stop_if_gen_disco : Optional[bool] = True: whether to stop the computation (returning a `DivergingPowerflow` exception)
if a generator is disconnected.

Detailed documentation
--------------------------

.. automodule:: lightsim2grid.lightSimBackend
:members:
:autosummary:
:private-members:


* :ref:`genindex`
Expand Down
2 changes: 1 addition & 1 deletion lightsim2grid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

__version__ = "0.9.0"
__version__ = "0.9.1"

__all__ = ["newtonpf", "SolverType", "ErrorType", "solver", "compilation_options"]

Expand Down
28 changes: 16 additions & 12 deletions lightsim2grid/elements/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,33 @@
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

__all__ = ["DataGen",
__all__ = ["GeneratorContainer",
"GenInfo",
"DataSGen",
"SGenContainer",
"SGenInfo",
"DataLoad",
"LoadContainer",
"LoadInfo",
"DataShunt",
"ShuntContainer",
"ShuntInfo",
"DataTrafo",
"TrafoContainer",
"TrafoInfo",
"DataLine",
"LineContainer",
"LineInfo",
"DCLineContainer",
"DCLineInfo",
]

from lightsim2grid_cpp import DataGen
from lightsim2grid_cpp import GeneratorContainer
from lightsim2grid_cpp import GenInfo
from lightsim2grid_cpp import DataSGen
from lightsim2grid_cpp import SGenContainer
from lightsim2grid_cpp import SGenInfo
from lightsim2grid_cpp import DataLoad
from lightsim2grid_cpp import LoadContainer
from lightsim2grid_cpp import LoadInfo
from lightsim2grid_cpp import DataShunt
from lightsim2grid_cpp import ShuntContainer
from lightsim2grid_cpp import ShuntInfo
from lightsim2grid_cpp import DataTrafo
from lightsim2grid_cpp import TrafoContainer
from lightsim2grid_cpp import TrafoInfo
from lightsim2grid_cpp import DataLine
from lightsim2grid_cpp import LineContainer
from lightsim2grid_cpp import LineInfo
from lightsim2grid_cpp import DCLineContainer
from lightsim2grid_cpp import DCLineInfo
53 changes: 38 additions & 15 deletions lightsim2grid/gridmodel/from_pandapower/_aux_add_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np
from packaging import version
import pandapower as pp

from ._pp_bus_to_ls_bus import pp_bus_to_ls
from ._my_const import _MIN_PP_VERSION_ADV_GRID_MODEL

def _aux_add_line(converter, model, pp_net, pp_to_ls=None):
"""
Expand All @@ -29,21 +32,41 @@ def _aux_add_line(converter, model, pp_net, pp_to_ls=None):
"Some pp_net.line[\"parallel\"] != 1 it is not handled by lightsim yet.")

#### find the right powerline parameters
line_r, line_x, line_h = \
converter.get_line_param(
pp_net.line["r_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["x_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["c_nf_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["g_us_per_km"].values * pp_net.line["length_km"].values,
pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"],
)

### add them to the grid
model.init_powerlines(line_r, line_x, line_h,
pp_bus_to_ls(pp_net.line["from_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.line["to_bus"].values, pp_to_ls)
)
if version.parse(pp.__version__) >= _MIN_PP_VERSION_ADV_GRID_MODEL:
# new pandapower with support for different h at both side
line_r, line_x, line_h_or, line_h_ex = \
converter.get_line_param(
pp_net.line["r_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["x_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["g_us_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["c_nf_per_km"].values * pp_net.line["length_km"].values,
pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"],
)

### add them to the grid
model.init_powerlines_full(line_r, line_x, line_h_or, line_h_ex,
pp_bus_to_ls(pp_net.line["from_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.line["to_bus"].values, pp_to_ls)
)

else:
# legacy pandapower, when they did not support lines with different h both side
line_r, line_x, line_h = \
converter.get_line_param_legacy(
pp_net.line["r_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["x_ohm_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["g_us_per_km"].values * pp_net.line["length_km"].values,
pp_net.line["c_nf_per_km"].values * pp_net.line["length_km"].values,
pp_net.bus.loc[pp_net.line["from_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.line["to_bus"]]["vn_kv"],
)

### add them to the grid
model.init_powerlines(line_r, line_x, line_h,
pp_bus_to_ls(pp_net.line["from_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.line["to_bus"].values, pp_to_ls)
)
for line_id, is_connected in enumerate(pp_net.line["in_service"].values):
if not is_connected:
# powerline is deactivated
Expand Down
80 changes: 55 additions & 25 deletions lightsim2grid/gridmodel/from_pandapower/_aux_add_trafo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

import warnings
import numpy as np
from ._pp_bus_to_ls_bus import pp_bus_to_ls
import pandapower as pp
from packaging import version

from ._pp_bus_to_ls_bus import pp_bus_to_ls
from ._my_const import _MIN_PP_VERSION_ADV_GRID_MODEL

def _aux_add_trafo(converter, model, pp_net, pp_to_ls):
"""
Expand Down Expand Up @@ -69,30 +72,57 @@ def _aux_add_trafo(converter, model, pp_net, pp_to_ls):
tap_angles_ = np.deg2rad(tap_angles_)

# compute physical parameters
trafo_r, trafo_x, trafo_b = \
converter.get_trafo_param(tap_step_pct,
tap_pos,
tap_angles_, # in radian !
is_tap_hv_side,
pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
pp_net.trafo["vk_percent"].values,
pp_net.trafo["vkr_percent"].values,
pp_net.trafo["sn_mva"].values,
pp_net.trafo["pfe_kw"].values,
pp_net.trafo["i0_percent"].values,
)

# initialize the grid
model.init_trafo(trafo_r,
trafo_x,
trafo_b,
tap_step_pct,
tap_pos,
shift_,
is_tap_hv_side,
pp_bus_to_ls(pp_net.trafo["hv_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.trafo["lv_bus"].values, pp_to_ls))
if version.parse(pp.__version__) >= _MIN_PP_VERSION_ADV_GRID_MODEL:
# TODO
trafo_r, trafo_x, trafo_b = \
converter.get_trafo_param(tap_step_pct,
tap_pos,
tap_angles_, # in radian !
is_tap_hv_side,
pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
pp_net.trafo["vk_percent"].values,
pp_net.trafo["vkr_percent"].values,
pp_net.trafo["sn_mva"].values,
pp_net.trafo["pfe_kw"].values,
pp_net.trafo["i0_percent"].values,
)

# initialize the grid
model.init_trafo(trafo_r,
trafo_x,
trafo_b,
tap_step_pct,
tap_pos,
shift_,
is_tap_hv_side,
pp_bus_to_ls(pp_net.trafo["hv_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.trafo["lv_bus"].values, pp_to_ls))
else:
trafo_r, trafo_x, trafo_b = \
converter.get_trafo_param_legacy(tap_step_pct,
tap_pos,
tap_angles_, # in radian !
is_tap_hv_side,
pp_net.bus.loc[pp_net.trafo["hv_bus"]]["vn_kv"],
pp_net.bus.loc[pp_net.trafo["lv_bus"]]["vn_kv"],
pp_net.trafo["vk_percent"].values,
pp_net.trafo["vkr_percent"].values,
pp_net.trafo["sn_mva"].values,
pp_net.trafo["pfe_kw"].values,
pp_net.trafo["i0_percent"].values,
)

# initialize the grid
model.init_trafo(trafo_r,
trafo_x,
trafo_b,
tap_step_pct,
tap_pos,
shift_,
is_tap_hv_side,
pp_bus_to_ls(pp_net.trafo["hv_bus"].values, pp_to_ls),
pp_bus_to_ls(pp_net.trafo["lv_bus"].values, pp_to_ls))

for tr_id, is_connected in enumerate(pp_net.trafo["in_service"].values):
if not is_connected:
Expand Down
11 changes: 11 additions & 0 deletions lightsim2grid/gridmodel/from_pandapower/_my_const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (c) 2024, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

from packaging import version
# pandapower version with more advanced grid modelling
_MIN_PP_VERSION_ADV_GRID_MODEL = version.parse("2.15")
Loading

0 comments on commit 275569f

Please sign in to comment.