Esempio n. 1
0
def _calc_pq_elements_and_add_on_ppc(net, ppc):
    # init values
    b, p, q = np.array([], dtype=int), np.array([]), np.array([])

    _is_elements = net["_is_elements"]
    voltage_depend_loads = net["_options"]["voltage_depend_loads"]
    for element in ["load", "sgen", "storage", "ward", "xward"]:
        tab = net[element]
        if len(tab):
            if element == "load" and voltage_depend_loads:
                cz = tab["const_z_percent"].values / 100.
                ci = tab["const_i_percent"].values / 100.
                if ((cz + ci) > 1).any():
                    raise ValueError(
                        "const_z_percent + const_i_percent need to be less or equal to "
                        + "100%!")

                # cumulative sum of constant-current loads
                b_zip = tab["bus"].values
                load_counter = Counter(b_zip)

                bus_lookup = net["_pd2ppc_lookups"]["bus"]
                b_zip = bus_lookup[b_zip]
                load_counter = {
                    bus_lookup[k]: v
                    for k, v in load_counter.items()
                }
                b_zip, ci_sum, cz_sum = _sum_by_group(b_zip, ci, cz)

                for bus, no_loads in load_counter.items():
                    ci_sum[b_zip == bus] /= no_loads
                    cz_sum[b_zip == bus] /= no_loads

                ppc["bus"][b_zip, CID] = ci_sum
                ppc["bus"][b_zip, CZD] = cz_sum
            active = _is_elements[element]
            sign = -1 if element == "sgen" else 1
            if element.endswith("ward"):
                p = np.hstack([p, tab["ps_mw"].values * active * sign])
                q = np.hstack([q, tab["qs_mvar"].values * active * sign])
            else:
                scaling = tab["scaling"].values
                p = np.hstack(
                    [p, tab["p_mw"].values * active * scaling * sign])
                q = np.hstack(
                    [q, tab["q_mvar"].values * active * scaling * sign])
            b = np.hstack([b, tab["bus"].values])

    # sum up p & q of bus elements
    if b.size:
        bus_lookup = net["_pd2ppc_lookups"]["bus"]
        b = bus_lookup[b]
        b, vp, vq = _sum_by_group(b, p, q)
        ppc["bus"][b, PD] = vp
        ppc["bus"][b, QD] = vq
