def test_ql_qc():
    net = nw.case9()
    net.sn_mva = 1.
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net, p_std_dev=0.01, q_std_dev=0.01)
    pf_vm_pu, pf_va_degree = net.res_bus.vm_pu, net.res_bus.va_degree

    #  give it a warm start
    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-3, 5)
    estimation_opt = OptAlgorithm(1e-6, 3000)

    eppci = estimation_wls.estimate(eppci)

    eppci = estimation_opt.estimate(eppci, estimator="ql", a=3, verbose=False)
    if not estimation_opt.successful:
        eppci = estimation_opt.estimate(eppci,
                                        estimator="ql",
                                        a=3,
                                        opt_method="Newton-CG",
                                        verbose=False)

    if not estimation_opt.successful:
        raise AssertionError("Estimation failed due to algorithm failing!")

    net = eppci2pp(net, ppc, eppci)

    if not np.allclose(pf_vm_pu, net.res_bus_est.vm_pu, atol=1e-2) or \
            not np.allclose(pf_va_degree, net.res_bus_est.va_degree, atol=5e-2):
        raise AssertionError("Estimation failed!")

    # give it a warm start
    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-6, 5)
    estimation_opt = OptAlgorithm(1e-6, 3000)

    eppci = estimation_wls.estimate(eppci)
    eppci = estimation_opt.estimate(eppci, estimator="qc", a=3, verbose=False)
    if not estimation_opt.successful:
        eppci = estimation_opt.estimate(eppci,
                                        estimator="qc",
                                        a=3,
                                        opt_method="Newton-CG",
                                        verbose=False)
    net = eppci2pp(net, ppc, eppci)

    if not np.allclose(pf_vm_pu, net.res_bus_est.vm_pu, atol=1e-2) or \
            not np.allclose(pf_va_degree, net.res_bus_est.va_degree, atol=5e-2):
        raise AssertionError("Estimation failed!")
Exemple #2
0
def test_case30_compare_classical_wls_opt_wls():
    net = nw.case30()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net)

    try:
        success = estimate(net, init='flat', algorithm="opt", estimator='wls')
        assert success
    except:
        # if failed give it a warm start
        net, ppc, eppci = pp2eppci(net)
        estimation_wls = WLSAlgorithm(1e-3, 3)
        estimation_opt = OptAlgorithm(1e-6, 1000)

        eppci = estimation_wls.estimate(eppci)
        eppci = estimation_opt.estimate(eppci, estimator="wls")
        assert estimation_opt.successful
        net = eppci2pp(net, ppc, eppci)

    net_wls = deepcopy(net)
    estimate(net_wls)
    assert np.allclose(net_wls.res_bus_est.vm_pu,
                       net.res_bus_est.vm_pu,
                       atol=1e-2)
    assert np.allclose(net_wls.res_bus_est.va_degree,
                       net.res_bus_est.va_degree,
                       atol=1e-2)
Exemple #3
0
def test_ql_qc():
    net = nw.case9()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net, p_std_dev=0.01, q_std_dev=0.01)
    pf_vm_pu, pf_va_degree = net.res_bus.vm_pu, net.res_bus.va_degree

    #  give it a warm start
    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-3, 5)
    estimation_opt = OptAlgorithm(1e-6, 3000)

    eppci = estimation_wls.estimate(eppci)
    try:
        eppci = estimation_opt.estimate(eppci, estimator="ql", a=3)
        assert estimation_opt.successful
    except:
        eppci = estimation_opt.estimate(eppci,
                                        estimator="ql",
                                        a=3,
                                        opt_method="Newton-CG")
        assert estimation_opt.successful
    net = eppci2pp(net, ppc, eppci)

    assert np.allclose(pf_vm_pu, net.res_bus_est.vm_pu, atol=1e-2)
    assert np.allclose(pf_va_degree, net.res_bus_est.va_degree, atol=5e-2)

    # give it a warm start
    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-6, 5)
    estimation_opt = OptAlgorithm(1e-6, 3000)

    eppci = estimation_wls.estimate(eppci)
    try:
        eppci = estimation_opt.estimate(eppci, estimator="qc", a=3)
        assert estimation_opt.successful
    except:
        eppci = estimation_opt.estimate(eppci,
                                        estimator="qc",
                                        a=3,
                                        opt_method="Newton-CG")
        assert estimation_opt.successful
    net = eppci2pp(net, ppc, eppci)

    assert np.allclose(pf_vm_pu, net.res_bus_est.vm_pu, atol=1e-2)
    assert np.allclose(pf_va_degree, net.res_bus_est.va_degree, atol=5e-2)
