Skip to content

Commit

Permalink
fixing a bug in LightSimBackend for grid2op compat version
Browse files Browse the repository at this point in the history
Signed-off-by: DONNOT Benjamin <[email protected]>
  • Loading branch information
BDonnot committed Oct 18, 2024
1 parent 9ce778a commit b781f19
Showing 1 changed file with 82 additions and 46 deletions.
128 changes: 82 additions & 46 deletions lightsim2grid/lightSimBackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ class LightSimBackend(Backend):

shunts_data_available = True
glop_version = Backend.glop_version if hasattr(Backend, "glop_version") else grid2op.__version__

if not hasattr(Backend, "n_busbar_per_sub"):
# for legacy grid2op
n_busbar_per_sub = DEFAULT_N_BUSBAR_PER_SUB


def __init__(self,
detailed_infos_for_cascading_failures: bool=False,
can_be_copied: bool=True,
Expand Down Expand Up @@ -673,8 +677,10 @@ def _load_grid_pypowsybl(self, path=None, filename=None):
self.gen_to_subid = np.array(this_gen_sub, dtype=dt_int)
self.line_or_to_subid = np.concatenate((this_lor_sub, this_tor_sub)).astype(dt_int)
self.line_ex_to_subid = np.concatenate((this_lex_sub, this_tex_sub)).astype(dt_int)
self.storage_to_subid = np.array(this_batt_sub, dtype=dt_int)
self.shunt_to_subid = np.array(this_sh_sub, dtype=dt_int)
if self.__has_storage:
self.storage_to_subid = np.array(this_batt_sub, dtype=dt_int)
if self.n_shunt is not None:
self.shunt_to_subid = np.array(this_sh_sub, dtype=dt_int)
else:
# consider effectively that each "voltage_levels" in powsybl grid
# is a substation (in the underlying gridmodel)
Expand All @@ -686,9 +692,11 @@ def _load_grid_pypowsybl(self, path=None, filename=None):
self.gen_to_subid = np.array(gen_sub.values.ravel(), dtype=dt_int)
self.line_or_to_subid = np.concatenate((lor_sub.values.ravel(), tor_sub.values.ravel())).astype(dt_int)
self.line_ex_to_subid = np.concatenate((lex_sub.values.ravel(), tex_sub.values.ravel())).astype(dt_int)
self.storage_to_subid = np.array(batt_sub.values.ravel(), dtype=dt_int)
if self.__has_storage:
self.storage_to_subid = np.array(batt_sub.values.ravel(), dtype=dt_int)
self.shunt_to_subid = np.array(sh_sub.values.ravel(), dtype=dt_int)
self.n_sub = grid_tmp.get_voltage_levels().shape[0]
if self.n_shunt is not None:
self.n_sub = grid_tmp.get_voltage_levels().shape[0]

# the names
use_grid2op_default_names = True
Expand Down Expand Up @@ -1030,29 +1038,40 @@ def _aux_finish_setup_after_reading(self):
self.storage_theta = np.full(cls.n_storage, dtype=dt_float, fill_value=np.NaN).reshape(-1)

self._count_object_per_bus()
self.topo_vect[cls.load_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_loads()]),
cls.load_to_subid)
self.topo_vect[cls.gen_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_generators()]),
cls.gen_to_subid)
self.topo_vect[cls.storage_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_storages()]),
cls.storage_to_subid)
lor_glob_bus = np.concatenate((np.array([el.bus_or_id for el in self._grid.get_lines()]),
np.array([el.bus_hv_id for el in self._grid.get_trafos()])))
self.topo_vect[cls.line_or_pos_topo_vect] = cls.global_bus_to_local(lor_glob_bus,
cls.line_or_to_subid)
lex_glob_bus = np.concatenate((np.array([el.bus_ex_id for el in self._grid.get_lines()]),
np.array([el.bus_lv_id for el in self._grid.get_trafos()])))
self.topo_vect[cls.line_ex_pos_topo_vect] = cls.global_bus_to_local(lex_glob_bus,
cls.line_ex_to_subid)

self._grid.tell_solver_need_reset()
self.__me_at_init = self._grid.copy()
self.__init_topo_vect = np.ones(cls.dim_topo, dtype=dt_int)
self.__init_topo_vect[:] = self.topo_vect
if cls.shunts_data_available:
self.sh_bus[:] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_shunts()]),
cls.shunt_to_subid)
# set the initial topology vector
n_sub_cls_orig = cls.n_sub
n_sub_ls_orig = LightSimBackend.n_sub
try:
cls.n_sub = self.n_sub
LightSimBackend.n_sub = self.n_sub
self.topo_vect[cls.load_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_loads()]),
cls.load_to_subid)
self.topo_vect[cls.gen_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_generators()]),
cls.gen_to_subid)
if self.__has_storage:
self.topo_vect[cls.storage_pos_topo_vect] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_storages()]),
cls.storage_to_subid)
lor_glob_bus = np.concatenate((np.array([el.bus_or_id for el in self._grid.get_lines()]),
np.array([el.bus_hv_id for el in self._grid.get_trafos()])))
self.topo_vect[cls.line_or_pos_topo_vect] = cls.global_bus_to_local(lor_glob_bus,
cls.line_or_to_subid)
lex_glob_bus = np.concatenate((np.array([el.bus_ex_id for el in self._grid.get_lines()]),
np.array([el.bus_lv_id for el in self._grid.get_trafos()])))
self.topo_vect[cls.line_ex_pos_topo_vect] = cls.global_bus_to_local(lex_glob_bus,
cls.line_ex_to_subid)

