コード例 #1
0
ファイル: runopf.py プロジェクト: ink-corp/nonlinear-opt
def runopf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs an optimal power flow.

    @see: L{rundcopf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ##-----  run the optimal power flow  -----
    r = opf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except IOError as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(r, fd, ppopt)
                fd.close()

    else:
        printpf(r, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, r)

    return r
コード例 #2
0
def _run_bfsw_ppc(ppc, ppopt=None):
    """
    SPARSE version of distribution power flow solution according to [1]
    :References:
    [1] Jen-Hao Teng, "A Direct Approach for Distribution System Load Flow Solutions", IEEE Transactions on Power Delivery, vol. 18, no. 3, pp. 882-887, July 2003.

    :param ppc: matpower-style case data
    :return: results (pypower style), success (flag about PF convergence)
    """
    ppci = ppc

    ppopt = ppoption(ppopt)

    baseMVA, bus, gen, branch = \
        ppci["baseMVA"], ppci["bus"], ppci["gen"], ppci["branch"]
    nbus = bus.shape[0]

    # get bus index lists of each type of bus
    ref, pv, pq = bustypes(bus, gen)

    # depth-first-search bus ordering and generating Direct Load Flow matrix DLF = BCBV * BIBC
    DLF, ppc_bfsw, buses_ordered_bfsw = bibc_bcbv(ppci)


    baseMVA_bfsw, bus_bfsw, gen_bfsw, branch_bfsw = \
        ppc_bfsw["baseMVA"], ppc_bfsw["bus"], ppc_bfsw["gen"], ppc_bfsw["branch"]

    time_start = time() # starting pf calculation timing

    # initialize voltages to flat start and buses with gens to their setpoints
    V0 = np.ones(nbus, dtype=complex)
    V0[gen[:, GEN_BUS].astype(int)] = gen[:, VG]

    Sbus_bfsw = makeSbus(baseMVA_bfsw, bus_bfsw, gen_bfsw)

    # update data matrices with solution
    Ybus_bfsw, Yf_bfsw, Yt_bfsw = makeYbus(baseMVA_bfsw, bus_bfsw, branch_bfsw)
    ## get bus index lists of each type of bus
    ref_bfsw, pv_bfsw, pq_bfsw = bustypes(bus_bfsw, gen_bfsw)

    # #-----  run the power flow  -----
    V_final, success = bfsw(DLF, bus_bfsw, gen_bfsw, branch_bfsw, baseMVA_bfsw, Ybus_bfsw, Sbus_bfsw, V0,
                                   ref_bfsw, pv_bfsw, pq_bfsw, ppopt=ppopt)

    V_final = V_final[np.argsort(buses_ordered_bfsw)]  # return bus voltages in original bus order


    # #----- output results to ppc ------
    ppci["et"] = time() - time_start    # pf time end

    # generate results for original bus ordering
    Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)

    bus, gen, branch = pfsoln(baseMVA, bus, gen, branch, Ybus, Yf, Yt, V_final, ref, pv, pq)

    ppci["success"] = success

    ppci["bus"], ppci["gen"], ppci["branch"] = bus, gen, branch

    return ppci, success
