Пример #1
0
    def control_step(self, net):
        """
        Implements one step of the Discrete controller, always stepping only one tap position up or down
        """
        if self.nothing_to_do(net):
            return

        vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu",
                              self._read_write_flag)
        self.tap_pos = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_pos", self._read_write_flag)

        increment = np.where(
            self.tap_side_coeff * self.tap_sign == 1,
            np.where(
                np.logical_and(vm_pu < self.vm_lower_pu,
                               self.tap_pos > self.tap_min), -1,
                np.where(
                    np.logical_and(vm_pu > self.vm_upper_pu,
                                   self.tap_pos < self.tap_max), 1, 0)),
            np.where(
                np.logical_and(vm_pu < self.vm_lower_pu,
                               self.tap_pos < self.tap_max), 1,
                np.where(
                    np.logical_and(vm_pu > self.vm_upper_pu,
                                   self.tap_pos > self.tap_min), -1, 0)))

        self.tap_pos += increment

        # WRITE TO NET
        write_to_net(net, self.trafotable, self.controlled_tid, 'tap_pos',
                     self.tap_pos, self._read_write_flag)
Пример #2
0
    def is_converged(self, net):
        """
        The ContinuousTapControl is converged, when the difference of the voltage between control steps is smaller
        than the Tolerance (tol).
        """
        if self.nothing_to_do(net):
            return True

        vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu",
                              self._read_write_flag)
        self.tap_pos = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_pos", self._read_write_flag)
        difference = 1 - self.vm_set_pu / vm_pu

        if self.check_tap_bounds:
            reached_limit = np.where(
                self.tap_side_coeff * self.tap_sign == 1,
                (vm_pu < self.vm_set_pu) & (self.tap_pos == self.tap_min) |
                (vm_pu > self.vm_set_pu) & (self.tap_pos == self.tap_max),
                (vm_pu < self.vm_set_pu) & (self.tap_pos == self.tap_max) |
                (vm_pu > self.vm_set_pu) & (self.tap_pos == self.tap_min))
            converged = np.logical_or(reached_limit,
                                      np.abs(difference) < self.tol)
        else:
            converged = np.abs(difference) < self.tol

        return np.all(converged)
Пример #3
0
 def is_converged(self, net):
     """
     Actual implementation of the convergence criteria: If controller is applied, it can stop
     """
     # read input values
     input_values = read_from_net(net, self.input_element,
                                  self.input_element_index,
                                  self.input_variable, self.read_flag)
     # calculate set values
     self.values = net.characteristic.object.at[self.characteristic_index](
         input_values)
     # read previous set values
     output_values = read_from_net(net, self.output_element,
                                   self.output_element_index,
                                   self.output_variable, self.write_flag)
     # compare old and new set values
     diff = self.values - output_values
     # write new set values
     write_to_net(net, self.output_element, self.output_element_index,
                  self.output_variable, self.values, self.write_flag)
     return self.applied and np.all(np.abs(diff) < self.tol)
Пример #4
0
    def _set_valid_tid_controlled_bus(self, net):
        self.trafobus = read_from_net(net, self.trafotable, self.tid,
                                      self.side + '_bus',
                                      self._read_write_flag)
        element_in_service = read_from_net(net, self.trafotable, self.tid,
                                           'in_service', self._read_write_flag)
        ext_grid_bus = np.isin(
            self.trafobus, net.ext_grid.loc[net.ext_grid.in_service,
                                            'bus'].values)
        tid_in_net = np.isin(self.tid, net[self.trafotable].index.values)
        controlled = np.logical_and(
            np.logical_and(element_in_service, tid_in_net),
            np.logical_not(ext_grid_bus))
        if self._read_write_flag == 'single_index':
            self.controlled_tid = self.tid if controlled else None
            self.controlled_bus = self.trafobus if controlled else None
        else:
            self.controlled_tid = self.tid[controlled]
            self.controlled_bus = self.trafobus[controlled]

        if np.all(~controlled):
            logger.warning(
                "All controlled buses are not valid: controller has no effect")
Пример #5
0
    def is_converged(self, net):
        """
        Checks if the voltage is within the desired voltage band, then returns True
        """
        if self.nothing_to_do(net):
            return True

        vm_pu = read_from_net(net, "res_bus", self.controlled_bus, "vm_pu",
                              self._read_write_flag)
        self.tap_pos = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_pos", self._read_write_flag)

        reached_limit = np.where(
            self.tap_side_coeff * self.tap_sign == 1,
            (vm_pu < self.vm_lower_pu) & (self.tap_pos == self.tap_min) |
            (vm_pu > self.vm_upper_pu) & (self.tap_pos == self.tap_max),
            (vm_pu < self.vm_lower_pu) & (self.tap_pos == self.tap_max) |
            (vm_pu > self.vm_upper_pu) & (self.tap_pos == self.tap_min))

        converged = np.logical_or(
            reached_limit,
            np.logical_and(self.vm_lower_pu < vm_pu, vm_pu < self.vm_upper_pu))

        return np.all(converged)
