Example #1
0
def _calc_trafo_parameter(net, ppc, bus_lookup, calculate_voltage_angles, trafo_model,
                          set_opf_constraints=False):
    '''
    Calculates the transformer parameter in per unit.

    **INPUT**:
        **net** - The Pandapower format network

    **RETURN**:
        **temp_para** -
        Temporary transformer parameter. Which is a np.complex128
        Numpy array. with the following order:
        0:hv_bus; 1:lv_bus; 2:r_pu; 3:x_pu; 4:b_pu; 5:tab, 6:shift
    '''
    temp_para = np.zeros(shape=(len(net["trafo"].index), 9), dtype=np.complex128)
    trafo = net["trafo"]
    temp_para[:, 0] = get_indices(trafo["hv_bus"].values, bus_lookup)
    temp_para[:, 1] = get_indices(trafo["lv_bus"].values, bus_lookup)
    temp_para[:, 2:6] = _calc_branch_values_from_trafo_df(net, ppc, bus_lookup, trafo_model)
    if calculate_voltage_angles:
        temp_para[:, 6] = trafo["shift_degree"].values
    else:
        temp_para[:, 6] = np.zeros(shape=(len(trafo.index),), dtype=np.complex128)
    temp_para[:, 7] = trafo["in_service"].values
    if set_opf_constraints:
        max_load = trafo.max_loading_percent if "max_loading_percent" in trafo else 1000
        temp_para[:, 8] = max_load / 100 * trafo.sn_kva / 1000
    return temp_para
Example #2
0
def _calc_impedance_parameter(net, bus_lookup):
    t = np.zeros(shape=(len(net["impedance"].index), 5), dtype=np.complex128)
    t[:, 0] = get_indices(net["impedance"]["from_bus"].values, bus_lookup)
    t[:, 1] = get_indices(net["impedance"]["to_bus"].values, bus_lookup)
    t[:, 2] = net["impedance"]["r_pu"] / net["impedance"]["sn_kva"] * 1000.
    t[:, 3] = net["impedance"]["x_pu"] / net["impedance"]["sn_kva"] * 1000.
    t[:, 4] = net["impedance"]["in_service"].values
    return t
Example #3
0
def _calc_xward_parameter(net, ppc, is_elems, bus_lookup):
    bus_is = is_elems['bus']
    baseR = np.square(get_values(ppc["bus"][:, BASE_KV], net["xward"]["bus"].values, bus_lookup))
    t = np.zeros(shape=(len(net["xward"].index), 5), dtype=np.complex128)
    xw_is = np.in1d(net["xward"].bus.values, bus_is.index) \
        & net["xward"].in_service.values.astype(bool)
    t[:, 0] = get_indices(net["xward"]["bus"].values, bus_lookup)
    t[:, 1] = get_indices(net["xward"]["ad_bus"].values, bus_lookup)
    t[:, 2] = net["xward"]["r_ohm"] / baseR
    t[:, 3] = net["xward"]["x_ohm"] / baseR
    t[:, 4] = xw_is
    return t
Example #4
0
def _calc_trafo3w_parameter(net, ppc, bus_lookup, calculate_voltage_angles, trafo_model):
    trafo_df = _trafo_df_from_trafo3w(net)

    temp_para = np.zeros(shape=(len(trafo_df), 8), dtype=np.complex128)
    temp_para[:, 0] = get_indices(trafo_df["hv_bus"].values, bus_lookup)
    temp_para[:, 1] = get_indices(trafo_df["lv_bus"].values, bus_lookup)
    temp_para[:, 2:6] = _calc_branch_values_from_trafo_df(
        net, ppc, bus_lookup, trafo_model, trafo_df)
    if calculate_voltage_angles:
        temp_para[:, 6] = trafo_df["shift_degree"].values
    else:
        temp_para[:, 6] = np.zeros(shape=(len(trafo_df.index),), dtype=np.complex128)
    temp_para[:, 7] = trafo_df["in_service"].values
    return temp_para
