def assert_grid_correct_after_powerflow(self): """ This method is called by the environment. It ensure that the backend remains consistent even after a powerflow has be run with :func:`Backend.runpf` method. :return: ``None`` :raise: :class:`grid2op.Exceptions.EnvError` and possibly all of its derived class. """ # test the results gives the proper size super().assert_grid_correct_after_powerflow() self.init_pp_backend.__class__ = self.init_pp_backend.init_grid(self) self._backend_action_class = _BackendAction.init_grid(self) self._init_action_to_set = self._backend_action_class() _init_action_to_set = self.get_action_to_set() self._init_action_to_set += _init_action_to_set
def __init__( self, path_grid_json, # complete path where the grid is represented as a json file name="dc_approx", is_dc=True, attr_x=("prod_p", "prod_v", "load_p", "load_q", "topo_vect"), # input that will be given to the proxy attr_y=("a_or", "a_ex", "p_or", "p_ex", "q_or", "q_ex", "prod_q", "load_v", "v_or", "v_ex"), # output that we want the proxy to predict ): BaseProxy.__init__(self, name=name, max_row_training_set=1, eval_batch_size=1, attr_x=attr_x, attr_y=attr_y) # datasets self._supported_output = { "a_or", "a_ex", "p_or", "p_ex", "q_or", "q_ex", "prod_q", "load_v", "v_or", "v_ex" } self.is_dc = is_dc for el in ("prod_p", "prod_v", "load_p", "load_q", "topo_vect"): if not el in self.attr_x: raise RuntimeError( f"The DC approximation need the variable \"{el}\" to be computed." ) for el in self.attr_y: if not el in self._supported_output: raise RuntimeError( f"This solver cannot output the variable \"{el}\" at the moment. " f"Only possible outputs are \"{self._supported_output}\".") # specific part to dc model self.solver = PandaPowerBackend() self.solver.set_env_name(self.name) self.solver.load_grid( path_grid_json) # the real powergrid of the environment self.solver.assert_grid_correct() self._bk_act_class = _BackendAction.init_grid(self.solver) self._act_class = CompleteAction.init_grid(self.solver) # internal variables (speed optimisation) self._indx_var = {} for el in ("prod_p", "prod_v", "load_p", "load_q", "topo_vect"): self._indx_var[el] = self.attr_x.index(el)
def load_grid(self, path=None, filename=None): # if self.init_pp_backend is None: self.init_pp_backend.load_grid(path, filename) self._grid = init(self.init_pp_backend._grid) self.n_line = self.init_pp_backend.n_line self.n_gen = self.init_pp_backend.n_gen self.n_load = self.init_pp_backend.n_load self.n_sub = self.init_pp_backend.n_sub self.sub_info = self.init_pp_backend.sub_info self.dim_topo = self.init_pp_backend.dim_topo self.load_to_subid = self.init_pp_backend.load_to_subid self.gen_to_subid = self.init_pp_backend.gen_to_subid self.line_or_to_subid = self.init_pp_backend.line_or_to_subid self.line_ex_to_subid = self.init_pp_backend.line_ex_to_subid self.load_to_sub_pos = self.init_pp_backend.load_to_sub_pos self.gen_to_sub_pos = self.init_pp_backend.gen_to_sub_pos self.line_or_to_sub_pos = self.init_pp_backend.line_or_to_sub_pos self.line_ex_to_sub_pos = self.init_pp_backend.line_ex_to_sub_pos self.prod_pu_to_kv = self.init_pp_backend.prod_pu_to_kv self.load_pu_to_kv = self.init_pp_backend.load_pu_to_kv self.lines_or_pu_to_kv = self.init_pp_backend.lines_or_pu_to_kv self.lines_ex_pu_to_kv = self.init_pp_backend.lines_ex_pu_to_kv self.name_gen = self.init_pp_backend.name_gen self.name_load = self.init_pp_backend.name_load self.name_line = self.init_pp_backend.name_line self.name_sub = self.init_pp_backend.name_sub self._compute_pos_big_topo() self.nb_bus_total = self.init_pp_backend._grid.bus.shape[0] self.thermal_limit_a = self.init_pp_backend.thermal_limit_a # deactive the buses that have been added nb_bus_init = self.init_pp_backend._grid.bus.shape[0] // 2 for i in range(nb_bus_init): self._grid.deactivate_bus(i + nb_bus_init) self.__nb_powerline = self.init_pp_backend._grid.line.shape[0] self.__nb_bus_before = self.init_pp_backend.get_nb_active_bus() self._init_bus_load = 1.0 * self.init_pp_backend._grid.load[ "bus"].values self._init_bus_gen = 1.0 * self.init_pp_backend._grid.gen["bus"].values self._init_bus_lor = 1.0 * self.init_pp_backend._grid.line[ "from_bus"].values self._init_bus_lex = 1.0 * self.init_pp_backend._grid.line[ "to_bus"].values t_for = 1.0 * self.init_pp_backend._grid.trafo["hv_bus"].values t_fex = 1.0 * self.init_pp_backend._grid.trafo["lv_bus"].values self._init_bus_lor = np.concatenate( (self._init_bus_lor, t_for)).astype(np.int) self._init_bus_lex = np.concatenate( (self._init_bus_lex, t_fex)).astype(np.int) self._big_topo_to_obj = [(None, None) for _ in range(self.dim_topo)] nm_ = "load" for load_id, pos_big_topo in enumerate(self.load_pos_topo_vect): self._big_topo_to_obj[pos_big_topo] = (load_id, nm_) nm_ = "gen" for gen_id, pos_big_topo in enumerate(self.gen_pos_topo_vect): self._big_topo_to_obj[pos_big_topo] = (gen_id, nm_) nm_ = "lineor" for l_id, pos_big_topo in enumerate(self.line_or_pos_topo_vect): self._big_topo_to_obj[pos_big_topo] = (l_id, nm_) nm_ = "lineex" for l_id, pos_big_topo in enumerate(self.line_ex_pos_topo_vect): self._big_topo_to_obj[pos_big_topo] = (l_id, nm_) self.prod_p = 1.0 * self.init_pp_backend._grid.gen["p_mw"].values self.next_prod_p = 1.0 * self.init_pp_backend._grid.gen["p_mw"].values # for shunts self.n_shunt = self.init_pp_backend.n_shunt self.shunt_to_subid = self.init_pp_backend.shunt_to_subid self.name_shunt = self.init_pp_backend.name_shunt self.shunts_data_available = self.init_pp_backend.shunts_data_available # number of object per bus, to activate, deactivate them self.nb_obj_per_bus = np.zeros(2 * self.__nb_bus_before, dtype=np.int) self.topo_vect = np.ones(self.dim_topo, dtype=np.int) if self.shunts_data_available: self.shunt_topo_vect = np.ones(self.n_shunt, dtype=np.int) self.p_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.q_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.v_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.a_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.p_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.q_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.v_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.a_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN) self.load_p = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN) self.load_q = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN) self.load_v = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN) self.prod_p = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN) self.prod_q = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN) self.prod_v = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN) self._count_object_per_bus() _init_action_to_set = self.get_action_to_set() self._backend_action_class = _BackendAction.init_grid(self) self._init_action_to_set = self._backend_action_class() self._init_action_to_set += _init_action_to_set
# load the backend backend = PandaPowerBackend() # all backend should be created like this backend.load_grid("matpower_case5.json") # this method has to be implemented # NB the format of data can change of course :-) # i converted it using pandapower converter to .mat using # "pandapower.converter.to_mpc" (https://pandapower.readthedocs.io/en/v1.2.0/converter/matpower.html) # we'll worry later on how to handle multiple files ;-) ## internal and performed automatically backend.set_env_name("example") # this has not to be implemented # now we list all "set" data # but first we need to create the object that will allow to interact with the backend from grid2op.Action._BackendAction import _BackendAction # internal bk_class = _BackendAction.init_grid(backend) # internal, done automatically env_to_backend = bk_class() # internal, done automatically action_class = BaseAction.init_grid(backend) # internal, done automatically my_action = action_class() # internal, done automatically # do a powerflow print("TEST MAKE POWERFLOW...") converged = backend.runpf() # need to be implemented assert converged # I reading back the data print("TEST READ DATA...") prod_p, prod_q, prod_v = backend.generators_info( ) # this method has to be implemented # it gives the values for each generator, and put it all to a vector assert np.all(np.abs(prod_p - [10., 21.72983]) <= tol)