示例#1
0
    def set_solver_type(self, solver_type):
        """
        Change the type of solver you want to use.

        Note that a powergrid should have been loaded for this function to work.

        This function does not modify :attr:`LightSimBackend.max_iter` nor :attr:`LightSimBackend.tol`. You might want
        to modify these values depending on the solver you are using.

        Notes
        ------
        By default, the fastest AC solver is used for your platform. This means that if KLU is available, then it is used
        otherwise it's SparseLU.

        This has to be set for every backend that you want to use. For example, you have to set it
        in the backend of the `_obs_env` of the observation and if you are using "grid2op.MultMixEnv` you
        have to set it in all mixes!

        Parameters
        ----------
        solver_type: lightsim2grid.SolverType
            The new type of solver you want to use. See backend.available_solvers for a list of available solver
            on your machine.
        """
        if not isinstance(solver_type, SolverType):
            raise BackendError(
                f"The solver type must be from type \"lightsim2grid.SolverType\" and not "
                f"{type(solver_type)}")
        if solver_type not in self.available_solvers:
            raise BackendError(
                f"The solver type provided \"{solver_type}\" is not available on your system. Available"
                f"solvers are {self.available_solvers}")
        self.__current_solver_type = copy.deepcopy(solver_type)
        self._grid.change_solver(self.__current_solver_type)
示例#2
0
    def set_tol(self, new_tol):
        """
        Set the tolerance of the powerflow. This means that the powerflow will stop when the Kirchhoff's Circuit Laws
        are met up to a tolerance of "new_tol".

        Decrease the tolerance might speed up the computation of the powerflow but will decrease the accuracy. We do
        not recommend to modify the default value of 1e-8.

        Parameters
        ----------
        new_tol: ``float``
            The new tolerance to use (should be a float > 0)

        Notes
        -------
        This has to be set for every backend that you want to use. For example, you have to set it
        in the backend of the `_obs_env` of the observation and if you are using "grid2op.MultMixEnv` you
        have to set it in all mixes!
        """
        try:
            new_tol = float(new_tol)
        except Exception as exc_:
            raise BackendError(
                f"Impossible to convert \"new_tol={new_tol}\" to an float with error \"{exc_}\""
            )
        if new_tol <= 0:
            raise BackendError(
                "new_tol should be a strictly positive float (float > 0)")
        self.tol = new_tol
示例#3
0
文件: Backend.py 项目: ronahi/Grid2Op
    def set_thermal_limit(self, limits):
        """
        .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\

            You can set the thermal limit directly in the environment.

        This function is used as a convenience function to set the thermal limits :attr:`Backend.thermal_limit_a`
        in amperes.

        It can be used at the beginning of an episode if the thermal limit are not present in the original data files
        or alternatively if the thermal limits depends on the period of the year (one in winter and one in summer
        for example).

        Parameters
        ----------
        limits: ``object``
            It can be understood differently according to its type:

            - If it's a ``numpy.ndarray``, then it is assumed the thermal limits are given in amperes in the same order
              as the powerlines computed in the backend. In that case it modifies all the thermal limits of all
              the powerlines at once.
            - If it's a ``dict`` it must have:

              - as key the powerline names (not all names are mandatory, in that case only the powerlines with the name
                in this dictionnary will be modified)
              - as value the new thermal limit (should be a strictly positive float).

        """
        if isinstance(limits, np.ndarray):
            if limits.shape[0] == self.n_line:
                self.thermal_limit_a = 1. * limits.astype(dt_float)
        elif isinstance(limits, dict):
            for el in limits.keys():
                if not el in self.name_line:
                    raise BackendError(
                        "You asked to modify the thermal limit of powerline named \"{}\" that is not "
                        "on the grid. Names of powerlines are {}".format(
                            el, self.name_line))
            for i, el in self.name_line:
                if el in limits:
                    try:
                        tmp = dt_float(limits[el])
                    except:
                        raise BackendError(
                            "Impossible to convert data ({}) for powerline named \"{}\" into float "
                            "values".format(limits[el], el))
                    if tmp <= 0:
                        raise BackendError(
                            "New thermal limit for powerlines \"{}\" is not positive ({})"
                            "".format(el, tmp))
                    self.thermal_limit_a[i] = tmp