コード例 #3
0
ファイル: runopf.py プロジェクト: Anastien/PYPOWER
def runopf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs an optimal power flow.

    @see: L{rundcopf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ##-----  run the optimal power flow  -----
    r = opf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except IOError as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(r, fd, ppopt)
                fd.close()

    else:
        printpf(r, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, r)

    return r
コード例 #4
0
 def __init__(self):
     self.name = "Stochastic Power Flow"
     from pypower.ppoption import ppoption
     opt = ppoption()
     opt["VERBOSE"] = 0
     opt["OUT_ALL"] = 0
     self.opt = opt
コード例 #5
0
def _optimal_powerflow(net, verbose, suppress_warnings, **kwargs):
    ac = net["_options"]["ac"]

    ppopt = ppoption(VERBOSE=verbose, OPF_FLOW_LIM=2, PF_DC=not ac, **kwargs)
    net["OPF_converged"] = False
    net["converged"] = False
    _add_auxiliary_elements(net)
    reset_results(net)

    ppc, ppci = _pd2ppc(net)
    if not ac:
        ppci["bus"][:, VM] = 1.0
    net["_ppc_opf"] = ppc
    if len(net.dcline) > 0:
        ppci = add_userfcn(ppci, 'formulation', _add_dcline_constraints, args=net)

    if suppress_warnings:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            result = opf(ppci, ppopt)
    else:
        result = opf(ppci, ppopt)
    net["_ppc_opf"] = result

    if not result["success"]:
        raise OPFNotConverged("Optimal Power Flow did not converge!")

    # ppci doesn't contain out of service elements, but ppc does -> copy results accordingly
    mode = net["_options"]["mode"]
    result = _copy_results_ppci_to_ppc(result, ppc, mode=mode)

    net["_ppc_opf"] = result
    net["OPF_converged"] = True
    _extract_results_opf(net, result)
    _clean_up(net)
コード例 #6
0
ファイル: gui_globals.py プロジェクト: susantoj/PYPOWER-Gui
def init():
    global ppc
    global ppopt
    
    ppc = {"version": '2'}
    
    ppc["baseMVA"] = 100.0
    
    ppc["bus"] = np.array([
        [1, 3, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [2, 2, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [3, 2, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [4, 1, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [5, 1, 90,  30, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [6, 1, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [7, 1, 100, 35, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [8, 1, 0,    0, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9],
        [9, 1, 125, 50, 0, 0, 1, 1, 0, 345, 1, 1.1, 0.9]
    ])
     
    ppc["branch"] = np.array([
        [1, 4, 0,      0.0576, 0,     250, 250, 250, 0, 0, 1, -360, 360],
        [4, 5, 0.017,  0.092,  0.158, 250, 250, 250, 0, 0, 1, -360, 360],
        [5, 6, 0.039,  0.17,   0.358, 150, 150, 150, 0, 0, 1, -360, 360],
        [3, 6, 0,      0.0586, 0,     300, 300, 300, 0, 0, 1, -360, 360],
        [6, 7, 0.0119, 0.1008, 0.209, 150, 150, 150, 0, 0, 1, -360, 360],
        [7, 8, 0.0085, 0.072,  0.149, 250, 250, 250, 0, 0, 1, -360, 360],
        [8, 2, 0,      0.0625, 0,     250, 250, 250, 0, 0, 1, -360, 360],
        [8, 9, 0.032,  0.161,  0.306, 250, 250, 250, 0, 0, 1, -360, 360],
        [9, 4, 0.01,   0.085,  0.176, 250, 250, 250, 0, 0, 1, -360, 360]
    ])
    
    ppc["gen"] = np.array([
        [1, 0,   0, 300, -300, 1.0, 100, 1, 250, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [2, 163, 0, 300, -300, 1.0, 100, 1, 300, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [3, 85,  0, 300, -300, 1.0, 100, 1, 270, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ])
    
    # OPF functions not yet implemented in GUI
    """
    ppc["areas"] = np.array([
        [1, 5]
    ])
    
    ppc["gencost"] = np.array([
        [2, 1500, 0, 3, 0.11,   5,   150],
        [2, 2000, 0, 3, 0.085,  1.2, 600],
        [2, 3000, 0, 3, 0.1225, 1,   335]
    ])
    """
    
    ppopt = ppoption()
    
    
    global filename   
    filename = ""    
    
    # Power flow settings
    global pf_settings
    pf_settings = {"Qlim": False, "max_iter": 25, "err_tol": 0.00001}
コード例 #7
0
ファイル: runuopf.py プロジェクト: charlie0389/PYPOWER
def runuopf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs an optimal power flow with unit-decommitment heuristic.

    @see: L{rundcopf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ##-----  run the unit de-commitment / optimal power flow  -----
    r = uopf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "wb")
        except Exception as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(r, fd, ppopt)
                fd.close()

    printpf(r, ppopt=ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, r)

    return r
コード例 #8
0
def test_to_ppc_and_mpc():
    # pypower cases to validate
    functions = [
        'case4gs', 'case6ww', 'case14', 'case30', 'case24_ieee_rts', 'case39'
    ]
    for fn in functions:
        # get pypower results
        pypower_module = __import__('pypower.' + fn)
        pypower_submodule = getattr(pypower_module, fn)
        pypower_function = getattr(pypower_submodule, fn)
        ppc_net = pypower_function()

        # get net from pandapower
        res_pypower, status_pypower = runpf(ppc_net,
                                            ppopt=ppoption(VERBOSE=0,
                                                           OUT_ALL=0))

        pandapower_module = __import__('pandapower', fromlist=['networks'])
        pandapower_function = getattr(pandapower_module.networks, fn)
        net = pandapower_function()
        reset_results(net)

        # convert to ppc
        ppc = cv.to_ppc(net)
        # convert to mpc
        mpc = cv.to_mpc(net)

        # runpf from converted ppc
        res_converted_pp, status_converted_pp = runpf(
            ppc, ppopt=ppoption(VERBOSE=0, OUT_ALL=0))

        if status_converted_pp and status_pypower:
            # get lookup pp2ppc
            bus_lookup = net["_pd2ppc_lookups"]["bus"]
            # check for equality in bus voltages
            pp_buses = bus_lookup[res_converted_pp['bus'][:,
                                                          BUS_I].astype(int)]
            assert np.allclose(res_converted_pp['bus'][pp_buses, VM:VA + 1],
                               res_pypower['bus'][:, VM:VA + 1])
            # ToDo: check equality of branch and gen values
            # pp_gen = bus_lookup[res_converted_pp['bus'][:, BUS_I].astype(int)]
            # assert np.allclose(res_pypower['gen'][res_pypower['order']['gen']['e2i'], PG:QG+1]
            #                    , res_converted_pp['gen'][:, PG:QG+1])
        else:
            raise LoadflowNotConverged("Loadflow did not converge!")
コード例 #9
0
ファイル: run.py プロジェクト: lucassm/cigre-montecarlo
def _runpppf(net, init, ac, calculate_voltage_angles, tolerance_kva, trafo_model,
             trafo_loading, enforce_q_lims, suppress_warnings, Numba, **kwargs):
    """
    Gets called by runpp or rundcpp with different arguments.
    """

    net["converged"] = False
    if (ac and not init == "results") or not ac:
        reset_results(net)

    # select elements in service (time consuming, so we do it once)
    is_elems = _select_is_elements(net)

    # convert pandapower net to ppc
    ppc, ppci, bus_lookup = _pd2ppc(net, is_elems, calculate_voltage_angles, enforce_q_lims,
                                   trafo_model, init_results=(init == "results"))
    net["_ppc"] = ppc
    if not "VERBOSE" in kwargs:
        kwargs["VERBOSE"] = 0

    # run the powerflow with or without warnings. If init='dc', AC PF will be
    # initialized with DC voltages
    if suppress_warnings:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            result = _runpf(ppci, init, ac, Numba, ppopt=ppopt.ppoption(ENFORCE_Q_LIMS=enforce_q_lims,
                                                                       PF_TOL=tolerance_kva * 1e-3, **kwargs))[0]

    else:
        result = _runpf(ppci, init, ac, Numba, ppopt=ppopt.ppoption(ENFORCE_Q_LIMS=enforce_q_lims,
                                                                   PF_TOL=tolerance_kva * 1e-3, **kwargs))[0]

    # ppci doesn't contain out of service elements, but ppc does -> copy results accordingly
    result = _copy_results_ppci_to_ppc(result, ppc)

    # raise if PF was not successful. If DC -> success is always 1
    if result["success"] != 1:
        raise LoadflowNotConverged("Loadflow did not converge!")
    else:
        net["_ppc"] = result
        net["converged"] = True

    _extract_results(net, result, is_elems, bus_lookup, trafo_loading, ac)
    _clean_up(net)
コード例 #10
0
def _runpppf_dd(net, init, ac, calculate_voltage_angles, tolerance_kva,
                trafo_model, trafo_loading, enforce_q_lims, numba, recycle,
                **kwargs):
    """
    Gets called by runpp or rundcpp with different arguments.
    """

    net["converged"] = False
    if (ac and not init == "results") or not ac:
        reset_results(net)

    # select elements in service (time consuming, so we do it once)
    is_elems = _select_is_elements(net, recycle)

    if recycle["ppc"] and "_ppc" in net and net[
            "_ppc"] is not None and "_bus_lookup" in net:
        # update the ppc from last cycle
        ppc, ppci, bus_lookup = _update_ppc(net, is_elems, recycle,
                                            calculate_voltage_angles,
                                            enforce_q_lims, trafo_model)
    else:
        # convert pandapower net to ppc
        ppc, ppci, bus_lookup = _pd2ppc(net,
                                        is_elems,
                                        calculate_voltage_angles,
                                        enforce_q_lims,
                                        trafo_model,
                                        init_results=(init == "results"))

    # store variables
    net["_ppc"] = ppc
    net["_bus_lookup"] = bus_lookup
    net["_is_elems"] = is_elems

    if not "VERBOSE" in kwargs:
        kwargs["VERBOSE"] = 0

    # run the powerflow
    result = _run_fbsw(ppci,
                       ppopt=ppoption(ENFORCE_Q_LIMS=enforce_q_lims,
                                      PF_TOL=tolerance_kva * 1e-3,
                                      **kwargs))[0]

    # ppci doesn't contain out of service elements, but ppc does -> copy results accordingly
    result = _copy_results_ppci_to_ppc(result, ppc, bus_lookup)

    # raise if PF was not successful. If DC -> success is always 1
    if result["success"] != 1:
        raise LoadflowNotConverged("Loadflow did not converge!")
    else:
        net["_ppc"] = result
        net["converged"] = True

    _extract_results(net, result, is_elems, bus_lookup, trafo_loading, ac)
    _clean_up(net)
コード例 #11
0
ファイル: t_makeLODF.py プロジェクト: redw0lf/PYPOWER
def t_makeLODF(quiet=False):
    """Tests for C{makeLODF}.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ntests = 31
    t_begin(ntests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_auction_case')
    verbose = 0  #not quiet

    ## load case
    ppc = loadcase(casefile)
    ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0)
    r = rundcopf(ppc, ppopt)
    baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch']
    _, bus, gen, branch = ext2int1(bus, gen, branch)

    ## compute injections and flows
    F0 = branch[:, PF]

    ## create some PTDF matrices
    H = makePTDF(baseMVA, bus, branch, 0)

    ## create some PTDF matrices
    try:
        LODF = makeLODF(branch, H)
    except ZeroDivisionError:
        pass

    ## take out non-essential lines one-by-one and see what happens
    ppc['bus'] = bus
    ppc['gen'] = gen
    branch0 = branch
    outages = r_[arange(12),
                 arange(13, 15),
                 arange(16, 18), [19],
                 arange(26, 33),
                 arange(34, 41)]
    for k in outages:
        ppc['branch'] = branch0.copy()
        ppc['branch'][k, BR_STATUS] = 0
        r, _ = rundcpf(ppc, ppopt)
        baseMVA, bus, gen, branch = \
                r['baseMVA'], r['bus'], r['gen'], r['branch']
        F = branch[:, PF]

        t_is(LODF[:, k], (F - F0) / F0[k], 6, 'LODF[:, %d]' % k)

    t_end()
コード例 #12
0
ファイル: rundcpf.py プロジェクト: Anastien/PYPOWER
def rundcpf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a DC power flow.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt, PF_DC=True)

    return runpf(casedata, ppopt, fname, solvedcase)
コード例 #13
0
ファイル: rundcpf.py プロジェクト: ink-corp/nonlinear-opt
def rundcpf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a DC power flow.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt, PF_DC=True)

    return runpf(casedata, ppopt, fname, solvedcase)
コード例 #14
0
ファイル: rundcopf.py プロジェクト: ZiiCee/PYPOWER
def rundcopf(casedata=None, ppopt=None, fname="", solvedcase=""):
    """Runs a DC optimal power flow.

    @see: L{runopf}, L{runduopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), "case9")
    ppopt = ppoption(ppopt, PF_DC=True)

    return runopf(casedata, ppopt, fname, solvedcase)
コード例 #15
0
def runduopf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a DC optimal power flow with unit-decommitment heuristic.

    @see: L{rundcopf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt, PF_DC=True)

    return runuopf(casedata, ppopt, fname, solvedcase)
コード例 #16
0
ファイル: t_makeLODF.py プロジェクト: charlie0389/PYPOWER
def t_makeLODF(quiet=False):
    """Tests for C{makeLODF}.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ntests = 31
    t_begin(ntests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_auction_case')
    verbose = 0#not quiet

    ## load case
    ppc = loadcase(casefile)
    ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0)
    r = rundcopf(ppc, ppopt)
    baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch']
    _, bus, gen, branch = ext2int1(bus, gen, branch)

    ## compute injections and flows
    F0  = branch[:, PF]

    ## create some PTDF matrices
    H = makePTDF(baseMVA, bus, branch, 0)

    ## create some PTDF matrices
    try:
        LODF = makeLODF(branch, H)
    except ZeroDivisionError:
        pass

    ## take out non-essential lines one-by-one and see what happens
    ppc['bus'] = bus
    ppc['gen'] = gen
    branch0 = branch
    outages = r_[arange(12), arange(13, 15), arange(16, 18),
                 [19], arange(26, 33), arange(34, 41)]
    for k in outages:
        ppc['branch'] = branch0.copy()
        ppc['branch'][k, BR_STATUS] = 0
        r, _ = rundcpf(ppc, ppopt)
        baseMVA, bus, gen, branch = \
                r['baseMVA'], r['bus'], r['gen'], r['branch']
        F = branch[:, PF]

        t_is(LODF[:, k], (F - F0) / F0[k], 6, 'LODF[:, %d]' % k)

    t_end()
コード例 #17
0
ファイル: dcopf.py プロジェクト: ink-corp/nonlinear-opt
def dcopf(*args, **kw_args):
    """Solves a DC optimal power flow.

    This is a simple wrapper function around L{opf} that sets the C{PF_DC}
    option to C{True} before calling L{opf}.
    See L{opf} for the details of input and output arguments.

    @see: L{rundcopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ppc, ppopt = opf_args2(*args, **kw_args)
    ppopt = ppoption(ppopt, PF_DC=1)

    return opf(ppc, ppopt)
コード例 #18
0
ファイル: dcopf.py プロジェクト: Anastien/PYPOWER
def dcopf(*args, **kw_args):
    """Solves a DC optimal power flow.

    This is a simple wrapper function around L{opf} that sets the C{PF_DC}
    option to C{True} before calling L{opf}.
    See L{opf} for the details of input and output arguments.

    @see: L{rundcopf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ppc, ppopt = opf_args2(*args, **kw_args);
    ppopt = ppoption(ppopt, PF_DC=1)

    return opf(ppc, ppopt)
コード例 #19
0
def calc_power_flow(case):
    # we run an opf, but real power output is fixed everywhere except a single quasi-slack bus,
    # so it just adjusts the voltage setpoints to minimize losses (and hopefully get more 
    # reasonable solutions than a raw power flow)
    #results = runopf(case)
    #results = runpf(case, ppopt=ppoption(ENFORCE_Q_LIMS=1))[0]
    results = runpf(case, ppopt=ppoption(OUT_ALL=0))[0]
    slack_bus = case["slack_bus"]
    slack_gens = case["slack_gens"]
    # add in the extra slack generation introduced by the model, so the results
    # show the operating state accurately (even if it differs from the proposed state)
    results["net_injection"][slack_bus] += (
        np.sum(results["gen"][slack_gens, PG] - case["gen"][slack_gens, PG])
    )
    return results
コード例 #20
0
def rundcpf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a DC power flow.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln

    Changes by University of Kassel: Different runpf is imported
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt, PF_DC=True)

    return runpf(casedata, ppopt, fname, solvedcase)
コード例 #21
0
def solve_pf(case, hour=None,
        results=None,
        ppopt=None,
        set_generator_status=False,
        fname='./runpf.log'):

    ppopt = ppoption(ppopt)

    fname = os.path.abspath(fname)

    baseMVA = case.baseMVA
    bus = case.bus.copy(deep=True)
    branch = case.branch.copy(deep=True)
    gen = case.gen.copy(deep=True)
    gencost = case.gen.copy(deep=True)

    if hour is not None:
        logger.debug("Setting bus load based on case.load")
        bus['PD'] = case.load.loc[hour]
        bus = bus.fillna(0)

    if hour is not None and results is not None:
        logger.debug("Setting GEN_STATUS and PG")
        if set_generator_status is True:
            gen['GEN_STATUS'] = results.unit_commitment.loc[hour].astype(int)
        gen['PG'] = results.power_generated.loc[hour]

    value = [i + 1 for i in range(0, len(bus.index))]
    bus_name = bus.index
    bus.index = value
    bus.index = bus.index.astype(int)
    branch['F_BUS'] = branch['F_BUS'].apply(lambda x: value[bus_name.get_loc(x)]).astype(int)
    branch['T_BUS'] = branch['T_BUS'].apply(lambda x: value[bus_name.get_loc(x)]).astype(int)
    gen['GEN_BUS'] = gen['GEN_BUS'].apply(lambda x: value[bus_name.get_loc(x)]).astype(int)

    bus = np.array(bus.reset_index())
    branch = np.array(branch)
    gen = np.array(gen)
    gencost = np.array(gencost)

    casedata = {'baseMVA': baseMVA,
                'gencost': gencost,
                'gen': gen,
                'branch': branch,
                'bus': bus}

    return runpf(casedata, ppopt=ppopt, fname=fname)
コード例 #22
0
ファイル: callrunpf.py プロジェクト: igorsowa9/opftest
def callrunpf(ppc_sol, verbose=0):
    if ppc_sol['branch'].shape[
            1] > 13:  # check if more columns than expected are included
        branchcopy = ppc_sol['branch']  # create copy of the original branch
        branch = ppc_sol[
            'branch'][:, 0:13]  # copy solution branch data except Pf Qf Pt Qt
        ppc_sol['branch'] = branch  # replace the original branch

    opt = ppoption(VERBOSE=verbose,
                   OUT_ALL=verbose)  # set verbose value (0 by default)
    r = runpf(ppc_sol, opt)  # execute power flow

    if 'branchcopy' in locals():  # check if branch copy was needed
        ppc_sol['branch'] = branchcopy  # return the original branch

    # returns the power flow solution struct
    return r[0]
コード例 #23
0
def draw_network(fignr=754):
	from matplotlib.pyplot import figure, show
	import networkx as nx

	casedata = get_topology()
	ppc = casedata
	ppopt = ppoption(PF_ALG=2)
	ppc = ext2int(ppc)
	figure(fignr)
	g = nx.Graph()
	i = ppc['bus'][:, BUS_I].astype(int)
	g.add_nodes_from(i, bgcolor='green')
	#nx.draw_networkx_nodes(g,pos=nx.spring_layout(g))
	fr = ppc['branch'][:, F_BUS].astype(int)
	to = ppc['branch'][:, T_BUS].astype(int)
	g.add_edges_from(zip(fr, to), color='magenta')
	nx.draw(g, with_labels=True, node_size=1000,node_color='skyblue',width=0.5)
	show()
コード例 #24
0
def _get_options(options, **kwargs):
    init_va_degree = options["init_va_degree"]
    ac = options["ac"]
    recycle = options["recycle"]
    numba = options["numba"]
    enforce_q_lims = options["enforce_q_lims"]
    tolerance_kva = options["tolerance_kva"]
    algorithm = options["algorithm"]
    max_iteration = options["max_iteration"]

    # algorithms implemented within pypower
    algorithm_pypower_dict = {'nr': 1, 'fdbx': 2, 'fdxb': 3, 'gs': 4}

    ppopt = ppoption(ENFORCE_Q_LIMS=enforce_q_lims, PF_TOL=tolerance_kva * 1e-3,
                     PF_ALG=algorithm_pypower_dict[algorithm], **kwargs)
    ppopt['PF_MAX_IT'] = max_iteration
    ppopt['PF_MAX_IT_GS'] = max_iteration
    ppopt['PF_MAX_IT_FD'] = max_iteration
    ppopt['VERBOSE'] = 0
    return init_va_degree, ac, numba, recycle, ppopt
コード例 #25
0
def draw_network(fignr=754):
    from matplotlib.pyplot import figure, show
    import networkx as nx

    casedata = get_topology()
    ppc = casedata
    ppopt = ppoption(PF_ALG=2)
    ppc = ext2int(ppc)
    figure(fignr)
    g = nx.Graph()
    i = ppc['bus'][:, BUS_I].astype(int)
    g.add_nodes_from(i, bgcolor='green')
    #nx.draw_networkx_nodes(g,pos=nx.spring_layout(g))
    fr = ppc['branch'][:, F_BUS].astype(int)
    to = ppc['branch'][:, T_BUS].astype(int)
    g.add_edges_from(zip(fr, to), color='magenta')
    nx.draw(g,
            with_labels=True,
            node_size=1000,
            node_color='skyblue',
            width=0.5)
    show()
コード例 #26
0
ファイル: runopf.py プロジェクト: jcrabtree/PYPOWER
def runopf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs an optimal power flow.

    @see: L{rundcopf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ##-----  run the optimal power flow  -----
    r = opf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "wb")
        except IOError, detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
コード例 #27
0
def uopf(*args):
    """Solves combined unit decommitment / optimal power flow.

    Solves a combined unit decommitment and optimal power flow for a single
    time period. Uses an algorithm similar to dynamic programming. It proceeds
    through a sequence of stages, where stage C{N} has C{N} generators shut
    down, starting with C{N=0}. In each stage, it forms a list of candidates
    (gens at their C{Pmin} limits) and computes the cost with each one of them
    shut down. It selects the least cost case as the starting point for the
    next stage, continuing until there are no more candidates to be shut down
    or no more improvement can be gained by shutting something down.
    If C{verbose} in ppopt (see L{ppoption} is C{true}, it prints progress
    info, if it is > 1 it prints the output of each individual opf.

    @see: L{opf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ##----- initialization -----
    t0 = time()                                 ## start timer

    ## process input arguments
    ppc, ppopt = opf_args2(*args)

    ## options
    verbose = ppopt["VERBOSE"]
    if verbose:      ## turn down verbosity one level for calls to opf
        ppopt = ppoption(ppopt, VERBOSE=verbose - 1)

    ##-----  do combined unit commitment/optimal power flow  -----

    ## check for sum(Pmin) > total load, decommit as necessary
    on   = find( (ppc["gen"][:, GEN_STATUS] > 0) & ~isload(ppc["gen"]) )   ## gens in service
    onld = find( (ppc["gen"][:, GEN_STATUS] > 0) &  isload(ppc["gen"]) )   ## disp loads in serv
    load_capacity = sum(ppc["bus"][:, PD]) - sum(ppc["gen"][onld, PMIN])   ## total load capacity
    Pmin = ppc["gen"][on, PMIN]
    while sum(Pmin) > load_capacity:
        ## shut down most expensive unit
        avgPmincost = totcost(ppc["gencost"][on, :], Pmin) / Pmin
        _, i = fairmax(avgPmincost)   ## pick one with max avg cost at Pmin
        i = on[i]                     ## convert to generator index

        if verbose:
            print('Shutting down generator %d so all Pmin limits can be satisfied.\n' % i)

        ## set generation to zero
        ppc["gen"][i, [PG, QG, GEN_STATUS]] = 0

        ## update minimum gen capacity
        on  = find( (ppc["gen"][:, GEN_STATUS] > 0) & ~isload(ppc["gen"]) )   ## gens in service
        Pmin = ppc["gen"][on, PMIN]

    ## run initial opf
    results = opf(ppc, ppopt)

    ## best case so far
    results1 = deepcopy(results)

    ## best case for this stage (ie. with n gens shut down, n=0,1,2 ...)
    results0 = deepcopy(results1)
    ppc["bus"] = results0["bus"].copy()     ## use these V as starting point for OPF

    while True:
        ## get candidates for shutdown
        candidates = find((results0["gen"][:, MU_PMIN] > 0) & (results0["gen"][:, PMIN] > 0))
        if len(candidates) == 0:
            break

        ## do not check for further decommitment unless we
        ##  see something better during this stage
        done = True

        for k in candidates:
            ## start with best for this stage
            ppc["gen"] = results0["gen"].copy()

            ## shut down gen k
            ppc["gen"][k, [PG, QG, GEN_STATUS]] = 0

            ## run opf
            results = opf(ppc, ppopt)

            ## something better?
            if results['success'] and (results["f"] < results1["f"]):
                results1 = deepcopy(results)
                k1 = k
                done = False   ## make sure we check for further decommitment

        if done:
            ## decommits at this stage did not help, so let's quit
            break
        else:
            ## shutting something else down helps, so let's keep going
            if verbose:
                print('Shutting down generator %d.\n' % k1)

            results0 = deepcopy(results1)
            ppc["bus"] = results0["bus"].copy()     ## use these V as starting point for OPF

    ## compute elapsed time
    et = time() - t0

    ## finish preparing output
    results0['et'] = et

    return results0
コード例 #28
0
ファイル: printpf.py プロジェクト: Anastien/PYPOWER
def printpf(baseMVA, bus=None, gen=None, branch=None, f=None, success=None,
            et=None, fd=None, ppopt=None):
    """Prints power flow results.

    Prints power flow and optimal power flow results to C{fd} (a file
    descriptor which defaults to C{stdout}), with the details of what
    gets printed controlled by the optional C{ppopt} argument, which is a
    PYPOWER options vector (see L{ppoption} for details).

    The data can either be supplied in a single C{results} dict, or
    in the individual arguments: C{baseMVA}, C{bus}, C{gen}, C{branch}, C{f},
    C{success} and C{et}, where C{f} is the OPF objective function value,
    C{success} is C{True} if the solution converged and C{False} otherwise,
    and C{et} is the elapsed time for the computation in seconds. If C{f} is
    given, it is assumed that the output is from an OPF run, otherwise it is
    assumed to be a simple power flow run.

    Examples::
        ppopt = ppoptions(OUT_GEN=1, OUT_BUS=0, OUT_BRANCH=0)
        fd = open(fname, 'w+b')
        results = runopf(ppc)
        printpf(results)
        printpf(results, fd)
        printpf(results, fd, ppopt)
        printpf(baseMVA, bus, gen, branch, f, success, et)
        printpf(baseMVA, bus, gen, branch, f, success, et, fd)
        printpf(baseMVA, bus, gen, branch, f, success, et, fd, ppopt)
        fd.close()

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ##----- initialization -----
    ## default arguments
    if isinstance(baseMVA, dict):
        have_results_struct = 1
        results = baseMVA
        if gen is None:
            ppopt = ppoption()   ## use default options
        else:
            ppopt = gen
        if (ppopt['OUT_ALL'] == 0):
            return     ## nothin' to see here, bail out now
        if bus is None:
            fd = stdout         ## print to stdout by default
        else:
            fd = bus
        baseMVA, bus, gen, branch, success, et = \
            results["baseMVA"], results["bus"], results["gen"], \
            results["branch"], results["success"], results["et"]
        if 'f' in results:
            f = results["f"]
        else:
            f = None
    else:
        have_results_struct = 0
        if ppopt is None:
            ppopt = ppoption()   ## use default options
            if fd is None:
                fd = stdout         ## print to stdout by default
        if ppopt['OUT_ALL'] == 0:
            return     ## nothin' to see here, bail out now

    isOPF = f is not None    ## FALSE -> only simple PF data, TRUE -> OPF data

    ## options
    isDC            = ppopt['PF_DC']        ## use DC formulation?
    OUT_ALL         = ppopt['OUT_ALL']
    OUT_ANY         = OUT_ALL == 1     ## set to true if any pretty output is to be generated
    OUT_SYS_SUM     = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_SYS_SUM'])
    OUT_AREA_SUM    = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_AREA_SUM'])
    OUT_BUS         = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BUS'])
    OUT_BRANCH      = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BRANCH'])
    OUT_GEN         = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_GEN'])
    OUT_ANY         = OUT_ANY | ((OUT_ALL == -1) and
                        (OUT_SYS_SUM or OUT_AREA_SUM or OUT_BUS or
                         OUT_BRANCH or OUT_GEN))

    if OUT_ALL == -1:
        OUT_ALL_LIM = ppopt['OUT_ALL_LIM']
    elif OUT_ALL == 1:
        OUT_ALL_LIM = 2
    else:
        OUT_ALL_LIM = 0

    OUT_ANY         = OUT_ANY or (OUT_ALL_LIM >= 1)
    if OUT_ALL_LIM == -1:
        OUT_V_LIM       = ppopt['OUT_V_LIM']
        OUT_LINE_LIM    = ppopt['OUT_LINE_LIM']
        OUT_PG_LIM      = ppopt['OUT_PG_LIM']
        OUT_QG_LIM      = ppopt['OUT_QG_LIM']
    else:
        OUT_V_LIM       = OUT_ALL_LIM
        OUT_LINE_LIM    = OUT_ALL_LIM
        OUT_PG_LIM      = OUT_ALL_LIM
        OUT_QG_LIM      = OUT_ALL_LIM

    OUT_ANY         = OUT_ANY or ((OUT_ALL_LIM == -1) and (OUT_V_LIM or OUT_LINE_LIM or OUT_PG_LIM or OUT_QG_LIM))
    ptol = 1e-4        ## tolerance for displaying shadow prices

    ## create map of external bus numbers to bus indices
    i2e = bus[:, BUS_I].astype(int)
    e2i = zeros(max(i2e) + 1, int)
    e2i[i2e] = arange(bus.shape[0])

    ## sizes of things
    nb = bus.shape[0]      ## number of buses
    nl = branch.shape[0]   ## number of branches
    ng = gen.shape[0]      ## number of generators

    ## zero out some data to make printout consistent for DC case
    if isDC:
        bus[:, r_[QD, BS]]          = zeros((nb, 2))
        gen[:, r_[QG, QMAX, QMIN]]  = zeros((ng, 3))
        branch[:, r_[BR_R, BR_B]]   = zeros((nl, 2))

    ## parameters
    ties = find(bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] !=
                   bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA])
                            ## area inter-ties
    tap = ones(nl)                           ## default tap ratio = 1 for lines
    xfmr = find(branch[:, TAP])           ## indices of transformers
    tap[xfmr] = branch[xfmr, TAP]            ## include transformer tap ratios
    tap = tap * exp(1j * pi / 180 * branch[:, SHIFT]) ## add phase shifters
    nzld = find((bus[:, PD] != 0.0) | (bus[:, QD] != 0.0))
    sorted_areas = sort(bus[:, BUS_AREA])
    ## area numbers
    s_areas = sorted_areas[r_[1, find(diff(sorted_areas)) + 1]]
    nzsh = find((bus[:, GS] != 0.0) | (bus[:, BS] != 0.0))
    allg = find( ~isload(gen) )
    ong  = find( (gen[:, GEN_STATUS] > 0) & ~isload(gen) )
    onld = find( (gen[:, GEN_STATUS] > 0) &  isload(gen) )
    V = bus[:, VM] * exp(-1j * pi / 180 * bus[:, VA])
    out = find(branch[:, BR_STATUS] == 0)        ## out-of-service branches
    nout = len(out)
    if isDC:
        loss = zeros(nl)
    else:
        loss = baseMVA * abs(V[e2i[ branch[:, F_BUS].astype(int) ]] / tap -
                             V[e2i[ branch[:, T_BUS].astype(int) ]])**2 / \
                    (branch[:, BR_R] - 1j * branch[:, BR_X])

    fchg = abs(V[e2i[ branch[:, F_BUS].astype(int) ]] / tap)**2 * branch[:, BR_B] * baseMVA / 2
    tchg = abs(V[e2i[ branch[:, T_BUS].astype(int) ]]      )**2 * branch[:, BR_B] * baseMVA / 2
    loss[out] = zeros(nout)
    fchg[out] = zeros(nout)
    tchg[out] = zeros(nout)

    ##----- print the stuff -----
    if OUT_ANY:
        ## convergence & elapsed time
        if success:
            fd.write('\nConverged in %.2f seconds' % et)
        else:
            fd.write('\nDid not converge (%.2f seconds)\n' % et)

        ## objective function value
        if isOPF:
            fd.write('\nObjective Function Value = %.2f $/hr' % f)

    if OUT_SYS_SUM:
        fd.write('\n================================================================================')
        fd.write('\n|     System Summary                                                           |')
        fd.write('\n================================================================================')
        fd.write('\n\nHow many?                How much?              P (MW)            Q (MVAr)')
        fd.write('\n---------------------    -------------------  -------------  -----------------')
        fd.write('\nBuses         %6d     Total Gen Capacity   %7.1f       %7.1f to %.1f' % (nb, sum(gen[allg, PMAX]), sum(gen[allg, QMIN]), sum(gen[allg, QMAX])))
        fd.write('\nGenerators     %5d     On-line Capacity     %7.1f       %7.1f to %.1f' % (len(allg), sum(gen[ong, PMAX]), sum(gen[ong, QMIN]), sum(gen[ong, QMAX])))
        fd.write('\nCommitted Gens %5d     Generation (actual)  %7.1f           %7.1f' % (len(ong), sum(gen[ong, PG]), sum(gen[ong, QG])))
        fd.write('\nLoads          %5d     Load                 %7.1f           %7.1f' % (len(nzld)+len(onld), sum(bus[nzld, PD])-sum(gen[onld, PG]), sum(bus[nzld, QD])-sum(gen[onld, QG])))
        fd.write('\n  Fixed        %5d       Fixed              %7.1f           %7.1f' % (len(nzld), sum(bus[nzld, PD]), sum(bus[nzld, QD])))
        fd.write('\n  Dispatchable %5d       Dispatchable       %7.1f of %-7.1f%7.1f' % (len(onld), -sum(gen[onld, PG]), -sum(gen[onld, PMIN]), -sum(gen[onld, QG])))
        fd.write('\nShunts         %5d     Shunt (inj)          %7.1f           %7.1f' % (len(nzsh),
            -sum(bus[nzsh, VM]**2 * bus[nzsh, GS]), sum(bus[nzsh, VM]**2 * bus[nzsh, BS]) ))
        fd.write('\nBranches       %5d     Losses (I^2 * Z)     %8.2f          %8.2f' % (nl, sum(loss.real), sum(loss.imag) ))
        fd.write('\nTransformers   %5d     Branch Charging (inj)     -            %7.1f' % (len(xfmr), sum(fchg) + sum(tchg) ))
        fd.write('\nInter-ties     %5d     Total Inter-tie Flow %7.1f           %7.1f' % (len(ties), sum(abs(branch[ties, PF]-branch[ties, PT])) / 2, sum(abs(branch[ties, QF]-branch[ties, QT])) / 2))
        fd.write('\nAreas          %5d' % len(s_areas))
        fd.write('\n')
        fd.write('\n                          Minimum                      Maximum')
        fd.write('\n                 -------------------------  --------------------------------')
        minv = min(bus[:, VM])
        mini = argmin(bus[:, VM])
        maxv = max(bus[:, VM])
        maxi = argmax(bus[:, VM])
        fd.write('\nVoltage Magnitude %7.3f p.u. @ bus %-4d     %7.3f p.u. @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        minv = min(bus[:, VA])
        mini = argmin(bus[:, VA])
        maxv = max(bus[:, VA])
        maxi = argmax(bus[:, VA])
        fd.write('\nVoltage Angle   %8.2f deg   @ bus %-4d   %8.2f deg   @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        if not isDC:
            maxv = max(loss.real)
            maxi = argmax(loss.real)
            fd.write('\nP Losses (I^2*R)             -              %8.2f MW    @ line %d-%d' % (maxv, branch[maxi, F_BUS], branch[maxi, T_BUS]))
            maxv = max(loss.imag)
            maxi = argmax(loss.imag)
            fd.write('\nQ Losses (I^2*X)             -              %8.2f MVAr  @ line %d-%d' % (maxv, branch[maxi, F_BUS], branch[maxi, T_BUS]))
        if isOPF:
            minv = min(bus[:, LAM_P])
            mini = argmin(bus[:, LAM_P])
            maxv = max(bus[:, LAM_P])
            maxi = argmax(bus[:, LAM_P])
            fd.write('\nLambda P        %8.2f $/MWh @ bus %-4d   %8.2f $/MWh @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
            minv = min(bus[:, LAM_Q])
            mini = argmin(bus[:, LAM_Q])
            maxv = max(bus[:, LAM_Q])
            maxi = argmax(bus[:, LAM_Q])
            fd.write('\nLambda Q        %8.2f $/MWh @ bus %-4d   %8.2f $/MWh @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        fd.write('\n')

    if OUT_AREA_SUM:
        fd.write('\n================================================================================')
        fd.write('\n|     Area Summary                                                             |')
        fd.write('\n================================================================================')
        fd.write('\nArea  # of      # of Gens        # of Loads         # of    # of   # of   # of')
        fd.write('\n Num  Buses   Total  Online   Total  Fixed  Disp    Shunt   Brchs  Xfmrs   Ties')
        fd.write('\n----  -----   -----  ------   -----  -----  -----   -----   -----  -----  -----')
        for i in range(len(s_areas)):
            a = s_areas[i]
            ib = find(bus[:, BUS_AREA] == a)
            ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & ~isload(gen))
            igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
            ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & isload(gen))
            inzld = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, PD], bus[:, QD]))
            inzsh = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, GS], bus[:, BS]))
            ibrch = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a))
            in_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] != a))
            out_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] != a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a))
            if not any(xfmr + 1):
                nxfmr = 0
            else:
                nxfmr = len(find((bus[e2i[branch[xfmr, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[xfmr, T_BUS].astype(int)], BUS_AREA] == a)))
            fd.write('\n%3d  %6d   %5d  %5d   %5d  %5d  %5d   %5d   %5d  %5d  %5d' %
                (a, len(ib), len(ig), len(igon), \
                len(inzld)+len(ildon), len(inzld), len(ildon), \
                len(inzsh), len(ibrch), nxfmr, len(in_tie)+len(out_tie)))

        fd.write('\n----  -----   -----  ------   -----  -----  -----   -----   -----  -----  -----')
        fd.write('\nTot: %6d   %5d  %5d   %5d  %5d  %5d   %5d   %5d  %5d  %5d' %
            (nb, len(allg), len(ong), len(nzld)+len(onld),
            len(nzld), len(onld), len(nzsh), nl, len(xfmr), len(ties)))
        fd.write('\n')
        fd.write('\nArea      Total Gen Capacity           On-line Gen Capacity         Generation')
        fd.write('\n Num     MW           MVAr            MW           MVAr             MW    MVAr')
        fd.write('\n----   ------  ------------------   ------  ------------------    ------  ------')
        for i in range(len(s_areas)):
            a = s_areas[i]
            ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & ~isload(gen))
            igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
            fd.write('\n%3d   %7.1f  %7.1f to %-7.1f  %7.1f  %7.1f to %-7.1f   %7.1f %7.1f' %
                (a, sum(gen[ig, PMAX]), sum(gen[ig, QMIN]), sum(gen[ig, QMAX]),
                sum(gen[igon, PMAX]), sum(gen[igon, QMIN]), sum(gen[igon, QMAX]),
                sum(gen[igon, PG]), sum(gen[igon, QG]) ))

        fd.write('\n----   ------  ------------------   ------  ------------------    ------  ------')
        fd.write('\nTot:  %7.1f  %7.1f to %-7.1f  %7.1f  %7.1f to %-7.1f   %7.1f %7.1f' %
                (sum(gen[allg, PMAX]), sum(gen[allg, QMIN]), sum(gen[allg, QMAX]),
                sum(gen[ong, PMAX]), sum(gen[ong, QMIN]), sum(gen[ong, QMAX]),
                sum(gen[ong, PG]), sum(gen[ong, QG]) ))
        fd.write('\n')
        fd.write('\nArea    Disp Load Cap       Disp Load         Fixed Load        Total Load')
        fd.write('\n Num      MW     MVAr       MW     MVAr       MW     MVAr       MW     MVAr')
        fd.write('\n----    ------  ------    ------  ------    ------  ------    ------  ------')
        Qlim = (gen[:, QMIN] == 0) * gen[:, QMAX] + (gen[:, QMAX] == 0) * gen[:, QMIN]
        for i in range(len(s_areas)):
            a = s_areas[i]
            ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & isload(gen))
            inzld = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, PD], bus[:, QD]))
            fd.write('\n%3d    %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f' %
                (a, -sum(gen[ildon, PMIN]),
                -sum(Qlim[ildon]),
                -sum(gen[ildon, PG]), -sum(gen[ildon, QG]),
                sum(bus[inzld, PD]), sum(bus[inzld, QD]),
                -sum(gen[ildon, PG]) + sum(bus[inzld, PD]),
                -sum(gen[ildon, QG]) + sum(bus[inzld, QD]) ))

        fd.write('\n----    ------  ------    ------  ------    ------  ------    ------  ------')
        fd.write('\nTot:   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f' %
                (-sum(gen[onld, PMIN]),
                -sum(Qlim[onld]),
                -sum(gen[onld, PG]), -sum(gen[onld, QG]),
                sum(bus[nzld, PD]), sum(bus[nzld, QD]),
                -sum(gen[onld, PG]) + sum(bus[nzld, PD]),
                -sum(gen[onld, QG]) + sum(bus[nzld, QD])) )
        fd.write('\n')
        fd.write('\nArea      Shunt Inj        Branch      Series Losses      Net Export')
        fd.write('\n Num      MW     MVAr     Charging      MW     MVAr       MW     MVAr')
        fd.write('\n----    ------  ------    --------    ------  ------    ------  ------')
        for i in range(len(s_areas)):
            a = s_areas[i]
            inzsh   = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, GS], bus[:, BS]))
            ibrch   = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a) & branch[:, BR_STATUS].astype(bool))
            in_tie  = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] != a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a) & branch[:, BR_STATUS].astype(bool))
            out_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] != a) & branch[:, BR_STATUS].astype(bool))
            fd.write('\n%3d    %7.1f %7.1f    %7.1f    %7.2f %7.2f   %7.1f %7.1f' %
                (a, -sum(bus[inzsh, VM]**2 * bus[inzsh, GS]),
                 sum(bus[inzsh, VM]**2 * bus[inzsh, BS]),
                 sum(fchg[ibrch]) + sum(tchg[ibrch]) + sum(fchg[out_tie]) + sum(tchg[in_tie]),
                 sum(real(loss[ibrch])) + sum(real(loss[r_[in_tie, out_tie]])) / 2,
                 sum(imag(loss[ibrch])) + sum(imag(loss[r_[in_tie, out_tie]])) / 2,
                 sum(branch[in_tie, PT])+sum(branch[out_tie, PF]) - sum(real(loss[r_[in_tie, out_tie]])) / 2,
                 sum(branch[in_tie, QT])+sum(branch[out_tie, QF]) - sum(imag(loss[r_[in_tie, out_tie]])) / 2  ))

        fd.write('\n----    ------  ------    --------    ------  ------    ------  ------')
        fd.write('\nTot:   %7.1f %7.1f    %7.1f    %7.2f %7.2f       -       -' %
            (-sum(bus[nzsh, VM]**2 * bus[nzsh, GS]),
             sum(bus[nzsh, VM]**2 * bus[nzsh, BS]),
             sum(fchg) + sum(tchg), sum(real(loss)), sum(imag(loss)) ))
        fd.write('\n')

    ## generator data
    if OUT_GEN:
        if isOPF:
            genlamP = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_P]
            genlamQ = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_Q]

        fd.write('\n================================================================================')
        fd.write('\n|     Generator Data                                                           |')
        fd.write('\n================================================================================')
        fd.write('\n Gen   Bus   Status     Pg        Qg   ')
        if isOPF: fd.write('   Lambda ($/MVA-hr)')
        fd.write('\n  #     #              (MW)     (MVAr) ')
        if isOPF: fd.write('     P         Q    ')
        fd.write('\n----  -----  ------  --------  --------')
        if isOPF: fd.write('  --------  --------')
        for k in range(len(ong)):
            i = ong[k]
            fd.write('\n%3d %6d     %2d ' % (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
            if (gen[i, GEN_STATUS] > 0) & logical_or(gen[i, PG], gen[i, QG]):
                fd.write('%10.2f%10.2f' % (gen[i, PG], gen[i, QG]))
            else:
                fd.write('       -         -  ')
            if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))

        fd.write('\n                     --------  --------')
        fd.write('\n            Total: %9.2f%10.2f' % (sum(gen[ong, PG]), sum(gen[ong, QG])))
        fd.write('\n')
        if any(onld + 1):
            fd.write('\n================================================================================')
            fd.write('\n|     Dispatchable Load Data                                                   |')
            fd.write('\n================================================================================')
            fd.write('\n Gen   Bus   Status     Pd        Qd   ')
            if isOPF: fd.write('   Lambda ($/MVA-hr)')
            fd.write('\n  #     #              (MW)     (MVAr) ')
            if isOPF: fd.write('     P         Q    ')
            fd.write('\n----  -----  ------  --------  --------')
            if isOPF: fd.write('  --------  --------')
            for k in range(len(onld)):
                i = onld[k]
                fd.write('\n%3d %6d     %2d ' % (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
                if (gen[i, GEN_STATUS] > 0) & logical_or(gen[i, PG], gen[i, QG]):
                    fd.write('%10.2f%10.2f' % (-gen[i, PG], -gen[i, QG]))
                else:
                    fd.write('       -         -  ')

                if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))
            fd.write('\n                     --------  --------')
            fd.write('\n            Total: %9.2f%10.2f' % (-sum(gen[onld, PG]), -sum(gen[onld, QG])))
            fd.write('\n')

    ## bus data
    if OUT_BUS:
        fd.write('\n================================================================================')
        fd.write('\n|     Bus Data                                                                 |')
        fd.write('\n================================================================================')
        fd.write('\n Bus      Voltage          Generation             Load        ')
        if isOPF: fd.write('  Lambda($/MVA-hr)')
        fd.write('\n  #   Mag(pu) Ang(deg)   P (MW)   Q (MVAr)   P (MW)   Q (MVAr)')
        if isOPF: fd.write('     P        Q   ')
        fd.write('\n----- ------- --------  --------  --------  --------  --------')
        if isOPF: fd.write('  -------  -------')
        for i in range(nb):
            fd.write('\n%5d%7.3f%9.3f' % tuple(bus[i, [BUS_I, VM, VA]]))
            if bus[i, BUS_TYPE] == REF:
                fd.write('*')
            else:
                fd.write(' ')
            g  = find((gen[:, GEN_STATUS] > 0) & (gen[:, GEN_BUS] == bus[i, BUS_I]) &
                        ~isload(gen))
            ld = find((gen[:, GEN_STATUS] > 0) & (gen[:, GEN_BUS] == bus[i, BUS_I]) &
                        isload(gen))
            if any(g + 1):
                fd.write('%9.2f%10.2f' % (sum(gen[g, PG]), sum(gen[g, QG])))
            else:
                fd.write('      -         -  ')

            if logical_or(bus[i, PD], bus[i, QD]) | any(ld + 1):
                if any(ld + 1):
                    fd.write('%10.2f*%9.2f*' % (bus[i, PD] - sum(gen[ld, PG]),
                                                bus[i, QD] - sum(gen[ld, QG])))
                else:
                    fd.write('%10.2f%10.2f ' % tuple(bus[i, [PD, QD]]))
            else:
                fd.write('       -         -   ')
            if isOPF:
                fd.write('%9.3f' % bus[i, LAM_P])
                if abs(bus[i, LAM_Q]) > ptol:
                    fd.write('%8.3f' % bus[i, LAM_Q])
                else:
                    fd.write('     -')
        fd.write('\n                        --------  --------  --------  --------')
        fd.write('\n               Total: %9.2f %9.2f %9.2f %9.2f' %
            (sum(gen[ong, PG]), sum(gen[ong, QG]),
             sum(bus[nzld, PD]) - sum(gen[onld, PG]),
             sum(bus[nzld, QD]) - sum(gen[onld, QG])))
        fd.write('\n')

    ## branch data
    if OUT_BRANCH:
        fd.write('\n================================================================================')
        fd.write('\n|     Branch Data                                                              |')
        fd.write('\n================================================================================')
        fd.write('\nBrnch   From   To    From Bus Injection   To Bus Injection     Loss (I^2 * Z)  ')
        fd.write('\n  #     Bus    Bus    P (MW)   Q (MVAr)   P (MW)   Q (MVAr)   P (MW)   Q (MVAr)')
        fd.write('\n-----  -----  -----  --------  --------  --------  --------  --------  --------')
        for i in range(nl):
            fd.write('\n%4d%7d%7d%10.2f%10.2f%10.2f%10.2f%10.3f%10.2f' %
                (i, branch[i, F_BUS], branch[i, T_BUS],
                     branch[i, PF], branch[i, QF], branch[i, PT], branch[i, QT],
                     loss[i].real, loss[i].imag))
        fd.write('\n                                                             --------  --------')
        fd.write('\n                                                    Total:%10.3f%10.2f' %
                (sum(real(loss)), sum(imag(loss))))
        fd.write('\n')

    ##-----  constraint data  -----
    if isOPF:
        ctol = ppopt['OPF_VIOLATION']   ## constraint violation tolerance
        ## voltage constraints
        if (not isDC) & (OUT_V_LIM == 2 | (OUT_V_LIM == 1 &
                             (any(bus[:, VM] < bus[:, VMIN] + ctol) |
                              any(bus[:, VM] > bus[:, VMAX] - ctol) |
                              any(bus[:, MU_VMIN] > ptol) |
                              any(bus[:, MU_VMAX] > ptol)))):
            fd.write('\n================================================================================')
            fd.write('\n|     Voltage Constraints                                                      |')
            fd.write('\n================================================================================')
            fd.write('\nBus #  Vmin mu    Vmin    |V|   Vmax    Vmax mu')
            fd.write('\n-----  --------   -----  -----  -----   --------')
            for i in range(nb):
                if (OUT_V_LIM == 2) | (OUT_V_LIM == 1 &
                             ((bus[i, VM] < bus[i, VMIN] + ctol) |
                              (bus[i, VM] > bus[i, VMAX] - ctol) |
                              (bus[i, MU_VMIN] > ptol) |
                              (bus[i, MU_VMAX] > ptol))):
                    fd.write('\n%5d' % bus[i, BUS_I])
                    if ((bus[i, VM] < bus[i, VMIN] + ctol) |
                            (bus[i, MU_VMIN] > ptol)):
                        fd.write('%10.3f' % bus[i, MU_VMIN])
                    else:
                        fd.write('      -   ')

                    fd.write('%8.3f%7.3f%7.3f' % tuple(bus[i, [VMIN, VM, VMAX]]))
                    if (bus[i, VM] > bus[i, VMAX] - ctol) | (bus[i, MU_VMAX] > ptol):
                        fd.write('%10.3f' % bus[i, MU_VMAX])
                    else:
                        fd.write('      -    ')
            fd.write('\n')

        ## generator P constraints
        if (OUT_PG_LIM == 2) | \
                ((OUT_PG_LIM == 1) & (any(gen[ong, PG] < gen[ong, PMIN] + ctol) |
                                      any(gen[ong, PG] > gen[ong, PMAX] - ctol) |
                                      any(gen[ong, MU_PMIN] > ptol) |
                                      any(gen[ong, MU_PMAX] > ptol))) | \
                ((not isDC) & ((OUT_QG_LIM == 2) |
                ((OUT_QG_LIM == 1) & (any(gen[ong, QG] < gen[ong, QMIN] + ctol) |
                                      any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
                                      any(gen[ong, MU_QMIN] > ptol) |
                                      any(gen[ong, MU_QMAX] > ptol))))):
            fd.write('\n================================================================================')
            fd.write('\n|     Generation Constraints                                                   |')
            fd.write('\n================================================================================')

        if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                                 (any(gen[ong, PG] < gen[ong, PMIN] + ctol) |
                                  any(gen[ong, PG] > gen[ong, PMAX] - ctol) |
                                  any(gen[ong, MU_PMIN] > ptol) |
                                  any(gen[ong, MU_PMAX] > ptol))):
            fd.write('\n Gen   Bus                Active Power Limits')
            fd.write('\n  #     #    Pmin mu    Pmin       Pg       Pmax    Pmax mu')
            fd.write('\n----  -----  -------  --------  --------  --------  -------')
            for k in range(len(ong)):
                i = ong[k]
                if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                            ((gen[i, PG] < gen[i, PMIN] + ctol) |
                             (gen[i, PG] > gen[i, PMAX] - ctol) |
                             (gen[i, MU_PMIN] > ptol) | (gen[i, MU_PMAX] > ptol))):
                    fd.write('\n%4d%6d ' % (i, gen[i, GEN_BUS]))
                    if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] > ptol):
                        fd.write('%8.3f' % gen[i, MU_PMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, PG]:
                        fd.write('%10.2f%10.2f%10.2f' % tuple(gen[i, [PMIN, PG, PMAX]]))
                    else:
                        fd.write('%10.2f       -  %10.2f' % tuple(gen[i, [PMIN, PMAX]]))
                    if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] > ptol):
                        fd.write('%9.3f' % gen[i, MU_PMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## generator Q constraints
        if (not isDC) & ((OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                                 (any(gen[ong, QG] < gen[ong, QMIN] + ctol) |
                                  any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
                                  any(gen[ong, MU_QMIN] > ptol) |
                                  any(gen[ong, MU_QMAX] > ptol)))):
            fd.write('\nGen  Bus              Reactive Power Limits')
            fd.write('\n #    #   Qmin mu    Qmin       Qg       Qmax    Qmax mu')
            fd.write('\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(ong)):
                i = ong[k]
                if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                            ((gen[i, QG] < gen[i, QMIN] + ctol) |
                             (gen[i, QG] > gen[i, QMAX] - ctol) |
                             (gen[i, MU_QMIN] > ptol) |
                             (gen[i, MU_QMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
                    if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] > ptol):
                        fd.write('%8.3f' % gen[i, MU_QMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, QG]:
                        fd.write('%10.2f%10.2f%10.2f' % tuple(gen[i, [QMIN, QG, QMAX]]))
                    else:
                        fd.write('%10.2f       -  %10.2f' % tuple(gen[i, [QMIN, QMAX]]))

                    if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] > ptol):
                        fd.write('%9.3f' % gen[i, MU_QMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## dispatchable load P constraints
        if (OUT_PG_LIM == 2) | (OUT_QG_LIM == 2) | \
                ((OUT_PG_LIM == 1) & (any(gen[onld, PG] < gen[onld, PMIN] + ctol) |
                                      any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
                                      any(gen[onld, MU_PMIN] > ptol) |
                                      any(gen[onld, MU_PMAX] > ptol))) | \
                ((OUT_QG_LIM == 1) & (any(gen[onld, QG] < gen[onld, QMIN] + ctol) |
                                      any(gen[onld, QG] > gen[onld, QMAX] - ctol) |
                                      any(gen[onld, MU_QMIN] > ptol) |
                                      any(gen[onld, MU_QMAX] > ptol))):
            fd.write('\n================================================================================')
            fd.write('\n|     Dispatchable Load Constraints                                            |')
            fd.write('\n================================================================================')
        if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                                 (any(gen[onld, PG] < gen[onld, PMIN] + ctol) |
                                  any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
                                  any(gen[onld, MU_PMIN] > ptol) |
                                  any(gen[onld, MU_PMAX] > ptol))):
            fd.write('\nGen  Bus               Active Power Limits')
            fd.write('\n #    #   Pmin mu    Pmin       Pg       Pmax    Pmax mu')
            fd.write('\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(onld)):
                i = onld[k]
                if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                            ((gen[i, PG] < gen[i, PMIN] + ctol) |
                             (gen[i, PG] > gen[i, PMAX] - ctol) |
                             (gen[i, MU_PMIN] > ptol) |
                             (gen[i, MU_PMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
                    if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] > ptol):
                        fd.write('%8.3f' % gen[i, MU_PMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, PG]:
                        fd.write('%10.2f%10.2f%10.2f' % gen[i, [PMIN, PG, PMAX]])
                    else:
                        fd.write('%10.2f       -  %10.2f' % gen[i, [PMIN, PMAX]])

                    if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] > ptol):
                        fd.write('%9.3f' % gen[i, MU_PMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## dispatchable load Q constraints
        if (not isDC) & ((OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                                 (any(gen[onld, QG] < gen[onld, QMIN] + ctol) |
                                  any(gen[onld, QG] > gen[onld, QMAX] - ctol) |
                                  any(gen[onld, MU_QMIN] > ptol) |
                                  any(gen[onld, MU_QMAX] > ptol)))):
            fd.write('\nGen  Bus              Reactive Power Limits')
            fd.write('\n #    #   Qmin mu    Qmin       Qg       Qmax    Qmax mu')
            fd.write('\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(onld)):
                i = onld[k]
                if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                            ((gen[i, QG] < gen[i, QMIN] + ctol) |
                             (gen[i, QG] > gen[i, QMAX] - ctol) |
                             (gen[i, MU_QMIN] > ptol) |
                             (gen[i, MU_QMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen(i, GEN_BUS)))
                    if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] > ptol):
                        fd.write('%8.3f' % gen[i, MU_QMIN])
                    else:
                        fd.write('     -  ')

                    if gen[i, QG]:
                        fd.write('%10.2f%10.2f%10.2f' % gen[i, [QMIN, QG, QMAX]])
                    else:
                        fd.write('%10.2f       -  %10.2f' % gen[i, [QMIN, QMAX]])

                    if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] > ptol):
                        fd.write('%9.3f' % gen[i, MU_QMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## line flow constraints
        if (ppopt['OPF_FLOW_LIM'] == 1) | isDC:  ## P limit
            Ff = branch[:, PF]
            Ft = branch[:, PT]
            strg = '\n  #     Bus    Pf  mu     Pf      |Pmax|      Pt      Pt  mu   Bus'
        elif ppopt['OPF_FLOW_LIM'] == 2:   ## |I| limit
            Ff = abs( (branch[:, PF] + 1j * branch[:, QF]) / V[e2i[branch[:, F_BUS].astype(int)]] )
            Ft = abs( (branch[:, PT] + 1j * branch[:, QT]) / V[e2i[branch[:, T_BUS].astype(int)]] )
            strg = '\n  #     Bus   |If| mu    |If|     |Imax|     |It|    |It| mu   Bus'
        else:                ## |S| limit
            Ff = abs(branch[:, PF] + 1j * branch[:, QF])
            Ft = abs(branch[:, PT] + 1j * branch[:, QT])
            strg = '\n  #     Bus   |Sf| mu    |Sf|     |Smax|     |St|    |St| mu   Bus'

        if (OUT_LINE_LIM == 2) | ((OUT_LINE_LIM == 1) &
                            (any((branch[:, RATE_A] != 0) & (abs(Ff) > branch[:, RATE_A] - ctol)) |
                             any((branch[:, RATE_A] != 0) & (abs(Ft) > branch[:, RATE_A] - ctol)) |
                             any(branch[:, MU_SF] > ptol) |
                             any(branch[:, MU_ST] > ptol))):
            fd.write('\n================================================================================')
            fd.write('\n|     Branch Flow Constraints                                                  |')
            fd.write('\n================================================================================')
            fd.write('\nBrnch   From     "From" End        Limit       "To" End        To')
            fd.write(strg)
            fd.write('\n-----  -----  -------  --------  --------  --------  -------  -----')
            for i in range(nl):
                if (OUT_LINE_LIM == 2) | ((OUT_LINE_LIM == 1) &
                       (((branch[i, RATE_A] != 0) & (abs(Ff[i]) > branch[i, RATE_A] - ctol)) |
                        ((branch[i, RATE_A] != 0) & (abs(Ft[i]) > branch[i, RATE_A] - ctol)) |
                        (branch[i, MU_SF] > ptol) | (branch[i, MU_ST] > ptol))):
                    fd.write('\n%4d%7d' % (i, branch[i, F_BUS]))
                    if (Ff[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_SF] > ptol):
                        fd.write('%10.3f' % branch[i, MU_SF])
                    else:
                        fd.write('      -   ')

                    fd.write('%9.2f%10.2f%10.2f' %
                        (Ff[i], branch[i, RATE_A], Ft[i]))
                    if (Ft[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_ST] > ptol):
                        fd.write('%10.3f' % branch[i, MU_ST])
                    else:
                        fd.write('      -   ')
                    fd.write('%6d' % branch[i, T_BUS])
            fd.write('\n')

    ## execute userfcn callbacks for 'printpf' stage
    if have_results_struct and 'userfcn' in results:
        if not isOPF:  ## turn off option for all constraints if it isn't an OPF
            ppopt = ppoption(ppopt, 'OUT_ALL_LIM', 0)
        run_userfcn(results["userfcn"], 'printpf', results, fd, ppopt)
コード例 #29
0
ファイル: runopf.py プロジェクト: redw0lf/PYPOWER
    ppopt = ppoption(ppopt)

    ##-----  run the optimal power flow  -----
    r = opf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except IOError as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(r, fd, ppopt)
                fd.close()

    else:
        printpf(r, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, r)

    return r


if __name__ == '__main__':
    ppopt = ppoption(OPF_ALG=580)
    runopf(None, ppopt)
コード例 #30
0
    def run(self,
            Testsys=case24_ieee_rts(),
            BETAlimit=0.0017,
            ITER_max=10000,
            SIMUNIT=1000):
        Nb = Testsys["bus"].shape[0]  # Load test system,Nb为节点数,Ng为发电机组数,Nl为馈线数
        Ng = Testsys["gen"].shape[0]
        Nl = Testsys["branch"].shape[0]

        # Set initial value
        iter = 0
        betavalue = float('inf')  # The stopping criteria停止迭代的标准
        row_index = 0
        # Build matrices that have fix dimension to avoid changing size in each loop
        eqstatus_total = np.zeros(
            (ITER_max, Ng + Nl + 3))  # 建一个100000*(33+38+3)的矩阵
        beta_table = np.zeros((1, ITER_max // SIMUNIT))  # "//"除法得到的才是整数
        edns_table = np.zeros((1, ITER_max // SIMUNIT))  # 存放评价指标,大小为1*1000
        lole_table = np.zeros((1, ITER_max // SIMUNIT))
        plc_table = np.zeros((1, ITER_max // SIMUNIT))
        genbus = np.nonzero((Testsys["bus"][:, PD]))[
            0]  # 第三列(python中坐标是2)是节点的有功功率,表示节点有有功负荷,此处返回该列非零元素的索引,共有17个元素非零
        sizegenbus = genbus.shape[0]  # 有负荷的节点数量赋值给sizegenbus
        Testsys["load"] = sum(Testsys["bus"][:, PD])  # 系统需要的总有功功率
        Testsys["gencost"] = np.tile([2, 0, 0, 3, 0, 0, 0],
                                     (Ng, 1))  # np.tile建立重复矩阵块(设置机组费用)
        # treat all load as negtive generator and set their parameters, then add these vitual generators to real gens
        # 将所有载荷视为负发电机,并设置其参数,然后将这些发电机加到实际的发电机中
        loadcost = np.tile([2, 0, 0, 3, 0, 1, 0],
                           (sizegenbus, 1))  # np.tile建立重复矩阵块(负荷的“机组费用”)
        Testsys["gencost"] = np.append(Testsys["gencost"], loadcost, axis=0)
        Index = copy.deepcopy(Testsys["gen"][0:sizegenbus, :])  # 将前17台机组的数据取出
        Index[:, 0:10] = np.hstack(
            (Testsys["bus"][genbus, 0].reshape(-1, 1),
             -Testsys["bus"][genbus, 2].reshape(-1, 1),
             -Testsys["bus"][genbus, 3].reshape(-1, 1),
             np.zeros(
                 (sizegenbus, 1)), -Testsys["bus"][genbus, 3].reshape(-1, 1),
             np.zeros((sizegenbus, 1)), Testsys["baseMVA"] * np.ones(
                 (sizegenbus, 1)), np.ones((sizegenbus, 1)),
             np.zeros(
                 (sizegenbus, 1)), -Testsys["bus"][genbus, 2].reshape(-1, 1)))
        #  负荷参数代替取出的机组数据,将负荷套入机组模型,上面矩阵取数注意与matlab相比坐标要减一
        Testsys["gen"] = np.append(Testsys["gen"], Index, axis=0)
        del Index
        Testsys["bus"][genbus, 2:4] = 0  # 将原来节点中的第3、4列(有功、无功)负荷设为零
        totalprob = failprob()  # 引用前面定义的函数
        ppopt = ppoption(
            PF_DC=1, VERBOSE=0, OUT_ALL=0, OPF_ALG_DC=200, OPF_FLOW_LIM=1
        )  # 可以通过ppoption()采用默认变量来看里面需要什么样的输入,这个按照matlab来输入没问题吧?
        result = runopf(casedata=Testsys, ppopt=ppopt)
        while (betavalue > BETAlimit) & (iter < ITER_max):
            eqstatus_indi = mc_sampling(
                totalprob, SIMUNIT, Ng,
                Nl)  # eqstatus为元件的状态矩阵,为1表示元件故障,为0表示原件正常
            eqstatus_indi = np.hstack(
                (eqstatus_indi, np.ones((eqstatus_indi.shape[0], 1)),
                 np.zeros((eqstatus_indi.shape[0], 2))))
            # 在eqstatus_indi矩阵中加入三列,第一列代表状态重复次数,第二列记载切负荷量大小(没有切负荷则为零),第三列记载是否为容量不足
            eqstatus_indi, ia1 = np.unique(eqstatus_indi,
                                           axis=0,
                                           return_inverse=True)  # 找出抽样中的相同结果
            for i in range(eqstatus_indi.shape[0]):
                eqstatus_indi[i,
                              Ng + Nl] = sum(ia1 == i)  # 将重复记录次数在第Ng + Nl + 1
            if iter:
                x = 0
                y = eqstatus_indi.shape[0]
                for i in range(y):
                    indi_x = eqstatus_indi[x, 0:Ng + Nl]
                    for j in range(row_index):
                        if (indi_x == eqstatus_total[j, 0:Ng + Nl]).all():
                            eqstatus_total[j, Ng + Nl] = eqstatus_total[
                                j, Ng + Nl] + eqstatus_indi[
                                    x,
                                    Ng + Nl]  # 遇见相同的,就在eqstatus_total的计数中累加次数
                            eqstatus_indi = np.delete(eqstatus_indi, x, axis=0)
                            x = x - 1
                            break
                    x = x + 1
                parfortemp = np.zeros((eqstatus_indi.shape[0], 2))
                para = [0] * eqstatus_indi.shape[0]
                n_sample = [0] * eqstatus_indi.shape[0]
                for i in range(eqstatus_indi.shape[0]):
                    para[i] = [0] * 5
                    para[i][0] = eqstatus_indi[i, 0:Ng + Nl]
                    para[i][1] = Testsys
                    para[i][2] = ppopt
                    para[i][3] = Ng
                    para[i][4] = Nl
                with Pool(self.n_processors) as p:
                    load_shedding = list(p.map(mc_simulation, para))
                parfortemp[:, 0] = np.asarray(load_shedding)
                parfortemp[:, 1] = (parfortemp[:, 0]) != 0
                eqstatus_indi[:, Ng + Nl + 1:Ng + Nl + 3] = parfortemp
                eqstatus_total[row_index:row_index +
                               eqstatus_indi.shape[0], :] = eqstatus_indi
                row_index = row_index + eqstatus_indi.shape[0]
            else:
                parfortemp = np.zeros((eqstatus_indi.shape[0], 2))
                para = [0] * eqstatus_indi.shape[0]
                c = [0] * eqstatus_indi.shape[0]
                for i in range(eqstatus_indi.shape[0]):
                    para[i] = [0] * 5
                    para[i][0] = eqstatus_indi[i, 0:Ng + Nl]
                    para[i][1] = Testsys
                    para[i][2] = ppopt
                    para[i][3] = Ng
                    para[i][4] = Nl
                with Pool(self.n_processors) as p:
                    load_shedding = list(p.map(mc_simulation, para))  # 计算负荷短缺值
                parfortemp[:, 0] = np.asarray(load_shedding)
                parfortemp[:, 1] = (parfortemp[:, 0]) != 0  # 记录是否负荷短缺
                eqstatus_indi[:, Ng + Nl + 1:Ng + Nl + 3] = parfortemp
                eqstatus_total[row_index:row_index +
                               eqstatus_indi.shape[0], :] = eqstatus_indi
                row_index = row_index + eqstatus_indi.shape[0]
            ## Update index
            edns = sum(
                eqstatus_total[0:row_index, Ng + Nl] *
                eqstatus_total[0:row_index, Ng + Nl + 1]) / (iter + SIMUNIT)
            lole = sum(eqstatus_total[0:row_index, Ng + Nl] *
                       eqstatus_total[0:row_index, Ng + Nl + 2]) / (
                           iter + SIMUNIT) * 8760
            plc = sum(
                eqstatus_total[0:row_index, Ng + Nl] *
                eqstatus_total[0:row_index, Ng + Nl + 2]) / (iter + SIMUNIT)
            betavalue = (sum(eqstatus_total[0:row_index, Ng + Nl] *
                             (eqstatus_total[0:row_index, Ng + Nl + 1] - edns)
                             **2))**0.5 / (iter + SIMUNIT) / edns

            beta_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = betavalue
            edns_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = edns
            lole_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = lole
            plc_table[0, ((iter + SIMUNIT) // SIMUNIT) - 1] = plc
            iter = iter + SIMUNIT
        return edns
コード例 #31
0
def t_opf_userfcns(quiet=False):
    """Tests for userfcn callbacks (reserves/iflims) w/OPF.

    Includes high-level tests of reserves and iflims implementations.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    t_begin(38, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case30_userfcns')
    verbose = 0#not quiet

    ppopt = ppoption(OPF_VIOLATION=1e-6, PDIPM_GRADTOL=1e-8,
                     PDIPM_COMPTOL=1e-8, PDIPM_COSTTOL=1e-9)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=verbose,
                     OPF_ALG=560, OPF_ALG_DC=200)
    #ppopt = ppoption(ppopt, OUT_ALL=-1, VERBOSE=2, OUT_GEN=1)

    ## run the OPF with fixed reserves
    t = 'fixed reserves : '
    ppc = loadcase(casefile)
    ppc = toggle_reserves(ppc, 'on')
    r = runopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['reserves']['R'], [25, 15, 0, 0, 19.3906, 0.6094], 4, [t, 'reserves.R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 5.5, 5.5], 4, [t, 'reserves.prc'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0.5, 0], 4, [t, 'reserves.mu.Pmax'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 4, [t, 'reserves.mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0], 4, [t, 'reserves.mu.u'])
    t_ok('P' not in r['if'], [t, 'no iflims'])
    t_is(r['reserves']['totalcost'], 177.8047, 4, [t, 'totalcost'])

    t = 'toggle_reserves(ppc, \'off\') : ';
    ppc = toggle_reserves(ppc, 'off')
    r = runopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_ok('R' not in r['reserves'], [t, 'no reserves'])
    t_ok('P' not in r['if'], [t, 'no iflims'])

    t = 'interface flow lims (DC) : '
    ppc = loadcase(casefile)
    ppc = toggle_iflims(ppc, 'on')
    r = rundcopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['if']['P'], [-15, 20], 4, [t, 'if.P'])
    t_is(r['if']['mu']['l'], [4.8427, 0], 4, [t, 'if.mu.l'])
    t_is(r['if']['mu']['u'], [0, 13.2573], 4, [t, 'if.mu.u'])
    t_is(r['branch'][13, PF], 8.244, 3, [t, 'flow in branch 14'])
    t_ok('R' not in r['reserves'], [t, 'no reserves'])

    t = 'reserves + interface flow lims (DC) : '
    ppc = loadcase(casefile)
    ppc = toggle_reserves(ppc, 'on')
    ppc = toggle_iflims(ppc, 'on')
    r = rundcopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['if']['P'], [-15, 20], 4, [t, 'if.P'])
    t_is(r['if']['mu']['l'], [4.8427, 0], 4, [t, 'if.mu.l'])
    t_is(r['if']['mu']['u'], [0, 38.2573], 4, [t, 'if.mu.u'])
    t_is(r['reserves']['R'], [25, 15, 0, 0, 16.9, 3.1], 4, [t, 'reserves.R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 5.5, 5.5], 4, [t, 'reserves.prc'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0.5, 0], 4, [t, 'reserves.mu.Pmax'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 4, [t, 'reserves.mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0], 4, [t, 'reserves.mu.u'])
    t_is(r['reserves']['totalcost'], 179.05, 4, [t, 'totalcost'])

    t = 'interface flow lims (AC) : '
    ppc = toggle_reserves(ppc, 'off')
    r = runopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['if']['P'], [-9.101, 21.432], 3, [t, 'if.P'])
    t_is(r['if']['mu']['l'], [0, 0], 4, [t, 'if.mu.l'])
    t_is(r['if']['mu']['u'], [0, 10.198], 3, [t, 'if.mu.u'])
    t_ok('R' not in r['reserves'], [t, 'no reserves'])

    t = 'interface flow lims (line out) : '
    ppc = loadcase(casefile)
    ppc = toggle_iflims(ppc, 'on')
    ppc['branch'][11, BR_STATUS] = 0      ## take out line 6-10
    r = rundcopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['if']['P'], [-15, 20], 4, [t, 'if.P'])
    t_is(r['if']['mu']['l'], [4.8427, 0], 4, [t, 'if.mu.l'])
    t_is(r['if']['mu']['u'], [0, 13.2573], 4, [t, 'if.mu.u'])
    t_is(r['branch'][13, PF], 10.814, 3, [t, 'flow in branch 14'])
    t_ok('R' not in r['reserves'], [t, 'no reserves'])

    # r['reserves']['R']
    # r['reserves']['prc']
    # r['reserves']['mu.Pmax']
    # r['reserves']['mu']['l']
    # r['reserves']['mu']['u']
    # r['reserves']['totalcost']
    #
    # r['if']['P']
    # r['if']['mu']['l']
    # r['if']['mu']['u']

    t_end()
コード例 #32
0
ファイル: runopf.py プロジェクト: Anastien/PYPOWER
    ppopt = ppoption(ppopt)

    ##-----  run the optimal power flow  -----
    r = opf(casedata, ppopt)

    ##-----  output results  -----
    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except IOError as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(r, fd, ppopt)
                fd.close()

    else:
        printpf(r, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, r)

    return r


if __name__ == '__main__':
    ppopt = ppoption(OPF_ALG=580)
    runopf(None, ppopt)
コード例 #33
0
ファイル: newtonpf.py プロジェクト: charlie0389/PYPOWER
def newtonpf(Ybus, Sbus, V0, ref, pv, pq, ppopt=None):
    """Solves the power flow using a full Newton's method.

    Solves for bus voltages given the full system admittance matrix (for
    all buses), the complex bus power injection vector (for all buses),
    the initial vector of complex bus voltages, and column vectors with
    the lists of bus indices for the swing bus, PV buses, and PQ buses,
    respectively. The bus voltage vector contains the set point for
    generator (including ref bus) buses, and the reference angle of the
    swing bus, as well as an initial guess for remaining magnitudes and
    angles. C{ppopt} is a PYPOWER options vector which can be used to
    set the termination tolerance, maximum number of iterations, and
    output options (see L{ppoption} for details). Uses default options if
    this parameter is not given. Returns the final complex voltages, a
    flag which indicates whether it converged or not, and the number of
    iterations performed.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ## default arguments
    if ppopt is None:
        ppopt = ppoption()

    ## options
    tol     = ppopt['PF_TOL']
    max_it  = ppopt['PF_MAX_IT']
    verbose = ppopt['VERBOSE']

    ## initialize
    converged = 0
    i = 0
    V = V0
    Va = angle(V)
    Vm = abs(V)

    ## set up indexing for updating V
    pvpq = r_[pv, pq]
    npv = len(pv)
    npq = len(pq)
    j1 = 0;         j2 = npv           ## j1:j2 - V angle of pv buses
    j3 = j2;        j4 = j2 + npq      ## j3:j4 - V angle of pq buses
    j5 = j4;        j6 = j4 + npq      ## j5:j6 - V mag of pq buses

    ## evaluate F(x0)
    mis = V * conj(Ybus * V) - Sbus
    F = r_[  mis[pv].real,
             mis[pq].real,
             mis[pq].imag  ]

    ## check tolerance
    normF = linalg.norm(F, Inf)
    if verbose > 1:
        sys.stdout.write('\n it    max P & Q mismatch (p.u.)')
        sys.stdout.write('\n----  ---------------------------')
        sys.stdout.write('\n%3d        %10.3e' % (i, normF))
    if normF < tol:
        converged = 1
        if verbose > 1:
            sys.stdout.write('\nConverged!\n')

    ## do Newton iterations
    while (not converged and i < max_it):
        ## update iteration counter
        i = i + 1

        ## evaluate Jacobian
        dS_dVm, dS_dVa = dSbus_dV(Ybus, V)

        J11 = dS_dVa[array([pvpq]).T, pvpq].real
        J12 = dS_dVm[array([pvpq]).T, pq].real
        J21 = dS_dVa[array([pq]).T, pvpq].imag
        J22 = dS_dVm[array([pq]).T, pq].imag

        J = vstack([
                hstack([J11, J12]),
                hstack([J21, J22])
            ], format="csr")

        ## compute update step
        dx = -1 * spsolve(J, F)

        ## update voltage
        if npv:
            Va[pv] = Va[pv] + dx[j1:j2]
        if npq:
            Va[pq] = Va[pq] + dx[j3:j4]
            Vm[pq] = Vm[pq] + dx[j5:j6]
        V = Vm * exp(1j * Va)
        Vm = abs(V)            ## update Vm and Va again in case
        Va = angle(V)          ## we wrapped around with a negative Vm

        ## evalute F(x)
        mis = V * conj(Ybus * V) - Sbus
        F = r_[  mis[pv].real,
                 mis[pq].real,
                 mis[pq].imag  ]

        ## check for convergence
        normF = linalg.norm(F, Inf)
        if verbose > 1:
            sys.stdout.write('\n%3d        %10.3e' % (i, normF))
        if normF < tol:
            converged = 1
            if verbose:
                sys.stdout.write("\nNewton's method power flow converged in "
                                 "%d iterations.\n" % i)

    if verbose:
        if not converged:
            sys.stdout.write("\nNewton's method power did not converge in %d "
                             "iterations.\n" % i)

    return V, converged, i
コード例 #34
0
def t_makePTDF(quiet=False):
    """Tests for C{makePTDF}.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ntests = 24
    t_begin(ntests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_opf')
    verbose = 0  #not quiet

    ## load case
    ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0)
    r = rundcopf(casefile, ppopt)
    baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch']
    _, bus, gen, branch = ext2int1(bus, gen, branch)
    nb = bus.shape[0]
    nbr = branch.shape[0]
    ng = gen.shape[0]

    ## compute injections and flows
    Cg = sparse((ones(ng), (gen[:, GEN_BUS], arange(ng))), (nb, ng))
    Pg = Cg * gen[:, PG]
    Pd = bus[:, PD]
    P = Pg - Pd
    ig = find(P > 0)
    il = find(P <= 0)
    F = branch[:, PF]

    ## create corresponding slack distribution matrices
    e1 = zeros((nb, 1))
    e1[0] = 1
    e4 = zeros((nb, 1))
    e4[3] = 1
    D1 = eye(nb, nb) - dot(e1, ones((1, nb)))
    D4 = eye(nb, nb) - dot(e4, ones((1, nb)))
    Deq = eye(nb, nb) - ones((nb, 1)) / nb * ones((1, nb))
    Dg = eye(nb) - matrix(Pd / sum(Pd)).T * ones(nb)
    Dd = eye(nb) - matrix(Pg / sum(Pg)).T * ones(nb)

    ## create some PTDF matrices
    H1 = makePTDF(baseMVA, bus, branch, 0)
    H4 = makePTDF(baseMVA, bus, branch, 3)
    Heq = makePTDF(baseMVA, bus, branch, ones(nb))
    Hg = makePTDF(baseMVA, bus, branch, Pd)
    Hd = makePTDF(baseMVA, bus, branch, Pg)

    ## matrices get properly transformed by slack dist matrices
    t_is(H1, dot(H1, D1), 8, 'H1  == H1 * D1')
    t_is(H4, dot(H1, D4), 8, 'H4  == H1 * D4')
    t_is(Heq, dot(H1, Deq), 8, 'Heq == H1 * Deq')
    t_is(Hg, dot(H1, Dg), 8, 'Hg  == H1 * Dg')
    t_is(Hd, dot(H1, Dd), 8, 'Hd  == H1 * Dd')
    t_is(H1, dot(Heq, D1), 8, 'H1  == Heq * D1')
    t_is(H4, dot(Heq, D4), 8, 'H4  == Heq * D4')
    t_is(Heq, dot(Heq, Deq), 8, 'Heq == Heq * Deq')
    t_is(Hg, dot(Heq, Dg), 8, 'Hg  == Heq * Dg')
    t_is(Hd, dot(Heq, Dd), 8, 'Hd  == Heq * Dd')
    t_is(H1, dot(Hg, D1), 8, 'H1  == Hg * D1')
    t_is(H4, dot(Hg, D4), 8, 'H4  == Hg * D4')
    t_is(Heq, dot(Hg, Deq), 8, 'Heq == Hg * Deq')
    t_is(Hg, dot(Hg, Dg), 8, 'Hg  == Hg * Dg')
    t_is(Hd, dot(Hg, Dd), 8, 'Hd  == Hg * Dd')

    ## PTDFs can reconstruct flows
    t_is(F, dot(H1, P), 3, 'Flow == H1  * P')
    t_is(F, dot(H4, P), 3, 'Flow == H4  * P')
    t_is(F, dot(Heq, P), 3, 'Flow == Heq * P')
    t_is(F, dot(Hg, P), 3, 'Flow == Hg  * P')
    t_is(F, dot(Hd, P), 3, 'Flow == Hd  * P')

    ## other
    t_is(F, dot(Hg, Pg), 3, 'Flow == Hg  * Pg')
    t_is(F, dot(Hd, (-Pd)), 3, 'Flow == Hd  * (-Pd)')
    t_is(zeros(nbr), dot(Hg, (-Pd)), 3, 'zeros == Hg  * (-Pd)')
    t_is(zeros(nbr), dot(Hd, Pg), 3, 'zeros == Hd  * Pg')

    t_end()
コード例 #35
0
ファイル: newtonpf.py プロジェクト: ink-corp/nonlinear-opt
def newtonpf(Ybus, Sbus, V0, ref, pv, pq, ppopt=None):
    """Solves the power flow using a full Newton's method.

    Solves for bus voltages given the full system admittance matrix (for
    all buses), the complex bus power injection vector (for all buses),
    the initial vector of complex bus voltages, and column vectors with
    the lists of bus indices for the swing bus, PV buses, and PQ buses,
    respectively. The bus voltage vector contains the set point for
    generator (including ref bus) buses, and the reference angle of the
    swing bus, as well as an initial guess for remaining magnitudes and
    angles. C{ppopt} is a PYPOWER options vector which can be used to
    set the termination tolerance, maximum number of iterations, and
    output options (see L{ppoption} for details). Uses default options if
    this parameter is not given. Returns the final complex voltages, a
    flag which indicates whether it converged or not, and the number of
    iterations performed.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if ppopt is None:
        ppopt = ppoption()

    ## options
    tol = ppopt['PF_TOL']
    max_it = ppopt['PF_MAX_IT']
    verbose = ppopt['VERBOSE']

    ## initialize
    converged = 0
    i = 0
    V = V0
    Va = angle(V)
    Vm = abs(V)

    ## set up indexing for updating V
    pvpq = r_[pv, pq]
    npv = len(pv)
    npq = len(pq)
    j1 = 0
    j2 = npv  ## j1:j2 - V angle of pv buses
    j3 = j2
    j4 = j2 + npq  ## j3:j4 - V angle of pq buses
    j5 = j4
    j6 = j4 + npq  ## j5:j6 - V mag of pq buses

    ## evaluate F(x0)
    mis = V * conj(Ybus * V) - Sbus
    F = r_[mis[pv].real, mis[pq].real, mis[pq].imag]

    ## check tolerance
    normF = linalg.norm(F, Inf)
    if verbose > 1:
        sys.stdout.write('\n it    max P & Q mismatch (p.u.)')
        sys.stdout.write('\n----  ---------------------------')
        sys.stdout.write('\n%3d        %10.3e' % (i, normF))
    if normF < tol:
        converged = 1
        if verbose > 1:
            sys.stdout.write('\nConverged!\n')

    ## do Newton iterations
    while (not converged and i < max_it):
        ## update iteration counter
        i = i + 1

        ## evaluate Jacobian
        dS_dVm, dS_dVa = dSbus_dV(Ybus, V)

        J11 = dS_dVa[array([pvpq]).T, pvpq].real
        J12 = dS_dVm[array([pvpq]).T, pq].real
        J21 = dS_dVa[array([pq]).T, pvpq].imag
        J22 = dS_dVm[array([pq]).T, pq].imag

        J = vstack([hstack([J11, J12]), hstack([J21, J22])], format="csr")

        ## compute update step
        dx = -1 * spsolve(J, F)

        ## update voltage
        if npv:
            Va[pv] = Va[pv] + dx[j1:j2]
        if npq:
            Va[pq] = Va[pq] + dx[j3:j4]
            Vm[pq] = Vm[pq] + dx[j5:j6]
        V = Vm * exp(1j * Va)
        Vm = abs(V)  ## update Vm and Va again in case
        Va = angle(V)  ## we wrapped around with a negative Vm

        ## evalute F(x)
        mis = V * conj(Ybus * V) - Sbus
        F = r_[mis[pv].real, mis[pq].real, mis[pq].imag]

        ## check for convergence
        normF = linalg.norm(F, Inf)
        if verbose > 1:
            sys.stdout.write('\n%3d        %10.3e' % (i, normF))
        if normF < tol:
            converged = 1
            if verbose:
                sys.stdout.write("\nNewton's method power flow converged in "
                                 "%d iterations.\n" % i)

    if verbose:
        if not converged:
            sys.stdout.write("\nNewton's method power did not converge in %d "
                             "iterations.\n" % i)

    return V, converged, i
コード例 #36
0
def t_opf_ipopt(quiet=False):
    """Tests for IPOPT-based AC optimal power flow.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    num_tests = 101

    t_begin(num_tests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_opf')
    verbose = 0#not quiet

    t0 = 'IPOPT : '
    ppopt = ppoption(OPF_VIOLATION=1e-6, PDIPM_GRADTOL=1e-8,
                   PDIPM_COMPTOL=1e-8, PDIPM_COSTTOL=1e-9)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=verbose, OPF_ALG=580)

    ## set up indices
    ib_data     = r_[arange(BUS_AREA + 1), arange(BASE_KV, VMIN + 1)]
    ib_voltage  = arange(VM, VA + 1)
    ib_lam      = arange(LAM_P, LAM_Q + 1)
    ib_mu       = arange(MU_VMAX, MU_VMIN + 1)
    ig_data     = r_[[GEN_BUS, QMAX, QMIN], arange(MBASE, APF + 1)]
    ig_disp     = array([PG, QG, VG])
    ig_mu       = arange(MU_PMAX, MU_QMIN + 1)
    ibr_data    = arange(ANGMAX + 1)
    ibr_flow    = arange(PF, QT + 1)
    ibr_mu      = array([MU_SF, MU_ST])
    ibr_angmu   = array([MU_ANGMIN, MU_ANGMAX])

    ## get solved AC power flow case from MAT-file
    soln9_opf = loadmat(join(tdir, 'soln9_opf.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf['bus_soln']
    gen_soln = soln9_opf['gen_soln']
    branch_soln = soln9_opf['branch_soln']
    f_soln = soln9_opf['f_soln'][0]

    ## run OPF
    t = t0
    r = runopf(casefile, ppopt)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])

    ## run with automatic conversion of single-block pwl to linear costs
    t = ''.join([t0, '(single-block PWL) : '])
    ppc = loadcase(casefile)
    ppc['gencost'][2, NCOST] = 2
    r = runopf(ppc, ppopt)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])
    xr = r_[r['var']['val']['Va'], r['var']['val']['Vm'], r['var']['val']['Pg'],
            r['var']['val']['Qg'], 0, r['var']['val']['y']]
    t_is(r['x'], xr, 8, [t, 'check on raw x returned from OPF'])

    ## get solved AC power flow case from MAT-file
    soln9_opf_Plim = loadmat(join(tdir, 'soln9_opf_Plim.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf_Plim['bus_soln']
    gen_soln = soln9_opf_Plim['gen_soln']
    branch_soln = soln9_opf_Plim['branch_soln']
    f_soln = soln9_opf_Plim['f_soln'][0]

    ## run OPF with active power line limits
    t = ''.join([t0, '(P line lim) : '])
    ppopt1 = ppoption(ppopt, OPF_FLOW_LIM=1)
    r = runopf(casefile, ppopt1)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])

    ##-----  test OPF with quadratic gen costs moved to generalized costs  -----
    ppc = loadcase(casefile)
    ppc['gencost'] = array([
        [2,   1500, 0,   3,   0.11,    5,   0],
        [2,   2000, 0,   3,   0.085,   1.2, 0],
        [2,   3000, 0,   3,   0.1225,  1,   0]
    ])
    r = runopf(ppc, ppopt)
    bus_soln, gen_soln, branch_soln, f_soln, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    branch_soln = branch_soln[:, :MU_ST + 1]

    A = None
    l = array([])
    u = array([])
    nb = ppc['bus'].shape[0]      # number of buses
    ng = ppc['gen'].shape[0]      # number of gens
    thbas = 0;                thend    = thbas + nb
    vbas     = thend;     vend     = vbas + nb
    pgbas    = vend;      pgend    = pgbas + ng
#    qgbas    = pgend;     qgend    = qgbas + ng
    nxyz = 2 * nb + 2 * ng
    N = sparse((ppc['baseMVA'] * ones(ng), (arange(ng), arange(pgbas, pgend))), (ng, nxyz))
    fparm = ones((ng, 1)) * array([[1, 0, 0, 1]])
    ix = argsort(ppc['gen'][:, 0])
    H = 2 * spdiags(ppc['gencost'][ix, 4], 0, ng, ng, 'csr')
    Cw = ppc['gencost'][ix, 5]
    ppc['gencost'][:, 4:7] = 0

    ## run OPF with quadratic gen costs moved to generalized costs
    t = ''.join([t0, 'w/quadratic generalized gen cost : '])
    r = opf(ppc, A, l, u, ppopt, N, fparm, H, Cw)
    f, bus, gen, branch, success = \
            r['f'], r['bus'], r['gen'], r['branch'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])
    t_is(r['cost']['usr'], f, 12, [t, 'user cost'])

    ##-----  run OPF with extra linear user constraints & costs  -----
    ## single new z variable constrained to be greater than or equal to
    ## deviation from 1 pu voltage at bus 1, linear cost on this z
    ## get solved AC power flow case from MAT-file
    soln9_opf_extras1 = loadmat(join(tdir, 'soln9_opf_extras1.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf_extras1['bus_soln']
    gen_soln = soln9_opf_extras1['gen_soln']
    branch_soln = soln9_opf_extras1['branch_soln']
    f_soln = soln9_opf_extras1['f_soln'][0]

    row = [0, 0, 1, 1]
    col = [9, 24, 9, 24]
    A = sparse(([-1, 1, 1, 1], (row, col)), (2, 25))
    u = array([Inf, Inf])
    l = array([-1, 1])

    N = sparse(([1], ([0], [24])), (1, 25))    ## new z variable only
    fparm = array([[1, 0, 0, 1]])              ## w = r = z
    H = sparse((1, 1))                ## no quadratic term
    Cw = array([100.0])

    t = ''.join([t0, 'w/extra constraints & costs 1 : '])
    r = opf(casefile, A, l, u, ppopt, N, fparm, H, Cw)
    f, bus, gen, branch, success = \
            r['f'], r['bus'], r['gen'], r['branch'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])
    t_is(r['var']['val']['z'], 0.025419, 6, [t, 'user variable'])
    t_is(r['cost']['usr'], 2.5419, 4, [t, 'user cost'])

    ##-----  test OPF with capability curves  -----
    ppc = loadcase(join(tdir, 't_case9_opfv2'))
    ## remove angle diff limits
    ppc['branch'][0, ANGMAX] =  360
    ppc['branch'][8, ANGMIN] = -360

    ## get solved AC power flow case from MAT-file
    soln9_opf_PQcap = loadmat(join(tdir, 'soln9_opf_PQcap.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf_PQcap['bus_soln']
    gen_soln = soln9_opf_PQcap['gen_soln']
    branch_soln = soln9_opf_PQcap['branch_soln']
    f_soln = soln9_opf_PQcap['f_soln'][0]

    ## run OPF with capability curves
    t = ''.join([t0, 'w/capability curves : '])
    r = runopf(ppc, ppopt)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])

    ##-----  test OPF with angle difference limits  -----
    ppc = loadcase(join(tdir, 't_case9_opfv2'))
    ## remove capability curves
    ppc['gen'][ix_(arange(1, 3),
                   [PC1, PC2, QC1MIN, QC1MAX, QC2MIN, QC2MAX])] = zeros((2, 6))

    ## get solved AC power flow case from MAT-file
    soln9_opf_ang = loadmat(join(tdir, 'soln9_opf_ang.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf_ang['bus_soln']
    gen_soln = soln9_opf_ang['gen_soln']
    branch_soln = soln9_opf_ang['branch_soln']
    f_soln = soln9_opf_ang['f_soln'][0]

    ## run OPF with angle difference limits
    t = ''.join([t0, 'w/angle difference limits : '])
    r = runopf(ppc, ppopt)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  1, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])
    t_is(branch[:, ibr_angmu ], branch_soln[:, ibr_angmu ],  2, [t, 'branch angle mu'])

    ##-----  test OPF with ignored angle difference limits  -----
    ## get solved AC power flow case from MAT-file
    soln9_opf = loadmat(join(tdir, 'soln9_opf.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_opf['bus_soln']
    gen_soln = soln9_opf['gen_soln']
    branch_soln = soln9_opf['branch_soln']
    f_soln = soln9_opf['f_soln'][0]

    ## run OPF with ignored angle difference limits
    t = ''.join([t0, 'w/ignored angle difference limits : '])
    ppopt1 = ppoption(ppopt, OPF_IGNORE_ANG_LIM=1)
    r = runopf(ppc, ppopt1)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    ## ang limits are not in this solution data, so let's remove them
    branch[0, ANGMAX] =  360
    branch[8, ANGMIN] = -360
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])

    t_end()
コード例 #37
0
ファイル: runpf.py プロジェクト: Anastien/PYPOWER
def runpf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a power flow.

    Runs a power flow [full AC Newton's method by default] and optionally
    returns the solved values in the data matrices, a flag which is C{True} if
    the algorithm was successful in finding a solution, and the elapsed
    time in seconds. All input arguments are optional. If C{casename} is
    provided it specifies the name of the input data file or dict
    containing the power flow data. The default value is 'case9'.

    If the ppopt is provided it overrides the default PYPOWER options
    vector and can be used to specify the solution algorithm and output
    options among other things. If the 3rd argument is given the pretty
    printed output will be appended to the file whose name is given in
    C{fname}. If C{solvedcase} is specified the solved case will be written
    to a case file in PYPOWER format with the specified name. If C{solvedcase}
    ends with '.mat' it saves the case as a MAT-file otherwise it saves it
    as a Python-file.

    If the C{ENFORCE_Q_LIMS} options is set to C{True} [default is false] then
    if any generator reactive power limit is violated after running the AC
    power flow, the corresponding bus is converted to a PQ bus, with Qg at
    the limit, and the case is re-run. The voltage magnitude at the bus
    will deviate from the specified value in order to satisfy the reactive
    power limit. If the reference bus is converted to PQ, the first
    remaining PV bus will be used as the slack bus for the next iteration.
    This may result in the real power output at this generator being
    slightly off from the specified values.

    Enforcing of generator Q limits inspired by contributions from Mu Lin,
    Lincoln University, New Zealand (1/14/05).

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ## options
    verbose = ppopt["VERBOSE"]
    qlim = ppopt["ENFORCE_Q_LIMS"]  ## enforce Q limits on gens?
    dc = ppopt["PF_DC"]             ## use DC formulation?

    ## read data
    ppc = loadcase(casedata)

    ## add zero columns to branch for flows if needed
    if ppc["branch"].shape[1] < QT:
        ppc["branch"] = c_[ppc["branch"],
                           zeros((ppc["branch"].shape[0],
                                  QT - ppc["branch"].shape[1] + 1))]

    ## convert to internal indexing
    ppc = ext2int(ppc)
    baseMVA, bus, gen, branch = \
        ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"]

    ## get bus index lists of each type of bus
    ref, pv, pq = bustypes(bus, gen)

    ## generator info
    on = find(gen[:, GEN_STATUS] > 0)      ## which generators are on?
    gbus = gen[on, GEN_BUS].astype(int)    ## what buses are they at?

    ##-----  run the power flow  -----
    t0 = time()
    if verbose > 0:
        v = ppver('all')
        stdout.write('PYPOWER Version %s, %s' % (v["Version"], v["Date"]))

    if dc:                               # DC formulation
        if verbose:
            stdout.write(' -- DC Power Flow\n')

        ## initial state
        Va0 = bus[:, VA] * (pi / 180)

        ## build B matrices and phase shift injections
        B, Bf, Pbusinj, Pfinj = makeBdc(baseMVA, bus, branch)

        ## compute complex bus power injections [generation - load]
        ## adjusted for phase shifters and real shunts
        Pbus = makeSbus(baseMVA, bus, gen).real - Pbusinj - bus[:, GS] / baseMVA

        ## "run" the power flow
        Va = dcpf(B, Pbus, Va0, ref, pv, pq)

        ## update data matrices with solution
        branch[:, [QF, QT]] = zeros((branch.shape[0], 2))
        branch[:, PF] = (Bf * Va + Pfinj) * baseMVA
        branch[:, PT] = -branch[:, PF]
        bus[:, VM] = ones(bus.shape[0])
        bus[:, VA] = Va * (180 / pi)
        ## update Pg for slack generator (1st gen at ref bus)
        ## (note: other gens at ref bus are accounted for in Pbus)
        ##      Pg = Pinj + Pload + Gs
        ##      newPg = oldPg + newPinj - oldPinj
        refgen = zeros(len(ref), dtype=int)
        for k in range(len(ref)):
            temp = find(gbus == ref[k])
            refgen[k] = on[temp[0]]
        gen[refgen, PG] = gen[refgen, PG] + (B[ref, :] * Va - Pbus[ref]) * baseMVA

        success = 1
    else:                                ## AC formulation
        alg = ppopt['PF_ALG']
        if verbose > 0:
            if alg == 1:
                solver = 'Newton'
            elif alg == 2:
                solver = 'fast-decoupled, XB'
            elif alg == 3:
                solver = 'fast-decoupled, BX'
            elif alg == 4:
                solver = 'Gauss-Seidel'
            else:
                solver = 'unknown'
            print(' -- AC Power Flow (%s)\n' % solver)

        ## initial state
        # V0    = ones(bus.shape[0])            ## flat start
        V0  = bus[:, VM] * exp(1j * pi/180 * bus[:, VA])
        V0[gbus] = gen[on, VG] / abs(V0[gbus]) * V0[gbus]

        if qlim:
            ref0 = ref                         ## save index and angle of
            Varef0 = bus[ref0, VA]             ##   original reference bus(es)
            limited = []                       ## list of indices of gens @ Q lims
            fixedQg = zeros(gen.shape[0])      ## Qg of gens at Q limits

        repeat = True
        while repeat:
            ## build admittance matrices
            Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)

            ## compute complex bus power injections [generation - load]
            Sbus = makeSbus(baseMVA, bus, gen)

            ## run the power flow
            alg = ppopt["PF_ALG"]
            if alg == 1:
                V, success, _ = newtonpf(Ybus, Sbus, V0, ref, pv, pq, ppopt)
            elif alg == 2 or alg == 3:
                Bp, Bpp = makeB(baseMVA, bus, branch, alg)
                V, success, _ = fdpf(Ybus, Sbus, V0, Bp, Bpp, ref, pv, pq, ppopt)
            elif alg == 4:
                V, success, _ = gausspf(Ybus, Sbus, V0, ref, pv, pq, ppopt)
            else:
                stderr.write('Only Newton''s method, fast-decoupled, and '
                             'Gauss-Seidel power flow algorithms currently '
                             'implemented.\n')

            ## update data matrices with solution
            bus, gen, branch = pfsoln(baseMVA, bus, gen, branch, Ybus, Yf, Yt, V, ref, pv, pq)

            if qlim:             ## enforce generator Q limits
                ## find gens with violated Q constraints
                gen_status = gen[:, GEN_STATUS] > 0
                qg_max_lim = gen[:, QG] > gen[:, QMAX]
                qg_min_lim = gen[:, QG] < gen[:, QMIN]
                
                mx = find( gen_status & qg_max_lim )
                mn = find( gen_status & qg_min_lim )
                
                if len(mx) > 0 or len(mn) > 0:  ## we have some Q limit violations
                    # No PV generators
                    if len(pv) == 0:
                        if verbose:
                            if len(mx) > 0:
                                print('Gen %d [only one left] exceeds upper Q limit : INFEASIBLE PROBLEM\n' % mx + 1)
                            else:
                                print('Gen %d [only one left] exceeds lower Q limit : INFEASIBLE PROBLEM\n' % mn + 1)

                        success = 0
                        break

                    ## one at a time?
                    if qlim == 2:    ## fix largest violation, ignore the rest
                        k = argmax(r_[gen[mx, QG] - gen[mx, QMAX],
                                      gen[mn, QMIN] - gen[mn, QG]])
                        if k > len(mx):
                            mn = mn[k - len(mx)]
                            mx = []
                        else:
                            mx = mx[k]
                            mn = []

                    if verbose and len(mx) > 0:
                        for i in range(len(mx)):
                            print('Gen ' + str(mx[i] + 1) + ' at upper Q limit, converting to PQ bus\n')

                    if verbose and len(mn) > 0:
                        for i in range(len(mn)):
                            print('Gen ' + str(mn[i] + 1) + ' at lower Q limit, converting to PQ bus\n')

                    ## save corresponding limit values
                    fixedQg[mx] = gen[mx, QMAX]
                    fixedQg[mn] = gen[mn, QMIN]
                    mx = r_[mx, mn].astype(int)

                    ## convert to PQ bus
                    gen[mx, QG] = fixedQg[mx]      ## set Qg to binding 
                    for i in range(len(mx)):            ## [one at a time, since they may be at same bus]
                        gen[mx[i], GEN_STATUS] = 0        ## temporarily turn off gen,
                        bi = gen[mx[i], GEN_BUS]   ## adjust load accordingly,
                        bus[bi, [PD, QD]] = (bus[bi, [PD, QD]] - gen[mx[i], [PG, QG]])
                    
                    if len(ref) > 1 and any(bus[gen[mx, GEN_BUS], BUS_TYPE] == REF):
                        raise ValueError('Sorry, PYPOWER cannot enforce Q '
                                         'limits for slack buses in systems '
                                         'with multiple slacks.')
                    
                    bus[gen[mx, GEN_BUS].astype(int), BUS_TYPE] = PQ   ## & set bus type to PQ

                    ## update bus index lists of each type of bus
                    ref_temp = ref
                    ref, pv, pq = bustypes(bus, gen)
                    if verbose and ref != ref_temp:
                        print('Bus %d is new slack bus\n' % ref)

                    limited = r_[limited, mx].astype(int)
                else:
                    repeat = 0 ## no more generator Q limits violated
            else:
                repeat = 0     ## don't enforce generator Q limits, once is enough

        if qlim and len(limited) > 0:
            ## restore injections from limited gens [those at Q limits]
            gen[limited, QG] = fixedQg[limited]    ## restore Qg value,
            for i in range(len(limited)):               ## [one at a time, since they may be at same bus]
                bi = gen[limited[i], GEN_BUS]           ## re-adjust load,
                bus[bi, [PD, QD]] = bus[bi, [PD, QD]] + gen[limited[i], [PG, QG]]
                gen[limited[i], GEN_STATUS] = 1           ## and turn gen back on
            
            if ref != ref0:
                ## adjust voltage angles to make original ref bus correct
                bus[:, VA] = bus[:, VA] - bus[ref0, VA] + Varef0

    ppc["et"] = time() - t0
    ppc["success"] = success

    ##-----  output results  -----
    ## convert back to original bus numbering & print results
    ppc["bus"], ppc["gen"], ppc["branch"] = bus, gen, branch
    results = int2ext(ppc)

    ## zero out result fields of out-of-service gens & branches
    if len(results["order"]["gen"]["status"]["off"]) > 0:
        results["gen"][ix_(results["order"]["gen"]["status"]["off"], [PG, QG])] = 0

    if len(results["order"]["branch"]["status"]["off"]) > 0:
        results["branch"][ix_(results["order"]["branch"]["status"]["off"], [PF, QF, PT, QT])] = 0

    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except Exception as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(results, fd, ppopt)
                fd.close()
    else:
        printpf(results, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, results)

    return results, success
コード例 #38
0
ファイル: t_opf_dc_pips.py プロジェクト: charlie0389/PYPOWER
def t_opf_dc_pips(quiet=False):
    """Tests for DC optimal power flow using PIPS solver.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    num_tests = 23

    t_begin(num_tests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_opf')
    verbose = 0#not quiet

    t0 = 'DC OPF (PIPS): '
    ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0, OPF_ALG_DC=200)

    ## run DC OPF

    ## set up indices
    ib_data     = r_[arange(BUS_AREA + 1), arange(BASE_KV, VMIN + 1)]
    ib_voltage  = arange(VM, VA + 1)
    ib_lam      = arange(LAM_P, LAM_Q + 1)
    ib_mu       = arange(MU_VMAX, MU_VMIN + 1)
    ig_data     = r_[[GEN_BUS, QMAX, QMIN], arange(MBASE, APF + 1)]
    ig_disp     = array([PG, QG, VG])
    ig_mu       = arange(MU_PMAX, MU_QMIN + 1)
    ibr_data    = arange(ANGMAX + 1)
    ibr_flow    = arange(PF, QT + 1)
    ibr_mu      = array([MU_SF, MU_ST])
    #ibr_angmu   = array([MU_ANGMIN, MU_ANGMAX])

    ## get solved DC power flow case from MAT-file
    soln9_dcopf = loadmat(join(tdir, 'soln9_dcopf.mat'), struct_as_record=True)
    ## defines bus_soln, gen_soln, branch_soln, f_soln
    bus_soln = soln9_dcopf['bus_soln']
    gen_soln = soln9_dcopf['gen_soln']
    branch_soln = soln9_dcopf['branch_soln']
    f_soln = soln9_dcopf['f_soln'][0]

    ## run OPF
    t = t0
    r = rundcopf(casefile, ppopt)
    bus, gen, branch, f, success = \
            r['bus'], r['gen'], r['branch'], r['f'], r['success']
    t_ok(success, [t, 'success'])
    t_is(f, f_soln, 3, [t, 'f'])
    t_is(   bus[:, ib_data   ],    bus_soln[:, ib_data   ], 10, [t, 'bus data'])
    t_is(   bus[:, ib_voltage],    bus_soln[:, ib_voltage],  3, [t, 'bus voltage'])
    t_is(   bus[:, ib_lam    ],    bus_soln[:, ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   bus[:, ib_mu     ],    bus_soln[:, ib_mu     ],  2, [t, 'bus mu'])
    t_is(   gen[:, ig_data   ],    gen_soln[:, ig_data   ], 10, [t, 'gen data'])
    t_is(   gen[:, ig_disp   ],    gen_soln[:, ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   gen[:, ig_mu     ],    gen_soln[:, ig_mu     ],  3, [t, 'gen mu'])
    t_is(branch[:, ibr_data  ], branch_soln[:, ibr_data  ], 10, [t, 'branch data'])
    t_is(branch[:, ibr_flow  ], branch_soln[:, ibr_flow  ],  3, [t, 'branch flow'])
    t_is(branch[:, ibr_mu    ], branch_soln[:, ibr_mu    ],  2, [t, 'branch mu'])

    ##-----  run OPF with extra linear user constraints & costs  -----
    ## two new z variables
    ##      0 <= z1, P2 - P1 <= z1
    ##      0 <= z2, P2 - P3 <= z2
    ## with A and N sized for DC opf
    ppc = loadcase(casefile)
    row = [0, 0, 0, 1, 1, 1]
    col = [9, 10, 12, 10, 11, 13]
    ppc['A'] = sparse(([-1, 1, -1, 1, -1, -1], (row, col)), (2, 14))
    ppc['u'] = array([0, 0])
    ppc['l'] = array([-Inf, -Inf])
    ppc['zl'] = array([0, 0])

    ppc['N'] = sparse(([1, 1], ([0, 1], [12, 13])), (2, 14))   ## new z variables only
    ppc['fparm'] = ones((2, 1)) * array([[1, 0, 0, 1]])           ## w = r = z
    ppc['H'] = sparse((2, 2))                            ## no quadratic term
    ppc['Cw'] = array([1000, 1])

    t = ''.join([t0, 'w/extra constraints & costs 1 : '])
    r = rundcopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['gen'][0, PG], 116.15974, 4, [t, 'Pg1 = 116.15974'])
    t_is(r['gen'][1, PG], 116.15974, 4, [t, 'Pg2 = 116.15974'])
    t_is(r['var']['val']['z'], [0, 0.3348], 4, [t, 'user vars'])
    t_is(r['cost']['usr'], 0.3348, 3, [t, 'user costs'])

    ## with A and N sized for AC opf
    ppc = loadcase(casefile)
    row = [0, 0, 0, 1, 1, 1]
    col = [18, 19, 24, 19, 20, 25]
    ppc['A'] = sparse(([-1, 1, -1, 1, -1, -1], (row, col)), (2, 26))
    ppc['u'] = array([0, 0])
    ppc['l'] = array([-Inf, -Inf])
    ppc['zl'] = array([0, 0])

    ppc['N'] = sparse(([1, 1], ([0, 1], [24, 25])), (2, 26))   ## new z variables only
    ppc['fparm'] = ones((2, 1)) * array([[1, 0, 0, 1]])        ## w = r = z
    ppc['H'] = sparse((2, 2))                            ## no quadratic term
    ppc['Cw'] = array([1000, 1])

    t = ''.join([t0, 'w/extra constraints & costs 2 : '])
    r = rundcopf(ppc, ppopt)
    t_ok(r['success'], [t, 'success'])
    t_is(r['gen'][0, PG], 116.15974, 4, [t, 'Pg1 = 116.15974'])
    t_is(r['gen'][1, PG], 116.15974, 4, [t, 'Pg2 = 116.15974'])
    t_is(r['var']['val']['z'], [0, 0.3348], 4, [t, 'user vars'])
    t_is(r['cost']['usr'], 0.3348, 3, [t, 'user costs'])

    t = ''.join([t0, 'infeasible : '])
    ## with A and N sized for DC opf
    ppc = loadcase(casefile)
    ppc['A'] = sparse(([1, 1], ([0, 0], [9, 10])), (1, 14))   ## Pg1 + Pg2
    ppc['u'] = array([Inf])
    ppc['l'] = array([600])
    r = rundcopf(ppc, ppopt)
    t_ok(not r['success'], [t, 'no success'])

    t_end()
コード例 #39
0
ファイル: t_runopf_w_res.py プロジェクト: charlie0389/PYPOWER
def t_runopf_w_res(quiet=False):
    """Tests C{runopf_w_res} and the associated callbacks.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    t_begin(46, quiet)

    verbose = 0#not quiet

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case30_userfcns')

    ppopt = ppoption(OPF_VIOLATION=1e-6, PDIPM_GRADTOL=1e-8,
                     PDIPM_COMPTOL=1e-8, PDIPM_COSTTOL=1e-9)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=verbose, OPF_ALG=560)

    t = 'runopf_w_res(''t_case30_userfcns'') : '
    r = runopf_w_res(casefile, ppopt)
    t_is(r['reserves']['R'], [25, 15, 0, 0, 19.3906, 0.6094], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 5.5, 5.5], 6, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 7, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0], 7, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0.5, 0], 7, [t, 'mu.Pmax'])
    ppc = loadcase(casefile)
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['qty'], ppc['reserves']['qty'], 12, [t, 'qty'])
    t_is(r['reserves']['totalcost'], 177.8047, 4, [t, 'totalcost'])

    t = 'gen 5 no reserves : ';
    ppc = loadcase(casefile)
    ppc['reserves']['zones'][:, 4] = 0
    ppc['reserves']['cost'] = delete(ppc['reserves']['cost'], 4)
    ppc['reserves']['qty'] = delete(ppc['reserves']['qty'], 4)
    r = runopf_w_res(ppc, ppopt)
    t_is(r['reserves']['R'], [25, 15, 0, 0, 0, 20], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 0, 5.5], 6, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 7, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0], 6, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0, 0], 7, [t, 'mu.Pmax'])
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['qty'], ppc['reserves']['qty'], 12, [t, 'qty'])
    t_is(r['reserves']['totalcost'], 187.5, 4, [t, 'totalcost'])

    t = 'extra offline gen : ';
    ppc = loadcase(casefile)
    idx = list(range(3)) + [4] + list(range(3, 6))
    ppc['gen'] = ppc['gen'][idx, :]
    ppc['gencost'] = ppc['gencost'][idx, :]
    ppc['reserves']['zones'] = ppc['reserves']['zones'][:, idx]
    ppc['reserves']['cost'] = ppc['reserves']['cost'][idx]
    ppc['reserves']['qty'] = ppc['reserves']['qty'][idx]
    ppc['gen'][3, GEN_STATUS] = 0
    r = runopf_w_res(ppc, ppopt)
    t_is(r['reserves']['R'], [25, 15, 0, 0, 0, 19.3906, 0.6094], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 5.5, 2, 5.5, 5.5], 6, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 0, 2, 0, 0], 7, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0, 0], 7, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0, 0.5, 0], 7, [t, 'mu.Pmax'])
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['qty'], ppc['reserves']['qty'], 12, [t, 'qty'])
    t_is(r['reserves']['totalcost'], 177.8047, 4, [t, 'totalcost'])

    t = 'both extra & gen 6 no res : ';
    ppc = loadcase(casefile)
    idx = list(range(3)) + [4] + list(range(3, 6))
    ppc['gen'] = ppc['gen'][idx, :]
    ppc['gencost'] = ppc['gencost'][idx, :]
    ppc['reserves']['zones'] = ppc['reserves']['zones'][:, idx]
    ppc['reserves']['cost'] = ppc['reserves']['cost'][idx]
    ppc['reserves']['qty'] = ppc['reserves']['qty'][idx]
    ppc['gen'][3, GEN_STATUS] = 0
    ppc['reserves']['zones'][:, 5] = 0
    ppc['reserves']['cost'] = delete(ppc['reserves']['cost'], 5)
    ppc['reserves']['qty'] = delete(ppc['reserves']['qty'], 5)
    r = runopf_w_res(ppc, ppopt)
    t_is(r['reserves']['R'], [25, 15, 0, 0, 0, 0, 20], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 5.5, 2, 0, 5.5], 6, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 0, 2, 0, 0], 7, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0, 0], 6, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0, 0, 0], 7, [t, 'mu.Pmax'])
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['qty'], ppc['reserves']['qty'], 12, [t, 'qty'])
    t_is(r['reserves']['totalcost'], 187.5, 4, [t, 'totalcost'])

    t = 'no qty (Rmax) : '
    ppc = loadcase(casefile)
    del ppc['reserves']['qty']
    r = runopf_w_res(ppc, ppopt)
    t_is(r['reserves']['R'], [39.3826, 0.6174, 0, 0, 19.3818, 0.6182], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 5.5, 5.5], 5, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 5, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0, 0, 0, 0, 0, 0], 7, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0.1, 0, 0, 0, 0.5, 0], 5, [t, 'mu.Pmax'])
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['totalcost'], 176.3708, 4, [t, 'totalcost'])

    t = 'RAMP_10, no qty (Rmax) : ';
    ppc = loadcase(casefile)
    del ppc['reserves']['qty']
    ppc['gen'][0, RAMP_10] = 25
    r = runopf_w_res(ppc, ppopt)
    t_is(r['reserves']['R'], [25, 15, 0, 0, 19.3906, 0.6094], 4, [t, 'R'])
    t_is(r['reserves']['prc'], [2, 2, 2, 2, 5.5, 5.5], 6, [t, 'prc'])
    t_is(r['reserves']['mu']['l'], [0, 0, 1, 2, 0, 0], 7, [t, 'mu.l'])
    t_is(r['reserves']['mu']['u'], [0.1, 0, 0, 0, 0, 0], 7, [t, 'mu.u'])
    t_is(r['reserves']['mu']['Pmax'], [0, 0, 0, 0, 0.5, 0], 7, [t, 'mu.Pmax'])
    t_is(r['reserves']['cost'], ppc['reserves']['cost'], 12, [t, 'cost'])
    t_is(r['reserves']['totalcost'], 177.8047, 4, [t, 'totalcost'])

    t_end()