Пример #6
0
    def _set_tap_side_coeff(self, net):
        tap_side = read_from_net(net, self.trafotable, self.controlled_tid,
                                 'tap_side', self._read_write_flag)
        if (len(np.setdiff1d(tap_side, ['hv', 'lv'])) > 0 and self.trafotype == "2W") or \
            (len(np.setdiff1d(tap_side, ['hv', 'lv', 'mv'])) > 0 and self.trafotype == "3W"):
            raise ValueError(
                "Trafo tap side (in net.%s) has to be either hv or lv, "
                "but received: %s for trafo %s" %
                (self.trafotable, tap_side, self.controlled_tid))

        if self._read_write_flag == "single_index":
            self.tap_side_coeff = 1 if tap_side == 'hv' else -1
            if self.tap_step_percent < 0:
                self.tap_side_coeff *= -1
        else:
            self.tap_side_coeff = np.where(tap_side == 'hv', 1, -1)
            self.tap_side_coeff[self.tap_step_percent < 0] *= -1
Пример #7
0
    def _set_t_nom(self, net):
        vn_hv_kv = read_from_net(net, self.trafotable, self.controlled_tid,
                                 'vn_hv_kv', self._read_write_flag)
        hv_bus = read_from_net(net, self.trafotable, self.controlled_tid,
                               'hv_bus', self._read_write_flag)
        vn_hv_bus_kv = read_from_net(net, "bus", hv_bus, 'vn_kv',
                                     self._read_write_flag)

        if self.trafotype == "3W" and self.side == "mv":
            vn_mv_kv = read_from_net(net, self.trafotable, self.controlled_tid,
                                     'vn_mv_kv', self._read_write_flag)
            mv_bus = read_from_net(net, self.trafotable, self.controlled_tid,
                                   'mv_bus', self._read_write_flag)
            vn_mv_bus_kv = read_from_net(net, "bus", mv_bus, 'vn_kv',
                                         self._read_write_flag)
            self.t_nom = vn_mv_kv / vn_hv_kv * vn_hv_bus_kv / vn_mv_bus_kv
        else:
            vn_lv_kv = read_from_net(net, self.trafotable, self.controlled_tid,
                                     'vn_lv_kv', self._read_write_flag)
            lv_bus = read_from_net(net, self.trafotable, self.controlled_tid,
                                   'lv_bus', self._read_write_flag)
            vn_lv_bus_kv = read_from_net(net, "bus", lv_bus, 'vn_kv',
                                         self._read_write_flag)
            self.t_nom = vn_lv_kv / vn_hv_kv * vn_hv_bus_kv / vn_lv_bus_kv
Пример #8
0
    def control_step(self, net):
        """
        Implements one step of the ContinuousTapControl
        """
        if self.nothing_to_do(net):
            return

        delta_vm_pu = read_from_net(net, "res_bus", self.controlled_bus,
                                    'vm_pu',
                                    self._read_write_flag) - self.vm_set_pu
        tc = delta_vm_pu / self.tap_step_percent * 100 / self.t_nom
        self.tap_pos = self.tap_pos + tc * self.tap_side_coeff * self.tap_sign
        if self.check_tap_bounds:
            self.tap_pos = np.clip(self.tap_pos, self.tap_min, self.tap_max)

        # WRITE TO NET
        # necessary in case the dtype of the column is int
        if net[self.trafotable].tap_pos.dtype != "float":
            net[self.trafotable].tap_pos = net[self.trafotable].tap_pos.astype(
                float)
        write_to_net(net, self.trafotable, self.controlled_tid, "tap_pos",
                     self.tap_pos, self._read_write_flag)
Пример #9
0
    def _set_tap_parameters(self, net):
        self.tap_min = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_min", self._read_write_flag)
        self.tap_max = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_max", self._read_write_flag)
        self.tap_neutral = read_from_net(net, self.trafotable,
                                         self.controlled_tid, "tap_neutral",
                                         self._read_write_flag)
        self.tap_step_percent = read_from_net(net, self.trafotable,
                                              self.controlled_tid,
                                              "tap_step_percent",
                                              self._read_write_flag)
        self.tap_step_degree = read_from_net(net, self.trafotable,
                                             self.controlled_tid,
                                             "tap_step_degree",
                                             self._read_write_flag)

        self.tap_pos = read_from_net(net, self.trafotable, self.controlled_tid,
                                     "tap_pos", self._read_write_flag)
        if self._read_write_flag == "single_index":
            self.tap_sign = 1 if np.isnan(self.tap_step_degree) else np.sign(
                np.cos(np.deg2rad(self.tap_step_degree)))
            if (self.tap_sign == 0) | (np.isnan(self.tap_sign)):
                self.tap_sign = 1
            if np.isnan(self.tap_pos):
                self.tap_pos = self.tap_neutral
        else:
            self.tap_sign = np.where(
                np.isnan(self.tap_step_degree), 1,
                np.sign(np.cos(np.deg2rad(self.tap_step_degree))))
            self.tap_sign = np.where(
                (self.tap_sign == 0) | (np.isnan(self.tap_sign)), 1,
                self.tap_sign)
            self.tap_pos = np.where(np.isnan(self.tap_pos), self.tap_neutral,
                                    self.tap_pos)

        if np.any(np.isnan(self.tap_min)) or np.any(np.isnan(
                self.tap_max)) or np.any(np.isnan(self.tap_step_percent)):
            logger.error(
                "Trafo-Controller has been initialized with NaN values, check "
                "net.trafo.tap_pos etc. if they are set correctly!")