self._grid.tell_solver_need_reset()
self.__me_at_init = self._grid.copy()
self.__init_topo_vect = np.ones(cls.dim_topo, dtype=dt_int)
self.__init_topo_vect[:] = self.topo_vect
if cls.shunts_data_available:
self.sh_bus[:] = cls.global_bus_to_local(np.array([el.bus_id for el in self._grid.get_shunts()]),
cls.shunt_to_subid)
finally:
cls.n_sub = n_sub_cls_orig
LightSimBackend.n_sub = n_sub_ls_orig

def assert_grid_correct_after_powerflow(self) -> None:
"""
This method is called by the environment. It ensure that the backend remains consistent even after a powerflow
Expand All @@ -1069,10 +1088,11 @@ def assert_grid_correct_after_powerflow(self) -> None:
self._backend_action_class = _BackendAction.init_grid(type(self))
self._init_action_to_set = self._backend_action_class()
try:
# feature added in grid2op 1.4 or 1.5
_init_action_to_set = self.get_action_to_set()
except TypeError as exc_:
_init_action_to_set = self._get_action_to_set_deprecated()
except TypeError:
# I am in legacy grid2op version...
_init_action_to_set = _dont_use_get_action_to_set_legacy(self)

self._init_action_to_set += _init_action_to_set
if self.prod_pu_to_kv is not None:
assert np.isfinite(self.prod_pu_to_kv).all()
Expand All @@ -1084,22 +1104,6 @@ def assert_grid_correct_after_powerflow(self) -> None:
assert np.isfinite(self.lines_ex_pu_to_kv).all()
if self.__has_storage and self.n_storage > 0 and self.storage_pu_to_kv is not None:
assert np.isfinite(self.storage_pu_to_kv).all()

def _get_action_to_set_deprecated(self):
warnings.warn("DEPRECATION: grid2op <=1.4 is not well supported with lightsim2grid. Lots of bugs have been"
"fixed since then. Please upgrade to grid2op >= 1.5",
DeprecationWarning)
line_status = self.get_line_status()
line_status = 2 * line_status - 1
line_status = line_status.astype(dt_int)
topo_vect = self.get_topo_vect()
prod_p, _, prod_v = self.generators_info()
load_p, load_q, _ = self.loads_info()
complete_action_class = CompleteAction.init_grid(self)
set_me = complete_action_class()
set_me.update({"set_line_status": line_status,
"set_bus": topo_vect})
return set_me

def _count_object_per_bus(self):
# should be called only when self.topo_vect and self.shunt_topo_vect are set
Expand Down Expand Up @@ -1582,7 +1586,7 @@ def _compute_shunt_bus_with_compat(self, shunt_bus):
# backward compat when this was not defined:
n_busbar_per_sub = DEFAULT_N_BUSBAR_PER_SUB
for i in range(n_busbar_per_sub):
res[(i * cls.n_sub <= shunt_bus) & (shunt_bus < (i+1) * cls.n_sub)] = i + 1
res[(i * self.n_sub <= shunt_bus) & (shunt_bus < (i+1) * self.n_sub)] = i + 1
res[shunt_bus == -1] = -1
self.sh_bus[:] = res

Expand Down Expand Up @@ -1625,3 +1629,35 @@ def reset(self,
if type(self).shunts_data_available:
self.sh_bus[:] = 1 # TODO self._compute_shunt_bus_with_compat(self._grid.get_all_shunt_buses())
self.topo_vect[:] = self.__init_topo_vect # TODO#


def _dont_use_global_bus_to_local_legacy(cls, global_bus: np.ndarray, to_sub_id: np.ndarray) -> np.ndarray:
res = (1 * global_bus).astype(dt_int) # make a copy
assert cls.n_busbar_per_sub >= 1, f"cls.n_busbar_per_sub should be >=1, found {cls.n_busbar_per_sub}"
assert cls.n_sub >= 1, f"cls.n_sub should be >=1, found {cls.n_sub}"
for i in range(cls.n_busbar_per_sub):
res[(i * cls.n_sub <= global_bus) & (global_bus < (i+1) * cls.n_sub)] = i + 1
res[global_bus == -1] = -1
return res


def _dont_use_get_action_to_set_legacy(self, *arg, **kwargs):
warnings.warn("DEPRECATION: grid2op <=1.4 is not well supported with lightsim2grid. Lots of bugs have been"
"fixed since then. Please upgrade to grid2op >= 1.10",
DeprecationWarning)
line_status = self.get_line_status()
line_status = 2 * line_status - 1
line_status = line_status.astype(dt_int)
topo_vect = self.get_topo_vect()
prod_p, _, prod_v = self.generators_info()
load_p, load_q, _ = self.loads_info()
complete_action_class = CompleteAction.init_grid(self)
set_me = complete_action_class()
set_me.update({"set_line_status": line_status,
"set_bus": topo_vect})
return set_me


if not hasattr(Backend, "global_bus_to_local"):
# for legacy grid2op
setattr(LightSimBackend, "global_bus_to_local", classmethod(_dont_use_global_bus_to_local_legacy))

0 comments on commit b781f19

Please sign in to comment.