コード例 #40
0
def runpf(casedata=None, ppopt=None, fname='', solvedcase=''):
    """Runs a power flow.

    Runs a power flow [full AC Newton's method by default] and optionally
    returns the solved values in the data matrices, a flag which is C{True} if
    the algorithm was successful in finding a solution, and the elapsed
    time in seconds. All input arguments are optional. If C{casename} is
    provided it specifies the name of the input data file or dict
    containing the power flow data. The default value is 'case9'.

    If the ppopt is provided it overrides the default PYPOWER options
    vector and can be used to specify the solution algorithm and output
    options among other things. If the 3rd argument is given the pretty
    printed output will be appended to the file whose name is given in
    C{fname}. If C{solvedcase} is specified the solved case will be written
    to a case file in PYPOWER format with the specified name. If C{solvedcase}
    ends with '.mat' it saves the case as a MAT-file otherwise it saves it
    as a Python-file.

    If the C{ENFORCE_Q_LIMS} options is set to C{True} [default is false] then
    if any generator reactive power limit is violated after running the AC
    power flow, the corresponding bus is converted to a PQ bus, with Qg at
    the limit, and the case is re-run. The voltage magnitude at the bus
    will deviate from the specified value in order to satisfy the reactive
    power limit. If the reference bus is converted to PQ, the first
    remaining PV bus will be used as the slack bus for the next iteration.
    This may result in the real power output at this generator being
    slightly off from the specified values.

    Enforcing of generator Q limits inspired by contributions from Mu Lin,
    Lincoln University, New Zealand (1/14/05).

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ## default arguments
    if casedata is None:
        casedata = join(dirname(__file__), 'case9')
    ppopt = ppoption(ppopt)

    ## options
    verbose = ppopt["VERBOSE"]
    qlim = ppopt["ENFORCE_Q_LIMS"]  ## enforce Q limits on gens?
    dc = ppopt["PF_DC"]  ## use DC formulation?

    ## read data
    ppc = loadcase(casedata)

    ## add zero columns to branch for flows if needed
    if ppc["branch"].shape[1] < QT:
        ppc["branch"] = c_[ppc["branch"],
                           zeros((ppc["branch"].shape[0],
                                  QT - ppc["branch"].shape[1] + 1))]

    ## convert to internal indexing
    ppc = ext2int(ppc)
    baseMVA, bus, gen, branch = \
        ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"]

    ## get bus index lists of each type of bus
    ref, pv, pq = bustypes(bus, gen)

    ## generator info
    on = find(gen[:, GEN_STATUS] > 0)  ## which generators are on?
    gbus = gen[on, GEN_BUS].astype(int)  ## what buses are they at?

    ##-----  run the power flow  -----
    t0 = time()
    if verbose > 0:
        v = ppver('all')
        stdout.write('PYPOWER Version %s, %s' % (v["Version"], v["Date"]))

    if dc:  # DC formulation
        if verbose:
            stdout.write(' -- DC Power Flow\n')

        ## initial state
        Va0 = bus[:, VA] * (pi / 180)

        ## build B matrices and phase shift injections
        B, Bf, Pbusinj, Pfinj = makeBdc(baseMVA, bus, branch)

        ## compute complex bus power injections [generation - load]
        ## adjusted for phase shifters and real shunts
        Pbus = makeSbus(baseMVA, bus,
                        gen).real - Pbusinj - bus[:, GS] / baseMVA

        ## "run" the power flow
        Va = dcpf(B, Pbus, Va0, ref, pv, pq)

        ## update data matrices with solution
        branch[:, [QF, QT]] = zeros((branch.shape[0], 2))
        branch[:, PF] = (Bf * Va + Pfinj) * baseMVA
        branch[:, PT] = -branch[:, PF]
        bus[:, VM] = ones(bus.shape[0])
        bus[:, VA] = Va * (180 / pi)
        ## update Pg for slack generator (1st gen at ref bus)
        ## (note: other gens at ref bus are accounted for in Pbus)
        ##      Pg = Pinj + Pload + Gs
        ##      newPg = oldPg + newPinj - oldPinj
        refgen = zeros(len(ref), dtype=int)
        for k in range(len(ref)):
            temp = find(gbus == ref[k])
            refgen[k] = on[temp[0]]
        gen[refgen,
            PG] = gen[refgen, PG] + (B[ref, :] * Va - Pbus[ref]) * baseMVA

        success = 1
    else:  ## AC formulation
        alg = ppopt['PF_ALG']
        if verbose > 0:
            if alg == 1:
                solver = 'Newton'
            elif alg == 2:
                solver = 'fast-decoupled, XB'
            elif alg == 3:
                solver = 'fast-decoupled, BX'
            elif alg == 4:
                solver = 'Gauss-Seidel'
            else:
                solver = 'unknown'
            print(' -- AC Power Flow (%s)\n' % solver)

        ## initial state
        # V0    = ones(bus.shape[0])            ## flat start
        V0 = bus[:, VM] * exp(1j * pi / 180 * bus[:, VA])
        V0[gbus] = gen[on, VG] / abs(V0[gbus]) * V0[gbus]

        if qlim:
            ref0 = ref  ## save index and angle of
            Varef0 = bus[ref0, VA]  ##   original reference bus(es)
            limited = []  ## list of indices of gens @ Q lims
            fixedQg = zeros(gen.shape[0])  ## Qg of gens at Q limits

        repeat = True
        while repeat:
            ## build admittance matrices
            Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)

            ## compute complex bus power injections [generation - load]
            Sbus = makeSbus(baseMVA, bus, gen)

            ## run the power flow
            alg = ppopt["PF_ALG"]
            if alg == 1:
                V, success, _ = newtonpf(Ybus, Sbus, V0, ref, pv, pq, ppopt)
            elif alg == 2 or alg == 3:
                Bp, Bpp = makeB(baseMVA, bus, branch, alg)
                V, success, _ = fdpf(Ybus, Sbus, V0, Bp, Bpp, ref, pv, pq,
                                     ppopt)
            elif alg == 4:
                V, success, _ = gausspf(Ybus, Sbus, V0, ref, pv, pq, ppopt)
            else:
                stderr.write('Only Newton'
                             's method, fast-decoupled, and '
                             'Gauss-Seidel power flow algorithms currently '
                             'implemented.\n')

            ## update data matrices with solution
            bus, gen, branch = pfsoln(baseMVA, bus, gen, branch, Ybus, Yf, Yt,
                                      V, ref, pv, pq)

            if qlim:  ## enforce generator Q limits
                ## find gens with violated Q constraints
                gen_status = gen[:, GEN_STATUS] > 0
                qg_max_lim = gen[:, QG] > gen[:, QMAX]
                qg_min_lim = gen[:, QG] < gen[:, QMIN]

                mx = find(gen_status & qg_max_lim)
                mn = find(gen_status & qg_min_lim)

                if len(mx) > 0 or len(
                        mn) > 0:  ## we have some Q limit violations
                    # No PV generators
                    if len(pv) == 0:
                        if verbose:
                            if len(mx) > 0:
                                print(
                                    'Gen %d [only one left] exceeds upper Q limit : INFEASIBLE PROBLEM\n'
                                    % mx + 1)
                            else:
                                print(
                                    'Gen %d [only one left] exceeds lower Q limit : INFEASIBLE PROBLEM\n'
                                    % mn + 1)

                        success = 0
                        break

                    ## one at a time?
                    if qlim == 2:  ## fix largest violation, ignore the rest
                        k = argmax(r_[gen[mx, QG] - gen[mx, QMAX],
                                      gen[mn, QMIN] - gen[mn, QG]])
                        if k > len(mx):
                            mn = mn[k - len(mx)]
                            mx = []
                        else:
                            mx = mx[k]
                            mn = []

                    if verbose and len(mx) > 0:
                        for i in range(len(mx)):
                            print('Gen ' + str(mx[i] + 1) +
                                  ' at upper Q limit, converting to PQ bus\n')

                    if verbose and len(mn) > 0:
                        for i in range(len(mn)):
                            print('Gen ' + str(mn[i] + 1) +
                                  ' at lower Q limit, converting to PQ bus\n')

                    ## save corresponding limit values
                    fixedQg[mx] = gen[mx, QMAX]
                    fixedQg[mn] = gen[mn, QMIN]
                    mx = r_[mx, mn].astype(int)

                    ## convert to PQ bus
                    gen[mx, QG] = fixedQg[mx]  ## set Qg to binding
                    for i in range(
                            len(mx)
                    ):  ## [one at a time, since they may be at same bus]
                        gen[mx[i],
                            GEN_STATUS] = 0  ## temporarily turn off gen,
                        bi = gen[mx[i], GEN_BUS]  ## adjust load accordingly,
                        bus[bi, [PD, QD]] = (bus[bi, [PD, QD]] -
                                             gen[mx[i], [PG, QG]])

                    if len(ref) > 1 and any(bus[gen[mx, GEN_BUS],
                                                BUS_TYPE] == REF):
                        raise ValueError('Sorry, PYPOWER cannot enforce Q '
                                         'limits for slack buses in systems '
                                         'with multiple slacks.')

                    bus[gen[mx, GEN_BUS].astype(int),
                        BUS_TYPE] = PQ  ## & set bus type to PQ

                    ## update bus index lists of each type of bus
                    ref_temp = ref
                    ref, pv, pq = bustypes(bus, gen)
                    if verbose and ref != ref_temp:
                        print('Bus %d is new slack bus\n' % ref)

                    limited = r_[limited, mx].astype(int)
                else:
                    repeat = 0  ## no more generator Q limits violated
            else:
                repeat = 0  ## don't enforce generator Q limits, once is enough

        if qlim and len(limited) > 0:
            ## restore injections from limited gens [those at Q limits]
            gen[limited, QG] = fixedQg[limited]  ## restore Qg value,
            for i in range(
                    len(limited
                        )):  ## [one at a time, since they may be at same bus]
                bi = gen[limited[i], GEN_BUS]  ## re-adjust load,
                bus[bi,
                    [PD, QD]] = bus[bi, [PD, QD]] + gen[limited[i], [PG, QG]]
                gen[limited[i], GEN_STATUS] = 1  ## and turn gen back on

            if ref != ref0:
                ## adjust voltage angles to make original ref bus correct
                bus[:, VA] = bus[:, VA] - bus[ref0, VA] + Varef0

    ppc["et"] = time() - t0
    ppc["success"] = success

    ##-----  output results  -----
    ## convert back to original bus numbering & print results
    ppc["bus"], ppc["gen"], ppc["branch"] = bus, gen, branch
    results = int2ext(ppc)

    ## zero out result fields of out-of-service gens & branches
    if len(results["order"]["gen"]["status"]["off"]) > 0:
        results["gen"][ix_(results["order"]["gen"]["status"]["off"],
                           [PG, QG])] = 0

    if len(results["order"]["branch"]["status"]["off"]) > 0:
        results["branch"][ix_(results["order"]["branch"]["status"]["off"],
                              [PF, QF, PT, QT])] = 0

    if fname:
        fd = None
        try:
            fd = open(fname, "a")
        except Exception as detail:
            stderr.write("Error opening %s: %s.\n" % (fname, detail))
        finally:
            if fd is not None:
                printpf(results, fd, ppopt)
                fd.close()
    else:
        printpf(results, stdout, ppopt)

    ## save solved case
    if solvedcase:
        savecase(solvedcase, results)

    return results, success
コード例 #41
0
ファイル: uopf.py プロジェクト: redw0lf/PYPOWER
def uopf(*args):
    """Solves combined unit decommitment / optimal power flow.

    Solves a combined unit decommitment and optimal power flow for a single
    time period. Uses an algorithm similar to dynamic programming. It proceeds
    through a sequence of stages, where stage C{N} has C{N} generators shut
    down, starting with C{N=0}. In each stage, it forms a list of candidates
    (gens at their C{Pmin} limits) and computes the cost with each one of them
    shut down. It selects the least cost case as the starting point for the
    next stage, continuing until there are no more candidates to be shut down
    or no more improvement can be gained by shutting something down.
    If C{verbose} in ppopt (see L{ppoption} is C{true}, it prints progress
    info, if it is > 1 it prints the output of each individual opf.

    @see: L{opf}, L{runuopf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    ##----- initialization -----
    t0 = time()  ## start timer

    ## process input arguments
    ppc, ppopt = opf_args2(*args)

    ## options
    verbose = ppopt["VERBOSE"]
    if verbose:  ## turn down verbosity one level for calls to opf
        ppopt = ppoption(ppopt, VERBOSE=verbose - 1)

    ##-----  do combined unit commitment/optimal power flow  -----

    ## check for sum(Pmin) > total load, decommit as necessary
    on = find((ppc["gen"][:, GEN_STATUS] > 0)
              & ~isload(ppc["gen"]))  ## gens in service
    onld = find((ppc["gen"][:, GEN_STATUS] > 0)
                & isload(ppc["gen"]))  ## disp loads in serv
    load_capacity = sum(ppc["bus"][:, PD]) - sum(
        ppc["gen"][onld, PMIN])  ## total load capacity
    Pmin = ppc["gen"][on, PMIN]
    while sum(Pmin) > load_capacity:
        ## shut down most expensive unit
        avgPmincost = totcost(ppc["gencost"][on, :], Pmin) / Pmin
        _, i = fairmax(avgPmincost)  ## pick one with max avg cost at Pmin
        i = on[i]  ## convert to generator index

        if verbose:
            print(
                'Shutting down generator %d so all Pmin limits can be satisfied.\n'
                % i)

        ## set generation to zero
        ppc["gen"][i, [PG, QG, GEN_STATUS]] = 0

        ## update minimum gen capacity
        on = find((ppc["gen"][:, GEN_STATUS] > 0)
                  & ~isload(ppc["gen"]))  ## gens in service
        Pmin = ppc["gen"][on, PMIN]

    ## run initial opf
    results = opf(ppc, ppopt)

    ## best case so far
    results1 = deepcopy(results)

    ## best case for this stage (ie. with n gens shut down, n=0,1,2 ...)
    results0 = deepcopy(results1)
    ppc["bus"] = results0["bus"].copy(
    )  ## use these V as starting point for OPF

    while True:
        ## get candidates for shutdown
        candidates = find((results0["gen"][:, MU_PMIN] > 0)
                          & (results0["gen"][:, PMIN] > 0))
        if len(candidates) == 0:
            break

        ## do not check for further decommitment unless we
        ##  see something better during this stage
        done = True

        for k in candidates:
            ## start with best for this stage
            ppc["gen"] = results0["gen"].copy()

            ## shut down gen k
            ppc["gen"][k, [PG, QG, GEN_STATUS]] = 0

            ## run opf
            results = opf(ppc, ppopt)

            ## something better?
            if results['success'] and (results["f"] < results1["f"]):
                results1 = deepcopy(results)
                k1 = k
                done = False  ## make sure we check for further decommitment

        if done:
            ## decommits at this stage did not help, so let's quit
            break
        else:
            ## shutting something else down helps, so let's keep going
            if verbose:
                print('Shutting down generator %d.\n' % k1)

            results0 = deepcopy(results1)
            ppc["bus"] = results0["bus"].copy(
            )  ## use these V as starting point for OPF

    ## compute elapsed time
    et = time() - t0

    ## finish preparing output
    results0['et'] = et

    return results0
コード例 #42
0
ファイル: t_runmarket.py プロジェクト: Python3pkg/PYPOWER
def t_runmarket(quiet=False):
    """Tests for code in C{runmkt}, C{smartmkt} and C{auction}.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    n_tests = 20

    t_begin(n_tests, quiet)

    try:
        from pypower.extras.smartmarket import runmarket
    except ImportError:
        t_skip(n_tests, 'smartmarket code not available')
        t_end
        return

    ppc = loadcase('t_auction_case')

    ppopt = ppoption(OPF_ALG=560, OUT_ALL_LIM=1, OUT_BRANCH=0, OUT_SYS_SUM=0)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=1)
    #ppopt = ppoption(ppopt, OUT_GEN=1, OUT_BRANCH=0, OUT_SYS_SUM=0)

    offers = {'P': {}, 'Q': {}}
    bids = {'P': {}, 'Q': {}}

    offers['P']['qty'] = array([[12, 24, 24], [12, 24, 24], [12, 24, 24],
                                [12, 24, 24], [12, 24, 24], [12, 24, 24]])
    offers['P']['prc'] = array([[20, 50, 60], [20, 40, 70], [20, 42, 80],
                                [20, 44, 90], [20, 46, 75], [20, 48, 60]])
    bids['P']['qty'] = array([[10, 10, 10], [10, 10, 10], [10, 10, 10]])
    bids['P']['prc'] = array([
        [100, 70, 60],
        #         [100, 64.3, 20],
        #         [100, 30.64545, 0],
        [100, 50, 20],
        [100, 60, 50]
    ])

    offers['Q']['qty'] = [60, 60, 60, 60, 60, 60, 0, 0, 0]
    offers['Q']['prc'] = [0, 0, 0, 0, 0, 3, 0, 0, 0]
    bids.Q['qty'] = [15, 15, 15, 15, 15, 15, 15, 12, 7.5]
    #     bids.Q['prc'] = [ 0, 0, 0, 0, 0, 0, 0, 83.9056, 0 ]
    bids.Q['prc'] = [0, 0, 0, 0, 0, 0, 0, 20, 0]

    t = 'marginal Q offer, marginal PQ bid, auction_type = 5'
    mkt = {'auction_type': 5, 't': [], 'u0': [], 'lim': []}
    r, co, cb, _, _, _, _ = runmarket(ppc, offers, bids, mkt, ppopt)
    co5 = co.copy()
    cb5 = cb.copy()

    #     [ co['P']['qty'] co['P']['prc'] ]
    #     [ cb['P']['qty'] cb['P']['prc'] ]
    #     [ co['Q']['qty'] co['Q']['prc'] ]
    #     [ cb['Q']['qty'] cb['Q']['prc'] ]

    i2e = r['bus'][:, BUS_I]
    e2i = sparse((max(i2e), 1))
    e2i[i2e] = list(range(r['bus'].size))
    G = find(isload(r['gen']) == 0)  ## real generators
    L = find(isload(r['gen']))  ## dispatchable loads
    Gbus = e2i[r['gen'][G, GEN_BUS]]
    Lbus = e2i[r['gen'][L, GEN_BUS]]

    t_is(co['P']['qty'],
         ones((6, 1)) * [12, 24, 0], 2, [t, ' : gen P quantities'])
    t_is(co['P']['prc'][0, :], 50.1578, 3, [t, ' : gen 1 P prices'])
    t_is(cb['P']['qty'], [[10, 10, 10], [10, 0.196, 0], [10, 10, 0]], 2,
         [t, ' : load P quantities'])
    t_is(cb['P']['prc'][1, :], 56.9853, 4, [t, ' : load 2 P price'])
    t_is(co['P']['prc'][:, 0], r['bus'][Gbus, LAM_P], 8,
         [t, ' : gen P prices'])
    t_is(cb['P']['prc'][:, 0], r['bus'][Lbus, LAM_P], 8,
         [t, ' : load P prices'])

    t_is(co['Q']['qty'],
         [4.2722, 11.3723, 14.1472, 22.8939, 36.7886, 12.3375, 0, 0, 0], 2,
         [t, ' : Q offer quantities'])
    t_is(co['Q']['prc'], [0, 0, 0, 0, 0, 3, 0.4861, 2.5367, 1.3763], 4,
         [t, ' : Q offer prices'])
    t_is(cb['Q']['qty'], [0, 0, 0, 0, 0, 0, 15, 4.0785, 5], 2,
         [t, ' : Q bid quantities'])
    t_is(cb['Q']['prc'], [0, 0, 0, 0, 0, 3, 0.4861, 2.5367, 1.3763], 4,
         [t, ' : Q bid prices'])
    t_is(co['Q']['prc'], r['bus'][[Gbus, Lbus], LAM_Q], 8,
         [t, ' : Q offer prices'])
    t_is(cb['Q']['prc'], co['Q']['prc'], 8, [t, ' : Q bid prices'])

    t = 'marginal Q offer, marginal PQ bid, auction_type = 0'
    mkt['auction_type'] = 0
    r, co, cb, _, _, _, _ = runmarket(ppc, offers, bids, mkt, ppopt)
    t_is(co['P']['qty'], co5['P']['qty'], 8, [t, ' : gen P quantities'])
    t_is(cb['P']['qty'], cb5['P']['qty'], 8, [t, ' : load P quantities'])
    t_is(co['P']['prc'], offers['P']['prc'], 8, [t, ' : gen P prices'])
    t_is(cb['P']['prc'], bids['P']['prc'], 8, [t, ' : load P prices'])

    t_is(co['Q']['qty'], co5['Q']['qty'], 8, [t, ' : gen Q quantities'])
    t_is(cb['Q']['qty'], cb5['Q']['qty'], 8, [t, ' : load Q quantities'])
    t_is(co['Q']['prc'], offers['Q']['prc'], 8, [t, ' : gen Q prices'])
    t_is(cb['Q']['prc'], bids['Q']['prc'], 8, [t, ' : load Q prices'])

    t_end
コード例 #43
0
ファイル: t_qps_pypower.py プロジェクト: Anastien/PYPOWER
def t_qps_pypower(quiet=False):
    """Tests of C{qps_pypower} QP solvers.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    algs = [200, 250, 400, 500, 600, 700]
    names = ['PIPS', 'sc-PIPS', 'IPOPT', 'CPLEX', 'MOSEK', 'Gurobi']
    check = [None, None, 'ipopt', 'cplex', 'mosek', 'gurobipy']

    n = 36
    t_begin(n * len(algs), quiet)

    for k in range(len(algs)):
        if check[k] is not None and not have_fcn(check[k]):
            t_skip(n, '%s not installed' % names[k])
        else:
            opt = {'verbose': 0, 'alg': algs[k]}

            if names[k] == 'PIPS' or names[k] == 'sc-PIPS':
                opt['pips_opt'] = {}
                opt['pips_opt']['comptol'] = 1e-8
            if names[k] == 'CPLEX':
#               alg = 0        ## default uses barrier method with NaN bug in lower lim multipliers
                alg = 2        ## use dual simplex
                ppopt = ppoption(CPLEX_LPMETHOD = alg, CPLEX_QPMETHOD = min([4, alg]))
                opt['cplex_opt'] = cplex_options([], ppopt)

            if names[k] == 'MOSEK':
#                alg = 5        ## use dual simplex
                ppopt = ppoption()
#                ppopt = ppoption(ppopt, MOSEK_LP_ALG = alg)
                ppopt = ppoption(ppopt, MOSEK_GAP_TOL=1e-9)
                opt['mosek_opt'] = mosek_options([], ppopt)

            t = '%s - 3-d LP : ' % names[k]
            ## example from 'doc linprog'
            c = array([-5, -4, -6], float)
            A = sparse([[1, -1,  1],
                        [3,  2,  4],
                        [3,  2,  0]], dtype=float)
            l = None
            u = array([20, 42, 30], float)
            xmin = array([0, 0, 0], float)
            x0 = None
            x, f, s, _, lam = qps_pypower(None, c, A, l, u, xmin, None, None, opt)
            t_is(s, 1, 12, [t, 'success'])
            t_is(x, [0, 15, 3], 6, [t, 'x'])
            t_is(f, -78, 6, [t, 'f'])
            t_is(lam['mu_l'], [0, 0, 0], 13, [t, 'lam.mu_l'])
            t_is(lam['mu_u'], [0, 1.5, 0.5], 9, [t, 'lam.mu_u'])
            t_is(lam['lower'], [1, 0, 0], 9, [t, 'lam.lower'])
            t_is(lam['upper'], zeros(shape(x)), 13, [t, 'lam.upper'])

            t = '%s - unconstrained 3-d quadratic : ' % names[k]
            ## from http://www.akiti.ca/QuadProgEx0Constr.html
            H = sparse([
                [ 5, -2, -1],
                [-2,  4,  3],
                [-1,  3,  5]
            ], dtype=float)
            c = array([2, -35, -47], float)
            x0 = array([0, 0, 0], float)
            x, f, s, _, lam = qps_pypower(H, c, opt=opt)
            t_is(s, 1, 12, [t, 'success'])
            t_is(x, [3, 5, 7], 8, [t, 'x'])
            t_is(f, -249, 13, [t, 'f'])
            t_ok(len(lam['mu_l']) == 0, [t, 'lam.mu_l'])
            t_ok(len(lam['mu_u']) == 0, [t, 'lam.mu_u'])
            t_is(lam['lower'], zeros(shape(x)), 13, [t, 'lam.lower'])
            t_is(lam['upper'], zeros(shape(x)), 13, [t, 'lam.upper'])

            t = '%s - constrained 2-d QP : ' % names[k]
            ## example from 'doc quadprog'
            H = sparse([[ 1, -1],
                        [-1,  2]], dtype=float)
            c = array([-2, -6], float)
            A = sparse([[ 1, 1],
                        [-1, 2],
                        [ 2, 1]], dtype=float)
            l = None
            u = array([2, 2, 3], float)
            xmin = array([0, 0])
            x0 = None
            x, f, s, _, lam = qps_pypower(H, c, A, l, u, xmin, None, x0, opt)
            t_is(s, 1, 12, [t, 'success'])
            t_is(x, array([2., 4.]) / 3, 7, [t, 'x'])
            t_is(f, -74. / 9, 6, [t, 'f'])
            t_is(lam['mu_l'], [0., 0., 0.], 13, [t, 'lam.mu_l'])
            t_is(lam['mu_u'], array([28., 4., 0.]) / 9, 7, [t, 'lam.mu_u'])
            t_is(lam['lower'], zeros(shape(x)), 8, [t, 'lam.lower'])
            t_is(lam['upper'], zeros(shape(x)), 13, [t, 'lam.upper'])

            t = '%s - constrained 4-d QP : ' % names[k]
            ## from http://www.jmu.edu/docs/sasdoc/sashtml/iml/chap8/sect12.htm
            H = sparse([[1003.1,  4.3,     6.3,     5.9],
                        [4.3,     2.2,     2.1,     3.9],
                        [6.3,     2.1,     3.5,     4.8],
                        [5.9,     3.9,     4.8,    10.0]])
            c = zeros(4)
            A = sparse([[   1,       1,       1,       1],
                        [0.17,    0.11,    0.10,    0.18]])
            l = array([1, 0.10])
            u = array([1, Inf])
            xmin = zeros(4)
            x0 = array([1, 0, 0, 1], float)
            x, f, s, _, lam = qps_pypower(H, c, A, l, u, xmin, None, x0, opt)
            t_is(s, 1, 12, [t, 'success'])
            t_is(x, array([0, 2.8, 0.2, 0]) / 3, 5, [t, 'x'])
            t_is(f, 3.29 / 3, 6, [t, 'f'])
            t_is(lam['mu_l'], array([6.58, 0]) / 3, 6, [t, 'lam.mu_l'])
            t_is(lam['mu_u'], [0, 0], 13, [t, 'lam.mu_u'])
            t_is(lam['lower'], [2.24, 0, 0, 1.7667], 4, [t, 'lam.lower'])
            t_is(lam['upper'], zeros(shape(x)), 13, [t, 'lam.upper'])

            t = '%s - (dict) constrained 4-d QP : ' % names[k]
            p = {'H': H, 'A': A, 'l': l, 'u': u, 'xmin': xmin, 'x0': x0, 'opt': opt}
            x, f, s, _, lam = qps_pypower(p)
            t_is(s, 1, 12, [t, 'success'])
            t_is(x, array([0, 2.8, 0.2, 0]) / 3, 5, [t, 'x'])
            t_is(f, 3.29 / 3, 6, [t, 'f'])
            t_is(lam['mu_l'], array([6.58, 0]) / 3, 6, [t, 'lam.mu_l'])
            t_is(lam['mu_u'], [0, 0], 13, [t, 'lam.mu_u'])
            t_is(lam['lower'], [2.24, 0, 0, 1.7667], 4, [t, 'lam.lower'])
            t_is(lam['upper'], zeros(shape(x)), 13, [t, 'lam.upper'])

            t = '%s - infeasible LP : ' % names[k]
            p = {'A': sparse([1, 1]), 'c': array([1, 1]), 'u': array([-1]),
                 'xmin': array([0, 0]), 'opt': opt}
            x, f, s, _, lam = qps_pypower(p)
            t_ok(s <= 0, [t, 'no success'])

    t_end()
コード例 #44
0
ファイル: t_pf.py プロジェクト: Anastien/PYPOWER
def t_pf(quiet=False):
    """Tests for power flow solvers.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    t_begin(33, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_pf')
    verbose = not quiet

    ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0)

    ## get solved AC power flow case from MAT-file
    ## defines bus_soln, gen_soln, branch_soln
    soln9_pf = loadmat(join(tdir, 'soln9_pf.mat'), struct_as_record=False)
    bus_soln = soln9_pf['bus_soln']
    gen_soln = soln9_pf['gen_soln']
    branch_soln = soln9_pf['branch_soln']

    ## run Newton PF
    t = 'Newton PF : ';
    ppopt = ppoption(ppopt, PF_ALG=1)
    results, success = runpf(casefile, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_ok(success, [t, 'success'])
    t_is(bus, bus_soln, 6, [t, 'bus'])
    t_is(gen, gen_soln, 6, [t, 'gen'])
    t_is(branch, branch_soln, 6, [t, 'branch'])

    ## run fast-decoupled PF (XB version)
    t = 'Fast Decoupled (XB) PF : ';
    ppopt = ppoption(ppopt, PF_ALG=2)
    results, success = runpf(casefile, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_ok(success, [t, 'success'])
    t_is(bus, bus_soln, 6, [t, 'bus'])
    t_is(gen, gen_soln, 6, [t, 'gen'])
    t_is(branch, branch_soln, 6, [t, 'branch'])

    ## run fast-decoupled PF (BX version)
    t = 'Fast Decoupled (BX) PF : ';
    ppopt = ppoption(ppopt, PF_ALG=3)
    results, success = runpf(casefile, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_ok(success, [t, 'success'])
    t_is(bus, bus_soln, 6, [t, 'bus'])
    t_is(gen, gen_soln, 6, [t, 'gen'])
    t_is(branch, branch_soln, 6, [t, 'branch'])

    ## run Gauss-Seidel PF
    t = 'Gauss-Seidel PF : ';
    ppopt = ppoption(ppopt, PF_ALG=4)
    results, success = runpf(casefile, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_ok(success, [t, 'success'])
    t_is(bus, bus_soln, 5, [t, 'bus'])
    t_is(gen, gen_soln, 5, [t, 'gen'])
    t_is(branch, branch_soln, 5, [t, 'branch'])

    ## get solved AC power flow case from MAT-file
    ## defines bus_soln, gen_soln, branch_soln
    soln9_dcpf = loadmat(join(tdir, 'soln9_dcpf.mat'), struct_as_record=False)
    bus_soln = soln9_dcpf['bus_soln']
    gen_soln = soln9_dcpf['gen_soln']
    branch_soln = soln9_dcpf['branch_soln']

    ## run DC PF
    t = 'DC PF : '
    results, success = rundcpf(casefile, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_ok(success, [t, 'success'])
    t_is(bus, bus_soln, 6, [t, 'bus'])
    t_is(gen, gen_soln, 6, [t, 'gen'])
    t_is(branch, branch_soln, 6, [t, 'branch'])

    ## check Qg distribution, when Qmin = Qmax
    t = 'check Qg : '
    ppopt = ppoption(ppopt, PF_ALG=1, VERBOSE=0)
    ppc = loadcase(casefile)
    ppc['gen'][0, [QMIN, QMAX]] = [20, 20]
    results, success = runpf(ppc, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_is(gen[0, QG], 24.07, 2, [t, 'single gen, Qmin = Qmax'])

    ppc['gen'] = r_[array([ ppc['gen'][0, :] ]), ppc['gen']]
    ppc['gen'][0, [QMIN, QMAX]] = [10, 10]
    ppc['gen'][1, [QMIN, QMAX]] = [ 0, 50]
    results, success = runpf(ppc, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_is(gen[0:2, QG], [10, 14.07], 2, [t, '2 gens, Qmin = Qmax for one'])

    ppc['gen'][0, [QMIN, QMAX]] = [10, 10]
    ppc['gen'][1, [QMIN, QMAX]] = [-50, -50]
    results, success = runpf(ppc, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_is(gen[0:2, QG], [12.03, 12.03], 2, [t, '2 gens, Qmin = Qmax for both'])

    ppc['gen'][0, [QMIN, QMAX]] = [0,  50]
    ppc['gen'][1, [QMIN, QMAX]] = [0, 100]
    results, success = runpf(ppc, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_is(gen[0:2, QG], [8.02, 16.05], 2, [t, '2 gens, proportional'])

    ppc['gen'][0, [QMIN, QMAX]] = [-50, 0]
    ppc['gen'][1, [QMIN, QMAX]] = [50, 150]
    results, success = runpf(ppc, ppopt)
    bus, gen, branch = results['bus'], results['gen'], results['branch']
    t_is(gen[0:2, QG], [-50 + 8.02, 50 + 16.05], 2, [t, '2 gens, proportional'])

    ## network with islands
    t = 'network w/islands : DC PF : '
    ppc0 = loadcase(casefile)
    ppc0['gen'][0, PG] = 60
    ppc0['gen'][0, [PMIN, PMAX, QMIN, QMAX, PG, QG]] = \
            ppc0['gen'][0, [PMIN, PMAX, QMIN, QMAX, PG, QG]] / 2
    ppc0['gen'] = r_[array([ ppc0['gen'][0, :] ]), ppc0['gen']]
    ppc1 = ppc0.copy()
    ppc  = ppc0.copy()
    nb = ppc['bus'].shape[0]
    ppc1['bus'][:, BUS_I]       = ppc1['bus'][:, BUS_I] + nb
    ppc1['branch'][:, F_BUS]    = ppc1['branch'][:, F_BUS] + nb
    ppc1['branch'][:, T_BUS]    = ppc1['branch'][:, T_BUS] + nb
    ppc1['gen'][:, GEN_BUS]     = ppc1['gen'][:, GEN_BUS] + nb
    ppc['bus']           = r_[ppc['bus'], ppc1['bus']]
    ppc['branch']        = r_[ppc['branch'], ppc1['branch']]
    ppc['gen']           = r_[ppc['gen'], ppc1['gen']]
    #ppopt = ppoption(ppopt, OUT_BUS=1, OUT_GEN=1, OUT_ALL=-1, VERBOSE=2)
    ppopt = ppoption(ppopt, VERBOSE=verbose)
    r = rundcpf(ppc, ppopt)
    t_is(r['bus'][  :9,  VA], bus_soln[:, VA], 8, [t, 'voltage angles 1'])
    t_is(r['bus'][10:18, VA], bus_soln[:, VA], 8, [t, 'voltage angles 2'])
    Pg = r_[gen_soln[0, PG] - 30, 30, gen_soln[1:3, PG]]
    t_is(r['gen'][ :4, PG], Pg, 8, [t, 'active power generation 1'])
    t_is(r['gen'][4:8, PG], Pg, 8, [t, 'active power generation 1'])

    t = 'network w/islands : AC PF : '
    ## get solved AC power flow case from MAT-file
    soln9_pf = loadmat(join(tdir, 'soln9_pf.mat'), struct_as_record=False)
    bus_soln = soln9_pf['bus_soln']
    gen_soln = soln9_pf['gen_soln']
    branch_soln = soln9_pf['branch_soln']
    r = runpf(ppc, ppopt)
    t_is(r['bus'][ :9,  VA], bus_soln[:, VA], 8, [t, 'voltage angles 1'])
    t_is(r['bus'][9:18, VA], bus_soln[:, VA], 8, [t, 'voltage angles 2'])
    Pg = r_[gen_soln[0, PG] - 30, 30, gen_soln[1:3, PG]]
    t_is(r['gen'][ :4, PG], Pg, 8, [t, 'active power generation 1'])
    t_is(r['gen'][4:8, PG], Pg, 8, [t, 'active power generation 1'])

    t_end()
コード例 #45
0
def _run_fbsw_dense(ppc, ppopt=None):
    """
    DENSE version of distribution power flow solution according to [1]
    :References:
    [1] Jen-Hao Teng, "A Direct Approach for Distribution System Load Flow Solutions", IEEE Transactions on Power Delivery, vol. 18, no. 3, pp. 882-887, July 2003.

    :param ppc: matpower-style case data
    :return: results (pypower style), success (flag about PF convergence)
    """
    # time_start = time()

    # path_search = nx.shortest_path

    # ppci = ext2int(ppc)
    ppci = ppc

    ppopt = ppoption(ppopt)

    baseMVA, bus, gen, branch = \
        ppci["baseMVA"], ppci["bus"], ppci["gen"], ppci["branch"]
    nbus = bus.shape[0]

    # get bus index lists of each type of bus
    ref, pv, pq = bustypes(bus, gen)

    root_bus = ref[
        0]  # reference bus is assumed as root bus for a radial network

    DLF, ppc_fbsw, buses_ordered_fbsw = bibc_bcbv_dense(ppci)

    baseMVA_fbsw, bus_fbsw, gen_fbsw, branch_fbsw = \
        ppc_fbsw["baseMVA"], ppc_fbsw["bus"], ppc_fbsw["gen"], ppc_fbsw["branch"]

    time_start = time()

    # initialize voltages to flat start and buses with gens to their setpoints
    V0 = np.ones(nbus, dtype=complex)
    V0[gen[:, GEN_BUS].astype(int)] = gen[:, VG]

    Sbus_fbsw = makeSbus(baseMVA_fbsw, bus_fbsw, gen_fbsw)

    # update data matrices with solution
    Ybus_fbsw, Yf_fbsw, Yt_fbsw = makeYbus(baseMVA_fbsw, bus_fbsw, branch_fbsw)
    ## get bus index lists of each type of bus
    ref_fbsw, pv_fbsw, pq_fbsw = bustypes(bus_fbsw, gen_fbsw)

    ##-----  run the power flow  -----

    # ###
    # LF initialization and calculation
    V_final, success = fbsw_dense(DLF,
                                  bus_fbsw,
                                  gen_fbsw,
                                  branch_fbsw,
                                  baseMVA_fbsw,
                                  Ybus_fbsw,
                                  Sbus_fbsw,
                                  V0,
                                  ref_fbsw,
                                  pv_fbsw,
                                  pq_fbsw,
                                  ppopt=ppopt)
    V_final = V_final[np.argsort(
        buses_ordered_fbsw)]  # return bus voltages in original bus order

    ppci["et"] = time() - time_start

    Sbus = makeSbus(baseMVA, bus, gen)
    # update data matrices with solution
    Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)

    bus, gen, branch = pfsoln(baseMVA, bus, gen, branch, Ybus, Yf, Yt, V_final,
                              ref, pv, pq)

    ppci["success"] = success

    ##-----  output results  -----
    ppci["bus"], ppci["gen"], ppci["branch"] = bus, gen, branch
    results = ppci

    return results, success
コード例 #46
0
ファイル: from_ppc.py プロジェクト: Tooblippe/pandapower
def validate_from_ppc(
    ppc_net,
    pp_net,
    max_diff_values={
        "vm_pu": 1e-6,
        "va_degree": 1e-5,
        "p_branch_kw": 1e-3,
        "q_branch_kvar": 1e-3,
        "p_gen_kw": 1e-3,
        "q_gen_kvar": 1e-3
    }):
    """
    This function validates the pypower case files to pandapower net structure conversion via a \
    comparison of loadflow calculations.

    INPUT:

        **ppc_net** - The pypower case file.

        **pp_net** - The pandapower network.

    OPTIONAL:

        **max_diff_values** - Dict of maximal allowed difference values. The keys must be
            'vm_pu', 'va_degree', 'p_branch_kw', 'q_branch_kvar', 'p_gen_kw' and 'q_gen_kvar' and
            the values floats.

    OUTPUT:

        **conversion_success** - conversion_success is returned as False if pypower or pandapower
            cannot calculate a power flow or if the maximum difference values (max_diff_values )
            cannot be hold.

    EXAMPLE:

        import pandapower.converter as pc

        from pypower import case4gs

        ppc_net = case4gs.case4gs()

        pp_net = cv.from_ppc(ppc_net, f_hz=60)

        cv.validate_from_ppc(ppc_net, pp_net)
    """
    # --- run a pypower power flow without print output
    ppopt = ppoption.ppoption(VERBOSE=0, OUT_ALL=0)
    ppc_res = runpf.runpf(ppc_net, ppopt)[0]

    # --- store pypower power flow results
    ppc_res_branch = ppc_res['branch'][:, 13:17]
    ppc_res_bus = ppc_res['bus'][:, 7:9]
    ppc_res_gen = ppc_res['gen'][:, 1:3]

    # --- try to run a pandapower power flow
    try:
        pp.runpp(pp_net,
                 init="dc",
                 calculate_voltage_angles=True,
                 trafo_model="pi")
    except:
        try:
            pp.runpp(pp_net,
                     calculate_voltage_angles=True,
                     init="flat",
                     trafo_model="pi")
        except:
            try:
                pp.runpp(pp_net, trafo_model="pi")
            except:
                if (ppc_res['success'] == 1) & (~pp_net.converged):
                    logger.error(
                        'The validation of ppc conversion fails because the pandapower net'
                        ' power flow does not converge.')
                elif (ppc_res['success'] != 1) & (pp_net.converged):
                    logger.error(
                        'The validation of ppc conversion fails because the power flow of '
                        'the pypower case does not converge.')
                elif (ppc_res['success'] != 1) & (~pp_net.converged):
                    logger.error(
                        'The power flow of both, the pypower case and the pandapower net, '
                        'do not converge.')
                return False

    # --- prepare power flow result comparison by reordering pp results as they are in ppc results
    if (ppc_res['success'] == 1) & (pp_net.converged):
        # --- pandapower bus result table
        pp_res_bus = array(pp_net.res_bus[['vm_pu', 'va_degree']])

        # --- pandapower gen result table
        pp_res_gen = zeros([1, 2])
        # consideration of parallel generators via storing how much generators have been considered
        # each node
        already_used_gen = Series(zeros([pp_net.bus.shape[0]]),
                                  index=pp_net.bus.index).astype(int)
        GENS = DataFrame(ppc_res['gen'][:, [0]].astype(int))
        change_q_compare = []
        for i, j in GENS.iterrows():
            current_bus_idx = pp.get_element_index(pp_net, 'bus', name=j[0])
            current_bus_type = int(ppc_res['bus'][current_bus_idx, 1])
            # ext_grid
            if current_bus_type == 3:
                if already_used_gen.at[current_bus_idx] == 0:
                    pp_res_gen = append(
                        pp_res_gen,
                        array(pp_net.res_ext_grid[
                            pp_net.ext_grid.bus == current_bus_idx][[
                                'p_kw', 'q_kvar'
                            ]])[already_used_gen.at[current_bus_idx]].reshape(
                                (1, 2)), 0)
                    already_used_gen.at[current_bus_idx] += 1
                else:
                    pp_res_gen = append(
                        pp_res_gen,
                        array(pp_net.res_sgen[
                            pp_net.sgen.bus == current_bus_idx][[
                                'p_kw', 'q_kvar'
                            ]])[already_used_gen.at[current_bus_idx] -
                                1].reshape((1, 2)), 0)
                    already_used_gen.at[current_bus_idx] += 1
                    change_q_compare += [j[0]]
            # gen
            elif current_bus_type == 2:
                pp_res_gen = append(
                    pp_res_gen,
                    array(pp_net.res_gen[pp_net.gen.bus == current_bus_idx][[
                        'p_kw', 'q_kvar'
                    ]])[already_used_gen.at[current_bus_idx]].reshape((1, 2)),
                    0)
                if already_used_gen.at[current_bus_idx] > 0:
                    change_q_compare += [j[0]]
                already_used_gen.at[current_bus_idx] += 1
            # sgen
            elif current_bus_type == 1:
                pp_res_gen = append(
                    pp_res_gen,
                    array(pp_net.res_sgen[pp_net.sgen.bus == current_bus_idx][[
                        'p_kw', 'q_kvar'
                    ]])[already_used_gen.at[current_bus_idx]].reshape((1, 2)),
                    0)
                already_used_gen.at[current_bus_idx] += 1
        pp_res_gen = pp_res_gen[1:, :]  # delete initial zero row

        # --- pandapower branch result table
        pp_res_branch = zeros([1, 4])
        # consideration of parallel branches via storing how much branches have been considered
        # each node-to-node-connection
        init1 = concat([pp_net.line.from_bus, pp_net.line.to_bus],
                       axis=1).drop_duplicates()
        init2 = concat([pp_net.trafo.hv_bus, pp_net.trafo.lv_bus],
                       axis=1).drop_duplicates()
        init1['hv_bus'] = nan
        init1['lv_bus'] = nan
        init2['from_bus'] = nan
        init2['to_bus'] = nan
        already_used_branches = concat([init1, init2], axis=0)
        already_used_branches['number'] = zeros(
            [already_used_branches.shape[0], 1]).astype(int)
        BRANCHES = DataFrame(ppc_res['branch'][:, [0, 1, 8, 9]])
        for i in BRANCHES.index:
            from_bus = pp.get_element_index(pp_net,
                                            'bus',
                                            name=int(ppc_res['branch'][i, 0]))
            to_bus = pp.get_element_index(pp_net,
                                          'bus',
                                          name=int(ppc_res['branch'][i, 1]))
            from_vn_kv = ppc_res['bus'][from_bus, 9]
            to_vn_kv = ppc_res['bus'][to_bus, 9]
            ratio = BRANCHES[2].at[i]
            angle = BRANCHES[3].at[i]
            # from line results
            if (from_vn_kv == to_vn_kv) & ((ratio == 0) |
                                           (ratio == 1)) & (angle == 0):
                pp_res_branch = append(
                    pp_res_branch,
                    array(
                        pp_net.res_line[(pp_net.line.from_bus == from_bus)
                                        & (pp_net.line.to_bus == to_bus)]
                        [['p_from_kw', 'q_from_kvar', 'p_to_kw',
                          'q_to_kvar']])[int(already_used_branches.number.loc[
                              (already_used_branches.from_bus == from_bus)
                              & (already_used_branches.to_bus == to_bus)].
                                             values)].reshape(1, 4), 0)
                already_used_branches.number.loc[
                    (already_used_branches.from_bus == from_bus)
                    & (already_used_branches.to_bus == to_bus)] += 1
            # from trafo results
            else:
                if from_vn_kv >= to_vn_kv:
                    pp_res_branch = append(
                        pp_res_branch,
                        array(pp_net.res_trafo[
                            (pp_net.trafo.hv_bus == from_bus)
                            & (pp_net.trafo.lv_bus == to_bus)][[
                                'p_hv_kw', 'q_hv_kvar', 'p_lv_kw', 'q_lv_kvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == from_bus)
                                & (already_used_branches.lv_bus == to_bus)].
                                    values)].reshape(1, 4), 0)
                    already_used_branches.number.loc[
                        (already_used_branches.hv_bus == from_bus)
                        & (already_used_branches.lv_bus == to_bus)] += 1
                else:  # switch hv-lv-connection of pypower connection buses
                    pp_res_branch = append(
                        pp_res_branch,
                        array(pp_net.res_trafo[
                            (pp_net.trafo.hv_bus == to_bus)
                            & (pp_net.trafo.lv_bus == from_bus)][[
                                'p_lv_kw', 'q_lv_kvar', 'p_hv_kw', 'q_hv_kvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == to_bus)
                                & (already_used_branches.lv_bus == from_bus)].
                                    values)].reshape(1, 4), 0)
                    already_used_branches.number.loc[
                        (already_used_branches.hv_bus == to_bus)
                        & (already_used_branches.lv_bus == from_bus)] += 1
        pp_res_branch = pp_res_branch[1:, :]  # delete initial zero row

        # --- do the power flow result comparison
        diff_res_bus = ppc_res_bus - pp_res_bus
        diff_res_branch = ppc_res_branch - pp_res_branch * 1e-3
        diff_res_gen = ppc_res_gen + pp_res_gen * 1e-3
        # comparison of buses with several generator units only as q sum
        GEN_uniq = GENS.drop_duplicates()
        for i in GEN_uniq.loc[GEN_uniq[0].isin(change_q_compare)].index:
            next_is = GEN_uniq.index[GEN_uniq.index > i]
            if len(next_is) > 0:
                next_i = next_is[0]
            else:
                next_i = GENS.index[-1] + 1
            if (next_i - i) > 1:
                diff_res_gen[i:next_i, 1] = sum(diff_res_gen[i:next_i, 1])
        # logger info
        logger.debug(
            "Maximum voltage magnitude difference between pypower and pandapower: "
            "%.2e pu" % max(abs(diff_res_bus[:, 0])))
        logger.debug(
            "Maximum voltage angle difference between pypower and pandapower: "
            "%.2e degree" % max(abs(diff_res_bus[:, 1])))
        logger.debug(
            "Maximum branch flow active power difference between pypower and pandapower: "
            "%.2e kW" % max(abs(diff_res_branch[:, [0, 2]] * 1e3)))
        logger.debug(
            "Maximum branch flow reactive power difference between pypower and "
            "pandapower: %.2e kVAr" %
            max(abs(diff_res_branch[:, [1, 3]] * 1e3)))
        logger.debug(
            "Maximum active power generation difference between pypower and pandapower: "
            "%.2e kW" % max(abs(diff_res_gen[:, 0] * 1e3)))
        logger.debug(
            "Maximum reactive power generation difference between pypower and pandapower: "
            "%.2e kVAr" % max(abs(diff_res_gen[:, 1] * 1e3)))
        if (max(abs(diff_res_bus[:, 0])) < 1e-3) & (max(abs(diff_res_bus[:, 1])) < 1e-3) & \
                (max(abs(diff_res_branch[:, [0, 2]])) < 1e-3) & \
                (max(abs(diff_res_branch[:, [1, 3]])) < 1e-3) & \
                (max(abs(diff_res_gen)) > 1e-1).any():
            logger.debug(
                "The active/reactive power generation difference possibly results "
                "because of a pypower error. Please validate "
                "the results via pypower loadflow."
            )  # this occurs e.g. at ppc case9
        # give a return
        if type(max_diff_values) == dict:
            if Series([
                    'q_gen_kvar', 'p_branch_kw', 'q_branch_kvar', 'p_gen_kw',
                    'va_degree', 'vm_pu'
            ]).isin(Series(list(max_diff_values.keys()))).all():
                if (max(abs(diff_res_bus[:, 0])) < max_diff_values['vm_pu']) & \
                        (max(abs(diff_res_bus[:, 1])) < max_diff_values['va_degree']) & \
                        (max(abs(diff_res_branch[:, [0, 2]])) < max_diff_values['p_branch_kw'] /
                            1e3) & \
                        (max(abs(diff_res_branch[:, [1, 3]])) < max_diff_values['q_branch_kvar'] /
                            1e3) & \
                        (max(abs(diff_res_gen[:, 0])) < max_diff_values['p_gen_kw'] / 1e3) & \
                        (max(abs(diff_res_gen[:, 1])) < max_diff_values['q_gen_kvar'] / 1e3):
                    return True
                else:
                    return False
            else:
                logger.debug('Not all requried dict keys are provided.')
        else:
            logger.debug("'max_diff_values' must be a dict.")
コード例 #47
0
def t_dcline(quiet=False):
    """Tests for DC line extension in L{{toggle_dcline}.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    num_tests = 50

    t_begin(num_tests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_dcline')
    if quiet:
        verbose = False
    else:
        verbose = False

    t0 = ''
    ppopt = ppoption(OPF_VIOLATION=1e-6, PDIPM_GRADTOL=1e-8,
            PDIPM_COMPTOL=1e-8, PDIPM_COSTTOL=1e-9)
    ppopt = ppoption(ppopt, OPF_ALG=560, OPF_ALG_DC=200)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=verbose)

    ## set up indices
    ib_data     = r_[arange(BUS_AREA + 1), arange(BASE_KV, VMIN + 1)]
    ib_voltage  = arange(VM, VA + 1)
    ib_lam      = arange(LAM_P, LAM_Q + 1)
    ib_mu       = arange(MU_VMAX, MU_VMIN + 1)
    ig_data     = r_[[GEN_BUS, QMAX, QMIN], arange(MBASE, APF + 1)]
    ig_disp     = array([PG, QG, VG])
    ig_mu       = arange(MU_PMAX, MU_QMIN + 1)
    ibr_data    = arange(ANGMAX + 1)
    ibr_flow    = arange(PF, QT + 1)
    ibr_mu      = array([MU_SF, MU_ST])
    ibr_angmu   = array([MU_ANGMIN, MU_ANGMAX])

    ## load case
    ppc0 = loadcase(casefile)
    del ppc0['dclinecost']
    ppc = ppc0
    ppc = toggle_dcline(ppc, 'on')
    ppc = toggle_dcline(ppc, 'off')
    ndc = ppc['dcline'].shape[0]

    ## run AC OPF w/o DC lines
    t = ''.join([t0, 'AC OPF (no DC lines) : '])
    r0 = runopf(ppc0, ppopt)
    success = r0['success']
    t_ok(success, [t, 'success'])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['f'], r0['f'], 8, [t, 'f'])
    t_is(   r['bus'][:,ib_data   ],    r0['bus'][:,ib_data   ], 10, [t, 'bus data'])
    t_is(   r['bus'][:,ib_voltage],    r0['bus'][:,ib_voltage],  3, [t, 'bus voltage'])
    t_is(   r['bus'][:,ib_lam    ],    r0['bus'][:,ib_lam    ],  3, [t, 'bus lambda'])
    t_is(   r['bus'][:,ib_mu     ],    r0['bus'][:,ib_mu     ],  2, [t, 'bus mu'])
    t_is(   r['gen'][:,ig_data   ],    r0['gen'][:,ig_data   ], 10, [t, 'gen data'])
    t_is(   r['gen'][:,ig_disp   ],    r0['gen'][:,ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(   r['gen'][:,ig_mu     ],    r0['gen'][:,ig_mu     ],  3, [t, 'gen mu'])
    t_is(r['branch'][:,ibr_data  ], r0['branch'][:,ibr_data  ], 10, [t, 'branch data'])
    t_is(r['branch'][:,ibr_flow  ], r0['branch'][:,ibr_flow  ],  3, [t, 'branch flow'])
    t_is(r['branch'][:,ibr_mu    ], r0['branch'][:,ibr_mu    ],  2, [t, 'branch mu'])

    t = ''.join([t0, 'AC PF (no DC lines) : '])
    ppc1 = {'baseMVA': r['baseMVA'],
            'bus': r['bus'][:, :VMIN + 1].copy(),
            'gen': r['gen'][:, :APF + 1].copy(),
            'branch': r['branch'][:, :ANGMAX + 1].copy(),
            'gencost': r['gencost'].copy(),
            'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()}
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(   rp['bus'][:,ib_voltage],    r['bus'][:,ib_voltage],  3, [t, 'bus voltage'])
    t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(rp['branch'][:,ibr_flow  ], r['branch'][:,ibr_flow  ],  3, [t, 'branch flow'])

    ## run with DC lines
    t = ''.join([t0, 'AC OPF (with DC lines) : '])
    ppc = toggle_dcline(ppc, 'on')
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected = array([
        [10,     8.9,  -10,       10, 1.0674, 1.0935],
        [2.2776, 2.2776, 0,        0, 1.0818, 1.0665],
        [0,      0,      0,        0, 1.0000, 1.0000],
        [10,     9.5,    0.0563, -10, 1.0778, 1.0665]
    ])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected, 4, [t, 'P Q V'])
    expected = array([
        [0, 0.8490, 0.6165, 0,      0,      0.2938],
        [0, 0,      0,      0.4290, 0.0739, 0],
        [0, 0,      0,      0,      0,      0],
        [0, 7.2209, 0,      0,      0.0739, 0]
    ])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected, 3, [t, 'mu'])

    t = ''.join([t0, 'AC PF (with DC lines) : '])
    ppc1 = {'baseMVA': r['baseMVA'],
            'bus': r['bus'][:, :VMIN + 1].copy(),
            'gen': r['gen'][:, :APF + 1].copy(),
            'branch': r['branch'][:, :ANGMAX + 1].copy(),
            'gencost': r['gencost'].copy(),
            'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()}
    ppc1 = toggle_dcline(ppc1, 'on')
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(   rp['bus'][:,ib_voltage],    r['bus'][:,ib_voltage], 3, [t, 'bus voltage'])
    #t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ], 3, [t, 'gen dispatch'])
    t_is(   rp['gen'][:2,ig_disp ],    r['gen'][:2,ig_disp ], 3, [t, 'gen dispatch'])
    t_is(   rp['gen'][2,PG        ],    r['gen'][2,PG        ], 3, [t, 'gen dispatch'])
    t_is(   rp['gen'][2,QG]+rp['dcline'][0,c.QF], r['gen'][2,QG]+r['dcline'][0,c.QF], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:,ibr_flow  ], r['branch'][:,ibr_flow  ], 3, [t, 'branch flow'])

    ## add appropriate P and Q injections and check angles and generation when running PF
    t = ''.join([t0, 'AC PF (with equivalent injections) : '])
    ppc1 = {'baseMVA': r['baseMVA'],
            'bus': r['bus'][:, :VMIN + 1].copy(),
            'gen': r['gen'][:, :APF + 1].copy(),
            'branch': r['branch'][:, :ANGMAX + 1].copy(),
            'gencost': r['gencost'].copy(),
            'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()}
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    for k in range(ndc):
        if ppc1['dcline'][k, c.BR_STATUS]:
            ff = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.F_BUS])
            tt = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.T_BUS])
            ppc1['bus'][ff, PD] = ppc1['bus'][ff, PD] + r['dcline'][k, c.PF]
            ppc1['bus'][ff, QD] = ppc1['bus'][ff, QD] - r['dcline'][k, c.QF]
            ppc1['bus'][tt, PD] = ppc1['bus'][tt, PD] - r['dcline'][k, c.PT]
            ppc1['bus'][tt, QD] = ppc1['bus'][tt, QD] - r['dcline'][k, c.QT]
            ppc1['bus'][ff, VM] = r['dcline'][k, c.VF]
            ppc1['bus'][tt, VM] = r['dcline'][k, c.VT]
            ppc1['bus'][ff, BUS_TYPE] = PV
            ppc1['bus'][tt, BUS_TYPE] = PV

    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(   rp['bus'][:,ib_voltage],    r['bus'][:,ib_voltage],  3, [t, 'bus voltage'])
    t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(rp['branch'][:,ibr_flow  ], r['branch'][:,ibr_flow  ],  3, [t, 'branch flow'])

    ## test DC OPF
    t = ''.join([t0, 'DC OPF (with DC lines) : '])
    ppc = ppc0.copy()
    ppc['gen'][0, PMIN] = 10
    ppc['branch'][4, RATE_A] = 100
    ppc = toggle_dcline(ppc, 'on')
    r = rundcopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected = array([
        [10, 8.9, 0, 0, 1.01, 1],
        [2,  2,   0, 0, 1,    1],
        [0,  0,   0, 0, 1,    1],
        [10, 9.5, 0, 0, 1, 0.98]
    ])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected, 4, [t, 'P Q V'])
    expected = array([
        [0,      1.8602, 0, 0, 0, 0],
        [1.8507, 0,      0, 0, 0, 0],
        [0,      0,      0, 0, 0, 0],
        [0,      0.2681, 0, 0, 0, 0]
    ])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected, 3, [t, 'mu'])

    t = ''.join([t0, 'DC PF (with DC lines) : '])
    ppc1 = {'baseMVA': r['baseMVA'],
            'bus': r['bus'][:, :VMIN + 1].copy(),
            'gen': r['gen'][:, :APF + 1].copy(),
            'branch': r['branch'][:, :ANGMAX + 1].copy(),
            'gencost': r['gencost'].copy(),
            'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()}
    ppc1 = toggle_dcline(ppc1, 'on')
    ppc1['bus'][:, VA] = 0
    rp = rundcpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(   rp['bus'][:,ib_voltage],    r['bus'][:,ib_voltage], 3, [t, 'bus voltage'])
    t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:,ibr_flow  ], r['branch'][:,ibr_flow  ], 3, [t, 'branch flow'])

    ## add appropriate P injections and check angles and generation when running PF
    t = ''.join([t0, 'DC PF (with equivalent injections) : '])
    ppc1 = {'baseMVA': r['baseMVA'],
            'bus': r['bus'][:, :VMIN + 1].copy(),
            'gen': r['gen'][:, :APF + 1].copy(),
            'branch': r['branch'][:, :ANGMAX + 1].copy(),
            'gencost': r['gencost'].copy(),
            'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()}
    ppc1['bus'][:, VA] = 0
    for k in range(ndc):
        if ppc1['dcline'][k, c.BR_STATUS]:
            ff = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.F_BUS])
            tt = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.T_BUS])
            ppc1['bus'][ff, PD] = ppc1['bus'][ff, PD] + r['dcline'][k, c.PF]
            ppc1['bus'][tt, PD] = ppc1['bus'][tt, PD] - r['dcline'][k, c.PT]
            ppc1['bus'][ff, BUS_TYPE] = PV
            ppc1['bus'][tt, BUS_TYPE] = PV

    rp = rundcpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(   rp['bus'][:,ib_voltage],    r['bus'][:,ib_voltage],  3, [t, 'bus voltage'])
    t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ],  3, [t, 'gen dispatch'])
    t_is(rp['branch'][:,ibr_flow  ], r['branch'][:,ibr_flow  ],  3, [t, 'branch flow'])

    ## run with DC lines
    t = ''.join([t0, 'AC OPF (with DC lines + poly cost) : '])
    ppc = loadcase(casefile)
    ppc = toggle_dcline(ppc, 'on')
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected1 = array([
        [10,     8.9,   -10,       10, 1.0663, 1.0936],
        [7.8429, 7.8429,  0,        0, 1.0809, 1.0667],
        [0,      0,       0,        0, 1.0000, 1.0000],
        [6.0549, 5.7522, -0.5897, -10, 1.0778, 1.0667]
    ])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    expected2 = array([
        [0, 0.7605, 0.6226, 0,      0,      0.2980],
        [0, 0,      0,      0.4275, 0.0792, 0],
        [0, 0,      0,      0,      0,      0],
        [0, 0,      0,      0,      0.0792, 0]
    ])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    ppc['dclinecost'][3, :8] = array([2, 0, 0, 4, 0, 0, 7.3, 0])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    t = ''.join([t0, 'AC OPF (with DC lines + pwl cost) : '])
    ppc['dclinecost'][3, :8] = array([1, 0, 0, 2, 0, 0, 10, 73])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    t_end()