示例#4
0
 def _klu_bus_from_grid2op_bus(self, grid2op_bus, grid2op_bus_init):
     if grid2op_bus == 1:
         res = grid2op_bus_init
     elif grid2op_bus == 2:
         res = grid2op_bus_init + self.__nb_bus_before
     else:
         raise BackendError("grid2op bus must be 0 1 or 2")
     return int(res)
示例#5
0
文件: Backend.py 项目: ronahi/Grid2Op
    def update_from_obs(self, obs):
        """
        Takes an observation as input and update the internal state of `self` to match the state of the backend
        that produced this observation.

        Only the "line_status", "topo_vect", "prod_p", "prod_v", "load_p" and "load_q" attributes of the
        observations are used.

        TODO we plan to set also the shunt information in the future.

        Notes
        -----
        If the observation is not perfect (for example with noise, or partial) this method will not work. You need
        to pass it a complete observation.

        For example, you might want to consider to have a state estimator if that is the case.

        Parameters
        ----------
        obs: :class:`grid2op.Observation.CompleteObservation`
            A complete observation describing the state of the grid you want this backend to be in.

        """
        # lazy loading to prevent circular reference
        from grid2op.Observation import CompleteObservation

        if not isinstance(obs, CompleteObservation):
            raise BackendError(
                "Impossible to set a backend to a state not represented by a "
                "\"grid2op.CompleteObservation\".")

        backend_action = self.my_bk_act_class()
        act = self._complete_action_class()
        line_status = self._aux_get_line_status_to_set(obs.line_status)
        # skip the action part and update directly the backend action !
        dict_ = {
            "set_bus": obs.topo_vect,
            "set_line_status": line_status,
            "injection": {
                "prod_p": obs.prod_p,
                "prod_v": obs.prod_v,
                "load_p": obs.load_p,
                "load_q": obs.load_q,
            }
        }

        if self.shunts_data_available and obs.shunts_data_available:
            mults = (self._sh_vnkv / obs._shunt_v)**2
            dict_["shunt"] = {
                "shunt_p": obs._shunt_p * mults,
                "shunt_q": obs._shunt_q * mults,
                "shunt_bus": obs._shunt_bus
            }

        act.update(dict_)
        backend_action += act
        self.apply_action(backend_action)
示例#6
0
文件: Backend.py 项目: ronahi/Grid2Op
    def sub_from_bus_id(self, bus_id):
        """
        .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\

        Optionnal method that allows to get the substation if the bus id is provided.

        :param bus_id:
        :return: the substation to which an object connected to bus with id `bus_id` is connected to.
        """
        raise BackendError(
            "This backend doesn't allow to get the substation from the bus id."
        )
示例#7
0
    def set_solver_max_iter(self, max_iter):
        """
        Set the maximum number of iteration the solver is allowed to perform.

        We do not recommend to modify the default value (10), unless you are using the GaussSeidel powerflow.
        This powerflow being slower, we do not recommend to use it.

        Recommendation:

        - for SolverType.SparseLU: 10
        - for SolverType.GaussSeidel: 10000
        - for SolverType.DC: this has no effect
        - for SolverType.SparseKLU: 10

        Parameters
        ----------
        max_iter: ``int``
            Maximum number of iteration the powerflow can run. It should be number >= 1

        Notes
        -------
        This has to be set for every backend that you want to use. For example, you have to set it
        in the backend of the `_obs_env` of the observation and if you are using "grid2op.MultMixEnv` you
        have to set it in all mixes!

        """
        try:
            max_iter = int(max_iter)
        except Exception as exc_:
            raise BackendError(
                f"Impossible to convert \"max_iter={max_iter}\" to an integer with exception \"{exc_}\""
            )
        if max_iter < 1:
            raise BackendError(
                "max_iter should be a strictly positive integer (integer >= 1)"
            )
        self.max_it = max_iter