Skip to content

Commit

Permalink
general improvement on some tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BDonnot committed Dec 15, 2023
1 parent 8cb71a0 commit 03ad59c
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 111 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,17 @@ Change Log

[1.9.8] - 20xx-yy-zz
----------------------
- [FIXED] the `backend.check_kirchoff` function was not correct when some elements were disconnected
(the wrong columns of the p_bus and q_bus was set in case of disconnected elements)
- [FIXED] `PandapowerBackend`, when no slack was present
- [FIXED] the "BaseBackendTest" class did not correctly detect divergence in most cases (which lead
to weird bugs in failing tests)
- [IMPROVED] the CI speed: by not testing every possible numpy version but only most ancient and most recent
- [IMPROVED] Runner now test grid2op version 1.9.6 and 1.9.7
- [IMPROVED] refacto `gridobj_cls._clear_class_attribute` and `gridobj_cls._clear_grid_dependant_class_attributes`
- [IMPROVED] the bahviour of the generic class `MakeBackend` used for the test suite.
- [IMPROVED] re introducing python 12 testing
- [IMPROVED] error messages in the automatic test suite (`AAATestBackendAPI`)

[1.9.7] - 2023-12-01
----------------------
Expand Down
121 changes: 71 additions & 50 deletions grid2op/Backend/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1124,30 +1124,35 @@ def check_kirchoff(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray
p_ex, q_ex, v_ex, *_ = self.lines_ex_info()
p_gen, q_gen, v_gen = self.generators_info()
p_load, q_load, v_load = self.loads_info()
if self.n_storage > 0:
cls = type(self)
if cls.n_storage > 0:
p_storage, q_storage, v_storage = self.storages_info()

# fist check the "substation law" : nothing is created at any substation
p_subs = np.zeros(self.n_sub, dtype=dt_float)
q_subs = np.zeros(self.n_sub, dtype=dt_float)
p_subs = np.zeros(cls.n_sub, dtype=dt_float)
q_subs = np.zeros(cls.n_sub, dtype=dt_float)

# check for each bus
p_bus = np.zeros((self.n_sub, 2), dtype=dt_float)
q_bus = np.zeros((self.n_sub, 2), dtype=dt_float)
p_bus = np.zeros((cls.n_sub, 2), dtype=dt_float)
q_bus = np.zeros((cls.n_sub, 2), dtype=dt_float)
v_bus = (
np.zeros((self.n_sub, 2, 2), dtype=dt_float) - 1.0
np.zeros((cls.n_sub, 2, 2), dtype=dt_float) - 1.0
) # sub, busbar, [min,max]
topo_vect = self.get_topo_vect()

# bellow i'm "forced" to do a loop otherwise, numpy do not compute the "+=" the way I want it to.
# for example, if two powerlines are such that line_or_to_subid is equal (eg both connected to substation 0)
# then numpy do not guarantee that `p_subs[self.line_or_to_subid] += p_or` will add the two "corresponding p_or"
# TODO this can be vectorized with matrix product, see example in obs.flow_bus_matrix (BaseObervation.py)
for i in range(self.n_line):
sub_or_id = self.line_or_to_subid[i]
sub_ex_id = self.line_ex_to_subid[i]
loc_bus_or = topo_vect[self.line_or_pos_topo_vect[i]] - 1
loc_bus_ex = topo_vect[self.line_ex_pos_topo_vect[i]] - 1
for i in range(cls.n_line):
sub_or_id = cls.line_or_to_subid[i]
sub_ex_id = cls.line_ex_to_subid[i]
if (topo_vect[cls.line_or_pos_topo_vect[i]] == -1 or
topo_vect[cls.line_ex_pos_topo_vect[i]] == -1):
# line is disconnected
continue
loc_bus_or = topo_vect[cls.line_or_pos_topo_vect[i]] - 1
loc_bus_ex = topo_vect[cls.line_ex_pos_topo_vect[i]] - 1

# for substations
p_subs[sub_or_id] += p_or[i]
Expand Down Expand Up @@ -1184,92 +1189,104 @@ def check_kirchoff(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray
v_bus[sub_ex_id,loc_bus_ex,][0] = min(v_bus[sub_ex_id,loc_bus_ex,][0],v_ex[i],)
v_bus[sub_ex_id,loc_bus_ex,][1] = max(v_bus[sub_ex_id,loc_bus_ex,][1],v_ex[i],)

for i in range(self.n_gen):
for i in range(cls.n_gen):
if topo_vect[cls.gen_pos_topo_vect[i]] == -1:
# gen is disconnected
continue

# for substations
p_subs[self.gen_to_subid[i]] -= p_gen[i]
q_subs[self.gen_to_subid[i]] -= q_gen[i]
p_subs[cls.gen_to_subid[i]] -= p_gen[i]
q_subs[cls.gen_to_subid[i]] -= q_gen[i]

# for bus
p_bus[
self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1
cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1
] -= p_gen[i]
q_bus[
self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1
cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1
] -= q_gen[i]

# compute max and min values
if v_gen[i]:
# but only if gen is connected
v_bus[self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1][
v_bus[cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1][
0
] = min(
v_bus[
self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1
cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1
][0],
v_gen[i],
)
v_bus[self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1][
v_bus[cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1][
1
] = max(
v_bus[
self.gen_to_subid[i], topo_vect[self.gen_pos_topo_vect[i]] - 1
cls.gen_to_subid[i], topo_vect[cls.gen_pos_topo_vect[i]] - 1
][1],
v_gen[i],
)

for i in range(self.n_load):
for i in range(cls.n_load):
if topo_vect[cls.load_pos_topo_vect[i]] == -1:
# load is disconnected
continue

# for substations
p_subs[self.load_to_subid[i]] += p_load[i]
q_subs[self.load_to_subid[i]] += q_load[i]
p_subs[cls.load_to_subid[i]] += p_load[i]
q_subs[cls.load_to_subid[i]] += q_load[i]

# for buses
p_bus[
self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1
cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1
] += p_load[i]
q_bus[
self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1
cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1
] += q_load[i]

# compute max and min values
if v_load[i]:
# but only if load is connected
v_bus[self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1][
v_bus[cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1][
0
] = min(
v_bus[
self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1
cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1
][0],
v_load[i],
)
v_bus[self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1][
v_bus[cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1][
1
] = max(
v_bus[
self.load_to_subid[i], topo_vect[self.load_pos_topo_vect[i]] - 1
cls.load_to_subid[i], topo_vect[cls.load_pos_topo_vect[i]] - 1
][1],
v_load[i],
)

for i in range(self.n_storage):
p_subs[self.storage_to_subid[i]] += p_storage[i]
q_subs[self.storage_to_subid[i]] += q_storage[i]
for i in range(cls.n_storage):
if topo_vect[cls.storage_pos_topo_vect[i]] == -1:
# storage is disconnected
continue

p_subs[cls.storage_to_subid[i]] += p_storage[i]
q_subs[cls.storage_to_subid[i]] += q_storage[i]
p_bus[
self.storage_to_subid[i], topo_vect[self.storage_pos_topo_vect[i]] - 1
cls.storage_to_subid[i], topo_vect[cls.storage_pos_topo_vect[i]] - 1
] += p_storage[i]
q_bus[
self.storage_to_subid[i], topo_vect[self.storage_pos_topo_vect[i]] - 1
cls.storage_to_subid[i], topo_vect[cls.storage_pos_topo_vect[i]] - 1
] += q_storage[i]

# compute max and min values
if v_storage[i] > 0:
# the storage unit is connected
v_bus[
self.storage_to_subid[i],
topo_vect[self.storage_pos_topo_vect[i]] - 1,
cls.storage_to_subid[i],
topo_vect[cls.storage_pos_topo_vect[i]] - 1,
][0] = min(
v_bus[
self.storage_to_subid[i],
topo_vect[self.storage_pos_topo_vect[i]] - 1,
cls.storage_to_subid[i],
topo_vect[cls.storage_pos_topo_vect[i]] - 1,
][0],
v_storage[i],
)
Expand All @@ -1278,29 +1295,33 @@ def check_kirchoff(self) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray
topo_vect[self.storage_pos_topo_vect[i]] - 1,
][1] = max(
v_bus[
self.storage_to_subid[i],
topo_vect[self.storage_pos_topo_vect[i]] - 1,
cls.storage_to_subid[i],
topo_vect[cls.storage_pos_topo_vect[i]] - 1,
][1],
v_storage[i],
)

if type(self).shunts_data_available:
if cls.shunts_data_available:
p_s, q_s, v_s, bus_s = self.shunt_info()
for i in range(self.n_shunt):
for i in range(cls.n_shunt):
if bus_s[i] == -1:
# shunt is disconnected
continue

# for substations
p_subs[self.shunt_to_subid[i]] += p_s[i]
q_subs[self.shunt_to_subid[i]] += q_s[i]
p_subs[cls.shunt_to_subid[i]] += p_s[i]
q_subs[cls.shunt_to_subid[i]] += q_s[i]

# for buses
p_bus[self.shunt_to_subid[i], bus_s[i] - 1] += p_s[i]
q_bus[self.shunt_to_subid[i], bus_s[i] - 1] += q_s[i]
p_bus[cls.shunt_to_subid[i], bus_s[i] - 1] += p_s[i]
q_bus[cls.shunt_to_subid[i], bus_s[i] - 1] += q_s[i]

# compute max and min values
v_bus[self.shunt_to_subid[i], bus_s[i] - 1][0] = min(
v_bus[self.shunt_to_subid[i], bus_s[i] - 1][0], v_s[i]
v_bus[cls.shunt_to_subid[i], bus_s[i] - 1][0] = min(
v_bus[cls.shunt_to_subid[i], bus_s[i] - 1][0], v_s[i]
)
v_bus[self.shunt_to_subid[i], bus_s[i] - 1][1] = max(
v_bus[self.shunt_to_subid[i], bus_s[i] - 1][1], v_s[i]
v_bus[cls.shunt_to_subid[i], bus_s[i] - 1][1] = max(
v_bus[cls.shunt_to_subid[i], bus_s[i] - 1][1], v_s[i]
)
else:
warnings.warn(
Expand Down
1 change: 1 addition & 0 deletions grid2op/Environment/baseEnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -2961,6 +2961,7 @@ def _aux_run_pf_after_state_properly_set(
self, action, init_line_status, new_p, except_
):
has_error = True
detailed_info = None
try:
# compute the next _grid state
beg_pf = time.perf_counter()
Expand Down
2 changes: 1 addition & 1 deletion grid2op/Environment/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ def _init_backend(
raise Grid2OpException(
"Impossible to initialize the powergrid, the powerflow diverge at iteration 0. "
"Available information are: {}".format(info)
)
) from info["exception"][0]

# test the backend returns object of the proper size
if need_process_backend:
Expand Down
Loading

0 comments on commit 03ad59c

Please sign in to comment.