コード例 #48
0
def opf_args(*args):
    """Parses and initializes OPF input arguments.

    Returns the full set of initialized OPF input arguments, filling in
    default values for missing arguments. See Examples below for the
    possible calling syntax options.

    Input arguments options::

        opf_args(ppc)
        opf_args(ppc, ppopt)
        opf_args(ppc, userfcn, ppopt)
        opf_args(ppc, A, l, u)
        opf_args(ppc, A, l, u, ppopt)
        opf_args(ppc, A, l, u, ppopt, N, fparm, H, Cw)
        opf_args(ppc, A, l, u, ppopt, N, fparm, H, Cw, z0, zl, zu)

        opf_args(baseMVA, bus, gen, branch, areas, gencost)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, ppopt)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, userfcn, ppopt)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, A, l, u)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ppopt)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ...
                                    ppopt, N, fparm, H, Cw)
        opf_args(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ...
                                    ppopt, N, fparm, H, Cw, z0, zl, zu)

    The data for the problem can be specified in one of three ways:
      1. a string (ppc) containing the file name of a PYPOWER case
      which defines the data matrices baseMVA, bus, gen, branch, and
      gencost (areas is not used at all, it is only included for
      backward compatibility of the API).
      2. a dict (ppc) containing the data matrices as fields.
      3. the individual data matrices themselves.

    The optional user parameters for user constraints (C{A, l, u}), user costs
    (C{N, fparm, H, Cw}), user variable initializer (z0), and user variable
    limits (C{zl, zu}) can also be specified as fields in a case dict,
    either passed in directly or defined in a case file referenced by name.

    When specified, C{A, l, u} represent additional linear constraints on the
    optimization variables, C{l <= A*[x z] <= u}. If the user specifies an C{A}
    matrix that has more columns than the number of "C{x}" (OPF) variables,
    then there are extra linearly constrained "C{z}" variables. For an
    explanation of the formulation used and instructions for forming the
    C{A} matrix, see the MATPOWER manual.

    A generalized cost on all variables can be applied if input arguments
    C{N}, C{fparm}, C{H} and C{Cw} are specified.  First, a linear
    transformation of the optimization variables is defined by means of
    C{r = N * [x z]}. Then, to each element of r a function is applied as
    encoded in the C{fparm} matrix (see Matpower manual). If the resulting
    vector is named C{w}, then C{H} and C{Cw} define a quadratic cost on
    C{w}: C{(1/2)*w'*H*w + Cw * w}.
    C{H} and C{N} should be sparse matrices and C{H} should also be symmetric.

    The optional C{ppopt} vector specifies PYPOWER options. See L{ppoption}
    for details and default values.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Carlos E. Murillo-Sanchez (PSERC Cornell & Universidad
    Autonoma de Manizales)
    @author: Richard Lincoln
    """
