Exemple #1
0
 def _calculate(self):
     logger.info("Calculating PTDF Matrix")
     self._calculate_ptdf()
     self._calculate_phi_adjust()
     self._calculate_phi_loss_constant()
     self._calculate_phase_shift()
     self._calculate_losses_phase_shift()
Exemple #2
0
def add_violations(gt_viol_lazy,
                   lt_viol_lazy,
                   PFV,
                   mb,
                   md,
                   solver,
                   ptdf_options,
                   PTDF,
                   time=None):

    model = mb.model()

    baseMVA = md.data['system']['baseMVA']

    persistent_solver = isinstance(solver, PersistentSolver)

    ## static information between runs
    rel_ptdf_tol = ptdf_options['rel_ptdf_tol']
    abs_ptdf_tol = ptdf_options['abs_ptdf_tol']

    ## helper for generating pf
    def _iter_over_viol_set(viol_set):
        for i in viol_set:
            bn = PTDF.branches_keys[i]
            if mb.pf[bn].expr is None:
                expr = libbranch.get_power_flow_expr_ptdf_approx(
                    mb,
                    bn,
                    PTDF,
                    abs_ptdf_tol=abs_ptdf_tol,
                    rel_ptdf_tol=rel_ptdf_tol)
                mb.pf[bn] = expr
            yield i, bn

    constr = mb.ineq_pf_branch_thermal_lb
    lt_viol_in_mb = mb._lt_idx_monitored
    for i, bn in _iter_over_viol_set(lt_viol_lazy):
        thermal_limit = PTDF.branch_limits_array[i]
        logger.info(
            _generate_flow_monitor_message('LB', bn, PFV[i], -thermal_limit,
                                           baseMVA, time))
        constr[bn] = (-thermal_limit, mb.pf[bn], None)
        lt_viol_in_mb.append(i)
        if persistent_solver:
            solver.add_constraint(constr[bn])

    constr = mb.ineq_pf_branch_thermal_ub
    gt_viol_in_mb = mb._gt_idx_monitored
    for i, bn in _iter_over_viol_set(gt_viol_lazy):
        thermal_limit = PTDF.branch_limits_array[i]
        logger.info(
            _generate_flow_monitor_message('UB', bn, PFV[i], thermal_limit,
                                           baseMVA, time))
        constr[bn] = (None, mb.pf[bn], thermal_limit)
        gt_viol_in_mb.append(i)
        if persistent_solver:
            solver.add_constraint(constr[bn])
Exemple #3
0
    def _calculate_total_and_monitored_violations(
            self, viol_array, viol_lazy_idx, monitored_indices, flow_variable,
            flow_array, index_names, limits, name, outer_name, other_flows):
        ## viol_idx_idx will be indexed by viol_lazy_idx
        viol_idx_idx = np.nonzero(viol_array > 0)[0]
        viol_idx = frozenset(viol_lazy_idx[viol_idx_idx])

        self.total_violations += len(viol_idx)

        viol_in_mb = viol_idx.intersection(monitored_indices)
        self.monitored_violations += len(viol_in_mb)

        for i in viol_in_mb:
            element_name = index_names[i]
            thermal_limit = limits[i]
            flow = flow_array[i]
            if outer_name:
                element_name = (outer_name, element_name)
                thermal_limit += other_flows[i]
                flow += other_flows[i]
            logger.info(self.prepend_str + _generate_flow_viol_warning(
                flow_variable, name, element_name, flow, thermal_limit,
                self.baseMVA, self.time))

        ## useful debugging code
        if logger.level <= logging.DEBUG:
            for i in monitored_indices:
                element_name = index_names[i]
                thermal_limit = limits[i]
                flow = flow_array[i]
                if outer_name:
                    element_name = (outer_name, element_name)
                    thermal_limit += other_flows[i]
                    flow += other_flows[i]
                    print(
                        f'contingency: {element_name[0]}, branch: {element_name[1]}'
                    )
                    print(f'delta: {flow_array[i]}')
                    print(f'base : {other_flows[i]}')
                    print(f'flow : {flow_array[i]+other_flows[i]}')
                    print(f'model: {pyo.value(flow_variable[element_name])}')
                    if not math.isclose(pyo.value(flow_variable[element_name]),
                                        flow_array[i] + other_flows[i]):
                        print(
                            f'contingency: {element_name[0]}, branch_idx: {i}')
                        diff = pyo.value(flow_variable[element_name]) - (
                            flow_array[i] + other_flows[i])
                        print(f'ABSOLUTE DIFFERENCE: { abs(diff) }')
                        flow_variable[element_name].pprint()
                        raise Exception()
                    print('')
                else:
                    print(f'{name}: {element_name}')
                    print(f'flow : {flow_array[i]}')
                    print(f'model: {pyo.value(flow_variable[element_name])}')
                    print('')