Example #5
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
Example #6
0
def reindex_junctions(net, junction_lookup):
    """
    Changes the index of net.junction and considers the new junction indices in all other
    pandapipes element tables.

    :param net: pandapipes network
    :type net: pandapipesNet
    :param junction_lookup: the keys are the old junction indices, the values the new junction \
            indices
    :type junction_lookup: dict
    :return: junction_lookup - the finally reindexed junction lookup (with corrections if necessary)
    :rtype: dict
    """

    not_fitting_junction_lookup_keys = set(junction_lookup.keys()) - set(
        net.junction.index)
    if len(not_fitting_junction_lookup_keys):
        logger.error(
            "These junction indices are unknown to net. Thus, they cannot be reindexed: "
            + str(not_fitting_junction_lookup_keys))

    missing_junction_indices = sorted(
        set(net.junction.index) - set(junction_lookup.keys()))
    if len(missing_junction_indices):
        duplicates = set(missing_junction_indices).intersection(
            set(junction_lookup.values()))
        if len(duplicates):
            logger.error(
                "The junctions %s are not listed in junction_lookup but their index is "
                "used as a new index. This would result in duplicated junction indices."
                % (str(duplicates)))
        else:
            junction_lookup.update({j: j for j in missing_junction_indices})

    net.junction.index = get_indices(net.junction.index, junction_lookup)
    if hasattr(net, "res_junction"):
        net.res_junction.index = get_indices(net.res_junction.index,
                                             junction_lookup)

    for element, value in element_junction_tuples(net=net):
        if element in net.keys():
            net[element][value] = get_indices(net[element][value],
                                              junction_lookup)
    net["junction_geodata"].set_index(get_indices(
        net["junction_geodata"].index, junction_lookup),
                                      inplace=True)
    return junction_lookup
Example #7
0
def reindex_elements(net, element, new_indices, old_indices=None):
    """
    Changes the index of net[element].

    :param net: pandapipes network
    :type net: pandapipesNet
    :param element: name of the element table
    :type element: str
    :param new_indices: list of new indices
    :type new_indices: iterable
    :param old_indices: list of old/previous indices which will be replaced. If None, all indices\
            are considered.
    :type old_indices: iterable, default None
    :return: No output.
    """

    old_indices = old_indices if old_indices is not None else net[element].index
    if not len(new_indices) or not net[element].shape[0]:
        return
    if len(new_indices) != len(old_indices):
        raise UserWarning(
            "The length of new indices to replace existing ones for %s does not "
            "match: %d (new) vs. %d (old)." %
            (element, len(new_indices), len(old_indices)))
    lookup = dict(zip(old_indices, new_indices))

    if element == "junction":
        reindex_junctions(net, lookup)
        return

    # --- reindex
    net[element]["index"] = net[element].index
    net[element].loc[old_indices, "index"] = get_indices(old_indices, lookup)
    net[element].set_index("index", inplace=True)

    # --- adapt geodata index
    geotable = element + "_geodata"
    if geotable in net and net[geotable].shape[0]:
        net[geotable]["index"] = net[geotable].index
        net[geotable].loc[old_indices,
                          "index"] = get_indices(old_indices, lookup)
        net[geotable].set_index("index", inplace=True)
Example #8
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
Example #9
0
def _calc_line_parameter(net, ppc, bus_lookup, set_opf_constraints=False):
    """
    calculates the line parameter in per unit.

    **INPUT**:
        **net** -The Pandapower format network

    **RETURN**:
        **t** - Temporary line parameter. Which is a complex128
                Nunmpy array. with the following order:
                0:bus_a; 1:bus_b; 2:r_pu; 3:x_pu; 4:b_pu
    """

    # baseR converts Ohm to p.u. Formula is U^2/Sref. Sref is 1 MVA and vn_kv is
    # in kV U^2* ((10^3 V)^2/10^6 VA) = U^2
    # Therefore division by 1 MVA is not necessary.
    line = net["line"]
    fb = get_indices(line["from_bus"], bus_lookup)
    tb = get_indices(line["to_bus"], bus_lookup)
    length = line["length_km"].values
    parallel = line["parallel"]
    baseR = np.square(ppc["bus"][fb, BASE_KV])
    t = np.zeros(shape=(len(line.index), 7), dtype=np.complex128)

    t[:, 0] = fb
    t[:, 1] = tb

    t[:, 2] = line["r_ohm_per_km"] * length / baseR / parallel
    t[:, 3] = line["x_ohm_per_km"] * length / baseR / parallel
    t[:, 4] = 2 * net.f_hz * math.pi * line["c_nf_per_km"] * 1e-9 * baseR * length * parallel
    t[:, 5] = line["in_service"]
    if set_opf_constraints:
        max_load = line.max_loading_percent if "max_loading_percent" in line else 1000
        vr = net.bus.vn_kv[fb].values * np.sqrt(3)
        t[:, 6] = max_load / 100 * line.imax_ka * line.df * parallel * vr
    return t