#    nargin = len([arg for arg in [baseMVA, bus, gen, branch, areas, gencost,
#                                  Au, lbu, ubu, ppopt, N, fparm, H, Cw,
#                                  z0, zl, zu] if arg is not None])
    nargin = len(args)

    userfcn = array([])
    ## passing filename or dict
    if isinstance(args[0], basestring) or isinstance(args[0], dict):
        # ----opf( baseMVA,     bus,   gen, branch, areas, gencost,    Au, lbu,  ubu, ppopt,  N, fparm, H, Cw, z0, zl, zu)
        # 12  opf(casefile,      Au,   lbu,    ubu, ppopt,       N, fparm,    H,  Cw,    z0, zl,    zu)
        # 9   opf(casefile,      Au,   lbu,    ubu, ppopt,       N, fparm,    H,  Cw)
        # 5   opf(casefile,      Au,   lbu,    ubu, ppopt)
        # 4   opf(casefile,      Au,   lbu,    ubu)
        # 3   opf(casefile, userfcn, ppopt)
        # 2   opf(casefile,   ppopt)
        # 1   opf(casefile)
        if nargin in [1, 2, 3, 4, 5, 9, 12]:
            casefile = args[0]
            if nargin == 12:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu,  ubu, ppopt,  N, fparm = args
                zu    = fparm
                zl    = N
                z0    = ppopt
                Cw    = ubu
                H     = lbu
                fparm = Au
                N     = gencost
                ppopt = areas
                ubu   = branch
                lbu   = gen
                Au    = bus
            elif nargin == 9:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu = args
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = ubu
                H     = lbu
                fparm = Au
                N     = gencost
                ppopt = areas
                ubu   = branch
                lbu   = gen
                Au    = bus
            elif nargin == 5:
                baseMVA, bus, gen, branch, areas = args
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = array([])
                H     = None
                fparm = array([])
                N     = None
                ppopt = areas
                ubu   = branch
                lbu   = gen
                Au    = bus
            elif nargin == 4:
                baseMVA, bus, gen, branch = args
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = array([])
                H     = None
                fparm = array([])
                N     = None
                ppopt = ppoption()
                ubu   = branch
                lbu   = gen
                Au    = bus
            elif nargin == 3:
                baseMVA, bus, gen = args
                userfcn = bus
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = array([])
                H     = None
                fparm = array([])
                N     = None
                ppopt = gen
                ubu   = array([])
                lbu   = array([])
                Au    = None
            elif nargin == 2:
                baseMVA, bus = args
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = array([])
                H     = None
                fparm = array([])
                N     = None
                ppopt = bus
                ubu   = array([])
                lbu   = array([])
                Au    = None
            elif nargin == 1:
                zu    = array([])
                zl    = array([])
                z0    = array([])
                Cw    = array([])
                H     = None
                fparm = array([])
                N     = None
                ppopt = ppoption()
                ubu   = array([])
                lbu   = array([])
                Au    = None
        else:
            stderr.write('opf_args: Incorrect input arg order, number or type\n')

        ppc = loadcase(casefile)
        baseMVA, bus, gen, branch, gencost = \
            ppc['baseMVA'], ppc['bus'], ppc['gen'], ppc['branch'], ppc['gencost']
        if 'areas' in ppc:
            areas = ppc['areas']
        else:
            areas = array([])
        if Au is None and 'A' in ppc:
            Au, lbu, ubu = ppc["A"], ppc["l"], ppc["u"]
        if N is None and 'N' in ppc:  ## these two must go together
            N, Cw = ppc["N"], ppc["Cw"]
        if H is None and 'H' in ppc:  ## will default to zeros
            H = ppc["H"]
        if (fparm is None or len(fparm) == 0) and 'fparm' in ppc:  ## will default to [1 0 0 1]
            fparm = ppc["fparm"]
        if (z0 is None or len(z0) == 0) and 'z0' in ppc:
            z0 = ppc["z0"]
        if (zl is None or len(zl) == 0) and 'zl' in ppc:
            zl = ppc["zl"]
        if (zu is None or len(zu) == 0) and 'zu' in ppc:
            zu = ppc["zu"]
        if (userfcn is None or len(userfcn) == 0) and 'userfcn' in ppc:
            userfcn = ppc['userfcn']
    else: ## passing individual data matrices
        # ----opf(baseMVA, bus, gen, branch, areas, gencost,      Au, lbu, ubu, ppopt, N, fparm, H, Cw, z0, zl, zu)
        # 17  opf(baseMVA, bus, gen, branch, areas, gencost,      Au, lbu, ubu, ppopt, N, fparm, H, Cw, z0, zl, zu)
        # 14  opf(baseMVA, bus, gen, branch, areas, gencost,      Au, lbu, ubu, ppopt, N, fparm, H, Cw)
        # 10  opf(baseMVA, bus, gen, branch, areas, gencost,      Au, lbu, ubu, ppopt)
        # 9   opf(baseMVA, bus, gen, branch, areas, gencost,      Au, lbu, ubu)
        # 8   opf(baseMVA, bus, gen, branch, areas, gencost, userfcn, ppopt)
        # 7   opf(baseMVA, bus, gen, branch, areas, gencost, ppopt)
        # 6   opf(baseMVA, bus, gen, branch, areas, gencost)
        if nargin in [6, 7, 8, 9, 10, 14, 17]:
            if nargin == 17:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, ppopt,  N, fparm, H, Cw, z0, zl, zu = args
            elif nargin == 14:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, ppopt,  N, fparm, H, Cw = args
                zu = array([])
                zl = array([])
                z0 = array([])
            elif nargin == 10:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, ppopt = args
                zu = array([])
                zl = array([])
                z0 = array([])
                Cw = array([])
                H = None
                fparm = array([])
                N = None
            elif nargin == 9:
                baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu = args
                zu = array([])
                zl = array([])
                z0 = array([])
                Cw = array([])
                H = None
                fparm = array([])
                N = None
                ppopt = ppoption()
            elif nargin == 8:
                baseMVA, bus, gen, branch, areas, gencost, userfcn, ppopt = args
                zu = array([])
                zl = array([])
                z0 = array([])
                Cw = array([])
                H = None
                fparm = array([])
                N = None
                ubu = array([])
                lbu = array([])
                Au = None
            elif nargin == 7:
                baseMVA, bus, gen, branch, areas, gencost, ppopt = args
                zu = array([])
                zl = array([])
                z0 = array([])
                Cw = array([])
                H = None
                fparm = array([])
                N = None
                ubu = array([])
                lbu = array([])
                Au = None
            elif nargin == 6:
                baseMVA, bus, gen, branch, areas, gencost = args
                zu = array([])
                zl = array([])
                z0 = array([])
                Cw = array([])
                H = None
                fparm = array([])
                N = None
                ppopt = ppoption()
                ubu = array([])
                lbu = array([])
                Au = None
        else:
            stderr.write('opf_args: Incorrect input arg order, number or type\n')

    if N is not None:
        nw = N.shape[0]
    else:
        nw = 0

    if nw:
        if Cw.shape[0] != nw:
            stderr.write('opf_args.m: dimension mismatch between N and Cw in '
                         'generalized cost parameters\n')
        if len(fparm) > 0 and fparm.shape[0] != nw:
            stderr.write('opf_args.m: dimension mismatch between N and fparm '
                         'in generalized cost parameters\n')
        if (H is not None) and (H.shape[0] != nw | H.shape[0] != nw):
            stderr.write('opf_args.m: dimension mismatch between N and H in '
                         'generalized cost parameters\n')
        if Au is not None:
            if Au.shape[0] > 0 and N.shape[1] != Au.shape[1]:
                stderr.write('opf_args.m: A and N must have the same number '
                             'of columns\n')
        ## make sure N and H are sparse
        if not issparse(N):
            stderr.write('opf_args.m: N must be sparse in generalized cost '
                         'parameters\n')
        if not issparse(H):
            stderr.write('opf_args.m: H must be sparse in generalized cost parameters\n')

    if Au is not None and not issparse(Au):
        stderr.write('opf_args.m: Au must be sparse\n')
    if ppopt == None or len(ppopt) == 0:
        ppopt = ppoption()

    return baseMVA, bus, gen, branch, gencost, Au, lbu, ubu, \
        ppopt, N, fparm, H, Cw, z0, zl, zu, userfcn, areas