Exemple #4
0
def test_shgm_ps():
    # we need an random eppci object to initialize estimator
    net = nw.case14()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net)
    _, _, eppci = pp2eppci(net)

    # Using the example from Mili's paper
    H = np.array([[10, -10], [1, 0], [-1, 0], [0, -1], [0, 1], [11, -10],
                  [-1, -1]])
    estm = SHGMEstimatorIRWLS(eppci, a=3)
    ps_estm = estm._ps(H)
    assert np.allclose(ps_estm,
                       np.array([8.39, 0.84, 0.84, 0.84, 0.84, 8.82, 1.68]),
                       atol=0.005)
def test_opt_lav():
    net = nw.case9()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net, with_random_error=False)

    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-3, 5)
    estimation_opt = OptAlgorithm(1e-6, 1000)

    eppci = estimation_wls.estimate(eppci)
    eppci = estimation_opt.estimate(eppci, estimator="lav", verbose=False)

    net = eppci2pp(net, ppc, eppci)

    if not np.allclose(net.res_bus.vm_pu, net.res_bus_est.vm_pu, atol=1e-2) or \
            not np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=5e-2):
        raise AssertionError("Estimation failed!")
Exemple #6
0
def test_opt_lav():
    net = nw.case9()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net, with_random_error=False)

    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-3, 5)
    estimation_opt = OptAlgorithm(1e-6, 1000)

    eppci = estimation_wls.estimate(eppci)
    eppci = estimation_opt.estimate(eppci, estimator="lav")
    assert estimation_opt.successful
    net = eppci2pp(net, ppc, eppci)

    assert np.allclose(net.res_bus.vm_pu, net.res_bus_est.vm_pu, atol=1e-2)
    assert np.allclose(net.res_bus.va_degree,
                       net.res_bus_est.va_degree,
                       atol=5e-2)
def test_lp_ortools_lav():
    '''
    If OR-Tools is installed, run this test.
    '''
    # Set the solver
    LPAlgorithm.ortools_available = True
    net = nw.case9()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net, with_random_error=False)

    net, ppc, eppci = pp2eppci(net)
    estimation_ortools_lp = LPAlgorithm(1e-3, 5)

    estimation_ortools = estimation_ortools_lp.estimate(eppci,
                                                        with_ortools=True)

    net = eppci2pp(net, ppc, eppci)

    if not np.allclose(net.res_bus.vm_pu, net.res_bus_est.vm_pu, atol=1e-2) or \
            not np.allclose(net.res_bus.va_degree, net.res_bus_est.va_degree, atol=5e-2):
        raise AssertionError("Estimation failed!")
def test_case9_compare_classical_wls_opt_wls():
    net = nw.case9()
    pp.runpp(net)
    add_virtual_meas_from_loadflow(net)

    # give it a warm start
    net, ppc, eppci = pp2eppci(net)
    estimation_wls = WLSAlgorithm(1e-3, 3)
    estimation_opt = OptAlgorithm(1e-6, 1000)

    eppci = estimation_wls.estimate(eppci)
    eppci = estimation_opt.estimate(eppci, estimator="wls", verbose=False)
    if not estimation_opt.successful:
        raise AssertionError("Estimation failed due to algorithm failing!")
    net = eppci2pp(net, ppc, eppci)

    net_wls = net.deepcopy()
    estimate(net_wls)

    if not np.allclose(net_wls.res_bus_est.vm_pu, net.res_bus_est.vm_pu, atol=1e-2) or \
            not np.allclose(net_wls.res_bus_est.va_degree, net.res_bus_est.va_degree, atol=1e-2):
        raise AssertionError("Estimation failed!")