Example #10
0
def test_get_indices():
    a = [i + 100 for i in range(10)]
    lookup = {idx: pos for pos, idx in enumerate(a)}
    lookup["before_fuse"] = a

    # First without fused buses no magic here
    # after fuse
    result = get_indices([102, 107], lookup, fused_indices=True)
    assert np.array_equal(result, [2, 7])

    # before fuse
    result = get_indices([2, 7], lookup, fused_indices=False)
    assert np.array_equal(result, [102, 107])

    # Same setup EXCEPT we have fused buses now (bus 102 and 107 are fused)
    lookup[107] = lookup[102]

    # after fuse
    result = get_indices([102, 107], lookup, fused_indices=True)
    assert np.array_equal(result, [2, 2])

    # before fuse
    result = get_indices([2, 7], lookup, fused_indices=False)
    assert np.array_equal(result, [102, 107])
Example #11
0
def create_continuous_bus_index(net):
    """
    Creates a continuous bus index starting at zero and replaces all
    references of old indices by the new ones.
    """
    new_bus_idxs = np.arange(len(net.bus))
    bus_lookup = dict(zip(net["bus"].index.values, new_bus_idxs))
    net.bus.index = new_bus_idxs

    for element, value in [("line", "from_bus"), ("line", "to_bus"),
                           ("trafo", "hv_bus"), ("trafo", "lv_bus"),
                           ("sgen", "bus"), ("load", "bus"), ("switch", "bus"),
                           ("ward", "bus"), ("xward", "bus"),
                           ("impedance", "from_bus"), ("impedance", "to_bus"),
                           ("shunt", "bus"), ("ext_grid", "bus")]:
        net[element][value] = get_indices(net[element][value], bus_lookup)
    return net
Example #12
0
def _get_bus_results(net,
                     ppc,
                     bus_lookup,
                     bus_pq,
                     return_voltage_angles,
                     ac=True):
    net["res_bus"]["p_kw"] = bus_pq[:, 0]
    if ac:
        net["res_bus"]["q_kvar"] = bus_pq[:, 1]

    ppi = net["bus"].index.values
    bus_idx = get_indices(ppi, bus_lookup)
    if ac:
        net["res_bus"]["vm_pu"] = ppc["bus"][bus_idx][:, VM]
    net["res_bus"].index = net["bus"].index
    if return_voltage_angles or not ac:
        net["res_bus"]["va_degree"] = ppc["bus"][bus_idx][:, VA]