コード例 #49
0
ファイル: printpf.py プロジェクト: samuraisoldier/pandapower
def printpf(baseMVA,
            bus=None,
            gen=None,
            branch=None,
            f=None,
            success=None,
            et=None,
            fd=None,
            ppopt=None):
    """Prints power flow results.

    Prints power flow and optimal power flow results to C{fd} (a file
    descriptor which defaults to C{stdout}), with the details of what
    gets printed controlled by the optional C{ppopt} argument, which is a
    PYPOWER options vector (see L{ppoption} for details).

    The data can either be supplied in a single C{results} dict, or
    in the individual arguments: C{baseMVA}, C{bus}, C{gen}, C{branch}, C{f},
    C{success} and C{et}, where C{f} is the OPF objective function value,
    C{success} is C{True} if the solution converged and C{False} otherwise,
    and C{et} is the elapsed time for the computation in seconds. If C{f} is
    given, it is assumed that the output is from an OPF run, otherwise it is
    assumed to be a simple power flow run.

    Examples::
        ppopt = ppoptions(OUT_GEN=1, OUT_BUS=0, OUT_BRANCH=0)
        fd = open(fname, 'w+b')
        results = runopf(ppc)
        printpf(results)
        printpf(results, fd)
        printpf(results, fd, ppopt)
        printpf(baseMVA, bus, gen, branch, f, success, et)
        printpf(baseMVA, bus, gen, branch, f, success, et, fd)
        printpf(baseMVA, bus, gen, branch, f, success, et, fd, ppopt)
        fd.close()

    @author: Ray Zimmerman (PSERC Cornell)
    """
    ##----- initialization -----
    ## default arguments
    if isinstance(baseMVA, dict):
        have_results_struct = 1
        results = baseMVA
        if gen is None:
            ppopt = ppoption()  ## use default options
        else:
            ppopt = gen
        if (ppopt['OUT_ALL'] == 0):
            return  ## nothin' to see here, bail out now
        if bus is None:
            fd = stdout  ## print to stdout by default
        else:
            fd = bus
        baseMVA, bus, gen, branch, success, et = \
            results["baseMVA"], results["bus"], results["gen"], \
            results["branch"], results["success"], results["et"]
        if 'f' in results:
            f = results["f"]
        else:
            f = None
    else:
        have_results_struct = 0
        if ppopt is None:
            ppopt = ppoption()  ## use default options
            if fd is None:
                fd = stdout  ## print to stdout by default
        if ppopt['OUT_ALL'] == 0:
            return  ## nothin' to see here, bail out now

    isOPF = f is not None  ## FALSE -> only simple PF data, TRUE -> OPF data

    ## options
    isDC = ppopt['PF_DC']  ## use DC formulation?
    OUT_ALL = ppopt['OUT_ALL']
    OUT_ANY = OUT_ALL == 1  ## set to true if any pretty output is to be generated
    OUT_SYS_SUM = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_SYS_SUM'])
    OUT_AREA_SUM = (OUT_ALL == 1) or ((OUT_ALL == -1)
                                      and ppopt['OUT_AREA_SUM'])
    OUT_BUS = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BUS'])
    OUT_BRANCH = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BRANCH'])
    OUT_GEN = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_GEN'])
    OUT_ANY = OUT_ANY | (
        (OUT_ALL == -1) and
        (OUT_SYS_SUM or OUT_AREA_SUM or OUT_BUS or OUT_BRANCH or OUT_GEN))

    if OUT_ALL == -1:
        OUT_ALL_LIM = ppopt['OUT_ALL_LIM']
    elif OUT_ALL == 1:
        OUT_ALL_LIM = 2
    else:
        OUT_ALL_LIM = 0

    OUT_ANY = OUT_ANY or (OUT_ALL_LIM >= 1)
    if OUT_ALL_LIM == -1:
        OUT_V_LIM = ppopt['OUT_V_LIM']
        OUT_LINE_LIM = ppopt['OUT_LINE_LIM']
        OUT_PG_LIM = ppopt['OUT_PG_LIM']
        OUT_QG_LIM = ppopt['OUT_QG_LIM']
    else:
        OUT_V_LIM = OUT_ALL_LIM
        OUT_LINE_LIM = OUT_ALL_LIM
        OUT_PG_LIM = OUT_ALL_LIM
        OUT_QG_LIM = OUT_ALL_LIM

    OUT_ANY = OUT_ANY or (
        (OUT_ALL_LIM == -1) and
        (OUT_V_LIM or OUT_LINE_LIM or OUT_PG_LIM or OUT_QG_LIM))
    ptol = 1e-4  ## tolerance for displaying shadow prices

    ## create map of external bus numbers to bus indices
    i2e = bus[:, BUS_I].astype(int)
    e2i = zeros(max(i2e) + 1, int)
    e2i[i2e] = arange(bus.shape[0])

    ## sizes of things
    nb = bus.shape[0]  ## number of buses
    nl = branch.shape[0]  ## number of branches
    ng = gen.shape[0]  ## number of generators

    ## zero out some data to make printout consistent for DC case
    if isDC:
        bus[:, r_[QD, BS]] = zeros((nb, 2))
        gen[:, r_[QG, QMAX, QMIN]] = zeros((ng, 3))
        branch[:, r_[BR_R, BR_B]] = zeros((nl, 2))

    ## parameters
    ties = find(
        bus[e2i[branch[:, F_BUS].real.astype(int)],
            BUS_AREA] != bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA])
    ## area inter-ties
    tap = ones(nl)  ## default tap ratio = 1 for lines
    xfmr = find(branch[:, TAP]).real  ## indices of transformers
    tap[xfmr] = branch[xfmr, TAP].real  ## include transformer tap ratios
    tap = tap * exp(-1j * pi / 180 * branch[:, SHIFT])  ## add phase shifters
    nzld = find((bus[:, PD] != 0.0) | (bus[:, QD] != 0.0))
    sorted_areas = sort(bus[:, BUS_AREA])
    ## area numbers
    s_areas = sorted_areas[r_[1, find(diff(sorted_areas)) + 1]]
    nzsh = find((bus[:, GS] != 0.0) | (bus[:, BS] != 0.0))
    allg = find(~isload(gen))
    ong = find((gen[:, GEN_STATUS] > 0) & ~isload(gen))
    onld = find((gen[:, GEN_STATUS] > 0) & isload(gen))
    V = bus[:, VM] * exp(-1j * pi / 180 * bus[:, VA])
    out = find(branch[:, BR_STATUS] == 0)  ## out-of-service branches
    nout = len(out)
    if isDC:
        loss = zeros(nl)
    else:
        loss = baseMVA * abs(V[e2i[ branch[:, F_BUS].real.astype(int) ]] / tap -
                             V[e2i[ branch[:, T_BUS].real.astype(int) ]])**2 / \
                    (branch[:, BR_R] - 1j * branch[:, BR_X])

    fchg = abs(V[e2i[branch[:, F_BUS].real.astype(int)]] /
               tap)**2 * branch[:, BR_B].real * baseMVA / 2
    tchg = abs(V[e2i[branch[:, T_BUS].real.astype(
        int)]])**2 * branch[:, BR_B].real * baseMVA / 2
    loss[out] = zeros(nout)
    fchg[out] = zeros(nout)
    tchg[out] = zeros(nout)

    ##----- print the stuff -----
    if OUT_ANY:
        ## convergence & elapsed time
        if success:
            fd.write('\nConverged in %.2f seconds' % et)
        else:
            fd.write('\nDid not converge (%.2f seconds)\n' % et)

        ## objective function value
        if isOPF:
            fd.write('\nObjective Function Value = %.2f $/hr' % f)

    if OUT_SYS_SUM:
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n|     System Summary                                                           |'
        )
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n\nHow many?                How much?              P (MW)            Q (MVAr)'
        )
        fd.write(
            '\n---------------------    -------------------  -------------  -----------------'
        )
        fd.write(
            '\nBuses         %6d     Total Gen Capacity   %7.1f       %7.1f to %.1f'
            % (nb, sum(gen[allg, PMAX]), sum(gen[allg,
                                                 QMIN]), sum(gen[allg, QMAX])))
        fd.write(
            '\nGenerators     %5d     On-line Capacity     %7.1f       %7.1f to %.1f'
            % (len(allg), sum(gen[ong, PMAX]), sum(
                gen[ong, QMIN]), sum(gen[ong, QMAX])))
        fd.write(
            '\nCommitted Gens %5d     Generation (actual)  %7.1f           %7.1f'
            % (len(ong), sum(gen[ong, PG]), sum(gen[ong, QG])))
        fd.write(
            '\nLoads          %5d     Load                 %7.1f           %7.1f'
            % (len(nzld) + len(onld), sum(bus[nzld, PD]) - sum(gen[onld, PG]),
               sum(bus[nzld, QD]) - sum(gen[onld, QG])))
        fd.write(
            '\n  Fixed        %5d       Fixed              %7.1f           %7.1f'
            % (len(nzld), sum(bus[nzld, PD]), sum(bus[nzld, QD])))
        fd.write(
            '\n  Dispatchable %5d       Dispatchable       %7.1f of %-7.1f%7.1f'
            % (len(onld), -sum(gen[onld, PG]), -sum(gen[onld, PMIN]),
               -sum(gen[onld, QG])))
        fd.write(
            '\nShunts         %5d     Shunt (inj)          %7.1f           %7.1f'
            % (len(nzsh), -sum(bus[nzsh, VM]**2 * bus[nzsh, GS]),
               sum(bus[nzsh, VM]**2 * bus[nzsh, BS])))
        fd.write(
            '\nBranches       %5d     Losses (I^2 * Z)     %8.2f          %8.2f'
            % (nl, sum(loss.real), sum(loss.imag)))
        fd.write(
            '\nTransformers   %5d     Branch Charging (inj)     -            %7.1f'
            % (len(xfmr), sum(fchg) + sum(tchg)))
        fd.write(
            '\nInter-ties     %5d     Total Inter-tie Flow %7.1f           %7.1f'
            % (len(ties), sum(abs(branch[ties, PF] - branch[ties, PT])) / 2,
               sum(abs(branch[ties, QF] - branch[ties, QT])) / 2))
        fd.write('\nAreas          %5d' % len(s_areas))
        fd.write('\n')
        fd.write(
            '\n                          Minimum                      Maximum')
        fd.write(
            '\n                 -------------------------  --------------------------------'
        )
        minv = min(bus[:, VM])
        mini = argmin(bus[:, VM])
        maxv = max(bus[:, VM])
        maxi = argmax(bus[:, VM])
        fd.write(
            '\nVoltage Magnitude %7.3f p.u. @ bus %-4d     %7.3f p.u. @ bus %-4d'
            % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        minv = min(bus[:, VA])
        mini = argmin(bus[:, VA])
        maxv = max(bus[:, VA])
        maxi = argmax(bus[:, VA])
        fd.write(
            '\nVoltage Angle   %8.2f deg   @ bus %-4d   %8.2f deg   @ bus %-4d'
            % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        if not isDC:
            maxv = max(loss.real)
            maxi = argmax(loss.real)
            fd.write(
                '\nP Losses (I^2*R)             -              %8.2f MW    @ line %d-%d'
                % (maxv, branch[maxi, F_BUS].real, branch[maxi, T_BUS].real))
            maxv = max(loss.imag)
            maxi = argmax(loss.imag)
            fd.write(
                '\nQ Losses (I^2*X)             -              %8.2f MVAr  @ line %d-%d'
                % (maxv, branch[maxi, F_BUS].real, branch[maxi, T_BUS].real))
        if isOPF:
            minv = min(bus[:, LAM_P])
            mini = argmin(bus[:, LAM_P])
            maxv = max(bus[:, LAM_P])
            maxi = argmax(bus[:, LAM_P])
            fd.write(
                '\nLambda P        %8.2f $/MWh @ bus %-4d   %8.2f $/MWh @ bus %-4d'
                % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
            minv = min(bus[:, LAM_Q])
            mini = argmin(bus[:, LAM_Q])
            maxv = max(bus[:, LAM_Q])
            maxi = argmax(bus[:, LAM_Q])
            fd.write(
                '\nLambda Q        %8.2f $/MWh @ bus %-4d   %8.2f $/MWh @ bus %-4d'
                % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
        fd.write('\n')

    if OUT_AREA_SUM:
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n|     Area Summary                                                             |'
        )
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\nArea  # of      # of Gens        # of Loads         # of    # of   # of   # of'
        )
        fd.write(
            '\n Num  Buses   Total  Online   Total  Fixed  Disp    Shunt   Brchs  Xfmrs   Ties'
        )
        fd.write(
            '\n----  -----   -----  ------   -----  -----  -----   -----   -----  -----  -----'
        )
        for i in range(len(s_areas)):
            a = s_areas[i]
            ib = find(bus[:, BUS_AREA] == a)
            ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                      & ~isload(gen))
            igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                        & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
            ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                         & (gen[:, GEN_STATUS] > 0) & isload(gen))
            inzld = find((bus[:, BUS_AREA] == a)
                         & logical_or(bus[:, PD], bus[:, QD]))
            inzsh = find((bus[:, BUS_AREA] == a)
                         & logical_or(bus[:, GS], bus[:, BS]))
            ibrch = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] == a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] == a))
            in_tie = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] == a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] != a))
            out_tie = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] != a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] == a))
            if not any(xfmr + 1):
                nxfmr = 0
            else:
                nxfmr = len(
                    find((bus[e2i[branch[xfmr, F_BUS].real.astype(int)],
                              BUS_AREA] == a)
                         & (bus[e2i[branch[xfmr, T_BUS].real.astype(int)],
                                BUS_AREA] == a)))
            fd.write('\n%3d  %6d   %5d  %5d   %5d  %5d  %5d   %5d   %5d  %5d  %5d' %
                (a, len(ib), len(ig), len(igon), \
                len(inzld)+len(ildon), len(inzld), len(ildon), \
                len(inzsh), len(ibrch), nxfmr, len(in_tie)+len(out_tie)))

        fd.write(
            '\n----  -----   -----  ------   -----  -----  -----   -----   -----  -----  -----'
        )
        fd.write(
            '\nTot: %6d   %5d  %5d   %5d  %5d  %5d   %5d   %5d  %5d  %5d' %
            (nb, len(allg), len(ong), len(nzld) + len(onld), len(nzld),
             len(onld), len(nzsh), nl, len(xfmr), len(ties)))
        fd.write('\n')
        fd.write(
            '\nArea      Total Gen Capacity           On-line Gen Capacity         Generation'
        )
        fd.write(
            '\n Num     MW           MVAr            MW           MVAr             MW    MVAr'
        )
        fd.write(
            '\n----   ------  ------------------   ------  ------------------    ------  ------'
        )
        for i in range(len(s_areas)):
            a = s_areas[i]
            ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                      & ~isload(gen))
            igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                        & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
            fd.write(
                '\n%3d   %7.1f  %7.1f to %-.1f  %7.1f  %7.1f to %-7.1f   %7.1f %7.1f'
                %
                (a, sum(gen[ig, PMAX]), sum(gen[ig, QMIN]), sum(
                    gen[ig, QMAX]), sum(gen[igon, PMAX]), sum(gen[igon, QMIN]),
                 sum(gen[igon, QMAX]), sum(gen[igon, PG]), sum(gen[igon, QG])))

        fd.write(
            '\n----   ------  ------------------   ------  ------------------    ------  ------'
        )
        #        fd.write('\nTot:  %7.1f  %7.1f to %-7.1f  %7.1f  %7.1f to %-7.1f   %7.1f %7.1f' %
        #                (sum(gen[allg, PMAX]), sum(gen[allg, QMIN]), sum(gen[allg, QMAX]),
        #                sum(gen[ong, PMAX]), sum(gen[ong, QMIN]), sum(gen[ong, QMAX]),
        #                sum(gen[ong, PG]), sum(gen[ong, QG]) ))
        fd.write('\n')
        fd.write(
            '\nArea    Disp Load Cap       Disp Load         Fixed Load        Total Load'
        )
        fd.write(
            '\n Num      MW     MVAr       MW     MVAr       MW     MVAr       MW     MVAr'
        )
        fd.write(
            '\n----    ------  ------    ------  ------    ------  ------    ------  ------'
        )
        Qlim = (gen[:, QMIN] == 0) * gen[:, QMAX] + (gen[:, QMAX]
                                                     == 0) * gen[:, QMIN]
        for i in range(len(s_areas)):
            a = s_areas[i]
            ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a)
                         & (gen[:, GEN_STATUS] > 0) & isload(gen))
            inzld = find((bus[:, BUS_AREA] == a)
                         & logical_or(bus[:, PD], bus[:, QD]))
            fd.write(
                '\n%3d    %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f'
                % (a, -sum(gen[ildon, PMIN]), -sum(Qlim[ildon]),
                   -sum(gen[ildon, PG]), -sum(gen[ildon, QG]),
                   sum(bus[inzld, PD]), sum(bus[inzld, QD]),
                   -sum(gen[ildon, PG]) + sum(bus[inzld, PD]),
                   -sum(gen[ildon, QG]) + sum(bus[inzld, QD])))

        fd.write(
            '\n----    ------  ------    ------  ------    ------  ------    ------  ------'
        )
        fd.write(
            '\nTot:   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f   %7.1f %7.1f' %
            (-sum(gen[onld, PMIN]), -sum(Qlim[onld]), -sum(gen[onld, PG]),
             -sum(gen[onld, QG]), sum(bus[nzld, PD]), sum(
                 bus[nzld, QD]), -sum(gen[onld, PG]) + sum(bus[nzld, PD]),
             -sum(gen[onld, QG]) + sum(bus[nzld, QD])))
        fd.write('\n')
        fd.write(
            '\nArea      Shunt Inj        Branch      Series Losses      Net Export'
        )
        fd.write(
            '\n Num      MW     MVAr     Charging      MW     MVAr       MW     MVAr'
        )
        fd.write(
            '\n----    ------  ------    --------    ------  ------    ------  ------'
        )
        for i in range(len(s_areas)):
            a = s_areas[i]
            inzsh = find((bus[:, BUS_AREA] == a)
                         & logical_or(bus[:, GS], bus[:, BS]))
            ibrch = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] == a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] == a)
                & branch[:, BR_STATUS].astype(bool))
            in_tie = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] != a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] == a)
                & branch[:, BR_STATUS].astype(bool))
            out_tie = find(
                (bus[e2i[branch[:, F_BUS].real.astype(int)], BUS_AREA] == a)
                & (bus[e2i[branch[:, T_BUS].real.astype(int)], BUS_AREA] != a)
                & branch[:, BR_STATUS].astype(bool))
            fd.write(
                '\n%3d    %7.1f %7.1f    %7.1f    %7.2f %7.2f   %7.1f %7.1f' %
                (a, -sum(bus[inzsh, VM]**2 * bus[inzsh, GS]),
                 sum(bus[inzsh, VM]**2 * bus[inzsh, BS]), sum(fchg[ibrch]) +
                 sum(tchg[ibrch]) + sum(fchg[out_tie]) + sum(tchg[in_tie]),
                 sum(real(loss[ibrch])) +
                 sum(real(loss[r_[in_tie, out_tie]])) / 2,
                 sum(imag(loss[ibrch])) +
                 sum(imag(loss[r_[in_tie, out_tie]])) / 2,
                 sum(branch[in_tie, PT]) + sum(branch[out_tie, PF]) -
                 sum(real(loss[r_[in_tie, out_tie]])) / 2,
                 sum(branch[in_tie, QT]) + sum(branch[out_tie, QF]) -
                 sum(imag(loss[r_[in_tie, out_tie]])) / 2))

        fd.write(
            '\n----    ------  ------    --------    ------  ------    ------  ------'
        )
        fd.write(
            '\nTot:   %7.1f %7.1f    %7.1f    %7.2f %7.2f       -       -' %
            (-sum(bus[nzsh, VM]**2 * bus[nzsh, GS]),
             sum(bus[nzsh, VM]**2 * bus[nzsh, BS]), sum(fchg) + sum(tchg),
             sum(real(loss)), sum(imag(loss))))
        fd.write('\n')

    ## generator data
    if OUT_GEN:
        if isOPF:
            genlamP = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_P]
            genlamQ = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_Q]

        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n|     Generator Data                                                           |'
        )
        fd.write(
            '\n================================================================================'
        )
        fd.write('\n Gen   Bus   Status     Pg        Qg   ')
        if isOPF: fd.write('   Lambda ($/MVA-hr)')
        fd.write('\n  #     #              (MW)     (MVAr) ')
        if isOPF: fd.write('     P         Q    ')
        fd.write('\n----  -----  ------  --------  --------')
        if isOPF: fd.write('  --------  --------')
        for k in range(len(ong)):
            i = ong[k]
            fd.write('\n%3d %6d     %2d ' %
                     (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
            if (gen[i, GEN_STATUS] > 0) & logical_or(gen[i, PG], gen[i, QG]):
                fd.write('%10.2f%10.2f' % (gen[i, PG], gen[i, QG]))
            else:
                fd.write('       -         -  ')
            if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))

        fd.write('\n                     --------  --------')
        fd.write('\n            Total: %9.2f%10.2f' %
                 (sum(gen[ong, PG]), sum(gen[ong, QG])))
        fd.write('\n')
        if any(onld + 1):
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\n|     Dispatchable Load Data                                                   |'
            )
            fd.write(
                '\n================================================================================'
            )
            fd.write('\n Gen   Bus   Status     Pd        Qd   ')
            if isOPF: fd.write('   Lambda ($/MVA-hr)')
            fd.write('\n  #     #              (MW)     (MVAr) ')
            if isOPF: fd.write('     P         Q    ')
            fd.write('\n----  -----  ------  --------  --------')
            if isOPF: fd.write('  --------  --------')
            for k in range(len(onld)):
                i = onld[k]
                fd.write('\n%3d %6d     %2d ' %
                         (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
                if (gen[i, GEN_STATUS] > 0) & logical_or(
                        gen[i, PG], gen[i, QG]):
                    fd.write('%10.2f%10.2f' % (-gen[i, PG], -gen[i, QG]))
                else:
                    fd.write('       -         -  ')

                if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))
            fd.write('\n                     --------  --------')
            fd.write('\n            Total: %9.2f%10.2f' %
                     (-sum(gen[onld, PG]), -sum(gen[onld, QG])))
            fd.write('\n')

    ## bus data
    if OUT_BUS:
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n|     Bus Data                                                                 |'
        )
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n Bus      Voltage          Generation             Load        ')
        if isOPF: fd.write('  Lambda($/MVA-hr)')
        fd.write(
            '\n  #   Mag(pu) Ang(deg)   P (MW)   Q (MVAr)   P (MW)   Q (MVAr)')
        if isOPF: fd.write('     P        Q   ')
        fd.write(
            '\n----- ------- --------  --------  --------  --------  --------')
        if isOPF: fd.write('  -------  -------')
        for i in range(nb):
            fd.write('\n%5d%7.3f%9.3f' % tuple(bus[i, [BUS_I, VM, VA]]))
            if bus[i, BUS_TYPE] == REF:
                fd.write('*')
            else:
                fd.write(' ')
            g = find((gen[:, GEN_STATUS] > 0)
                     & (gen[:, GEN_BUS] == bus[i, BUS_I]) & ~isload(gen))
            ld = find((gen[:, GEN_STATUS] > 0)
                      & (gen[:, GEN_BUS] == bus[i, BUS_I]) & isload(gen))
            if any(g + 1):
                fd.write('%9.2f%10.2f' % (sum(gen[g, PG]), sum(gen[g, QG])))
            else:
                fd.write('      -         -  ')

            if logical_or(bus[i, PD], bus[i, QD]) | any(ld + 1):
                if any(ld + 1):
                    fd.write('%10.2f*%9.2f*' % (bus[i, PD] - sum(gen[ld, PG]),
                                                bus[i, QD] - sum(gen[ld, QG])))
                else:
                    fd.write('%10.2f%10.2f ' % tuple(bus[i, [PD, QD]]))
            else:
                fd.write('       -         -   ')
            if isOPF:
                fd.write('%9.3f' % bus[i, LAM_P])
                if abs(bus[i, LAM_Q]) > ptol:
                    fd.write('%8.3f' % bus[i, LAM_Q])
                else:
                    fd.write('     -')
        fd.write(
            '\n                        --------  --------  --------  --------')
        fd.write('\n               Total: %9.2f %9.2f %9.2f %9.2f' %
                 (sum(gen[ong, PG]), sum(gen[ong, QG]), sum(bus[nzld, PD]) -
                  sum(gen[onld, PG]), sum(bus[nzld, QD]) - sum(gen[onld, QG])))
        fd.write('\n')

    ## branch data
    if OUT_BRANCH:
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\n|     Branch Data                                                              |'
        )
        fd.write(
            '\n================================================================================'
        )
        fd.write(
            '\nBrnch   From   To    From Bus Injection   To Bus Injection     Loss (I^2 * Z)  '
        )
        fd.write(
            '\n  #     Bus    Bus    P (MW)   Q (MVAr)   P (MW)   Q (MVAr)   P (MW)   Q (MVAr)'
        )
        fd.write(
            '\n-----  -----  -----  --------  --------  --------  --------  --------  --------'
        )
        for i in range(nl):
            fd.write(
                '\n%4d%7d%7d%10.2f%10.2f%10.2f%10.2f%10.3f%10.2f' %
                (i, branch[i, F_BUS].real, branch[i, T_BUS].real,
                 branch[i, PF].real, branch[i, QF].real, branch[i, PT].real,
                 branch[i, QT].real, loss[i].real, loss[i].imag))
        fd.write(
            '\n                                                             --------  --------'
        )
        fd.write(
            '\n                                                    Total:%10.3f%10.2f'
            % (sum(real(loss)), sum(imag(loss))))
        fd.write('\n')

    ##-----  constraint data  -----
    if isOPF:
        ctol = ppopt['OPF_VIOLATION']  ## constraint violation tolerance
        ## voltage constraints
        if (not isDC) & (
                OUT_V_LIM == 2 |
            (OUT_V_LIM == 1 &
             (any(bus[:, VM] < bus[:, VMIN] + ctol)
              | any(bus[:, VM] > bus[:, VMAX] - ctol)
              | any(bus[:, MU_VMIN] > ptol) | any(bus[:, MU_VMAX] > ptol)))):
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\n|     Voltage Constraints                                                      |'
            )
            fd.write(
                '\n================================================================================'
            )
            fd.write('\nBus #  Vmin mu    Vmin    |V|   Vmax    Vmax mu')
            fd.write('\n-----  --------   -----  -----  -----   --------')
            for i in range(nb):
                if (OUT_V_LIM == 2) | (OUT_V_LIM == 1 &
                                       ((bus[i, VM] < bus[i, VMIN] + ctol) |
                                        (bus[i, VM] > bus[i, VMAX] - ctol) |
                                        (bus[i, MU_VMIN] > ptol) |
                                        (bus[i, MU_VMAX] > ptol))):
                    fd.write('\n%5d' % bus[i, BUS_I])
                    if ((bus[i, VM] < bus[i, VMIN] + ctol) |
                        (bus[i, MU_VMIN] > ptol)):
                        fd.write('%10.3f' % bus[i, MU_VMIN])
                    else:
                        fd.write('      -   ')

                    fd.write('%8.3f%7.3f%7.3f' %
                             tuple(bus[i, [VMIN, VM, VMAX]]))
                    if (bus[i, VM] > bus[i, VMAX] - ctol) | (bus[i, MU_VMAX] >
                                                             ptol):
                        fd.write('%10.3f' % bus[i, MU_VMAX])
                    else:
                        fd.write('      -    ')
            fd.write('\n')

        ## generator P constraints
        if (OUT_PG_LIM == 2) | \
                ((OUT_PG_LIM == 1) & (any(gen[ong, PG] < gen[ong, PMIN] + ctol) |
                                      any(gen[ong, PG] > gen[ong, PMAX] - ctol) |
                                      any(gen[ong, MU_PMIN] > ptol) |
                                      any(gen[ong, MU_PMAX] > ptol))) | \
                ((not isDC) & ((OUT_QG_LIM == 2) |
                ((OUT_QG_LIM == 1) & (any(gen[ong, QG] < gen[ong, QMIN] + ctol) |
                                      any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
                                      any(gen[ong, MU_QMIN] > ptol) |
                                      any(gen[ong, MU_QMAX] > ptol))))):
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\n|     Generation Constraints                                                   |'
            )
            fd.write(
                '\n================================================================================'
            )

        if (OUT_PG_LIM == 2) | (
            (OUT_PG_LIM == 1) &
            (any(gen[ong, PG] < gen[ong, PMIN] + ctol)
             | any(gen[ong, PG] > gen[ong, PMAX] - ctol)
             | any(gen[ong, MU_PMIN] > ptol) | any(gen[ong, MU_PMAX] > ptol))):
            fd.write('\n Gen   Bus                Active Power Limits')
            fd.write(
                '\n  #     #    Pmin mu    Pmin       Pg       Pmax    Pmax mu'
            )
            fd.write(
                '\n----  -----  -------  --------  --------  --------  -------'
            )
            for k in range(len(ong)):
                i = ong[k]
                if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                                        ((gen[i, PG] < gen[i, PMIN] + ctol) |
                                         (gen[i, PG] > gen[i, PMAX] - ctol) |
                                         (gen[i, MU_PMIN] > ptol) |
                                         (gen[i, MU_PMAX] > ptol))):
                    fd.write('\n%4d%6d ' % (i, gen[i, GEN_BUS]))
                    if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] >
                                                             ptol):
                        fd.write('%8.3f' % gen[i, MU_PMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, PG]:
                        fd.write('%10.2f%10.2f%10.2f' %
                                 tuple(gen[i, [PMIN, PG, PMAX]]))
                    else:
                        fd.write('%10.2f       -  %10.2f' %
                                 tuple(gen[i, [PMIN, PMAX]]))
                    if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] >
                                                             ptol):
                        fd.write('%9.3f' % gen[i, MU_PMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## generator Q constraints
        if (not isDC) & ((OUT_QG_LIM == 2) | (
            (OUT_QG_LIM == 1) &
            (any(gen[ong, QG] < gen[ong, QMIN] + ctol)
             | any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
             any(gen[ong, MU_QMIN] > ptol) | any(gen[ong, MU_QMAX] > ptol)))):
            fd.write('\nGen  Bus              Reactive Power Limits')
            fd.write(
                '\n #    #   Qmin mu    Qmin       Qg       Qmax    Qmax mu')
            fd.write(
                '\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(ong)):
                i = ong[k]
                if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                                        ((gen[i, QG] < gen[i, QMIN] + ctol) |
                                         (gen[i, QG] > gen[i, QMAX] - ctol) |
                                         (gen[i, MU_QMIN] > ptol) |
                                         (gen[i, MU_QMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
                    if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] >
                                                             ptol):
                        fd.write('%8.3f' % gen[i, MU_QMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, QG]:
                        fd.write('%10.2f%10.2f%10.2f' %
                                 tuple(gen[i, [QMIN, QG, QMAX]]))
                    else:
                        fd.write('%10.2f       -  %10.2f' %
                                 tuple(gen[i, [QMIN, QMAX]]))

                    if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] >
                                                             ptol):
                        fd.write('%9.3f' % gen[i, MU_QMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## dispatchable load P constraints
        if (OUT_PG_LIM == 2) | (OUT_QG_LIM == 2) | \
                ((OUT_PG_LIM == 1) & (any(gen[onld, PG] < gen[onld, PMIN] + ctol) |
                                      any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
                                      any(gen[onld, MU_PMIN] > ptol) |
                                      any(gen[onld, MU_PMAX] > ptol))) | \
                ((OUT_QG_LIM == 1) & (any(gen[onld, QG] < gen[onld, QMIN] + ctol) |
                                      any(gen[onld, QG] > gen[onld, QMAX] - ctol) |
                                      any(gen[onld, MU_QMIN] > ptol) |
                                      any(gen[onld, MU_QMAX] > ptol))):
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\n|     Dispatchable Load Constraints                                            |'
            )
            fd.write(
                '\n================================================================================'
            )
        if (OUT_PG_LIM == 2) | (
            (OUT_PG_LIM == 1) &
            (any(gen[onld, PG] < gen[onld, PMIN] + ctol)
             | any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
             any(gen[onld, MU_PMIN] > ptol) | any(gen[onld, MU_PMAX] > ptol))):
            fd.write('\nGen  Bus               Active Power Limits')
            fd.write(
                '\n #    #   Pmin mu    Pmin       Pg       Pmax    Pmax mu')
            fd.write(
                '\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(onld)):
                i = onld[k]
                if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
                                        ((gen[i, PG] < gen[i, PMIN] + ctol) |
                                         (gen[i, PG] > gen[i, PMAX] - ctol) |
                                         (gen[i, MU_PMIN] > ptol) |
                                         (gen[i, MU_PMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
                    if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] >
                                                             ptol):
                        fd.write('%8.3f' % gen[i, MU_PMIN])
                    else:
                        fd.write('     -  ')
                    if gen[i, PG]:
                        fd.write('%10.2f%10.2f%10.2f' %
                                 gen[i, [PMIN, PG, PMAX]])
                    else:
                        fd.write('%10.2f       -  %10.2f' %
                                 gen[i, [PMIN, PMAX]])

                    if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] >
                                                             ptol):
                        fd.write('%9.3f' % gen[i, MU_PMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## dispatchable load Q constraints
        if (not isDC) & ((OUT_QG_LIM == 2) |
                         ((OUT_QG_LIM == 1) &
                          (any(gen[onld, QG] < gen[onld, QMIN] + ctol)
                           | any(gen[onld, QG] > gen[onld, QMAX] - ctol)
                           | any(gen[onld, MU_QMIN] > ptol)
                           | any(gen[onld, MU_QMAX] > ptol)))):
            fd.write('\nGen  Bus              Reactive Power Limits')
            fd.write(
                '\n #    #   Qmin mu    Qmin       Qg       Qmax    Qmax mu')
            fd.write(
                '\n---  ---  -------  --------  --------  --------  -------')
            for k in range(len(onld)):
                i = onld[k]
                if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
                                        ((gen[i, QG] < gen[i, QMIN] + ctol) |
                                         (gen[i, QG] > gen[i, QMAX] - ctol) |
                                         (gen[i, MU_QMIN] > ptol) |
                                         (gen[i, MU_QMAX] > ptol))):
                    fd.write('\n%3d%5d' % (i, gen(i, GEN_BUS)))
                    if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] >
                                                             ptol):
                        fd.write('%8.3f' % gen[i, MU_QMIN])
                    else:
                        fd.write('     -  ')

                    if gen[i, QG]:
                        fd.write('%10.2f%10.2f%10.2f' %
                                 gen[i, [QMIN, QG, QMAX]])
                    else:
                        fd.write('%10.2f       -  %10.2f' %
                                 gen[i, [QMIN, QMAX]])

                    if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] >
                                                             ptol):
                        fd.write('%9.3f' % gen[i, MU_QMAX])
                    else:
                        fd.write('      -  ')
            fd.write('\n')

        ## line flow constraints
        if (ppopt['OPF_FLOW_LIM'] == 1) | isDC:  ## P limit
            Ff = branch[:, PF]
            Ft = branch[:, PT]
            strg = '\n  #     Bus    Pf  mu     Pf      |Pmax|      Pt      Pt  mu   Bus'
        elif ppopt['OPF_FLOW_LIM'] == 2:  ## |I| limit
            Ff = abs((branch[:, PF] + 1j * branch[:, QF]) /
                     V[e2i[branch[:, F_BUS].astype(int)]])
            Ft = abs((branch[:, PT] + 1j * branch[:, QT]) /
                     V[e2i[branch[:, T_BUS].astype(int)]])
            strg = '\n  #     Bus   |If| mu    |If|     |Imax|     |It|    |It| mu   Bus'
        else:  ## |S| limit
            Ff = abs(branch[:, PF] + 1j * branch[:, QF])
            Ft = abs(branch[:, PT] + 1j * branch[:, QT])
            strg = '\n  #     Bus   |Sf| mu    |Sf|     |Smax|     |St|    |St| mu   Bus'

        if (OUT_LINE_LIM == 2) | (
            (OUT_LINE_LIM == 1) &
            (any((branch[:, RATE_A] != 0) &
                 (abs(Ff) > branch[:, RATE_A] - ctol)) | any(
                     (branch[:, RATE_A] != 0) &
                     (abs(Ft) > branch[:, RATE_A] - ctol))
             | any(branch[:, MU_SF] > ptol) | any(branch[:, MU_ST] > ptol))):
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\n|     Branch Flow Constraints                                                  |'
            )
            fd.write(
                '\n================================================================================'
            )
            fd.write(
                '\nBrnch   From     "From" End        Limit       "To" End        To'
            )
            fd.write(strg)
            fd.write(
                '\n-----  -----  -------  --------  --------  --------  -------  -----'
            )
            for i in range(nl):
                if (OUT_LINE_LIM == 2) | ((OUT_LINE_LIM == 1) & (
                    ((branch[i, RATE_A] != 0) &
                     (abs(Ff[i]) > branch[i, RATE_A] - ctol)) |
                    ((branch[i, RATE_A] != 0) &
                     (abs(Ft[i]) > branch[i, RATE_A] - ctol)) |
                    (branch[i, MU_SF] > ptol) | (branch[i, MU_ST] > ptol))):
                    fd.write('\n%4d%7d' % (i, branch[i, F_BUS]))
                    if (Ff[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_SF] >
                                                             ptol):
                        fd.write('%10.3f' % branch[i, MU_SF])
                    else:
                        fd.write('      -   ')

                    fd.write('%9.2f%10.2f%10.2f' %
                             (Ff[i], branch[i, RATE_A], Ft[i]))
                    if (Ft[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_ST] >
                                                             ptol):
                        fd.write('%10.3f' % branch[i, MU_ST])
                    else:
                        fd.write('      -   ')
                    fd.write('%6d' % branch[i, T_BUS])
            fd.write('\n')

    ## execute userfcn callbacks for 'printpf' stage
    if have_results_struct and 'userfcn' in results:
        if not isOPF:  ## turn off option for all constraints if it isn't an OPF
            ppopt = ppoption(ppopt, 'OUT_ALL_LIM', 0)
        run_userfcn(results["userfcn"], 'printpf', results, fd, ppopt)