Exemple #9
0
    def __init__(self, lcc_info, bnd_meas_info, key, fast_decoupled):
        self.net, self.tie_line_param, self.bnd_meas, self.bnd_zi, self.bnd_Ri = lcc_info
        self.bnd_meas_info = bnd_meas_info
        self.key = key
        self.secure = self.key is not None
        if self.secure:
            self.enc = Deg2PaillierThreshold(self.key)
        self.fast_decoupled = fast_decoupled

        self.net, self.ppc, self.eppci = pp2eppci(self.net, 'flat', 'flat',
                                                  True, None)
        self.sem = ExtendedBaseAlgebra(self.eppci)
        self.Ri_inv = csr_matrix(np.diagflat(1 / self.eppci.r_cov**2))
        self.E = self.eppci.E

        # If using the fast-decoupled model, bnd_flow_H can be computed locally
        self.bnd_flow_Hi = self._compute_bnd_flow_H(
        ) if self.fast_decoupled else None
        self.Hi, self.Gi, self.delta_yi = None, None, None
        self.bnd_hi, self.bnd_Hi = None, None
        self.ui = None
        pass
    def estimate(self,
                 v_start='flat',
                 delta_start='flat',
                 calculate_voltage_angles=True,
                 zero_injection=None,
                 fuse_buses_with_bb_switch='all',
                 **opt_vars):
        """
        The function estimate is the main function of the module. It takes up to three input
        arguments: v_start, delta_start and calculate_voltage_angles. The first two are the initial
        state variables for the estimation process. Usually they can be initialized in a
        "flat-start" condition: All voltages being 1.0 pu and all voltage angles being 0 degrees.
        In this case, the parameters can be left at their default values (None). If the estimation
        is applied continuously, using the results from the last estimation as the starting
        condition for the current estimation can decrease the  amount of iterations needed to
        estimate the current state. The third parameter defines whether all voltage angles are
        calculated absolutely, including phase shifts from transformers. If only the relative
        differences between buses are required, this parameter can be set to False. Returned is a
        boolean value, which is true after a successful estimation and false otherwise.
        The resulting complex voltage will be written into the pandapower network. The result
        fields are found res_bus_est of the pandapower network.
        INPUT:
            **net** - The net within this line should be created
            **v_start** (np.array, shape=(1,), optional) - Vector with initial values for all
            voltage magnitudes in p.u. (sorted by bus index)
            **delta_start** (np.array, shape=(1,), optional) - Vector with initial values for all
            voltage angles in degrees (sorted by bus index)
        OPTIONAL:
        **tolerance** - (float) - When the maximum state change between iterations is less than
        tolerance, the process stops. Default is 1e-6

        **maximum_iterations** - (integer) - Maximum number of iterations. Default is 10

        **calculate_voltage_angles** - (boolean) - Take into account absolute voltage angles and phase
        shifts in transformers, if init is 'slack'. Default is True
        
        **zero_injection** - (str, iterable, None) - Defines which buses are zero injection bus or the method
        to identify zero injection bus, with 'wls_estimator' virtual measurements will be added, with 
        'wls_estimator with zero constraints' the buses will be handled as constraints
            "auto": all bus without p,q measurement, without p, q value (load, sgen...) and aux buses will be
                identified as zero injection bus  
            "aux_bus": only aux bus will be identified as zero injection bus
            None: no bus will be identified as zero injection bus
            iterable: the iterable should contain index of the zero injection bus and also aux bus will be identified
                as zero-injection bus

        **fuse_buses_with_bb_switch** - (str, iterable, None) - Defines how buses with closed bb switches should 
        be handled, if fuse buses will only fused to one for calculation, if not fuse, an auxiliary bus and 
        auxiliary line will be automatically added to the network to make the buses with different p,q injection
        measurements identifieble
            "all": all buses with bb-switches will be fused, the same as the default behaviour in load flow
            None: buses with bb-switches and individual p,q measurements will be reconfigurated
                by auxiliary elements
            iterable: the iterable should contain the index of buses to be fused, the behaviour is contigous e.g.
                if one of the bus among the buses connected through bb switch is given, then all of them will still
                be fused
        OUTPUT:
            **successful** (boolean) - True if the estimation process was successful
        Optional estimation variables:
            The bus power injections can be accessed with *se.s_node_powers* and the estimated
            values corresponding to the (noisy) measurement values with *se.hx*. (*hx* denotes h(x))
        EXAMPLE:
            success = estimate(np.array([1.0, 1.0, 1.0]), np.array([0.0, 0.0, 0.0]))
        """
        # check if all parameter are allowed
        for var_name in opt_vars.keys():
            if var_name not in ALLOWED_OPT_VAR:
                self.logger.warning("Caution! %s is not allowed as parameter" % var_name \
                                    + " for estimate and will be ignored!")

        if self.net is None:
            raise UserWarning(
                "SE Component was not initialized with a network.")

        # change the configuration of the pp net to avoid auto fusing of buses connected
        # through bb switch with elements on each bus if this feature enabled
        bus_to_be_fused = None
        if fuse_buses_with_bb_switch != 'all' and not self.net.switch.empty:
            if isinstance(fuse_buses_with_bb_switch, str):
                raise UserWarning(
                    "fuse_buses_with_bb_switch parameter is not correctly initialized"
                )
            elif hasattr(fuse_buses_with_bb_switch, '__iter__'):
                bus_to_be_fused = fuse_buses_with_bb_switch
            set_bb_switch_impedance(self.net, bus_to_be_fused)

        self.net, self.ppc, self.eppci = pp2eppci(
            self.net,
            v_start=v_start,
            delta_start=delta_start,
            calculate_voltage_angles=calculate_voltage_angles,
            zero_injection=zero_injection,
            ppc=self.ppc,
            eppci=self.eppci)

        # Estimate voltage magnitude and angle with the given estimator
        self.eppci = self.solver.estimate(self.eppci, **opt_vars)

        if self.solver.successful:
            self.net = eppci2pp(self.net, self.ppc, self.eppci)
        else:
            self.logger.warning(
                "Estimation failed! Pandapower network failed to update!")

        # clear the aux elements and calculation results created for the substitution of bb switches
        if fuse_buses_with_bb_switch != 'all' and not self.net.switch.empty:
            reset_bb_switch_impedance(self.net)

        # if recycle is not wished, reset ppc, ppci
        if not self.recycle:
            self.ppc, self.eppci = None, None
        return self.solver.successful