Example #13
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
Example #14
0
def _build_bus_ppc(net, ppc, is_elems, init_results=False, set_opf_constraints=False):
    """
    """
    if len(net["trafo3w"]) > 0:
        # TODO: include directly in pd2ppc so that buses are only in ppc, not in pandapower. LT
        _create_trafo3w_buses(net, init_results)
    if len(net["xward"]) > 0:
        # TODO: include directly in pd2ppc so that buses are only in ppc, not in pandapower. LT
        _create_xward_buses(net, init_results)

    # get buses as set
    bus_list = set(net["bus"].index.values)
    # get in service elements
    eg_is = is_elems['eg']
    gen_is = is_elems['gen']
    bus_is = is_elems['bus']

    # create a mapping from arbitrary pp-index to a consecutive index starting at zero (ppc-index)
    # To sort the array first, so that PV comes first, three steps are necessary:

    # 1. Find PV / Slack nodes and place them first (necessary for fast generation of Jacobi-Matrix)
    # get indices of PV (and ref) buses
    if len(net["xward"]) > 0:
        # add xwards if available
        pv_ref = set((np.r_[eg_is["bus"].values, gen_is["bus"].values, net["xward"][
                     net["xward"].in_service == 1]["ad_bus"].values]).flatten())
    else:
        pv_ref = set(np.r_[eg_is["bus"].values, gen_is["bus"].values].flatten())

    # 2. Add PQ buses without switches
    slidx = (net["switch"]["closed"].values == 1) & (net["switch"]["et"].values == "b") &\
            (net["switch"]["bus"].isin(bus_is.index).values) & (
                net["switch"]["element"].isin(bus_is.index).values)

    # get buses with switches
    switch_buses = set((np.r_[net["switch"]["bus"].values[slidx], net[
                       "switch"]["element"].values[slidx]]).flatten())
    pq_buses_without_switches = (bus_list - switch_buses) - pv_ref

    # consecutive values for pv, ref, and non switch pq buses
    npArange = np.arange(len(pq_buses_without_switches) + len(pv_ref))
    # buses in PandaPower
    PandaBusses = sorted(pv_ref) + sorted(pq_buses_without_switches)
    # generate bus_lookup PandaPower -> [PV, PQ(without switches)]
    bus_lookup = dict(zip(PandaBusses, npArange))

    # 3. Add PQ buses with switches and fuse them
    v = defaultdict(set)

    # get the pp-indices of the buses for those switches
    fbus = net["switch"]["bus"].values[slidx]
    tbus = net["switch"]["element"].values[slidx]

    # create a mapping to map each bus to itself at frist ...
    ds = DisjointSet({e: e for e in chain(fbus, tbus)})
    for f, t in zip(fbus, tbus):
        ds.union(f, t)

    for a in ds:
        v[ds.find(a)].add(a)
    disjoint_sets = [e for e in v.values() if len(e) > 1]

    i = npArange[-1]

    # check if PV buses need to be fused
    # if yes: the sets with PV buses must be found (which is slow)
    # if no: the check can be omitted
    if any(i in fbus or i in tbus for i in pv_ref):
        for dj in disjoint_sets:
            pv_buses_in_set = pv_ref & dj
            nr_pv_bus = len(pv_buses_in_set)
            if nr_pv_bus == 0:
                i += 1
                map_to = i
                bus = dj.pop()
                PandaBusses.append(bus)
                bus_lookup[bus] = map_to
            elif nr_pv_bus == 1:
                map_to = bus_lookup[pv_buses_in_set.pop()]
            else:
                raise UserWarning("Can't fuse two PV buses")
            for bus in dj:
                bus_lookup[bus] = map_to
    else:
        for dj in disjoint_sets:
            # new bus to map to
            i += 1
            map_to = i
            # get bus ID and append to Panda bus list
            bus = dj.pop()
            PandaBusses.append(bus)
            bus_lookup[bus] = map_to
            for bus in dj:
                bus_lookup[bus] = map_to

    # init ppc with zeros
    ppc["bus"] = np.zeros(shape=(i + 1, 13), dtype=float)
    # fill ppc with init values
    ppc["bus"][:] = np.array([0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1.1, 0.9])
    ppc["bus"][:, BUS_I] = np.arange(i + 1)

    # change the voltages of the buses to the values in net
    ppc["bus"][:, BASE_KV] = net["bus"].vn_kv.ix[PandaBusses]

    if init_results is True and len(net["res_bus"]) > 0:
        int_index = get_indices(net["bus"].index.values, bus_lookup)
        ppc["bus"][int_index, 7] = net["res_bus"]["vm_pu"].values
        ppc["bus"][int_index, 8] = net["res_bus"].va_degree.values

    if set_opf_constraints:
        if "max_vm_pu" in net.bus:
            ppc["bus"][:, VMAX] = net["bus"].max_vm_pu.loc[PandaBusses]
        else:
            ppc["bus"][:, VMAX] = 10
        if "min_vm_pu" in net.bus:
            ppc["bus"][:, VMIN] = net["bus"].min_vm_pu.loc[PandaBusses]
        else:
            ppc["bus"][:, VMIN] = 0

    return bus_lookup