コード例 #50
0
ファイル: gausspf.py プロジェクト: ink-corp/nonlinear-opt
def gausspf(Ybus, Sbus, V0, ref, pv, pq, ppopt=None):
    """Solves the power flow using a Gauss-Seidel method.

    Solves for bus voltages given the full system admittance matrix (for
    all buses), the complex bus power injection vector (for all buses),
    the initial vector of complex bus voltages, and column vectors with
    the lists of bus indices for the swing bus, PV buses, and PQ buses,
    respectively. The bus voltage vector contains the set point for
    generator (including ref bus) buses, and the reference angle of the
    swing bus, as well as an initial guess for remaining magnitudes and
    angles. C{ppopt} is a PYPOWER options vector which can be used to
    set the termination tolerance, maximum number of iterations, and
    output options (see C{ppoption} for details). Uses default options
    if this parameter is not given. Returns the final complex voltages,
    a flag which indicates whether it converged or not, and the number
    of iterations performed.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Alberto Borghetti (University of Bologna, Italy)
    """
    ## default arguments
    if ppopt is None:
        ppopt = ppoption()

    ## options
    tol     = ppopt['PF_TOL']
    max_it  = ppopt['PF_MAX_IT_GS']
    verbose = ppopt['VERBOSE']

    ## initialize
    converged = 0
    i = 0
    V = V0.copy()
    #Va = angle(V)
    Vm = abs(V)

    ## set up indexing for updating V
    npv = len(pv)
    npq = len(pq)
    pvpq = r_[pv, pq]

    ## evaluate F(x0)
    mis = V * conj(Ybus * V) - Sbus
    F = r_[  mis[pvpq].real,
             mis[pq].imag   ]

    ## check tolerance
    normF = linalg.norm(F, Inf)
    if verbose > 1:
        sys.stdout.write('\n it    max P & Q mismatch (p.u.)')
        sys.stdout.write('\n----  ---------------------------')
        sys.stdout.write('\n%3d        %10.3e' % (i, normF))
    if normF < tol:
        converged = 1
        if verbose > 1:
            sys.stdout.write('\nConverged!\n')

    ## do Gauss-Seidel iterations
    while (not converged and i < max_it):
        ## update iteration counter
        i = i + 1

        ## update voltage
        ## at PQ buses
        for k in pq[list(range(npq))]:
            tmp = (conj(Sbus[k] / V[k]) - Ybus[k, :] * V) / Ybus[k, k]
            V[k] = V[k] + asscalar(tmp)

        ## at PV buses
        if npv:
            for k in pv[list(range(npv))]:
                tmp = (V[k] * conj(Ybus[k,:] * V)).imag
                Sbus[k] = Sbus[k].real + 1j * asscalar(tmp)
                tmp = (conj(Sbus[k] / V[k]) - Ybus[k, :] * V) / Ybus[k, k]
                V[k] = V[k] + asscalar(tmp)
#               V[k] = Vm[k] * V[k] / abs(V[k])
            V[pv] = Vm[pv] * V[pv] / abs(V[pv])

        ## evalute F(x)
        mis = V * conj(Ybus * V) - Sbus
        F = r_[  mis[pv].real,
                 mis[pq].real,
                 mis[pq].imag  ]

        ## check for convergence
        normF = linalg.norm(F, Inf)
        if verbose > 1:
            sys.stdout.write('\n%3d        %10.3e' % (i, normF))
        if normF < tol:
            converged = 1
            if verbose:
                sys.stdout.write('\nGauss-Seidel power flow converged in '
                                 '%d iterations.\n' % i)

    if verbose:
        if not converged:
            sys.stdout.write('Gauss-Seidel power did not converge in %d '
                             'iterations.' % i)

    return V, converged, i
