Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)