Example #15
0
def _build_gen_ppc(net, ppc, is_elems, bus_lookup, enforce_q_lims, calculate_voltage_angles):
    '''
    Takes the empty ppc network and fills it with the gen values. The gen
    datatype will be float afterwards.

    **INPUT**:
        **net** -The Pandapower format network

        **ppc** - The PYPOWER format network to fill in values
    '''
    # get in service elements
    eg_is = is_elems['eg']
    gen_is = is_elems['gen']

    eg_end = len(eg_is)
    gen_end = eg_end + len(gen_is)
    xw_end = gen_end + len(net["xward"])

    q_lim_default = 1e9  # which is 1000 TW - should be enough for distribution grids.

    # initialize generator matrix
    ppc["gen"] = np.zeros(shape=(xw_end, 21), dtype=float)
    ppc["gen"][:] = np.array([0, 0, 0, q_lim_default, -q_lim_default, 1.,
                              1., 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

    # add ext grid / slack data
    ppc["gen"][:eg_end, GEN_BUS] = get_indices(eg_is["bus"].values, bus_lookup)
    ppc["gen"][:eg_end, VG] = eg_is["vm_pu"].values
    ppc["gen"][:eg_end, GEN_STATUS] = eg_is["in_service"].values

    # set bus values for external grid buses
    eg_buses = get_indices(eg_is["bus"].values, bus_lookup)
    if calculate_voltage_angles:
        ppc["bus"][eg_buses, VA] = eg_is["va_degree"].values
    ppc["bus"][eg_buses, BUS_TYPE] = REF

    # add generator / pv data
    if gen_end > eg_end:
        ppc["gen"][eg_end:gen_end, GEN_BUS] = get_indices(gen_is["bus"].values, bus_lookup)
        ppc["gen"][eg_end:gen_end, PG] = - gen_is["p_kw"].values * 1e-3 * gen_is["scaling"].values
        ppc["gen"][eg_end:gen_end, VG] = gen_is["vm_pu"].values

        # set bus values for generator buses
        gen_buses = get_indices(gen_is["bus"].values, bus_lookup)
        ppc["bus"][gen_buses, BUS_TYPE] = PV
        ppc["bus"][gen_buses, VM] = gen_is["vm_pu"].values

        if enforce_q_lims:
            ppc["gen"][eg_end:gen_end, QMIN] = -gen_is["max_q_kvar"].values * 1e-3
            ppc["gen"][eg_end:gen_end, QMAX] = -gen_is["min_q_kvar"].values * 1e-3

            qmax = ppc["gen"][eg_end:gen_end, [QMIN]]
            ncn.copyto(qmax, -q_lim_default, where=np.isnan(qmax))
            ppc["gen"][eg_end:gen_end, [QMIN]] = qmax

            qmin = ppc["gen"][eg_end:gen_end, [QMAX]]
            ncn.copyto(qmin, q_lim_default, where=np.isnan(qmin))
            ppc["gen"][eg_end:gen_end, [QMAX]] = qmin

    # add extended ward pv node data
    if xw_end > gen_end:
        xw = net["xward"]
        bus_is = is_elems['bus']
        xw_is = np.in1d(xw.bus.values, bus_is.index) \
            & xw.in_service.values.astype(bool)
        ppc["gen"][gen_end:xw_end, GEN_BUS] = get_indices(xw["ad_bus"].values, bus_lookup)
        ppc["gen"][gen_end:xw_end, VG] = xw["vm_pu"].values
        ppc["gen"][gen_end:xw_end, GEN_STATUS] = xw_is
        ppc["gen"][gen_end:xw_end, QMIN] = -q_lim_default
        ppc["gen"][gen_end:xw_end, QMAX] = q_lim_default

        xward_buses = get_indices(net["xward"]["ad_bus"].values, bus_lookup)
        ppc["bus"][xward_buses[xw_is], BUS_TYPE] = PV
        ppc["bus"][xward_buses[~xw_is], BUS_TYPE] = NONE
        ppc["bus"][xward_buses, VM] = net["xward"]["vm_pu"].values
Example #16
0
def _get_shunt_results(net, ppc, bus_lookup, bus_pq, bus_is, ac=True):
    b, p, q = np.array([]), np.array([]), np.array([])
    s = net["shunt"]
    if len(s) > 0:
        sidx = get_indices(s["bus"], bus_lookup)
        shunt_is = np.in1d(s.bus.values, bus_is.index) \
            & s.in_service.values.astype(bool)
        u_shunt = ppc["bus"][sidx, VM]
        u_shunt = np.nan_to_num(u_shunt)
        p_shunt = u_shunt**2 * net["shunt"]["p_kw"].values * shunt_is
        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
            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 = get_indices(w["bus"], bus_lookup)
        ward_is = np.in1d(w.bus.values, bus_is.index) \
            & w.in_service.values.astype(bool)
        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 = get_indices(xw["bus"], bus_lookup)
        xward_is = np.in1d(xw.bus.values, bus_is.index) \
            & xw.in_service.values.astype(bool)
        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 = get_indices(b_pp, bus_lookup, fused_indices=False)

    bus_pq[b_ppc, 0] += vp
    if ac:
        bus_pq[b_ppc, 1] += vq
Example #17
0
def _get_p_q_results(net, ppc, bus_lookup, bus_is, ac=True):
    bus_pq = np.zeros(shape=(len(net["bus"].index), 2), dtype=np.float)
    b, p, q = np.array([]), np.array([]), np.array([])

    l = net["load"]
    if len(l) > 0:
        load_is = np.in1d(l.bus.values, bus_is.index) \
            & l.in_service.values.astype(bool)
        scaling = l["scaling"].values
        pl = l["p_kw"].values * scaling * load_is
        net["res_load"]["p_kw"] = pl
        p = np.hstack([p, pl])
        if ac:
            ql = l["q_kvar"].values * scaling * load_is
            net["res_load"]["q_kvar"] = ql
            q = np.hstack([q, ql])
        b = np.hstack([b, l["bus"].values])
        net["res_load"].index = net["load"].index

    sg = net["sgen"]
    if len(sg) > 0:
        sgen_is = np.in1d(sg.bus.values, bus_is.index) \
            & sg.in_service.values.astype(bool)
        scaling = sg["scaling"].values
        psg = sg["p_kw"].values * scaling * sgen_is
        net["res_sgen"]["p_kw"] = psg
        p = np.hstack([p, psg])
        if ac:
            qsg = sg["q_kvar"].values * scaling * sgen_is
            net["res_sgen"]["q_kvar"] = qsg
            q = np.hstack([q, qsg])
        b = np.hstack([b, sg["bus"].values])
        net["res_sgen"].index = net["sgen"].index

    w = net["ward"]
    if len(w) > 0:
        ward_is = np.in1d(w.bus.values, bus_is.index) \
            & w.in_service.values.astype(bool)
        pw = w["ps_kw"].values * ward_is
        net["res_ward"]["p_kw"] = pw
        p = np.hstack([p, pw])
        if ac:
            qw = w["qs_kvar"].values * ward_is
            q = np.hstack([q, qw])
            net["res_ward"]["q_kvar"] = qw
        b = np.hstack([b, w["bus"].values])

    xw = net["xward"]
    if len(xw) > 0:
        xward_is = np.in1d(xw.bus.values, bus_is.index) \
            & xw.in_service.values.astype(bool)
        pxw = xw["ps_kw"].values * xward_is
        p = np.hstack([p, pxw])
        net["res_xward"]["p_kw"] = pxw
        if ac:
            qxw = xw["qs_kvar"].values * xward_is
            net["res_xward"]["q_kvar"] = qxw
            q = np.hstack([q, qxw])
        b = np.hstack([b, xw["bus"].values])
    if not ac:
        q = np.zeros(len(p))
    b_pp, vp, vq = _sum_by_group(b.astype(int), p, q)
    b_ppc = get_indices(b_pp, bus_lookup, fused_indices=False)
    bus_pq[b_ppc, 0] = vp
    bus_pq[b_ppc, 1] = vq
    return bus_pq
Example #18
0
def _switch_branches(n, ppc, is_elems, bus_lookup):
    """
    Updates the ppc["branch"] matrix with the changed from or to values
    according of the status of switches

    **INPUT**:
        **pd_net** - The Pandapower format network

        **ppc** - The PYPOWER format network to fill in values
    """

    # get in service elements
    lines_is = is_elems['line']
    bus_is = is_elems['bus']

    # opened bus line switches
    slidx = (n["switch"]["closed"].values == 0) \
        & (n["switch"]["et"].values == "l")

    # check if there are multiple opened switches at a line (-> set line out of service)
    sw_elem = n['switch'].ix[slidx].element
    m = np.zeros_like(sw_elem, dtype=bool)
    m[np.unique(sw_elem, return_index=True)[1]] = True

    # if non unique elements are in sw_elem (= multiple opened bus line switches)
    if np.count_nonzero(m) < len(sw_elem):
        # set branch in ppc out of service
        # get from and to buses of these branches
        ppc_from = get_indices(lines_is.ix[sw_elem[~m]].from_bus, bus_lookup)
        ppc_to = get_indices(lines_is.ix[sw_elem[~m]].to_bus, bus_lookup)
        ppc_idx = np.in1d(ppc['branch'][:, 0], ppc_from)\
            & np.in1d(ppc['branch'][:, 1], ppc_to)
        ppc["branch"][ppc_idx, BR_STATUS] = 0

        # drop from in service lines as well
        lines_is = lines_is.drop(sw_elem[~m])

    # opened switches at in service lines
    slidx = slidx\
        & (np.in1d(n["switch"]["element"].values, lines_is.index)) \
        & (np.in1d(n["switch"]["bus"].values, bus_is.index))
    nlo = np.count_nonzero(slidx)

    stidx = (n.switch["closed"].values == 0) & (n.switch["et"].values == "t")
    nto = np.count_nonzero(stidx)

    if (nlo + nto) > 0:
        n_bus = len(ppc["bus"])

        if nlo:
            future_buses = [ppc["bus"]]
            line_switches = n["switch"].loc[slidx]

            # determine on which side the switch is located
            mapfunc = partial(_gather_branch_switch_info, branch_type="l", net=n)
            ls_info = list(map(mapfunc,
                               line_switches["bus"].values,
                               line_switches["element"].values))
            # we now have the following matrix
            # 0: 1 if switch is at to_bus, 0 else
            # 1: bus of the switch
            # 2: position of the line a switch is connected to
            ls_info = np.array(ls_info, dtype=int)

            # build new buses
            new_ls_buses = np.zeros(shape=(nlo, 13), dtype=float)
            new_indices = np.arange(n_bus, n_bus + nlo)
            # the newly created buses
            new_ls_buses[:] = np.array([0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1.1, 0.9])
            new_ls_buses[:, 0] = new_indices
            new_ls_buses[:, 9] = get_values(ppc["bus"][:, BASE_KV], ls_info[:, 1], bus_lookup)
#             set voltage of new buses to voltage on other branch end
            to_buses = ppc["branch"][ls_info[ls_info[:, 0].astype(bool), 2], 1].real.astype(int)
            from_buses = ppc["branch"][ls_info[np.logical_not(ls_info[:, 0]), 2], 0].real\
                .astype(int)
            if len(to_buses):
                ix = ls_info[:, 0] == 1
                new_ls_buses[ix, 7] = ppc["bus"][to_buses, 7]
                new_ls_buses[ix, 8] = ppc["bus"][to_buses, 8]
            if len(from_buses):
                ix = ls_info[:, 0] == 0
                new_ls_buses[ix, 7] = ppc["bus"][from_buses, 7]
                new_ls_buses[ix, 8] = ppc["bus"][from_buses, 8]

            future_buses.append(new_ls_buses)

            # re-route the end of lines to a new bus
            ppc["branch"][ls_info[ls_info[:, 0].astype(bool), 2], 1] = \
                new_indices[ls_info[:, 0].astype(bool)]
            ppc["branch"][ls_info[np.logical_not(ls_info[:, 0]), 2], 0] = \
                new_indices[np.logical_not(ls_info[:, 0])]

            ppc["bus"] = np.vstack(future_buses)

        if nto:
            future_buses = [ppc["bus"]]
            trafo_switches = n["switch"].loc[stidx]

            # determine on which side the switch is located
            mapfunc = partial(_gather_branch_switch_info, branch_type="t", net=n)
            ts_info = list(map(mapfunc,
                               trafo_switches["bus"].values,
                               trafo_switches["element"].values))
            # we now have the following matrix
            # 0: 1 if switch is at lv_bus, 0 else
            # 1: bus of the switch
            # 2: position of the trafo a switch is connected to
            ts_info = np.array(ts_info, dtype=int)

            # build new buses
            new_ts_buses = np.zeros(shape=(nto, 13), dtype=float)
            new_indices = np.arange(n_bus + nlo, n_bus + nlo + nto)
            new_ts_buses[:] = np.array([0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1.1, 0.9])
            new_ts_buses[:, 0] = new_indices
            new_ts_buses[:, 9] = get_values(ppc["bus"][:, BASE_KV],
                                            ts_info[:, 1], bus_lookup)
            # set voltage of new buses to voltage on other branch end
            to_buses = ppc["branch"][ts_info[ts_info[:, 0].astype(bool), 2], 1].real.astype(int)
            from_buses = ppc["branch"][ts_info[np.logical_not(ts_info[:, 0]), 2], 0].real\
                .astype(int)

            # set newly created buses to voltage on other side of
            if len(to_buses):
                ix = ts_info[:, 0] == 1
                taps = ppc["branch"][ts_info[ts_info[:, 0].astype(bool), 2], 8].real
                shift = ppc["branch"][ts_info[ts_info[:, 0].astype(bool), 2], 9].real
                new_ts_buses[ix, 7] = ppc["bus"][to_buses, 7] * taps
                new_ts_buses[ix, 8] = ppc["bus"][to_buses, 8] + shift
            if len(from_buses):
                ix = ts_info[:, 0] == 0
                taps = ppc["branch"][ts_info[np.logical_not(ts_info[:, 0]), 2], 8].real
                shift = ppc["branch"][ts_info[np.logical_not(ts_info[:, 0]), 2], 9].real
                new_ts_buses[ix, 7] = ppc["bus"][from_buses, 7] * taps
                new_ts_buses[ix, 8] = ppc["bus"][from_buses, 8] + shift

            future_buses.append(new_ts_buses)

            # re-route the hv/lv-side of the trafo to a new bus
            # (trafo entries follow line entries)
            at_lv_bus = ts_info[:, 0].astype(bool)
            at_hv_bus = ~at_lv_bus
            ppc["branch"][len(n.line) + ts_info[at_lv_bus, 2], 1] = \
                new_indices[at_lv_bus]
            ppc["branch"][len(n.line) + ts_info[at_hv_bus, 2], 0] = \
                new_indices[at_hv_bus]

            ppc["bus"] = np.vstack(future_buses)
Example #19
0
def _get_gen_results(net,
                     ppc,
                     is_elems,
                     bus_lookup,
                     pq_bus,
                     return_voltage_angles,
                     ac=True):
    # get in service elements
    gen_is = is_elems['gen']
    eg_is = is_elems['eg']

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

    # get results for external grids
    # bus index of in service egs
    gidx = eg_is.bus.values
    n_res_eg = len(net['ext_grid'])
    # indices of in service gens in the ppc
    gidx_ppc = np.searchsorted(ppc['gen'][:, GEN_BUS],
                               get_indices(eg_is["bus"], bus_lookup))
    # mask for indices of in service gens in net['res_gen']
    idx_eg = np.in1d(net['ext_grid'].bus, gidx)
    # read results from ppc for these buses
    p = np.zeros(n_res_eg)
    p[idx_eg] = -ppc["gen"][gidx_ppc, PG] * 1e3
    # store result in net['res']
    net["res_ext_grid"]["p_kw"] = p

    # if ac PF q results are also available
    if ac:
        q = np.zeros(n_res_eg)
        q[idx_eg] = -ppc["gen"][gidx_ppc, QG] * 1e3
        net["res_ext_grid"]["q_kvar"] = q

    # get bus values for pq_bus
    b = net['ext_grid'].bus.values
    # copy index for results
    net["res_ext_grid"].index = net['ext_grid'].index

    # get results for gens
    if gen_end > eg_end:

        # bus index of in service gens
        gidx = gen_is.bus.values
        n_res_gen = len(net['gen'])

        b = np.hstack([b, net['gen'].bus.values])

        # indices of in service gens in the ppc
        gidx_ppc = np.searchsorted(ppc['gen'][:, GEN_BUS],
                                   get_indices(gen_is["bus"], bus_lookup))
        # mask for indices of in service gens in net['res_gen']
        idx_gen = np.in1d(net['gen'].bus, gidx)

        # read results from ppc for these buses
        p_gen = np.zeros(n_res_gen)
        p_gen[idx_gen] = -ppc["gen"][gidx_ppc, PG] * 1e3
        if ac:
            q_gen = np.zeros(n_res_gen)
            q_gen[idx_gen] = -ppc["gen"][gidx_ppc, QG] * 1e3

        v_pu = np.zeros(n_res_gen)
        v_pu[idx_gen] = ppc["bus"][gidx_ppc][:, VM]
        net["res_gen"]["vm_pu"] = v_pu
        if return_voltage_angles:
            v_a = np.zeros(n_res_gen)
            v_a[idx_gen] = ppc["bus"][gidx_ppc][:, VA]
            net["res_gen"]["va_degree"] = v_a
        net["res_gen"].index = net['gen'].index

        # store result in net['res']
        p = np.hstack([p, p_gen])
        net["res_gen"]["p_kw"] = p_gen
        if ac:
            q = np.hstack([q, q_gen])
            net["res_gen"]["q_kvar"] = q_gen

    if not ac:
        q = np.zeros(len(p))
    b_sum, p_sum, q_sum = _sum_by_group(b, p, q)
    b = get_indices(b_sum, bus_lookup, fused_indices=False)
    pq_bus[b, 0] += p_sum
    pq_bus[b, 1] += q_sum