Esempio n. 2
0
def _add_ext_grid_sc_impedance(net, ppc):
    from pandapower.shortcircuit.idx_bus import C_MAX, C_MIN
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    case = net._options["case"]
    eg = net._is_elements["ext_grid"]
    if len(eg) == 0:
        return
    eg_buses = eg.bus.values
    eg_buses_ppc = bus_lookup[eg_buses]

    c = ppc["bus_sc"][eg_buses_ppc,
                      C_MAX] if case == "max" else ppc["bus_sc"][eg_buses_ppc,
                                                                 C_MIN]
    s_sc = eg["s_sc_%s_mva" % case].values
    rx = eg["rx_%s" % case].values

    z_grid = c / s_sc
    x_grid = np.sqrt(z_grid**2 / (rx**2 + 1))
    r_grid = np.sqrt(z_grid**2 - x_grid**2)
    eg["r"] = r_grid
    eg["x"] = x_grid

    y_grid = 1 / (r_grid + x_grid * 1j)
    buses, gs, bs = _sum_by_group(eg_buses_ppc, y_grid.real, y_grid.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 3
0
def _calc_shunts_and_add_on_ppc(net, ppc):
    # init values
    b, p, q = np.array([], dtype=int), np.array([]), np.array([])
    # get in service elements
    _is_elements = net["_is_elements"]

    s = net["shunt"]
    if len(s) > 0:
        vl = _is_elements["shunt"] / np.float64(1000.)
        q = np.hstack([q, s["q_kvar"].values * vl])
        p = np.hstack([p, s["p_kw"].values * vl])
        b = np.hstack([b, s["bus"].values])

    w = net["ward"]
    if len(w) > 0:
        vl = _is_elements["ward"] / np.float64(1000.)
        q = np.hstack([q, w["qz_kvar"].values * vl])
        p = np.hstack([p, w["pz_kw"].values * vl])
        b = np.hstack([b, w["bus"].values])

    xw = net["xward"]
    if len(xw) > 0:
        vl = _is_elements["xward"] / np.float64(1000.)
        q = np.hstack([q, xw["qz_kvar"].values * vl])
        p = np.hstack([p, xw["pz_kw"].values * vl])
        b = np.hstack([b, xw["bus"].values])

    # if array is not empty
    if b.size:
        bus_lookup = net["_pd2ppc_lookups"]["bus"]
        b = bus_lookup[b]
        b, vp, vq = _sum_by_group(b, p, q)

        ppc["bus"][b, GS] = vp
        ppc["bus"][b, BS] = -vq
Esempio n. 4
0
def _get_p_q_results(net, bus_lookup_aranged):
    # results to be filled (bus, p in kw, q in kvar)
    bus_pq = np.zeros(shape=(len(net["bus"].index), 2), dtype=np.float)
    b, p, q = np.array([]), np.array([]), np.array([])

    ac = net["_options"]["ac"]
    if net["_options"]["voltage_depend_loads"] and ac:
        # voltage dependend loads need special treatment here
        p, q, b = write_voltage_dependend_load_results(net, p, q, b)
        elements = ["sgen", "storage", "ward", "xward"]
    else:
        elements = ["load", "sgen", "storage", "ward", "xward"]

    for element in elements:
        if len(net[element]):
            write_pq_results_to_element(net, element)
            p_el, q_el, bus_el = get_p_q_b(net, element)
            p = np.hstack([p, p_el])
            q = np.hstack([q, q_el])
            b = np.hstack([b, bus_el])

    if not ac:
        q = np.zeros(len(p))

    # sum pq results from every element to be written to net['bus'] later on
    b_pp, vp, vq = _sum_by_group(b.astype(int), p, q)
    b_ppc = bus_lookup_aranged[b_pp]
    bus_pq[b_ppc, 0] = vp
    bus_pq[b_ppc, 1] = vq
    return bus_pq
Esempio n. 5
0
def _current_source_current(net, ppc):
    ppc["bus"][:, IKCV] = 0
    ppc["bus"][:, IKSS2] = 0
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    if not False in net.sgen.current_source.values:
        sgen = net.sgen[net._is_elements["sgen"]]
    else:
        sgen = net.sgen[net._is_elements["sgen"] & net.sgen.current_source]
    if len(sgen) == 0:
        return
    if any(pd.isnull(sgen.sn_mva)):
        raise ValueError(
            "sn_mva needs to be specified for all sgens in net.sgen.sn_mva")
    baseI = ppc["internal"]["baseI"]
    sgen_buses = sgen.bus.values
    sgen_buses_ppc = bus_lookup[sgen_buses]
    Zbus = ppc["internal"]["Zbus"]
    if not "k" in sgen:
        raise ValueError(
            "Nominal to short-circuit current has to specified in net.sgen.k")
    i_sgen_pu = sgen.sn_mva.values / net.sn_mva * sgen.k.values
    buses, ikcv_pu, _ = _sum_by_group(sgen_buses_ppc, i_sgen_pu, i_sgen_pu)
    ppc["bus"][buses, IKCV] = ikcv_pu
    ppc["bus"][:, IKSS2] = abs(1 / np.diag(Zbus) *
                               np.dot(Zbus, ppc["bus"][:, IKCV] * -1j) / baseI)
    ppc["bus"][buses, IKCV] /= baseI[buses]
Esempio n. 6
0
def _get_xward_branch_results(net,
                              ppc,
                              bus_lookup_aranged,
                              pq_buses,
                              suffix=None):
    ac = net["_options"]["ac"]

    if not "xward" in net._pd2ppc_lookups["branch"]:
        return
    f, t = net._pd2ppc_lookups["branch"]["xward"]
    p_branch_xward = ppc["branch"][f:t, PF].real
    net["res_xward"][
        "p_mw"].values[:] = net["res_xward"]["p_mw"].values + p_branch_xward
    if ac:
        q_branch_xward = ppc["branch"][f:t, QF].real
        net["res_xward"]["q_mvar"].values[:] = net["res_xward"][
            "q_mvar"].values + q_branch_xward
    else:
        q_branch_xward = np.zeros(len(p_branch_xward))
    b_pp, p, q = _sum_by_group(net["xward"]["bus"].values, p_branch_xward,
                               q_branch_xward)
    b_ppc = bus_lookup_aranged[b_pp]

    pq_buses[b_ppc, 0] += p
    pq_buses[b_ppc, 1] += q
    aux_buses = net["_pd2ppc_lookups"]["bus"][net["_pd2ppc_lookups"]["aux"]
                                              ["xward"]]

    res_xward_df = net["res_xward"] if suffix is None else net["res_xward%s" %
                                                               suffix]

    res_xward_df["va_internal_degree"].values[:] = ppc["bus"][aux_buses, VA]
    res_xward_df["vm_internal_pu"].values[:] = ppc["bus"][aux_buses, VM]
    res_xward_df.index = net["xward"].index
Esempio n. 7
0
def _add_gen_sc_impedance(net, ppc):
    from pandapower.shortcircuit.idx_bus import C_MAX
    gen = net["gen"][net._is_elements["gen"]]
    if len(gen) == 0:
        return
    gen_buses = gen.bus.values
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    gen_buses_ppc = bus_lookup[gen_buses]
    vn_gen = gen.vn_kv.values
    sn_gen = gen.sn_mva.values

    rdss_pu = gen.rdss_pu.values
    xdss_pu = gen.xdss_pu.values
    gens_without_r = np.isnan(rdss_pu)
    if gens_without_r.any():
        #  use the estimations from the IEC standard for generators without defined rdss_pu
        lv_gens = (vn_gen <= 1.) & gens_without_r
        hv_gens = (vn_gen > 1.) & gens_without_r
        large_hv_gens = (sn_gen >= 100) & hv_gens
        small_hv_gens = (sn_gen < 100) & hv_gens
        rdss_pu[lv_gens] = 0.15 * xdss_pu[lv_gens]
        rdss_pu[large_hv_gens] = 0.05 * xdss_pu[large_hv_gens]
        rdss_pu[small_hv_gens] = 0.07 * xdss_pu[small_hv_gens]

    vn_net = ppc["bus"][gen_buses_ppc, BASE_KV]
    cmax = ppc["bus"][gen_buses_ppc, C_MAX]
    phi_gen = np.arccos(gen.cos_phi.values)
    kg = vn_gen / vn_net * cmax / (1 + xdss_pu * np.sin(phi_gen))

    z_gen = (rdss_pu + xdss_pu * 1j) * kg / sn_gen
    y_gen = 1 / z_gen

    buses, gs, bs = _sum_by_group(gen_buses_ppc, y_gen.real, y_gen.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 8
0
def _calc_shunts_and_add_on_ppc(net, ppc, is_elems, bus_lookup):
    # get in service elements
    bus_is = is_elems['bus']

    s = net["shunt"]
    shunt_is = np.in1d(s.bus.values, bus_is.index) \
        & s.in_service.values.astype(bool)
    vl = shunt_is / np.float64(1000.)
    sp = s["p_kw"].values * vl
    sq = s["q_kvar"].values * vl

    w = net["ward"]
    ward_is = np.in1d(w.bus.values, bus_is.index) \
        & w.in_service.values.astype(bool)
    vl = ward_is / np.float64(1000.)
    wp = w["pz_kw"].values * vl
    wq = w["qz_kvar"].values * vl

    xw = net["xward"]
    xward_is = np.in1d(xw.bus.values, bus_is.index) \
        & xw.in_service.values.astype(bool)
    vl = xward_is / np.float64(1000.)
    xwp = xw["pz_kw"].values * vl
    xwq = xw["qz_kvar"].values * vl

    b = get_indices(np.hstack([s["bus"].values, w["bus"].values, xw["bus"].values]), bus_lookup)
    b, vp, vq = _sum_by_group(b, np.hstack([sp, wp, xwp]), np.hstack([sq, wq, xwq]))

    ppc["bus"][b, GS] = vp
    ppc["bus"][b, BS] = -vq
Esempio n. 9
0
def _add_ext_grid_sc_impedance(net, ppc):
    from pandapower.shortcircuit.idx_bus import C_MAX, C_MIN
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    case = net._options["case"]
    eg = net["ext_grid"][net._is_elements["ext_grid"]]
    if len(eg) == 0:
        return
    eg_buses = eg.bus.values
    eg_buses_ppc = bus_lookup[eg_buses]

    c = ppc["bus"][eg_buses_ppc,
                   C_MAX] if case == "max" else ppc["bus"][eg_buses_ppc, C_MIN]
    if not "s_sc_%s_mva" % case in eg:
        raise ValueError(
            "short circuit apparent power s_sc_%s_mva needs to be specified for "
            + "external grid" % case)
    s_sc = eg["s_sc_%s_mva" % case].values
    if not "rx_%s" % case in eg:
        raise ValueError(
            "short circuit R/X rate rx_%s needs to be specified for external grid"
            % case)
    rx = eg["rx_%s" % case].values

    z_grid = c / s_sc
    x_grid = z_grid / np.sqrt(rx**2 + 1)
    r_grid = rx * x_grid
    eg["r"] = r_grid
    eg["x"] = x_grid

    y_grid = 1 / (r_grid + x_grid * 1j)
    buses, gs, bs = _sum_by_group(eg_buses_ppc, y_grid.real, y_grid.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 10
0
def _add_gen_sc_impedance(net, ppc):
    from pandapower.shortcircuit.idx_bus import C_MAX
    gen = net["gen"][net._is_elements["gen"]]
    if len(gen) == 0:
        return
    gen_buses = gen.bus.values
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    gen_buses_ppc = bus_lookup[gen_buses]

    vn_net = ppc["bus"][gen_buses_ppc, BASE_KV]
    cmax = ppc["bus"][gen_buses_ppc, C_MAX]
    phi_gen = np.arccos(gen.cos_phi)

    vn_gen = gen.vn_kv.values
    sn_gen = gen.sn_kva.values

    z_r = vn_net**2 / sn_gen * 1e3
    x_gen = gen.xdss.values / 100 * z_r
    r_gen = gen.rdss.values / 100 * z_r

    kg = _generator_correction_factor(vn_net, vn_gen, cmax, phi_gen, gen.xdss)
    y_gen = 1 / ((r_gen + x_gen * 1j) * kg)

    buses, gs, bs = _sum_by_group(gen_buses_ppc, y_gen.real, y_gen.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 11
0
def _calc_loads_and_add_on_ppc_opf(net, ppc):
    """ we need to exclude controllable sgens from the bus table
    """
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    # get in service elements
    _is_elements = net["_is_elements"]

    l = net["load"]
    if not l.empty:
        l["controllable"] = _controllable_to_bool(l["controllable"])
        vl = (_is_elements["load"]
              & ~l["controllable"]) * l["scaling"].values.T / np.float64(1000.)
        lp = l["p_kw"].values * vl
        lq = l["q_kvar"].values * vl
    else:
        lp = []
        lq = []

    sgen = net["sgen"]
    if not sgen.empty:
        sgen["controllable"] = _controllable_to_bool(sgen["controllable"])
        vl = (_is_elements["sgen"] & ~sgen["controllable"]) * sgen["scaling"].values.T / \
            np.float64(1000.)
        sp = sgen["p_kw"].values * vl
        sq = sgen["q_kvar"].values * vl
    else:
        sp = []
        sq = []

    b = bus_lookup[np.hstack([l["bus"].values, sgen["bus"].values])]
    b, vp, vq = _sum_by_group(b, np.hstack([lp, sp]), np.hstack([lq, sq]))

    ppc["bus"][b, PD] = vp
    ppc["bus"][b, QD] = vq
Esempio n. 12
0
def _get_gen_results(net, ppc, bus_lookup_aranged, pq_bus):
    ac = net["_options"]["ac"]

    eg_end = len(net['ext_grid'])
    gen_end = eg_end + len(net['gen'])

    if eg_end > 0:
        b, p, q = _get_ext_grid_results(net, ppc)
    else:
        b, p, q = [], [], []  # np.array([]), np.array([]), np.array([])

    # get results for gens
    if gen_end > eg_end:
        b, p, q = _get_pp_gen_results(net, ppc, b, p, q)

    if len(net.dcline) > 0:
        _get_dcline_results(net)
        b = np.hstack([b, net.dcline[["from_bus", "to_bus"]].values.flatten()])
        p = np.hstack(
            [p, net.res_dcline[["p_from_mw", "p_to_mw"]].values.flatten()])
        q = np.hstack(
            [q, net.res_dcline[["q_from_mvar", "q_to_mvar"]].values.flatten()])

    if not ac:
        q = np.zeros(len(p))
    b_sum, p_sum, q_sum = _sum_by_group(b, p, q)
    b = bus_lookup_aranged[b_sum.astype(int)]
    pq_bus[b, 0] -= p_sum
    pq_bus[b, 1] -= q_sum
Esempio n. 13
0
def _add_motor_impedances_ppc(net, ppc):
    if net._options["case"] == "min":
        return
    motor = net["motor"][net._is_elements["motor"]]
    if motor.empty:
        return
    for par in ["vn_kv", "lrc_pu", "efficiency_n_percent", "cos_phi_n", "rx", "pn_mech_mw"]:
        if any(pd.isnull(motor[par])):
            raise UserWarning("%s needs to be specified for all motors in net.motor.%s" % (par, par))
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    motor_buses_ppc = bus_lookup[motor.bus.values]
    vn_net = ppc["bus"][motor_buses_ppc, BASE_KV]

    efficiency = motor.efficiency_n_percent.values
    cos_phi = motor.cos_phi_n.values
    p_mech = motor.pn_mech_mw.values
    vn_kv = motor.vn_kv.values
    lrc = motor.lrc_pu.values
    rx = motor.rx.values

    s_motor = p_mech / (efficiency/100 * cos_phi)
    z_motor_ohm = 1 / lrc * vn_kv**2 / s_motor
    z_motor_pu = z_motor_ohm / (vn_net**2 / net.sn_mva)

    x_motor_pu = z_motor_pu / np.sqrt(rx ** 2 + 1)
    r_motor_pu = rx * x_motor_pu
    y_motor_pu = 1 / (r_motor_pu + x_motor_pu * 1j)

    buses, gs, bs = _sum_by_group(motor_buses_ppc, y_motor_pu.real, y_motor_pu.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 14
0
def _calc_shunts_and_add_on_ppc(net, ppc):
    # init values
    b, p, q = np.array([], dtype=int), np.array([]), np.array([])
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    # get in service elements
    _is_elements = net["_is_elements"]

    s = net["shunt"]
    if len(s) > 0:
        vl = _is_elements["shunt"]
        v_ratio = (ppc["bus"][bus_lookup[s["bus"].values], BASE_KV] /
                   s["vn_kv"].values)**2
        q = np.hstack(
            [q, s["q_mvar"].values * s["step"].values * v_ratio * vl])
        p = np.hstack([p, s["p_mw"].values * s["step"].values * v_ratio * vl])
        b = np.hstack([b, s["bus"].values])

    w = net["ward"]
    if len(w) > 0:
        vl = _is_elements["ward"]
        q = np.hstack([q, w["qz_mvar"].values * vl])
        p = np.hstack([p, w["pz_mw"].values * vl])
        b = np.hstack([b, w["bus"].values])

    xw = net["xward"]
    if len(xw) > 0:
        vl = _is_elements["xward"]
        q = np.hstack([q, xw["qz_mvar"].values * vl])
        p = np.hstack([p, xw["pz_mw"].values * vl])
        b = np.hstack([b, xw["bus"].values])

    loss_location = net._options["trafo3w_losses"].lower()
    trafo3w = net["trafo3w"]
    if loss_location == "star" and len(trafo3w) > 0:

        pfe_mw = trafo3w["pfe_kw"].values * 1e-3
        i0 = trafo3w["i0_percent"].values
        sn_mva = trafo3w["sn_hv_mva"].values

        q_mvar = (sn_mva * i0 / 100.)**2 - pfe_mw**2
        q_mvar[q_mvar < 0] = 0
        q_mvar = np.sqrt(q_mvar)

        vn_hv_trafo = trafo3w["vn_hv_kv"].values
        vn_hv_bus = ppc["bus"][bus_lookup[trafo3w.hv_bus.values], BASE_KV]
        v_ratio = (vn_hv_bus / vn_hv_trafo)**2

        q = np.hstack([q, q_mvar * v_ratio])
        p = np.hstack([p, pfe_mw * v_ratio])
        b = np.hstack([b, net._pd2ppc_lookups["aux"]["trafo3w"]])

    # if array is not empty
    if b.size:
        b = bus_lookup[b]
        b, vp, vq = _sum_by_group(b, p, q)

        ppc["bus"][b, GS] = vp
        ppc["bus"][b, BS] = -vq
Esempio n. 15
0
def _get_p_q_results_opf(net, ppc, bus_lookup_aranged):
    bus_pq = zeros(shape=(len(net["bus"].index), 2), dtype=float)
    b, p, q = array([]), array([]), array([])

    _is_elements = net["_is_elements"]

    l = net["load"]
    if len(l) > 0:
        load_is = _is_elements["load"]
        load_ctrl = l["controllable"].values
        scaling = l["scaling"].values
        pl = l["p_kw"].values * scaling * load_is * invert(load_ctrl)
        ql = l["q_kvar"].values * scaling * load_is * invert(load_ctrl)
        if any(load_ctrl):
            # get load index in ppc
            lidx_ppc = net._pd2ppc_lookups["load_controllable"][
                _is_elements["load_controllable"].index]
            pl[load_is & load_ctrl] = -ppc["gen"][lidx_ppc, PG] * 1000
            ql[load_is & load_ctrl] = -ppc["gen"][lidx_ppc, QG] * 1000

        net["res_load"]["p_kw"] = pl
        net["res_load"]["q_kvar"] = ql
        p = hstack([p, pl])
        q = hstack([q, ql])
        b = hstack([b, l["bus"].values])
        net["res_load"].index = net["load"].index

    sg = net["sgen"]
    if len(sg) > 0:
        sgen_is = _is_elements["sgen"]
        sgen_ctrl = sg["controllable"].values
        scaling = sg["scaling"].values
        psg = sg["p_kw"].values * scaling * sgen_is * invert(sgen_ctrl)
        qsg = sg["q_kvar"].values * scaling * sgen_is * invert(sgen_ctrl)
        if any(sgen_ctrl):
            # get gen index in ppc
            gidx_ppc = net._pd2ppc_lookups["sgen_controllable"][
                _is_elements["sgen_controllable"].index]
            psg[sgen_is & sgen_ctrl] = -ppc["gen"][gidx_ppc, PG] * 1000
            qsg[sgen_is & sgen_ctrl] = -ppc["gen"][gidx_ppc, QG] * 1000

        net["res_sgen"]["p_kw"] = psg
        net["res_sgen"]["q_kvar"] = qsg
        q = hstack([q, qsg])
        p = hstack([p, psg])
        b = hstack([b, sg["bus"].values])
        net["res_sgen"].index = net["sgen"].index

    b_pp, vp, vq = _sum_by_group(b.astype(int), p, q)
    b_ppc = bus_lookup_aranged[b_pp]
    bus_pq[b_ppc, 0] = vp
    bus_pq[b_ppc, 1] = vq
    return bus_pq
Esempio n. 16
0
def _normalise_slack_weights(ppc, gen_mask, xward_mask, xward_pq_buses):
    """Unitise the slack contribution factors in each island to sum to 1."""
    subnets = _subnetworks(ppc)
    gen_buses = ppc['gen'][gen_mask, GEN_BUS].astype(np.int64)

    # it is possible that xward and gen are at the same bus (but not reasonable)
    if len(np.intersect1d(gen_buses, xward_pq_buses)):
        raise NotImplementedError(
            "Found some of the xward PQ buses with slack weight > 0 that coincide with PV or SL buses."
            "This configuration is not supported.")

    gen_buses = np.r_[gen_buses, xward_pq_buses]
    slack_weights_gen = np.r_[ppc['gen'][gen_mask, SL_FAC],
                              ppc['gen'][xward_mask,
                                         SL_FAC]].astype(np.float64)

    # only 1 ext_grid (reference bus) supported and all others are considered as PV buses,
    # 1 ext_grid is used as slack and others are converted to PV nodes internally;
    # calculate dist_slack for all SL and PV nodes that have non-zero slack weight:
    buses_with_slack_weights = ppc['gen'][ppc['gen'][:, SL_FAC] != 0,
                                          GEN_BUS].astype(np.int64)
    if np.sum(ppc['bus'][buses_with_slack_weights, BUS_TYPE] == REF) > 1:
        logger.info(
            "Distributed slack calculation is implemented only for one reference type bus, "
            "other reference buses will be converted to PV buses internally.")

    for subnet in subnets:
        subnet_gen_mask = np.isin(gen_buses, subnet)
        sum_slack_weights = np.sum(slack_weights_gen[subnet_gen_mask])
        if np.isclose(sum_slack_weights, 0):
            # ppc['gen'][subnet_gen_mask, SL_FAC] = 0
            raise ValueError("Distributed slack contribution factors in "
                             "island '%s' sum to zero." % str(subnet))
        elif sum_slack_weights < 0:
            raise ValueError(
                "Distributed slack contribution factors in island '%s'" %
                str(subnet) +
                " sum to negative value. Please correct the data.")
        else:
            # ppc['gen'][subnet_gen_mask, SL_FAC] /= sum_slack_weights
            slack_weights_gen /= sum_slack_weights
            buses, slack_weights_bus, _ = _sum_by_group(
                gen_buses[subnet_gen_mask], slack_weights_gen[subnet_gen_mask],
                slack_weights_gen[subnet_gen_mask])
            ppc['bus'][buses, SL_FAC_BUS] = slack_weights_bus

    # raise NotImplementedError if there are several separate zones for distributed slack:
    if not np.isclose(sum(ppc['bus'][:, SL_FAC_BUS]), 1):
        raise NotImplementedError(
            "Distributed slack calculation is not implemented for several separate zones at once, "
            "please calculate the zones separately.")
Esempio n. 17
0
def _get_xward_branch_results(net, ppc, bus_lookup, pq_buses, f, t, ac=True):
    p_branch_xward = ppc["branch"][f:t, PF].real * 1e3
    net["res_xward"]["p_kw"] += p_branch_xward
    if ac:
        q_branch_xward = ppc["branch"][f:t, QF].real * 1e3
        net["res_xward"]["q_kvar"] += q_branch_xward
    else:
        q_branch_xward = np.zeros(len(p_branch_xward))
    b_pp, p, q = _sum_by_group(net["xward"]["bus"].values, p_branch_xward,
                               q_branch_xward)
    b_ppc = get_indices(b_pp, bus_lookup, fused_indices=False)

    pq_buses[b_ppc, 0] += p
    pq_buses[b_ppc, 1] += q
Esempio n. 18
0
def _calc_shunts_and_add_on_ppc(net, ppc):
    # init values
    b, p, q = np.array([], dtype=int), np.array([]), np.array([])
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    # get in service elements
    _is_elements = net["_is_elements"]

    s = net["shunt"]
    if len(s) > 0:
        vl = _is_elements["shunt"] / np.float64(1000.)
        v_ratio = (ppc["bus"][bus_lookup[s["bus"].values], BASE_KV] /
                   s["vn_kv"].values)**2
        q = np.hstack([q, s["q_kvar"].values * s["step"] * v_ratio * vl])
        p = np.hstack([p, s["p_kw"].values * s["step"] * v_ratio * vl])
        b = np.hstack([b, s["bus"].values])

    w = net["ward"]
    if len(w) > 0:
        vl = _is_elements["ward"] / np.float64(1000.)
        q = np.hstack([q, w["qz_kvar"].values * vl])
        p = np.hstack([p, w["pz_kw"].values * vl])
        b = np.hstack([b, w["bus"].values])

    xw = net["xward"]
    if len(xw) > 0:
        vl = _is_elements["xward"] / np.float64(1000.)
        q = np.hstack([q, xw["qz_kvar"].values * vl])
        p = np.hstack([p, xw["pz_kw"].values * vl])
        b = np.hstack([b, xw["bus"].values])

    # constant-impedance loads if voltage_depend_loads=True
    l = net["load"]
    voltage_depend_loads = net["_options"]["voltage_depend_loads"]
    if len(l) > 0 and voltage_depend_loads:
        cz = l["const_z_percent"].values / 100.
        vl = _is_elements["load"] * l["scaling"].values.T * cz / np.float64(
            1000.)
        q = np.hstack([q, l["q_kvar"].values * vl])
        p = np.hstack([p, l["p_kw"].values * vl])
        b = np.hstack([b, l["bus"].values])

    # if array is not empty
    if b.size:
        b = bus_lookup[b]
        b, vp, vq = _sum_by_group(b, p, q)

        ppc["bus"][b, GS] = vp
        ppc["bus"][b, BS] = -vq
Esempio n. 19
0
def _load_mapping(net, ppci1):
    """
    Takes three phase P, Q values from PQ elements
    sums them up for each bus
    maps them in ppc bus order and forms s_abc matrix
    """
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    params = dict()
    phases = ['a', 'b', 'c']
    load_types = ['wye', 'delta']
    load_elements = ['load', 'asymmetric_load', 'sgen', 'asymmetric_sgen']
    # =============================================================================
    #        Loop to initialize and feed s_abc wye and delta values
    # =============================================================================
    for phase in phases:
        for typ in load_types:
            params['S' + phase +
                   typ] = (ppci1["bus"][:, PD] + ppci1["bus"][:, QD] * 1j) * 0
            params['p' + phase + typ] = np.array(
                [])  # p values from loads/sgens
            params['q' + phase + typ] = np.array(
                [])  # q values from loads/sgens
            params['P' + phase + typ] = np.array([])  # Aggregated Active Power
            params['Q' + phase + typ] = np.array(
                [])  # Aggregated reactive Power
            params['b' + phase + typ] = np.array(
                [], dtype=int)  # bus map for phases
            params['b' + typ] = np.array(
                [], dtype=int)  # aggregated bus map(s_abc)
            for element in load_elements:
                _get_elements(params, net, element, phase, typ)
            # Mapping constant power loads to buses
            if params['b' + typ].size:
                params['b' + phase + typ] = bus_lookup[params['b' + typ]]
                params['b'+phase+typ], params['P'+phase+typ],\
                    params['Q'+phase+typ] = _sum_by_group(params['b'+phase+typ],
                                                          params['p'+phase+typ],
                                                          params['q'+phase+typ] * 1j)
                params['S'+phase+typ][params['b'+phase+typ]] = \
                    (params['P'+phase+typ] + params['Q'+phase+typ])
    Sabc_del = np.vstack(
        (params['Sadelta'], params['Sbdelta'], params['Scdelta']))
    Sabc_wye = np.vstack((params['Sawye'], params['Sbwye'], params['Scwye']))
    # last return varaible left for constant impedance loads
    return Sabc_del, Sabc_wye
Esempio n. 20
0
def _add_xward_sc_z(net, ppc):
    # TODO: Check if this should be ward or xward
    ward = net["xward"][net._is_elements_final["xward"]]
    if len(ward) == 0:
        return
    ward_buses = ward.bus.values
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    ward_buses_ppc = bus_lookup[ward_buses]

    vn_net = net.bus.loc[ward_buses, "vn_kv"].values
    r_ward, x_ward = ward["r_ohm"].values, ward["x_ohm"].values
    z_ward = (r_ward + x_ward*1j)
    z_ward_pu = z_ward / vn_net ** 2
    y_ward_pu = 1 / z_ward_pu

    buses, gs, bs = _sum_by_group(ward_buses_ppc, y_ward_pu.real, y_ward_pu.imag)
    ppc["bus"][buses, GS] += gs
    ppc["bus"][buses, BS] += bs
Esempio n. 21
0
def _calc_loads_and_add_on_ppc_pf(net, ppc):
    # init values
    b, p, q = np.array([], dtype=int), np.array([]), np.array([])

    # get in service elements
    _is_elements = net["_is_elements"]

    l = net["load"]
    # element_is = check if element is at a bus in service & element is in service
    if len(l) > 0:
        vl = _is_elements["load"] * l["scaling"].values.T / np.float64(1000.)
        q = np.hstack([q, l["q_kvar"].values * vl])
        p = np.hstack([p, l["p_kw"].values * vl])
        b = np.hstack([b, l["bus"].values])

    s = net["sgen"]
    if len(s) > 0:
        vl = _is_elements["sgen"] * s["scaling"].values.T / np.float64(1000.)
        q = np.hstack([q, s["q_kvar"].values * vl])
        p = np.hstack([p, s["p_kw"].values * vl])
        b = np.hstack([b, s["bus"].values])

    w = net["ward"]
    if len(w) > 0:
        vl = _is_elements["ward"] / np.float64(1000.)
        q = np.hstack([q, w["qs_kvar"].values * vl])
        p = np.hstack([p, w["ps_kw"].values * vl])
        b = np.hstack([b, w["bus"].values])

    xw = net["xward"]
    if len(xw) > 0:
        vl = _is_elements["xward"] / np.float64(1000.)
        q = np.hstack([q, xw["qs_kvar"].values * vl])
        p = np.hstack([p, xw["ps_kw"].values * vl])
        b = np.hstack([b, xw["bus"].values])

    # if array is not empty
    if b.size:
        bus_lookup = net["_pd2ppc_lookups"]["bus"]
        b = bus_lookup[b]
        b, vp, vq = _sum_by_group(b, p, q)

        ppc["bus"][b, PD] = vp
        ppc["bus"][b, QD] = vq
Esempio n. 22
0
def _add_sgen_sc_impedance(net, ppc):
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    sgen = net.sgen[net._is_elements["sgen"]]
    if len(sgen) == 0:
        return
    if any(pd.isnull(sgen.sn_kva)):
        raise UserWarning(
            "sn_kva needs to be specified for all sgens in net.sgen.sn_kva")
    sgen_buses = sgen.bus.values
    sgen_buses_ppc = bus_lookup[sgen_buses]

    z_sgen = 1 / (sgen.sn_kva.values * 1e-3) / 3  #1 us reference voltage in pu
    x_sgen = np.sqrt(z_sgen**2 / (0.1**2 + 1))
    r_sgen = np.sqrt(z_sgen**2 - x_sgen**2)
    y_sgen = 1 / (r_sgen + x_sgen * 1j)

    buses, gs, bs = _sum_by_group(sgen_buses_ppc, y_sgen.real, y_sgen.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 23
0
def _add_motor_impedances_ppc(net, ppc):
    sgen = net.sgen[net._is_elements["sgen"]]
    if "motor" not in sgen.type.values:
        return
    motor = sgen[sgen.type == "motor"]
    for par in ["sn_kva", "rx", "k"]:
        if any(pd.isnull(motor[par])):
            raise UserWarning("%s needs to be specified for all motors in net.sgen.%s" % (par, par))
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    motor_buses = motor.bus.values
    motor_buses_ppc = bus_lookup[motor_buses]

    z_motor = 1 / (motor.sn_kva.values * 1e-3) / motor.k  # vn_kv**2 becomes 1**2=1 in per unit
    x_motor = z_motor / np.sqrt(motor.rx ** 2 + 1)
    r_motor = motor.rx * x_motor
    y_motor = 1 / (r_motor + x_motor * 1j)

    buses, gs, bs = _sum_by_group(motor_buses_ppc, y_motor.real, y_motor.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs
Esempio n. 24
0
def _get_xward_branch_results(net, ppc, bus_lookup_aranged, pq_buses):
    ac = net["_options"]["ac"]

    if not "xward" in net._pd2ppc_lookups["branch"]:
        return
    f, t = net._pd2ppc_lookups["branch"]["xward"]
    p_branch_xward = ppc["branch"][f:t, PF].real * 1e3
    net["res_xward"]["p_kw"] += p_branch_xward
    if ac:
        q_branch_xward = ppc["branch"][f:t, QF].real * 1e3
        net["res_xward"]["q_kvar"] += q_branch_xward
    else:
        q_branch_xward = np.zeros(len(p_branch_xward))
    b_pp, p, q = _sum_by_group(net["xward"]["bus"].values, p_branch_xward,
                               q_branch_xward)
    b_ppc = bus_lookup_aranged[b_pp]

    pq_buses[b_ppc, 0] += p
    pq_buses[b_ppc, 1] += q
    net["res_xward"].index = net["xward"].index
Esempio n. 25
0
def _calc_loads_and_add_on_ppc(net, ppc, is_elems, bus_lookup):
    # get in service elements
    bus_is = is_elems['bus']

    l = net["load"]
    # element_is = check if element is at a bus in service & element is in service
    load_is = np.in1d(l.bus.values, bus_is.index) \
        & l.in_service.values.astype(bool)
    vl = load_is * l["scaling"].values.T / np.float64(1000.)
    lp = l["p_kw"].values * vl
    lq = l["q_kvar"].values * vl

    s = net["sgen"]
    sgen_is = np.in1d(s.bus.values, bus_is.index) \
        & s.in_service.values.astype(bool)
    vl = sgen_is * s["scaling"].values.T / np.float64(1000.)
    sp = s["p_kw"].values * vl
    sq = s["q_kvar"].values * vl

    w = net["ward"]
    ward_is = np.in1d(w.bus.values, bus_is.index) \
        & w.in_service.values.astype(bool)
    vl = ward_is / np.float64(1000.)
    wp = w["ps_kw"].values * vl
    wq = w["qs_kvar"].values * vl

    xw = net["xward"]
    xward_is = np.in1d(xw.bus.values, bus_is.index) \
        & xw.in_service.values.astype(bool)
    vl = xward_is / np.float64(1000.)
    xwp = xw["ps_kw"].values * vl
    xwq = xw["qs_kvar"].values * vl

    b = get_indices(np.hstack([l["bus"].values, s["bus"].values, w["bus"].values, xw["bus"].values]
                              ), bus_lookup)
    b, vp, vq = _sum_by_group(b, np.hstack([lp, sp, wp, xwp]), np.hstack([lq, sq, wq, xwq]))

    ppc["bus"][b, PD] = vp
    ppc["bus"][b, QD] = vq
Esempio n. 26
0
def _current_source_current(net, ppc):
    ppc["bus"][:, IKCV] = 0
    ppc["bus"][:, IKSS2] = 0
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    if not "motor" in net.sgen.type.values:
        sgen = net.sgen[net._is_elements["sgen"]]
    else:
        sgen = net.sgen[(net._is_elements["sgen"])
                        & (net.sgen.type != "motor")]
    if len(sgen) == 0:
        return
    if any(pd.isnull(sgen.sn_kva)):
        raise UserWarning(
            "sn_kva needs to be specified for all sgens in net.sgen.sn_kva")
    baseI = ppc["internal"]["baseI"]
    sgen_buses = sgen.bus.values
    sgen_buses_ppc = bus_lookup[sgen_buses]
    Zbus = ppc["internal"]["Zbus"]
    i_sgen_pu = sgen.sn_kva.values / net.sn_kva * sgen.k.values
    buses, ikcv_pu, _ = _sum_by_group(sgen_buses_ppc, i_sgen_pu, i_sgen_pu)
    ppc["bus"][buses, IKCV] = ikcv_pu
    ppc["bus"][:, IKSS2] = abs(1 / np.diag(Zbus) *
                               np.dot(Zbus, ppc["bus"][:, IKCV] * -1j) / baseI)
    ppc["bus"][buses, IKCV] /= baseI[buses]
Esempio n. 27
0
def _calc_ib_generator(net, ppci):
    Zbus = ppci["internal"]["Zbus"]
    baseI = ppci["internal"]["baseI"]
    tk_s = net._options['tk_s']
    c = 1.1

    z_equiv = ppci["bus"][:, R_EQUIV] + ppci["bus"][:, X_EQUIV] * 1j
    I_ikss = c / z_equiv / ppci["bus"][:,
                                       BASE_KV] / np.sqrt(3) * ppci["baseMVA"]
    I_ikss = c * ppci["bus"][:, BASE_KV] / np.sqrt(3) / z_equiv

    # calculate voltage source branch current
    # I_ikss = ppci["bus"][:, IKSS1]
    V_ikss = (I_ikss * baseI) * Zbus

    gen = net["gen"][net._is_elements["gen"]]
    gen_vn_kv = gen.vn_kv.values

    gen_buses = ppci['gen'][:, GEN_BUS].astype(np.int64)
    gen_mbase = ppci['gen'][:, MBASE]
    gen_i_rg = gen_mbase / (np.sqrt(3) * gen_vn_kv)

    gen_buses_ppc, gen_sn_mva, I_rG = _sum_by_group(gen_buses, gen_mbase,
                                                    gen_i_rg)

    # shunt admittance of generator buses and generator short circuit current
    # YS = ppci["bus"][gen_buses_ppc, GS] + ppci["bus"][gen_buses_ppc, BS] * 1j
    # I_kG = V_ikss.T[:, gen_buses_ppc] * YS / baseI[gen_buses_ppc]

    xdss_pu = gen.xdss_pu.values
    rdss_pu = gen.rdss_pu.values
    cosphi = gen.cos_phi.values
    X_dsss = xdss_pu * np.square(gen_vn_kv) / gen_mbase
    R_dsss = rdss_pu * np.square(gen_vn_kv) / gen_mbase

    K_G = ppci['bus'][gen_buses, BASE_KV] / gen_vn_kv * c / (
        1 + xdss_pu * np.sin(np.arccos(cosphi)))
    Z_G = (R_dsss + 1j * X_dsss)

    I_kG = c * ppci['bus'][gen_buses, BASE_KV] / np.sqrt(3) / (Z_G * K_G)

    dV_G = 1j * X_dsss * K_G * I_kG
    V_Is = c * ppci['bus'][gen_buses, BASE_KV] / np.sqrt(3)

    # I_kG_contribution = I_kG.sum(axis=1)
    # ratio_SG_ikss = I_kG_contribution / I_ikss
    # close_to_SG = ratio_SG_ikss > 5e-2

    close_to_SG = I_kG / I_rG > 2

    if tk_s == 2e-2:
        mu = 0.84 + 0.26 * np.exp(-0.26 * abs(I_kG) / I_rG)
    elif tk_s == 5e-2:
        mu = 0.71 + 0.51 * np.exp(-0.3 * abs(I_kG) / I_rG)
    elif tk_s == 10e-2:
        mu = 0.62 + 0.72 * np.exp(-0.32 * abs(I_kG) / I_rG)
    elif tk_s >= 25e-2:
        mu = 0.56 + 0.94 * np.exp(-0.38 * abs(I_kG) / I_rG)
    else:
        raise UserWarning(
            'not implemented for other tk_s than 20ms, 50ms, 100ms and >=250ms'
        )

    mu = np.clip(mu, 0, 1)

    I_ikss_G = abs(I_ikss - np.sum((1 - mu) * I_kG, axis=1))

    # I_ikss_G = I_ikss - np.sum(abs(V_ikss.T[:, gen_buses_ppc]) * (1-mu) * I_kG, axis=1)

    I_ikss_G = abs(I_ikss - np.sum(dV_G / V_Is * (1 - mu) * I_kG, axis=1))

    return I_ikss_G
Esempio n. 28
0
def _add_trafo_sc_impedance_zero(net, ppc, trafo_df=None):
    if trafo_df is None:
        trafo_df = net["trafo"]
    branch_lookup = net["_pd2ppc_lookups"]["branch"]
    if not "trafo" in branch_lookup:
        return
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    mode = net["_options"]["mode"]
    f, t = branch_lookup["trafo"]
    trafo_df["_ppc_idx"] = range(f, t)
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    buses_all, gs_all, bs_all = np.array([],
                                         dtype=int), np.array([]), np.array([])
    for vector_group, trafos in trafo_df.groupby("vector_group"):
        ppc_idx = trafos["_ppc_idx"].values.astype(int)
        ppc["branch"][ppc_idx, BR_STATUS] = 0

        if vector_group in ["Yy", "Yd", "Dy", "Dd"]:
            continue

        vk_percent = trafos["vk_percent"].values.astype(float)
        vkr_percent = trafos["vkr_percent"].values.astype(float)
        sn_mva = trafos["sn_mva"].values.astype(float)
        vk0_percent = trafos["vk0_percent"].values.astype(float)
        vkr0_percent = trafos["vkr0_percent"].values.astype(float)
        lv_buses = trafos["lv_bus"].values.astype(int)
        hv_buses = trafos["hv_bus"].values.astype(int)
        lv_buses_ppc = bus_lookup[lv_buses]
        hv_buses_ppc = bus_lookup[hv_buses]
        mag0_percent = trafos.mag0_percent.values.astype(float)
        mag0_rx = trafos["mag0_rx"].values.astype(float)
        si0_hv_partial = trafos.si0_hv_partial.values.astype(float)
        parallel = trafos.parallel.values.astype(float)
        in_service = trafos["in_service"].astype(int)

        ppc["branch"][ppc_idx, F_BUS] = hv_buses_ppc
        ppc["branch"][ppc_idx, T_BUS] = lv_buses_ppc

        vn_trafo_hv, vn_trafo_lv, shift = _calc_tap_from_dataframe(net, trafos)
        vn_lv = ppc["bus"][lv_buses_ppc, BASE_KV]
        ratio = _calc_nominal_ratio_from_dataframe(ppc, trafos, vn_trafo_hv,
                                                   vn_trafo_lv, bus_lookup)
        ppc["branch"][ppc_idx, TAP] = ratio
        ppc["branch"][ppc_idx, SHIFT] = shift

        # zero seq. transformer impedance
        tap_lv = np.square(
            vn_trafo_lv / vn_lv
        ) * net.sn_mva  # adjust for low voltage side voltage converter
        z_sc = vk0_percent / 100. / sn_mva * tap_lv
        r_sc = vkr0_percent / 100. / sn_mva * tap_lv
        z_sc = z_sc.astype(float)
        r_sc = r_sc.astype(float)
        x_sc = np.sign(z_sc) * np.sqrt(z_sc**2 - r_sc**2)
        z0_k = (r_sc + x_sc * 1j) / parallel
        if mode == "sc":
            from pandapower.shortcircuit.idx_bus import C_MAX
            cmax = net._ppc["bus"][lv_buses_ppc, C_MAX]
            kt = _transformer_correction_factor(vk_percent, vkr_percent,
                                                sn_mva, cmax)
            z0_k *= kt
        y0_k = 1 / z0_k
        # zero sequence transformer magnetising impedance
        z_m = vk0_percent * mag0_percent / 100. / sn_mva * tap_lv
        x_m = z_m / np.sqrt(mag0_rx**2 + 1)
        r_m = x_m * mag0_rx
        r0_trafo_mag = r_m / parallel
        x0_trafo_mag = x_m / parallel
        z0_mag = r0_trafo_mag + x0_trafo_mag * 1j

        if vector_group == "Dyn":
            buses_all = np.hstack([buses_all, lv_buses_ppc])
            gs_all = np.hstack([gs_all, y0_k.real * in_service])
            bs_all = np.hstack([bs_all, y0_k.imag * in_service])

        elif vector_group == "YNd":
            buses_all = np.hstack([buses_all, hv_buses_ppc])
            gs_all = np.hstack([gs_all, y0_k.real * in_service])
            bs_all = np.hstack([bs_all, y0_k.imag * in_service])

        elif vector_group == "Yyn":
            buses_all = np.hstack([buses_all, lv_buses_ppc])
            y = 1 / (z0_mag + z0_k).astype(complex)
            gs_all = np.hstack([gs_all, y.real * in_service])
            bs_all = np.hstack([bs_all, y.imag * in_service])

        elif vector_group == "YNyn":
            ppc["branch"][ppc_idx, BR_STATUS] = in_service
            # convert the t model to pi model
            z1 = si0_hv_partial * z0_k
            z2 = (1 - si0_hv_partial) * z0_k
            z3 = z0_mag

            z_temp = z1 * z2 + z2 * z3 + z1 * z3
            za = z_temp / z2
            zb = z_temp / z1
            zc = z_temp / z3

            ppc["branch"][ppc_idx, BR_R] = zc.real
            ppc["branch"][ppc_idx, BR_X] = zc.imag
            y = 2 / za
            ppc["branch"][ppc_idx, BR_B] = y.imag - y.real * 1j
            # add a shunt element parallel to zb if the leakage impedance distribution is unequal
            #TODO: this only necessary if si0_hv_partial!=0.5 --> test
            zs = (za * zb) / (za - zb)
            ys = 1 / zs.astype(complex)
            buses_all = np.hstack([buses_all, lv_buses_ppc])
            gs_all = np.hstack([gs_all, ys.real * in_service])
            bs_all = np.hstack([bs_all, ys.imag * in_service])
        elif vector_group == "YNy":
            buses_all = np.hstack([buses_all, hv_buses_ppc])
            y = 1 / (z0_mag + z0_k).astype(complex)
            gs_all = np.hstack([gs_all, y.real * in_service])
            bs_all = np.hstack([bs_all, y.imag * in_service])
        elif vector_group[-1].isdigit():
            raise ValueError(
                "Unknown transformer vector group %s - please specify vector group without phase shift number. Phase shift can be specified in net.trafo.shift_degree"
                % vector_group)
        else:
            raise ValueError(
                "Transformer vector group %s is unknown / not implemented" %
                vector_group)

    buses, gs, bs = aux._sum_by_group(buses_all, gs_all, bs_all)
    ppc["bus"][buses, GS] += gs
    ppc["bus"][buses, BS] += bs
    del net.trafo["_ppc_idx"]
Esempio n. 29
0
    z_grid = c / s_sc
    x_grid = z_grid / np.sqrt(rx**2 + 1)
    r_grid = rx * x_grid
    eg["r"] = r_grid
    eg["x"] = x_grid

    # ext_grid zero sequence impedance
    if case == "max":
        x0_grid = net.ext_grid["x0x_%s" % case] * x_grid
        r0_grid = net.ext_grid["r0x0_%s" % case] * x0_grid
    elif case == "min":
        x0_grid = net.ext_grid["x0x_%s" % case] * x_grid
        r0_grid = net.ext_grid["r0x0_%s" % case] * x0_grid
    y0_grid = 1 / (r0_grid + x0_grid * 1j)
    buses, gs, bs = aux._sum_by_group(eg_buses_ppc, y0_grid.real, y0_grid.imag)
    ppc["bus"][buses, GS] = gs
    ppc["bus"][buses, BS] = bs


def _add_line_sc_impedance_zero(net, ppc):
    branch_lookup = net["_pd2ppc_lookups"]["branch"]
    if not "line" in branch_lookup:
        return
    line = net["line"]
    bus_lookup = net["_pd2ppc_lookups"]["bus"]
    length = line["length_km"].values
    parallel = line["parallel"].values

    fb = bus_lookup[line["from_bus"].values]
    tb = bus_lookup[line["to_bus"].values]
Esempio n. 30
0
def _get_shunt_results(net, ppc, bus_lookup_aranged, bus_pq):
    ac = net["_options"]["ac"]

    b, p, q = np.array([]), np.array([]), np.array([])
    _is_elements = net["_is_elements"]
    bus_lookup = net["_pd2ppc_lookups"]["bus"]

    s = net["shunt"]
    if len(s) > 0:
        sidx = bus_lookup[s["bus"].values]
        shunt_is = _is_elements["shunt"]
        u_shunt = ppc["bus"][sidx, VM]
        step = s["step"]
        v_ratio = (ppc["bus"][sidx, BASE_KV] / net["shunt"]["vn_kv"].values) ** 2
        u_shunt = np.nan_to_num(u_shunt)
        p_shunt = u_shunt ** 2 * net["shunt"]["p_kw"].values * shunt_is * v_ratio * step
        net["res_shunt"]["p_kw"] = p_shunt
        p = np.hstack([p, p_shunt])
        if ac:
            net["res_shunt"]["vm_pu"] = u_shunt
            q_shunt = u_shunt ** 2 * net["shunt"]["q_kvar"].values * shunt_is * v_ratio * step
            net["res_shunt"]["q_kvar"] = q_shunt
            q = np.hstack([q, q_shunt])
        b = np.hstack([b, s["bus"].values])
        net["res_shunt"].index = net["shunt"].index

    w = net["ward"]
    if len(w) > 0:
        widx = bus_lookup[w["bus"].values]
        ward_is = _is_elements["ward"]
        u_ward = ppc["bus"][widx, VM]
        u_ward = np.nan_to_num(u_ward)
        p_ward = u_ward ** 2 * net["ward"]["pz_kw"].values * ward_is
        net["res_ward"]["p_kw"] += p_ward
        p = np.hstack([p, p_ward])
        if ac:
            net["res_ward"]["vm_pu"] = u_ward
            q_ward = u_ward ** 2 * net["ward"]["qz_kvar"].values * ward_is
            net["res_ward"]["q_kvar"] += q_ward
            q = np.hstack([q, q_ward])
        b = np.hstack([b, w["bus"].values])
        net["res_ward"].index = net["ward"].index

    xw = net["xward"]
    if len(xw) > 0:
        widx = bus_lookup[xw["bus"].values]
        xward_is = _is_elements["xward"]
        u_xward = ppc["bus"][widx, VM]
        u_xward = np.nan_to_num(u_xward)
        p_xward = u_xward ** 2 * net["xward"]["pz_kw"].values * xward_is
        net["res_xward"]["p_kw"] += p_xward
        p = np.hstack([p, p_xward])
        if ac:
            net["res_xward"]["vm_pu"] = u_xward
            q_xward = u_xward ** 2 * net["xward"]["qz_kvar"].values * xward_is
            net["res_xward"]["q_kvar"] += q_xward
            q = np.hstack([q, q_xward])
        b = np.hstack([b, xw["bus"].values])
        net["res_xward"].index = net["xward"].index

    if not ac:
        q = np.zeros(len(p))
    b_pp, vp, vq = _sum_by_group(b.astype(int), p, q)
    b_ppc = bus_lookup_aranged[b_pp]

    bus_pq[b_ppc, 0] += vp
    if ac:
        bus_pq[b_ppc, 1] += vq