Skip to content

Commit

Permalink
improve consistency in gridmodel and input parameters for lines and t…
Browse files Browse the repository at this point in the history
…rafos
  • Loading branch information
BDonnot committed Aug 27, 2024
1 parent 70e9a87 commit 996eeff
Show file tree
Hide file tree
Showing 13 changed files with 199 additions and 112 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ TODO: in ContingencyAnalysisCpp: add back the `if(!ac_solver_used)` inside the
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)
- [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
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,6 +7,9 @@
# This file is part of LightSim2grid, LightSim2grid implements a c++ backend targeting the Grid2Op platform.

import numpy as np
from packaging import version
_MIN_PP_VERSION = version.parse("2.14.6")
import pandapower as pp

from ._pp_bus_to_ls_bus import pp_bus_to_ls

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:
# 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
6 changes: 3 additions & 3 deletions lightsim2grid/gridmodel/from_pypowsybl/_from_pypowsybl.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ def init(net : pypo.network,
b2 = df_line["b2"].values * v2*v2/sn_mva + (v2-v1)*tmp_.imag*v2/sn_mva
g1 = df_line["g1"].values * v1*v1/sn_mva + (v1-v2)*tmp_.real*v1/sn_mva
g2 = df_line["g2"].values * v2*v2/sn_mva + (v2-v1)*tmp_.real*v2/sn_mva
line_h_or = (b1 + 1j * g1)
line_h_ex = (b2 + 1j * g2)
line_h_or = (g1 + 1j * b1)
line_h_ex = (g2 + 1j * b2)
lor_bus, lor_disco = _aux_get_bus(bus_df, df_line, conn_key="connected1", bus_key="bus1_id")
lex_bus, lex_disco = _aux_get_bus(bus_df, df_line, conn_key="connected2", bus_key="bus2_id")
model.init_powerlines_full(line_r,
Expand Down Expand Up @@ -178,7 +178,7 @@ def init(net : pypo.network,
tex_bus, tex_disco = _aux_get_bus(bus_df, df_trafo, conn_key="connected2", bus_key="bus2_id")
model.init_trafo(df_trafo["r"].values / trafo_to_pu,
df_trafo["x"].values / trafo_to_pu,
2.*(1j*df_trafo["g"].values + df_trafo["b"].values) * trafo_to_pu,
2.*(df_trafo["g"].values + 1j * df_trafo["b"].values) * trafo_to_pu,
tap_step_pct,
tap_pos,
shift_,
Expand Down
24 changes: 12 additions & 12 deletions lightsim2grid/lightSimBackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,20 +628,20 @@ def _load_grid_pypowsybl(self, path=None, filename=None):
use_grid2op_default_names = False

if use_grid2op_default_names:
self.name_load = np.array([f"load_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_loads())])
self.name_gen = np.array([f"gen_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_generators())])
self.name_load = np.array([f"load_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_loads())]).astype(str)
self.name_gen = np.array([f"gen_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_generators())]).astype(str)
self.name_line = np.array([f"{el.bus_or_id}_{el.bus_ex_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_lines())] +
[f"{el.bus_hv_id}_{el.bus_lv_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_trafos())])
self.name_storage = np.array([f"storage_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_storages())])
self.name_shunt = np.array([f"shunt_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_shunts())])
[f"{el.bus_hv_id}_{el.bus_lv_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_trafos())]).astype(str)
self.name_storage = np.array([f"storage_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_storages())]).astype(str)
self.name_shunt = np.array([f"shunt_{el.bus_id}_{id_obj}" for id_obj, el in enumerate(self._grid.get_shunts())]).astype(str)
else:
self.name_load = np.array(load_sub.index)
self.name_gen = np.array(gen_sub.index)
self.name_line = np.concatenate((lor_sub.index, tor_sub.index))
self.name_storage = np.array(batt_sub.index)
self.name_shunt = np.array(sh_sub.index)
self.name_sub = np.array(buses_sub_id.index)
self.name_load = np.array(load_sub.index.astype(str))
self.name_gen = np.array(gen_sub.index.astype(str))
self.name_line = np.concatenate((lor_sub.index.astype(str), tor_sub.index.astype(str)))
self.name_storage = np.array(batt_sub.index.astype(str))
self.name_shunt = np.array(sh_sub.index.astype(str))
self.name_sub = np.array(buses_sub_id.index.astype(str))

if "reconnect_disco_gen" in loader_kwargs and loader_kwargs["reconnect_disco_gen"]:
for el in self._grid.get_generators():
if not el.connected:
Expand Down
Loading

0 comments on commit 996eeff

Please sign in to comment.