Exemple #4
0
    def _calculate_ptdf_factorization(self):
        logger.info("Calculating PTDF Matrix Factorization")
        MLU, B_dA, ref_bus_mask, contingency_compensators, B_dA_I, I = \
                tx_calc.calculate_ptdf_factorization(self._branches,
                                                     self._buses,self.branches_keys,
                                                     self.buses_keys,
                                                     self._reference_bus,
                                                     self._base_point,
                                                     contingencies=self.contingencies,
                                                     mapping_bus_to_idx=self._busname_to_index_map,
                                                     mapping_branch_to_idx=self._branchname_to_index_map,
                                                     interfaces = self.interfaces,
                                                     index_set_interface = self.interface_keys,)

        self.MLU = MLU
        self.B_dA = B_dA
        self.ref_bus_mask = ref_bus_mask
        self.contingency_compensators = contingency_compensators
        self.B_dA_I = B_dA_I

        self._calculate_phase_shift_flow_adjuster()
        self._calculate_phi_adjust(ref_bus_mask)

        self.phase_shift_flow_adjuster_array_interface = I @ self.phase_shift_flow_adjuster_array
Exemple #5
0
def _lazy_ptdf_dcopf_model_solve_loop(m,
                                      md,
                                      solver,
                                      solver_tee=True,
                                      symbolic_solver_labels=False,
                                      iteration_limit=100000):
    '''
    The lazy PTDF DCOPF solver loop. This function iteratively
    adds violated transmission constraints until either the result is
    transmission feasible or we're tracking every violated constraint
    in the model

    Parameters
    ----------
    m : pyomo.environ.ConcreteModel
        An egret DCOPF model with no transmission constraints
    md : egret.data.ModelData
        An egret ModelData object
    solver : pyomo.opt.solver
        A pyomo solver object
    solver_tee : bool (optional)
        For displaying the solver log (default is True)
    symbolic_solver_labels : bool (optional)
        Use symbolic solver labels when writing to the solver (default is False)
    iteration_limit : int (optional)
        Number of iterations before a hard termination (default is 100000)

    Returns
    -------
    egret.common.lazy_ptdf_utils.LazyPTDFTerminationCondition : the termination status
    pyomo.opt.results.SolverResults : The results object from the pyomo solver
    int : The number of iterations before termination

    '''
    from pyomo.solvers.plugins.solvers.persistent_solver import PersistentSolver

    PTDF = m._PTDF

    ptdf_options = m._ptdf_options

    persistent_solver = isinstance(solver, PersistentSolver)

    for i in range(iteration_limit):

        PFV, PFV_I, viol_num, mon_viol_num, viol_lazy, int_viol_lazy \
                = lpu.check_violations(m, md, PTDF, ptdf_options['max_violations_per_iteration'])

        iter_status_str = "iteration {0}, found {1} violation(s)".format(
            i, viol_num)
        if mon_viol_num:
            iter_status_str += ", {} of which are already monitored".format(
                mon_viol_num)

        logger.info(iter_status_str)

        if viol_num <= 0:
            ## in this case, there are no violations!
            ## load the duals now too, if we're using a persistent solver
            if persistent_solver:
                solver.load_duals()
            return lpu.LazyPTDFTerminationCondition.NORMAL

        elif viol_num == mon_viol_num:
            logger.warning(
                'WARNING: Terminating with monitored violations! Result is not transmission feasible.'
            )
            if persistent_solver:
                solver.load_duals()
            return lpu.LazyPTDFTerminationCondition.FLOW_VIOLATION

        lpu.add_violations(viol_lazy, int_viol_lazy, PFV, PFV_I, m, md, solver,
                           ptdf_options, PTDF)
        total_flow_constr_added = len(viol_lazy) + len(int_viol_lazy)
        logger.info("iteration {0}, added {1} flow constraint(s)".format(
            i, total_flow_constr_added))

        if persistent_solver:
            solver.solve(m,
                         tee=solver_tee,
                         load_solutions=False,
                         save_results=False)
            solver.load_vars()
        else:
            solver.solve(m,
                         tee=solver_tee,
                         symbolic_solver_labels=symbolic_solver_labels)

    else:  # we hit the iteration limit
        logger.warning(
            'WARNING: Exiting on maximum iterations for lazy PTDF model. Result is not transmission feasible.'
        )
        if persistent_solver:
            solver.load_duals()
        return lpu.LazyPTDFTerminationCondition.ITERATION_LIMIT