コード例 #51
0
ファイル: t_hessian.py プロジェクト: ink-corp/nonlinear-opt
def t_hessian(quiet=False):
    """Numerical tests of 2nd derivative code.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    t_begin(44, quiet)

    ## run powerflow to get solved case
    ppopt = ppoption(VERBOSE=0, OUT_ALL=0)
    results, _ = runpf(case30(), ppopt)
    baseMVA, bus, gen, branch = \
        results['baseMVA'], results['bus'], results['gen'], results['branch']

    ## switch to internal bus numbering and build admittance matrices
    _, bus, gen, branch = ext2int1(bus, gen, branch)
    Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)
    Vm = bus[:, VM]
    Va = bus[:, VA] * (pi / 180)
    V = Vm * exp(1j * Va)
    f = branch[:, F_BUS]       ## list of "from" buses
    t = branch[:, T_BUS]       ## list of "to" buses
    nl = len(f)
    nb = len(V)
    Cf = sparse((ones(nl), (range(nl), f)), (nl, nb))  ## connection matrix for line & from buses
    Ct = sparse((ones(nl), (range(nl), t)), (nl, nb))  ## connection matrix for line & to buses
    pert = 1e-8

    ##-----  check d2Sbus_dV2 code  -----
    t = ' - d2Sbus_dV2 (complex power injections)'
    lam = 10 * random.rand(nb)
    num_Haa = zeros((nb, nb), complex)
    num_Hav = zeros((nb, nb), complex)
    num_Hva = zeros((nb, nb), complex)
    num_Hvv = zeros((nb, nb), complex)
    dSbus_dVm, dSbus_dVa = dSbus_dV(Ybus, V)
    Haa, Hav, Hva, Hvv = d2Sbus_dV2(Ybus, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dSbus_dVm_ap, dSbus_dVa_ap = dSbus_dV(Ybus, Vap)
        num_Haa[:, i] = (dSbus_dVa_ap - dSbus_dVa).T * lam / pert
        num_Hva[:, i] = (dSbus_dVm_ap - dSbus_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dSbus_dVm_mp, dSbus_dVa_mp = dSbus_dV(Ybus, Vmp)
        num_Hav[:, i] = (dSbus_dVa_mp - dSbus_dVa).T * lam / pert
        num_Hvv[:, i] = (dSbus_dVm_mp - dSbus_dVm).T * lam / pert

    t_is(Haa.todense(), num_Haa, 4, ['Haa', t])
    t_is(Hav.todense(), num_Hav, 4, ['Hav', t])
    t_is(Hva.todense(), num_Hva, 4, ['Hva', t])
    t_is(Hvv.todense(), num_Hvv, 4, ['Hvv', t])

    ##-----  check d2Sbr_dV2 code  -----
    t = ' - d2Sbr_dV2 (complex power flows)'
    lam = 10 * random.rand(nl)
    # lam = [1 zeros(nl-1, 1)]
    num_Gfaa = zeros((nb, nb), complex)
    num_Gfav = zeros((nb, nb), complex)
    num_Gfva = zeros((nb, nb), complex)
    num_Gfvv = zeros((nb, nb), complex)
    num_Gtaa = zeros((nb, nb), complex)
    num_Gtav = zeros((nb, nb), complex)
    num_Gtva = zeros((nb, nb), complex)
    num_Gtvv = zeros((nb, nb), complex)
    dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, _, _ = dSbr_dV(branch, Yf, Yt, V)
    Gfaa, Gfav, Gfva, Gfvv = d2Sbr_dV2(Cf, Yf, V, lam)
    Gtaa, Gtav, Gtva, Gtvv = d2Sbr_dV2(Ct, Yt, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \
            dSbr_dV(branch, Yf, Yt, Vap)
        num_Gfaa[:, i] = (dSf_dVa_ap - dSf_dVa).T * lam / pert
        num_Gfva[:, i] = (dSf_dVm_ap - dSf_dVm).T * lam / pert
        num_Gtaa[:, i] = (dSt_dVa_ap - dSt_dVa).T * lam / pert
        num_Gtva[:, i] = (dSt_dVm_ap - dSt_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \
            dSbr_dV(branch, Yf, Yt, Vmp)
        num_Gfav[:, i] = (dSf_dVa_mp - dSf_dVa).T * lam / pert
        num_Gfvv[:, i] = (dSf_dVm_mp - dSf_dVm).T * lam / pert
        num_Gtav[:, i] = (dSt_dVa_mp - dSt_dVa).T * lam / pert
        num_Gtvv[:, i] = (dSt_dVm_mp - dSt_dVm).T * lam / pert

    t_is(Gfaa.todense(), num_Gfaa, 4, ['Gfaa', t])
    t_is(Gfav.todense(), num_Gfav, 4, ['Gfav', t])
    t_is(Gfva.todense(), num_Gfva, 4, ['Gfva', t])
    t_is(Gfvv.todense(), num_Gfvv, 4, ['Gfvv', t])

    t_is(Gtaa.todense(), num_Gtaa, 4, ['Gtaa', t])
    t_is(Gtav.todense(), num_Gtav, 4, ['Gtav', t])
    t_is(Gtva.todense(), num_Gtva, 4, ['Gtva', t])
    t_is(Gtvv.todense(), num_Gtvv, 4, ['Gtvv', t])

    ##-----  check d2Ibr_dV2 code  -----
    t = ' - d2Ibr_dV2 (complex currents)'
    lam = 10 * random.rand(nl)
    # lam = [1, zeros(nl-1)]
    num_Gfaa = zeros((nb, nb), complex)
    num_Gfav = zeros((nb, nb), complex)
    num_Gfva = zeros((nb, nb), complex)
    num_Gfvv = zeros((nb, nb), complex)
    num_Gtaa = zeros((nb, nb), complex)
    num_Gtav = zeros((nb, nb), complex)
    num_Gtva = zeros((nb, nb), complex)
    num_Gtvv = zeros((nb, nb), complex)
    dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, _, _ = dIbr_dV(branch, Yf, Yt, V)
    Gfaa, Gfav, Gfva, Gfvv = d2Ibr_dV2(Yf, V, lam)

    Gtaa, Gtav, Gtva, Gtvv = d2Ibr_dV2(Yt, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap = \
            dIbr_dV(branch, Yf, Yt, Vap)
        num_Gfaa[:, i] = (dIf_dVa_ap - dIf_dVa).T * lam / pert
        num_Gfva[:, i] = (dIf_dVm_ap - dIf_dVm).T * lam / pert
        num_Gtaa[:, i] = (dIt_dVa_ap - dIt_dVa).T * lam / pert
        num_Gtva[:, i] = (dIt_dVm_ap - dIt_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp = \
            dIbr_dV(branch, Yf, Yt, Vmp)
        num_Gfav[:, i] = (dIf_dVa_mp - dIf_dVa).T * lam / pert
        num_Gfvv[:, i] = (dIf_dVm_mp - dIf_dVm).T * lam / pert
        num_Gtav[:, i] = (dIt_dVa_mp - dIt_dVa).T * lam / pert
        num_Gtvv[:, i] = (dIt_dVm_mp - dIt_dVm).T * lam / pert

    t_is(Gfaa.todense(), num_Gfaa, 4, ['Gfaa', t])
    t_is(Gfav.todense(), num_Gfav, 4, ['Gfav', t])
    t_is(Gfva.todense(), num_Gfva, 4, ['Gfva', t])
    t_is(Gfvv.todense(), num_Gfvv, 4, ['Gfvv', t])

    t_is(Gtaa.todense(), num_Gtaa, 4, ['Gtaa', t])
    t_is(Gtav.todense(), num_Gtav, 4, ['Gtav', t])
    t_is(Gtva.todense(), num_Gtva, 4, ['Gtva', t])
    t_is(Gtvv.todense(), num_Gtvv, 4, ['Gtvv', t])

    ##-----  check d2ASbr_dV2 code  -----
    t = ' - d2ASbr_dV2 (squared apparent power flows)'
    lam = 10 * random.rand(nl)
    # lam = [1 zeros(nl-1, 1)]
    num_Gfaa = zeros((nb, nb), complex)
    num_Gfav = zeros((nb, nb), complex)
    num_Gfva = zeros((nb, nb), complex)
    num_Gfvv = zeros((nb, nb), complex)
    num_Gtaa = zeros((nb, nb), complex)
    num_Gtav = zeros((nb, nb), complex)
    num_Gtva = zeros((nb, nb), complex)
    num_Gtvv = zeros((nb, nb), complex)
    dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = dSbr_dV(branch, Yf, Yt, V)
    dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \
                            dAbr_dV(dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St)
    Gfaa, Gfav, Gfva, Gfvv = d2ASbr_dV2(dSf_dVa, dSf_dVm, Sf, Cf, Yf, V, lam)
    Gtaa, Gtav, Gtva, Gtvv = d2ASbr_dV2(dSt_dVa, dSt_dVm, St, Ct, Yt, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \
            dSbr_dV(branch, Yf, Yt, Vap)
        dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \
            dAbr_dV(dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap)
        num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert
        num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert
        num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert
        num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \
            dSbr_dV(branch, Yf, Yt, Vmp)
        dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \
            dAbr_dV(dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp)
        num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert
        num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert
        num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert
        num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert

    t_is(Gfaa.todense(), num_Gfaa, 2, ['Gfaa', t])
    t_is(Gfav.todense(), num_Gfav, 2, ['Gfav', t])
    t_is(Gfva.todense(), num_Gfva, 2, ['Gfva', t])
    t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t])

    t_is(Gtaa.todense(), num_Gtaa, 2, ['Gtaa', t])
    t_is(Gtav.todense(), num_Gtav, 2, ['Gtav', t])
    t_is(Gtva.todense(), num_Gtva, 2, ['Gtva', t])
    t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t])

    ##-----  check d2ASbr_dV2 code  -----
    t = ' - d2ASbr_dV2 (squared real power flows)'
    lam = 10 * random.rand(nl)
    # lam = [1 zeros(nl-1, 1)]
    num_Gfaa = zeros((nb, nb), complex)
    num_Gfav = zeros((nb, nb), complex)
    num_Gfva = zeros((nb, nb), complex)
    num_Gfvv = zeros((nb, nb), complex)
    num_Gtaa = zeros((nb, nb), complex)
    num_Gtav = zeros((nb, nb), complex)
    num_Gtva = zeros((nb, nb), complex)
    num_Gtvv = zeros((nb, nb), complex)
    dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = dSbr_dV(branch, Yf, Yt, V)
    dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \
           dAbr_dV(dSf_dVa.real, dSf_dVm.real, dSt_dVa.real, dSt_dVm.real, Sf.real, St.real)
    Gfaa, Gfav, Gfva, Gfvv = d2ASbr_dV2(dSf_dVa.real, dSf_dVm.real, Sf.real, Cf, Yf, V, lam)
    Gtaa, Gtav, Gtva, Gtvv = d2ASbr_dV2(dSt_dVa.real, dSt_dVm.real, St.real, Ct, Yt, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \
            dSbr_dV(branch, Yf, Yt, Vap)
        dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \
            dAbr_dV(dSf_dVa_ap.real, dSf_dVm_ap.real, dSt_dVa_ap.real, dSt_dVm_ap.real, Sf_ap.real, St_ap.real)
        num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert
        num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert
        num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert
        num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \
            dSbr_dV(branch, Yf, Yt, Vmp)
        dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \
            dAbr_dV(dSf_dVa_mp.real, dSf_dVm_mp.real, dSt_dVa_mp.real, dSt_dVm_mp.real, Sf_mp.real, St_mp.real)
        num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert
        num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert
        num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert
        num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert

    t_is(Gfaa.todense(), num_Gfaa, 2, ['Gfaa', t])
    t_is(Gfav.todense(), num_Gfav, 2, ['Gfav', t])
    t_is(Gfva.todense(), num_Gfva, 2, ['Gfva', t])
    t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t])

    t_is(Gtaa.todense(), num_Gtaa, 2, ['Gtaa', t])
    t_is(Gtav.todense(), num_Gtav, 2, ['Gtav', t])
    t_is(Gtva.todense(), num_Gtva, 2, ['Gtva', t])
    t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t])

    ##-----  check d2AIbr_dV2 code  -----
    t = ' - d2AIbr_dV2 (squared current magnitudes)'
    lam = 10 * random.rand(nl)
    # lam = [1 zeros(nl-1, 1)]
    num_Gfaa = zeros((nb, nb), complex)
    num_Gfav = zeros((nb, nb), complex)
    num_Gfva = zeros((nb, nb), complex)
    num_Gfvv = zeros((nb, nb), complex)
    num_Gtaa = zeros((nb, nb), complex)
    num_Gtav = zeros((nb, nb), complex)
    num_Gtva = zeros((nb, nb), complex)
    num_Gtvv = zeros((nb, nb), complex)
    dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It = dIbr_dV(branch, Yf, Yt, V)
    dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \
                            dAbr_dV(dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It)
    Gfaa, Gfav, Gfva, Gfvv = d2AIbr_dV2(dIf_dVa, dIf_dVm, If, Yf, V, lam)
    Gtaa, Gtav, Gtva, Gtvv = d2AIbr_dV2(dIt_dVa, dIt_dVm, It, Yt, V, lam)
    for i in range(nb):
        Vap = V.copy()
        Vap[i] = Vm[i] * exp(1j * (Va[i] + pert))
        dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap = \
            dIbr_dV(branch, Yf, Yt, Vap)
        dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \
            dAbr_dV(dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap)
        num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert
        num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert
        num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert
        num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert

        Vmp = V.copy()
        Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i])
        dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp = \
            dIbr_dV(branch, Yf, Yt, Vmp)
        dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \
            dAbr_dV(dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp)
        num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert
        num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert
        num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert
        num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert

    t_is(Gfaa.todense(), num_Gfaa, 3, ['Gfaa', t])
    t_is(Gfav.todense(), num_Gfav, 3, ['Gfav', t])
    t_is(Gfva.todense(), num_Gfva, 3, ['Gfva', t])
    t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t])

    t_is(Gtaa.todense(), num_Gtaa, 3, ['Gtaa', t])
    t_is(Gtav.todense(), num_Gtav, 3, ['Gtav', t])
    t_is(Gtva.todense(), num_Gtva, 3, ['Gtva', t])
    t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t])

    t_end()
コード例 #52
0
def t_loadcase(quiet=False):
    """Test that C{loadcase} works with an object as well as case file.

    @author: Ray Zimmerman (PSERC Cornell)
    @author: Richard Lincoln
    """
    t_begin(240, quiet)

    ## compare result of loading from M-file file to result of using data matrices
    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_opf')
    matfile  = join(tdir, 't_mat9_opf')
    pfcasefile = join(tdir, 't_case9_pf')
    pfmatfile  = join(tdir, 't_mat9_pf')
    casefilev2 = join(tdir, 't_case9_opfv2')
    matfilev2  = join(tdir, 't_mat9_opfv2')
    pfcasefilev2 = join(tdir, 't_case9_pfv2')
    pfmatfilev2  = join(tdir, 't_mat9_pfv2')

    ## read version 1 OPF data matrices
    baseMVA, bus, gen, branch, areas, gencost = t_case9_opf()
    ## save as .mat file
    savemat(matfile + '.mat', {'baseMVA': baseMVA, 'bus': bus, 'gen': gen,
            'branch': branch, 'areas': areas, 'gencost': gencost}, oned_as='row')

    ## read version 2 OPF data matrices
    ppc = t_case9_opfv2()
    ## save as .mat file
    savemat(matfilev2 + '.mat', {'ppc': ppc}, oned_as='column')

    ## prepare expected matrices for v1 load
    ## (missing gen cap curve & branch ang diff lims)
    tmp1 = (ppc['baseMVA'], ppc['bus'].copy(), ppc['gen'].copy(), ppc['branch'].copy(),
        ppc['areas'].copy(), ppc['gencost'].copy())
    tmp2 = (ppc['baseMVA'], ppc['bus'].copy(), ppc['gen'].copy(), ppc['branch'].copy(),
        ppc['areas'].copy(), ppc['gencost'].copy())
    ## remove capability curves, angle difference limits
    tmp1[2][1:3, [PC1, PC2, QC1MIN, QC1MAX, QC2MIN, QC2MAX]] = zeros((2,6))
    tmp1[3][0, ANGMAX] = 360
    tmp1[3][8, ANGMIN] = -360

    baseMVA, bus, gen, branch, areas, gencost = tmp1

    ##-----  load OPF data into individual matrices  -----
    t = 'loadcase(opf_PY_file_v1) without .py extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(casefile, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_PY_file_v1) with .py extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(casefile + '.py', False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_MAT_file_v1) without .mat extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(matfile, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_MAT_file_v1) with .mat extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(matfile + '.mat', False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v2 load
    baseMVA, bus, gen, branch, areas, gencost = tmp2

    t = 'loadcase(opf_PY_file_v2) without .py extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(casefilev2, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_PY_file_v2) with .py extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(casefilev2 + '.py', False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_MAT_file_v2) without .mat extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(matfilev2, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_MAT_file_v2) with .mat extension : '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = \
            loadcase(matfilev2 + '.mat', False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])
    t_is(areas1,    areas,      12, [t, 'areas'])
    t_is(gencost1,  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v1 load
    baseMVA, bus, gen, branch, areas, gencost = tmp1

    t = 'loadcase(opf_struct_v1) (no version): '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = t_case9_opf()
    c = {}
    c['baseMVA']   = baseMVA1
    c['bus']       = bus1.copy()
    c['gen']       = gen1.copy()
    c['branch']    = branch1.copy()
    c['areas']     = areas1.copy()
    c['gencost']   = gencost1.copy()
    baseMVA2, bus2, gen2, branch2, areas2, gencost2 = loadcase(c, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])
    t_is(areas2,    areas,      12, [t, 'areas'])
    t_is(gencost2,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_struct_v1) (version=\'1\'): '
    c['version']   = '1'
    baseMVA2, bus2, gen2, branch2, areas2, gencost2 = loadcase(c, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])
    t_is(areas2,    areas,      12, [t, 'areas'])
    t_is(gencost2,  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v2 load
    baseMVA, bus, gen, branch, areas, gencost = tmp2

    t = 'loadcase(opf_struct_v2) (no version): '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['areas']     = areas.copy()
    c['gencost']   = gencost.copy()
    baseMVA2, bus2, gen2, branch2, areas2, gencost2 = loadcase(c, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])
    t_is(areas2,    areas,      12, [t, 'areas'])
    t_is(gencost2,  gencost,    12, [t, 'gencost'])

    t = 'loadcase(opf_struct_v2) (version=''2''): '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['areas']     = areas.copy()
    c['gencost']   = gencost.copy()
    c['version']   = '2'
    baseMVA2, bus2, gen2, branch2, areas2, gencost2 = loadcase(c, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])
    t_is(areas2,    areas,      12, [t, 'areas'])
    t_is(gencost2,  gencost,    12, [t, 'gencost'])

    ##-----  load OPF data into struct  -----
    ## prepare expected matrices for v1 load
    baseMVA, bus, gen, branch, areas, gencost = tmp1

    t = 'ppc = loadcase(opf_PY_file_v1) without .py extension : '
    ppc1 = loadcase(casefile)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_PY_file_v1) with .py extension : '
    ppc1 = loadcase(casefile + '.py')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_MAT_file_v1) without .mat extension : '
    ppc1 = loadcase(matfile)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_MAT_file_v1) with .mat extension : '
    ppc1 = loadcase(matfile + '.mat')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v2 load
    baseMVA, bus, gen, branch, areas, gencost = tmp2

    t = 'ppc = loadcase(opf_PY_file_v2) without .m extension : '
    ppc1 = loadcase(casefilev2)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_PY_file_v2) with .py extension : '
    ppc1 = loadcase(casefilev2 + '.py')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_MAT_file_v2) without .mat extension : '
    ppc1 = loadcase(matfilev2)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_MAT_file_v2) with .mat extension : '
    ppc1 = loadcase(matfilev2 + '.mat')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc1['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc1['gencost'],  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v1 load
    baseMVA, bus, gen, branch, areas, gencost = tmp1

    t = 'ppc = loadcase(opf_struct_v1) (no version): '
    baseMVA1, bus1, gen1, branch1, areas1, gencost1 = t_case9_opf()
    c = {}
    c['baseMVA']   = baseMVA1
    c['bus']       = bus1.copy()
    c['gen']       = gen1.copy()
    c['branch']    = branch1.copy()
    c['areas']     = areas1.copy()
    c['gencost']   = gencost1.copy()
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc2['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc2['gencost'],  gencost,    12, [t, 'gencost'])

    t = 'ppc = loadcase(opf_struct_v1) (version=''1''): '
    c['version']   = '1'
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc2['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc2['gencost'],  gencost,    12, [t, 'gencost'])

    ## prepare expected matrices for v2 load
    baseMVA, bus, gen, branch, areas, gencost = tmp2

    t = 'ppc = loadcase(opf_struct_v2) (no version): '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['areas']     = areas.copy()
    c['gencost']   = gencost.copy()
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc2['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc2['gencost'],  gencost,    12, [t, 'gencost'])
    t_ok(ppc2['version'] == '2', [t, 'version'])

    t = 'ppc = loadcase(opf_struct_v2) (version=''2''): '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['areas']     = areas.copy()
    c['gencost']   = gencost.copy()
    c['version']   = '2'
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])
    t_is(ppc2['areas'],    areas,      12, [t, 'areas'])
    t_is(ppc2['gencost'],  gencost,    12, [t, 'gencost'])


    ## read version 1 PF data matrices
    baseMVA, bus, gen, branch = t_case9_pf()
    savemat(pfmatfile + '.mat',
        {'baseMVA': baseMVA, 'bus': bus, 'gen': gen, 'branch': branch},
        oned_as='column')

    ## read version 2 PF data matrices
    ppc = t_case9_pfv2()
    tmp = (ppc['baseMVA'], ppc['bus'].copy(),
           ppc['gen'].copy(), ppc['branch'].copy())
    baseMVA, bus, gen, branch = tmp
    ## save as .mat file
    savemat(pfmatfilev2 + '.mat', {'ppc': ppc}, oned_as='column')

    ##-----  load PF data into individual matrices  -----
    t = 'loadcase(pf_PY_file_v1) without .py extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfcasefile, False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_PY_file_v1) with .py extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfcasefile + '.py', False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_MAT_file_v1) without .mat extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfmatfile, False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_MAT_file_v1) with .mat extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfmatfile + '.mat', False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_PY_file_v2) without .py extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfcasefilev2, False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_PY_file_v2) with .py extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfcasefilev2 + '.py', False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_MAT_file_v2) without .mat extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfmatfilev2, False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_MAT_file_v2) with .mat extension : '
    baseMVA1, bus1, gen1, branch1 = \
            loadcase(pfmatfilev2 + '.mat', False, False, False)
    t_is(baseMVA1,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus1,      bus,        12, [t, 'bus'])
    t_is(gen1,      gen,        12, [t, 'gen'])
    t_is(branch1,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_struct_v1) (no version): '
    baseMVA1, bus1, gen1, branch1 = t_case9_pf()
    c = {}
    c['baseMVA']   = baseMVA1
    c['bus']       = bus1.copy()
    c['gen']       = gen1.copy()
    c['branch']    = branch1.copy()
    baseMVA2, bus2, gen2, branch2 = loadcase(c, False, False, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_struct_v1) (version=''1''): '
    c['version']   = '1'
    baseMVA2, bus2, gen2, branch2 = loadcase(c, False, False, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])

    t = 'loadcase(pf_struct_v2) : '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['version']   = '2'
    baseMVA2, bus2, gen2, branch2 = loadcase(c, False, False, False)
    t_is(baseMVA2,  baseMVA,    12, [t, 'baseMVA'])
    t_is(bus2,      bus,        12, [t, 'bus'])
    t_is(gen2,      gen,        12, [t, 'gen'])
    t_is(branch2,   branch,     12, [t, 'branch'])






    ##-----  load PF data into struct  -----
    t = 'ppc = loadcase(pf_PY_file_v1) without .py extension : '
    ppc1 = loadcase(pfcasefile)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_PY_file_v1) with .py extension : '
    ppc1 = loadcase(pfcasefile + '.py')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_MAT_file_v1) without .mat extension : '
    ppc1 = loadcase(pfmatfile)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_MAT_file_v1) with .mat extension : '
    ppc1 = loadcase(pfmatfile + '.mat')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_PY_file_v2) without .py extension : '
    ppc1 = loadcase(pfcasefilev2)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_PY_file_v2) with .py extension : '
    ppc1 = loadcase(pfcasefilev2 + '.py')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_MAT_file_v2) without .mat extension : '
    ppc1 = loadcase(pfmatfilev2)
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_MAT_file_v2) with .mat extension : '
    ppc1 = loadcase(pfmatfilev2 + '.mat')
    t_is(ppc1['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc1['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc1['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc1['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_struct_v1) (no version): '
    baseMVA1, bus1, gen1, branch1 = t_case9_pf()
    c = {}
    c['baseMVA']   = baseMVA1
    c['bus']       = bus1.copy()
    c['gen']       = gen1.copy()
    c['branch']    = branch1.copy()
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_struct_v1) (version=''1''): '
    c['version']   = '1'
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])

    t = 'ppc = loadcase(pf_struct_v2) : '
    c = {}
    c['baseMVA']   = baseMVA
    c['bus']       = bus.copy()
    c['gen']       = gen.copy()
    c['branch']    = branch.copy()
    c['version']   = '2'
    ppc2 = loadcase(c)
    t_is(ppc2['baseMVA'],  baseMVA,    12, [t, 'baseMVA'])
    t_is(ppc2['bus'],      bus,        12, [t, 'bus'])
    t_is(ppc2['gen'],      gen,        12, [t, 'gen'])
    t_is(ppc2['branch'],   branch,     12, [t, 'branch'])

    ## cleanup
    os.remove(matfile + '.mat')
    os.remove(pfmatfile + '.mat')
    os.remove(matfilev2 + '.mat')
    os.remove(pfmatfilev2 + '.mat')

    t = 'runpf(my_PY_file)'
    ppopt = ppoption(VERBOSE=0, OUT_ALL=0)
    results3, success = runpf(pfcasefile, ppopt)
    baseMVA3, bus3, gen3, branch3 = results3['baseMVA'], results3['bus'], \
            results3['gen'], results3['branch']
    t_ok( success, t )

    t = 'runpf(my_object)'
    results4, success = runpf(c, ppopt)
    baseMVA4, bus4, gen4, branch4 = results4['baseMVA'], results4['bus'], \
            results4['gen'], results4['branch']
    t_ok( success, t )

    t = 'runpf result comparison : '
    t_is(baseMVA3,  baseMVA4,   12, [t, 'baseMVA'])
    t_is(bus3,      bus4,       12, [t, 'bus'])
    t_is(gen3,      gen4,       12, [t, 'gen'])
    t_is(branch3,   branch4,    12, [t, 'branch'])

    t = 'runpf(modified_struct)'
    c['gen'][2, 1] = c['gen'][2, 1] + 1            ## increase gen 3 output by 1
    results5, success = runpf(c, ppopt)
    gen5 = results5['gen']
    t_is(gen5[0, 1], gen4[0, 1] - 1, 1, t)   ## slack bus output should decrease by 1

    t_end()
コード例 #53
0
def t_dcline(quiet=False):
    """Tests for DC line extension in L{{toggle_dcline}.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    num_tests = 50

    t_begin(num_tests, quiet)

    tdir = dirname(__file__)
    casefile = join(tdir, 't_case9_dcline')
    if quiet:
        verbose = False
    else:
        verbose = False

    t0 = ''
    ppopt = ppoption(OPF_VIOLATION=1e-6,
                     PDIPM_GRADTOL=1e-8,
                     PDIPM_COMPTOL=1e-8,
                     PDIPM_COSTTOL=1e-9)
    ppopt = ppoption(ppopt, OPF_ALG=560, OPF_ALG_DC=200)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=verbose)

    ## set up indices
    ib_data = r_[arange(BUS_AREA + 1), arange(BASE_KV, VMIN + 1)]
    ib_voltage = arange(VM, VA + 1)
    ib_lam = arange(LAM_P, LAM_Q + 1)
    ib_mu = arange(MU_VMAX, MU_VMIN + 1)
    ig_data = r_[[GEN_BUS, QMAX, QMIN], arange(MBASE, APF + 1)]
    ig_disp = array([PG, QG, VG])
    ig_mu = arange(MU_PMAX, MU_QMIN + 1)
    ibr_data = arange(ANGMAX + 1)
    ibr_flow = arange(PF, QT + 1)
    ibr_mu = array([MU_SF, MU_ST])
    ibr_angmu = array([MU_ANGMIN, MU_ANGMAX])

    ## load case
    ppc0 = loadcase(casefile)
    del ppc0['dclinecost']
    ppc = ppc0
    ppc = toggle_dcline(ppc, 'on')
    ppc = toggle_dcline(ppc, 'off')
    ndc = ppc['dcline'].shape[0]

    ## run AC OPF w/o DC lines
    t = ''.join([t0, 'AC OPF (no DC lines) : '])
    r0 = runopf(ppc0, ppopt)
    success = r0['success']
    t_ok(success, [t, 'success'])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['f'], r0['f'], 8, [t, 'f'])
    t_is(r['bus'][:, ib_data], r0['bus'][:, ib_data], 10, [t, 'bus data'])
    t_is(r['bus'][:, ib_voltage], r0['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    t_is(r['bus'][:, ib_lam], r0['bus'][:, ib_lam], 3, [t, 'bus lambda'])
    t_is(r['bus'][:, ib_mu], r0['bus'][:, ib_mu], 2, [t, 'bus mu'])
    t_is(r['gen'][:, ig_data], r0['gen'][:, ig_data], 10, [t, 'gen data'])
    t_is(r['gen'][:, ig_disp], r0['gen'][:, ig_disp], 3, [t, 'gen dispatch'])
    t_is(r['gen'][:, ig_mu], r0['gen'][:, ig_mu], 3, [t, 'gen mu'])
    t_is(r['branch'][:, ibr_data], r0['branch'][:, ibr_data], 10,
         [t, 'branch data'])
    t_is(r['branch'][:, ibr_flow], r0['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])
    t_is(r['branch'][:, ibr_mu], r0['branch'][:, ibr_mu], 2, [t, 'branch mu'])

    t = ''.join([t0, 'AC PF (no DC lines) : '])
    ppc1 = {
        'baseMVA': r['baseMVA'],
        'bus': r['bus'][:, :VMIN + 1].copy(),
        'gen': r['gen'][:, :APF + 1].copy(),
        'branch': r['branch'][:, :ANGMAX + 1].copy(),
        'gencost': r['gencost'].copy(),
        'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()
    }
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(rp['bus'][:, ib_voltage], r['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    t_is(rp['gen'][:, ig_disp], r['gen'][:, ig_disp], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:, ibr_flow], r['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])

    ## run with DC lines
    t = ''.join([t0, 'AC OPF (with DC lines) : '])
    ppc = toggle_dcline(ppc, 'on')
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected = array([[10, 8.9, -10, 10, 1.0674, 1.0935],
                      [2.2776, 2.2776, 0, 0, 1.0818, 1.0665],
                      [0, 0, 0, 0, 1.0000, 1.0000],
                      [10, 9.5, 0.0563, -10, 1.0778, 1.0665]])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected, 4, [t, 'P Q V'])
    expected = array([[0, 0.8490, 0.6165, 0, 0, 0.2938],
                      [0, 0, 0, 0.4290, 0.0739, 0], [0, 0, 0, 0, 0, 0],
                      [0, 7.2209, 0, 0, 0.0739, 0]])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected, 3, [t, 'mu'])

    t = ''.join([t0, 'AC PF (with DC lines) : '])
    ppc1 = {
        'baseMVA': r['baseMVA'],
        'bus': r['bus'][:, :VMIN + 1].copy(),
        'gen': r['gen'][:, :APF + 1].copy(),
        'branch': r['branch'][:, :ANGMAX + 1].copy(),
        'gencost': r['gencost'].copy(),
        'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()
    }
    ppc1 = toggle_dcline(ppc1, 'on')
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(rp['bus'][:, ib_voltage], r['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    #t_is(   rp['gen'][:,ig_disp   ],    r['gen'][:,ig_disp   ], 3, [t, 'gen dispatch'])
    t_is(rp['gen'][:2, ig_disp], r['gen'][:2, ig_disp], 3, [t, 'gen dispatch'])
    t_is(rp['gen'][2, PG], r['gen'][2, PG], 3, [t, 'gen dispatch'])
    t_is(rp['gen'][2, QG] + rp['dcline'][0, c.QF],
         r['gen'][2, QG] + r['dcline'][0, c.QF], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:, ibr_flow], r['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])

    ## add appropriate P and Q injections and check angles and generation when running PF
    t = ''.join([t0, 'AC PF (with equivalent injections) : '])
    ppc1 = {
        'baseMVA': r['baseMVA'],
        'bus': r['bus'][:, :VMIN + 1].copy(),
        'gen': r['gen'][:, :APF + 1].copy(),
        'branch': r['branch'][:, :ANGMAX + 1].copy(),
        'gencost': r['gencost'].copy(),
        'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()
    }
    ppc1['bus'][:, VM] = 1
    ppc1['bus'][:, VA] = 0
    for k in range(ndc):
        if ppc1['dcline'][k, c.BR_STATUS]:
            ff = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.F_BUS])
            tt = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.T_BUS])
            ppc1['bus'][ff, PD] = ppc1['bus'][ff, PD] + r['dcline'][k, c.PF]
            ppc1['bus'][ff, QD] = ppc1['bus'][ff, QD] - r['dcline'][k, c.QF]
            ppc1['bus'][tt, PD] = ppc1['bus'][tt, PD] - r['dcline'][k, c.PT]
            ppc1['bus'][tt, QD] = ppc1['bus'][tt, QD] - r['dcline'][k, c.QT]
            ppc1['bus'][ff, VM] = r['dcline'][k, c.VF]
            ppc1['bus'][tt, VM] = r['dcline'][k, c.VT]
            ppc1['bus'][ff, BUS_TYPE] = PV
            ppc1['bus'][tt, BUS_TYPE] = PV

    rp = runpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(rp['bus'][:, ib_voltage], r['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    t_is(rp['gen'][:, ig_disp], r['gen'][:, ig_disp], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:, ibr_flow], r['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])

    ## test DC OPF
    t = ''.join([t0, 'DC OPF (with DC lines) : '])
    ppc = ppc0.copy()
    ppc['gen'][0, PMIN] = 10
    ppc['branch'][4, RATE_A] = 100
    ppc = toggle_dcline(ppc, 'on')
    r = rundcopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected = array([[10, 8.9, 0, 0, 1.01, 1], [2, 2, 0, 0, 1, 1],
                      [0, 0, 0, 0, 1, 1], [10, 9.5, 0, 0, 1, 0.98]])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected, 4, [t, 'P Q V'])
    expected = array([[0, 1.8602, 0, 0, 0, 0], [1.8507, 0, 0, 0, 0, 0],
                      [0, 0, 0, 0, 0, 0], [0, 0.2681, 0, 0, 0, 0]])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected, 3, [t, 'mu'])

    t = ''.join([t0, 'DC PF (with DC lines) : '])
    ppc1 = {
        'baseMVA': r['baseMVA'],
        'bus': r['bus'][:, :VMIN + 1].copy(),
        'gen': r['gen'][:, :APF + 1].copy(),
        'branch': r['branch'][:, :ANGMAX + 1].copy(),
        'gencost': r['gencost'].copy(),
        'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()
    }
    ppc1 = toggle_dcline(ppc1, 'on')
    ppc1['bus'][:, VA] = 0
    rp = rundcpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(rp['bus'][:, ib_voltage], r['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    t_is(rp['gen'][:, ig_disp], r['gen'][:, ig_disp], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:, ibr_flow], r['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])

    ## add appropriate P injections and check angles and generation when running PF
    t = ''.join([t0, 'DC PF (with equivalent injections) : '])
    ppc1 = {
        'baseMVA': r['baseMVA'],
        'bus': r['bus'][:, :VMIN + 1].copy(),
        'gen': r['gen'][:, :APF + 1].copy(),
        'branch': r['branch'][:, :ANGMAX + 1].copy(),
        'gencost': r['gencost'].copy(),
        'dcline': r['dcline'][:, :c.LOSS1 + 1].copy()
    }
    ppc1['bus'][:, VA] = 0
    for k in range(ndc):
        if ppc1['dcline'][k, c.BR_STATUS]:
            ff = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.F_BUS])
            tt = find(ppc1['bus'][:, BUS_I] == ppc1['dcline'][k, c.T_BUS])
            ppc1['bus'][ff, PD] = ppc1['bus'][ff, PD] + r['dcline'][k, c.PF]
            ppc1['bus'][tt, PD] = ppc1['bus'][tt, PD] - r['dcline'][k, c.PT]
            ppc1['bus'][ff, BUS_TYPE] = PV
            ppc1['bus'][tt, BUS_TYPE] = PV

    rp = rundcpf(ppc1, ppopt)
    success = rp['success']
    t_ok(success, [t, 'success'])
    t_is(rp['bus'][:, ib_voltage], r['bus'][:, ib_voltage], 3,
         [t, 'bus voltage'])
    t_is(rp['gen'][:, ig_disp], r['gen'][:, ig_disp], 3, [t, 'gen dispatch'])
    t_is(rp['branch'][:, ibr_flow], r['branch'][:, ibr_flow], 3,
         [t, 'branch flow'])

    ## run with DC lines
    t = ''.join([t0, 'AC OPF (with DC lines + poly cost) : '])
    ppc = loadcase(casefile)
    ppc = toggle_dcline(ppc, 'on')
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    expected1 = array([[10, 8.9, -10, 10, 1.0663, 1.0936],
                       [7.8429, 7.8429, 0, 0, 1.0809, 1.0667],
                       [0, 0, 0, 0, 1.0000, 1.0000],
                       [6.0549, 5.7522, -0.5897, -10, 1.0778, 1.0667]])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    expected2 = array([[0, 0.7605, 0.6226, 0, 0, 0.2980],
                       [0, 0, 0, 0.4275, 0.0792, 0], [0, 0, 0, 0, 0, 0],
                       [0, 0, 0, 0, 0.0792, 0]])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    ppc['dclinecost'][3, :8] = array([2, 0, 0, 4, 0, 0, 7.3, 0])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    t = ''.join([t0, 'AC OPF (with DC lines + pwl cost) : '])
    ppc['dclinecost'][3, :8] = array([1, 0, 0, 2, 0, 0, 10, 73])
    r = runopf(ppc, ppopt)
    success = r['success']
    t_ok(success, [t, 'success'])
    t_is(r['dcline'][:, c.PF:c.VT + 1], expected1, 4, [t, 'P Q V'])
    t_is(r['dcline'][:, c.MU_PMIN:c.MU_QMAXT + 1], expected2, 3, [t, 'mu'])

    t_end()
コード例 #54
0
ファイル: fdpf.py プロジェクト: Anastien/PYPOWER
def fdpf(Ybus, Sbus, V0, Bp, Bpp, ref, pv, pq, ppopt=None):
    """Solves the power flow using a fast decoupled method.

    Solves for bus voltages given the full system admittance matrix (for
    all buses), the complex bus power injection vector (for all buses),
    the initial vector of complex bus voltages, the FDPF matrices B prime
    and B double prime, and column vectors with the lists of bus indices
    for the swing bus, PV buses, and PQ buses, respectively. The bus voltage
    vector contains the set point for generator (including ref bus)
    buses, and the reference angle of the swing bus, as well as an initial
    guess for remaining magnitudes and angles. C{ppopt} is a PYPOWER options
    vector which can be used to set the termination tolerance, maximum
    number of iterations, and output options (see L{ppoption} for details).
    Uses default options if this parameter is not given. Returns the
    final complex voltages, a flag which indicates whether it converged
    or not, and the number of iterations performed.

    @see: L{runpf}

    @author: Ray Zimmerman (PSERC Cornell)
    """
    if ppopt is None:
        ppopt = ppoption()

    ## options
    tol     = ppopt['PF_TOL']
    max_it  = ppopt['PF_MAX_IT_FD']
    verbose = ppopt['VERBOSE']

    ## initialize
    converged = 0
    i = 0
    V = V0
    Va = angle(V)
    Vm = abs(V)

    ## set up indexing for updating V
    #npv = len(pv)
    #npq = len(pq)
    pvpq = r_[pv, pq]

    ## evaluate initial mismatch
    mis = (V * conj(Ybus * V) - Sbus) / Vm
    P = mis[pvpq].real
    Q = mis[pq].imag

    ## check tolerance
    normP = linalg.norm(P, Inf)
    normQ = linalg.norm(Q, Inf)
    if verbose > 1:
        sys.stdout.write('\niteration     max mismatch (p.u.)  ')
        sys.stdout.write('\ntype   #        P            Q     ')
        sys.stdout.write('\n---- ----  -----------  -----------')
        sys.stdout.write('\n  -  %3d   %10.3e   %10.3e' % (i, normP, normQ))
    if normP < tol and normQ < tol:
        converged = 1
        if verbose > 1:
            sys.stdout.write('\nConverged!\n')

    ## reduce B matrices
    Bp = Bp[array([pvpq]).T, pvpq].tocsc() # splu requires a CSC matrix
    Bpp = Bpp[array([pq]).T, pq].tocsc()

    ## factor B matrices
    Bp_solver = splu(Bp)
    Bpp_solver = splu(Bpp)

    ## do P and Q iterations
    while (not converged and i < max_it):
        ## update iteration counter
        i = i + 1

        ##-----  do P iteration, update Va  -----
        dVa = -Bp_solver.solve(P)

        ## update voltage
        Va[pvpq] = Va[pvpq] + dVa
        V = Vm * exp(1j * Va)

        ## evalute mismatch
        mis = (V * conj(Ybus * V) - Sbus) / Vm
        P = mis[pvpq].real
        Q = mis[pq].imag

        ## check tolerance
        normP = linalg.norm(P, Inf)
        normQ = linalg.norm(Q, Inf)
        if verbose > 1:
            sys.stdout.write("\n  %s  %3d   %10.3e   %10.3e" %
                             (type,i, normP, normQ))
        if normP < tol and normQ < tol:
            converged = 1
            if verbose:
                sys.stdout.write('\nFast-decoupled power flow converged in %d '
                    'P-iterations and %d Q-iterations.\n' % (i, i - 1))
            break

        ##-----  do Q iteration, update Vm  -----
        dVm = -Bpp_solver.solve(Q)

        ## update voltage
        Vm[pq] = Vm[pq] + dVm
        V = Vm * exp(1j * Va)

        ## evalute mismatch
        mis = (V * conj(Ybus * V) - Sbus) / Vm
        P = mis[pvpq].real
        Q = mis[pq].imag

        ## check tolerance
        normP = linalg.norm(P, Inf)
        normQ = linalg.norm(Q, Inf)
        if verbose > 1:
            sys.stdout.write('\n  Q  %3d   %10.3e   %10.3e' % (i, normP, normQ))
        if normP < tol and normQ < tol:
            converged = 1
            if verbose:
                sys.stdout.write('\nFast-decoupled power flow converged in %d '
                    'P-iterations and %d Q-iterations.\n' % (i, i))
            break

    if verbose:
        if not converged:
            sys.stdout.write('\nFast-decoupled power flow did not converge in '
                             '%d iterations.' % i)

    return V, converged, i
コード例 #55
0
ファイル: t_runmarket.py プロジェクト: Anastien/PYPOWER
def t_runmarket(quiet=False):
    """Tests for code in C{runmkt}, C{smartmkt} and C{auction}.

    @author: Ray Zimmerman (PSERC Cornell)
    """
    n_tests = 20

    t_begin(n_tests, quiet)

    try:
        from pypower.extras.smartmarket import runmarket
    except ImportError:
        t_skip(n_tests, 'smartmarket code not available')
        t_end;
        return

    ppc = loadcase('t_auction_case')

    ppopt = ppoption(OPF_ALG=560, OUT_ALL_LIM=1,
                     OUT_BRANCH=0, OUT_SYS_SUM=0)
    ppopt = ppoption(ppopt, OUT_ALL=0, VERBOSE=1)
    #ppopt = ppoption(ppopt, OUT_GEN=1, OUT_BRANCH=0, OUT_SYS_SUM=0)

    offers = {'P': {}, 'Q': {}}
    bids = {'P': {}, 'Q': {}}

    offers['P']['qty'] = array([
        [12, 24, 24],
        [12, 24, 24],
        [12, 24, 24],
        [12, 24, 24],
        [12, 24, 24],
        [12, 24, 24]
    ])
    offers['P']['prc'] = array([
        [20, 50, 60],
        [20, 40, 70],
        [20, 42, 80],
        [20, 44, 90],
        [20, 46, 75],
        [20, 48, 60]
    ])
    bids['P']['qty'] = array([
        [10, 10, 10],
        [10, 10, 10],
        [10, 10, 10]
    ])
    bids['P']['prc'] = array([
        [100, 70, 60],
#         [100, 64.3, 20],
#         [100, 30.64545, 0],
        [100, 50, 20],
        [100, 60, 50]
    ])

    offers['Q']['qty'] = [ 60, 60, 60, 60, 60, 60, 0, 0, 0 ]
    offers['Q']['prc'] = [ 0, 0, 0, 0, 0, 3, 0, 0, 0 ]
    bids.Q['qty'] = [ 15, 15, 15, 15, 15, 15, 15, 12, 7.5 ]
#     bids.Q['prc'] = [ 0, 0, 0, 0, 0, 0, 0, 83.9056, 0 ]
    bids.Q['prc'] = [ 0, 0, 0, 0, 0, 0, 0, 20, 0 ]

    t = 'marginal Q offer, marginal PQ bid, auction_type = 5'
    mkt = {'auction_type': 5,
                      't': [],
                     'u0': [],
                    'lim': []}
    r, co, cb, _, _, _, _ = runmarket(ppc, offers, bids, mkt, ppopt)
    co5 = co.copy()
    cb5 = cb.copy()

#     [ co['P']['qty'] co['P']['prc'] ]
#     [ cb['P']['qty'] cb['P']['prc'] ]
#     [ co['Q']['qty'] co['Q']['prc'] ]
#     [ cb['Q']['qty'] cb['Q']['prc'] ]

    i2e = r['bus'][:, BUS_I]
    e2i = sparse((max(i2e), 1))
    e2i[i2e] = range(r['bus'].size)
    G = find( isload(r['gen']) == 0 )   ## real generators
    L = find( isload(r['gen']) )        ## dispatchable loads
    Gbus = e2i[r['gen'][G, GEN_BUS]]
    Lbus = e2i[r['gen'][L, GEN_BUS]]

    t_is( co['P']['qty'], ones((6, 1)) * [12, 24, 0], 2, [t, ' : gen P quantities'] )
    t_is( co['P']['prc'][0, :], 50.1578, 3, [t, ' : gen 1 P prices'] )
    t_is( cb['P']['qty'], [[10, 10, 10], [10, 0.196, 0], [10, 10, 0]], 2, [t, ' : load P quantities'] )
    t_is( cb['P']['prc'][1, :], 56.9853, 4, [t, ' : load 2 P price'] )
    t_is( co['P']['prc'][:, 0], r['bus'][Gbus, LAM_P], 8, [t, ' : gen P prices'] )
    t_is( cb['P']['prc'][:, 0], r['bus'][Lbus, LAM_P], 8, [t, ' : load P prices'] )

    t_is( co['Q']['qty'], [4.2722, 11.3723, 14.1472, 22.8939, 36.7886, 12.3375, 0, 0, 0], 2, [t, ' : Q offer quantities'] )
    t_is( co['Q']['prc'], [0, 0, 0, 0, 0, 3, 0.4861, 2.5367, 1.3763], 4, [t, ' : Q offer prices'] )
    t_is( cb['Q']['qty'], [0, 0, 0, 0, 0, 0, 15, 4.0785, 5], 2, [t, ' : Q bid quantities'] )
    t_is( cb['Q']['prc'], [0, 0, 0, 0, 0, 3, 0.4861, 2.5367, 1.3763], 4, [t, ' : Q bid prices'] )
    t_is( co['Q']['prc'], r['bus'][[Gbus, Lbus], LAM_Q], 8, [t, ' : Q offer prices'] )
    t_is( cb['Q']['prc'], co['Q']['prc'], 8, [t, ' : Q bid prices'] )

    t = 'marginal Q offer, marginal PQ bid, auction_type = 0'
    mkt['auction_type'] = 0
    r, co, cb, _, _, _, _ = runmarket(ppc, offers, bids, mkt, ppopt)
    t_is( co['P']['qty'], co5['P']['qty'], 8, [t, ' : gen P quantities'] )
    t_is( cb['P']['qty'], cb5['P']['qty'], 8, [t, ' : load P quantities'] )
    t_is( co['P']['prc'], offers['P']['prc'], 8, [t, ' : gen P prices'] )
    t_is( cb['P']['prc'], bids['P']['prc'], 8, [t, ' : load P prices'] )

    t_is( co['Q']['qty'], co5['Q']['qty'], 8, [t, ' : gen Q quantities'] )
    t_is( cb['Q']['qty'], cb5['Q']['qty'], 8, [t, ' : load Q quantities'] )
    t_is( co['Q']['prc'], offers['Q']['prc'], 8, [t, ' : gen Q prices'] )
    t_is( cb['Q']['prc'], bids['Q']['prc'], 8, [t, ' : load Q prices'] )


    t_end