Ejemplo n.º 1
0
            "x": dist.loc[net.bus.index.values].values,
            "y": voltages.loc[net.bus.index.values].values
        },
        index=net.bus.index)
    return bgd


if __name__ == "__main__":
    import pandapower as pp
    import pandapower.networks as nw
    import pandas as pd
    import networkx as nx
    import plotting

    net = nw.mv_oberrhein()
    pp.runpp(net)
    mg = top.create_nxgraph(net, respect_switches=True)
    feeders = list(
        top.connected_components(mg, notravbuses=set(net.trafo.lv_bus.values)))
    lines_with_open_switches = set(
        net.switch.query("not closed and et == 'l'").element.values)

    fig, axs = plt.subplots(2)
    for bgd, ax in zip(
        [net.bus_geodata, voltage_profile_to_bus_geodata(net)], axs):
        for color, f in zip(["C0", "C1", "C2", "C3"], feeders):
            l = set(net.line.index[net.line.from_bus.isin(
                f)]) - lines_with_open_switches
            c = plotting.create_line_collection(net,
                                                lines=l,
                                                use_bus_geodata=True,
Ejemplo n.º 2
0
def example_multivoltage():
    """
    Returns the multivoltage example network from the pandapower tutorials.

    OUTPUT:
        net - multivoltage example network

    EXAMPLE:

    >>> import pandapower.networks
    >>> net = pandapower.networks.example_multivoltage()

    """
    net = pp.create_empty_network()

    # --- Busses

    # HV
    # Double busbar
    pp.create_bus(net, name='Double Busbar 1', vn_kv=380, type='b')
    pp.create_bus(net, name='Double Busbar 2', vn_kv=380, type='b')

    for i in range(10):
        pp.create_bus(net, name='Bus DB T%s' % i, vn_kv=380, type='n')

    for i in range(1, 5):
        pp.create_bus(net, name='Bus DB %s' % i, vn_kv=380, type='n')

    # Single busbar
    pp.create_bus(net, name='Single Busbar', vn_kv=110, type='b')

    for i in range(1, 6):
        pp.create_bus(net, name='Bus SB %s' % i, vn_kv=110, type='n')

    for i in range(1, 6):
        for j in [1, 2]:
            pp.create_bus(net,
                          name='Bus SB T%s.%s' % (i, j),
                          vn_kv=110,
                          type='n')

    # Remaining
    for i in range(1, 5):
        pp.create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n')

    # MV
    pp.create_bus(net, name='Bus MV0 20kV', vn_kv=20, type='n')

    for i in range(8):
        pp.create_bus(net, name='Bus MV%s' % i, vn_kv=10, type='n')

    # LV
    pp.create_bus(net, name='Bus LV0', vn_kv=0.4, type='n')

    for i in range(1, 6):
        pp.create_bus(net, name='Bus LV1.%s' % i, vn_kv=0.4, type='m')

    for i in range(1, 5):
        pp.create_bus(net, name='Bus LV2.%s' % i, vn_kv=0.4, type='m')

    pp.create_bus(net, name='Bus LV2.2.1', vn_kv=0.4, type='m')
    pp.create_bus(net, name='Bus LV2.2.2', vn_kv=0.4, type='m')

    # --- Lines

    # HV
    hv_lines = pd.DataFrame()
    hv_lines['line_name'] = ['HV Line%s' % i for i in range(1, 7)]
    hv_lines['from_bus'] = [
        'Bus SB 2', 'Bus HV1', 'Bus HV2', 'Bus HV1', 'Bus HV3', 'Bus SB 3'
    ]
    hv_lines['to_bus'] = [
        'Bus HV1', 'Bus HV2', 'Bus HV4', 'Bus HV4', 'Bus HV4', 'Bus HV3'
    ]
    hv_lines['std_type'] = '184-AL1/30-ST1A 110.0'
    hv_lines['length'] = [30, 20, 30, 15, 25, 30]
    hv_lines['parallel'] = [1, 1, 1, 1, 1, 2]

    for _, hv_line in hv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", hv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", hv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=hv_line.length,
                       std_type=hv_line.std_type,
                       name=hv_line.line_name,
                       parallel=hv_line.parallel)

    # MV
    mv_lines = pd.DataFrame()
    mv_lines['line_name'] = ['MV Line%s' % i for i in range(1, 9)]
    mv_lines['from_bus'] = ['Bus MV%s' % i for i in list(range(7)) + [0]]
    mv_lines['to_bus'] = ['Bus MV%s' % i for i in list(range(1, 8)) + [7]]
    mv_lines['length'] = 1.5
    mv_lines['std_type'] = 'NA2XS2Y 1x185 RM/25 12/20 kV'

    for _, mv_line in mv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", mv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", mv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=mv_line.length,
                       std_type=mv_line.std_type,
                       name=mv_line.line_name)

    # LV
    lv_lines = pd.DataFrame()
    lv_line_idx = [
        '1.1', '1.2', '1.3', '1.4', '1.6', '2.1', '2.2', '2.3', '2.4', '2.2.1',
        '2.2.2'
    ]
    lv_lines['line_name'] = ['LV Line%s' % i for i in lv_line_idx]
    lv_line_idx = [
        '0', '1.1', '1.2', '1.3', '1.4', '0', '2.1', '2.2', '2.3', '2.2',
        '2.2.1'
    ]
    lv_lines['from_bus'] = ['Bus LV%s' % i for i in lv_line_idx]
    lv_line_idx = [
        '1.1', '1.2', '1.3', '1.4', '1.5', '2.1', '2.2', '2.3', '2.4', '2.2.1',
        '2.2.2'
    ]
    lv_lines['to_bus'] = ['Bus LV%s' % i for i in lv_line_idx]
    lv_lines['length'] = [0.08] * 5 + [0.12] * 6
    lv_lines['std_type'] = ['NAYY 4x120 SE'] * 7 + ['15-AL1/3-ST1A 0.4'] * 4

    for _, lv_line in lv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", lv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", lv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=lv_line.length,
                       std_type=lv_line.std_type,
                       name=lv_line.line_name)

    # --- Transformer

    hv_bus = pp.get_element_index(net, "bus", "Bus DB 2")
    lv_bus = pp.get_element_index(net, "bus", "Bus SB 1")
    pp.create_transformer_from_parameters(net,
                                          hv_bus,
                                          lv_bus,
                                          sn_kva=300000,
                                          vn_hv_kv=380,
                                          vn_lv_kv=110,
                                          vscr_percent=0.06,
                                          vsc_percent=8,
                                          pfe_kw=0,
                                          i0_percent=0,
                                          tp_pos=0,
                                          shift_degree=0,
                                          name='EHV-HV-Trafo')

    hv_bus = pp.get_element_index(net, "bus", "Bus MV4")
    lv_bus = pp.get_element_index(net, "bus", "Bus LV0")
    pp.create_transformer_from_parameters(net,
                                          hv_bus,
                                          lv_bus,
                                          sn_kva=400,
                                          vn_hv_kv=10,
                                          vn_lv_kv=0.4,
                                          vscr_percent=1.325,
                                          vsc_percent=4,
                                          pfe_kw=0.95,
                                          i0_percent=0.2375,
                                          tp_side="hv",
                                          tp_mid=0,
                                          tp_min=-2,
                                          tp_max=2,
                                          tp_st_percent=2.5,
                                          tp_pos=0,
                                          shift_degree=150,
                                          name='MV-LV-Trafo')

    # Trafo3w
    hv_bus = pp.get_element_index(net, "bus", "Bus HV2")
    mv_bus = pp.get_element_index(net, "bus", "Bus MV0 20kV")
    lv_bus = pp.get_element_index(net, "bus", "Bus MV0")
    pp.create_transformer3w_from_parameters(net,
                                            hv_bus,
                                            mv_bus,
                                            lv_bus,
                                            vn_hv_kv=110,
                                            vn_mv_kv=20,
                                            vn_lv_kv=10,
                                            sn_hv_kva=40000,
                                            sn_mv_kva=15000,
                                            sn_lv_kva=25000,
                                            vsc_hv_percent=10.1,
                                            vsc_mv_percent=10.1,
                                            vsc_lv_percent=10.1,
                                            vscr_hv_percent=0.266667,
                                            vscr_mv_percent=0.033333,
                                            vscr_lv_percent=0.04,
                                            pfe_kw=0,
                                            i0_percent=0,
                                            shift_mv_degree=30,
                                            shift_lv_degree=30,
                                            tp_side="hv",
                                            tp_mid=0,
                                            tp_min=-8,
                                            tp_max=8,
                                            tp_st_percent=1.25,
                                            tp_pos=0,
                                            name='HV-MV-MV-Trafo')

    # --- Static generators

    # HV
    pp.create_sgen(net,
                   pp.get_element_index(net, "bus", 'Bus SB 5'),
                   p_kw=-20000,
                   q_kvar=-4000,
                   sn_kva=45000,
                   type='WP',
                   name='Wind Park')

    # MV
    mv_sgens = pd.DataFrame()
    mv_sgens['sgen_name'] = [
        'Biogas plant', 'Further MV Generator', 'Industry Generator', 'PV Park'
    ]
    mv_sgens['bus'] = ['Bus MV6', 'Bus MV0', 'Bus MV0 20kV', 'Bus MV5']
    mv_sgens['p'] = [-500, -500, -15000, -2000]
    mv_sgens['q'] = [0, -50, -3000, -100]
    mv_sgens['sn'] = [750, 1000, 20000, 5000]
    mv_sgens['type'] = ['SGEN', 'SGEN', 'SGEN', 'PV']

    for _, sgen in mv_sgens.iterrows():
        bus_idx = pp.get_element_index(net, "bus", sgen.bus)
        pp.create_sgen(net,
                       bus_idx,
                       p_kw=sgen.p,
                       q_kvar=sgen.q,
                       sn_kva=sgen.sn,
                       type=sgen.type,
                       name=sgen.sgen_name)

    # LV
    lv_sgens = pd.DataFrame()
    lv_sgens['sgen_name'] = ['PV'] + ['PV(%s)' % i for i in range(1, 6)]
    lv_sgens['bus'] = [
        'Bus LV%s' % i for i in ['1.1', '1.3', '2.3', '2.4', '2.2.1', '2.2.2']
    ]
    lv_sgens['p'] = [-6, -5, -5, -5, -5, -5]
    lv_sgens['q'] = 0
    lv_sgens['sn'] = [12, 10, 10, 10, 10, 10]
    lv_sgens['type'] = 'PV'

    for _, sgen in lv_sgens.iterrows():
        bus_idx = pp.get_element_index(net, "bus", sgen.bus)
        pp.create_sgen(net,
                       bus_idx,
                       p_kw=sgen.p,
                       q_kvar=sgen.q,
                       sn_kva=sgen.sn,
                       type=sgen.type,
                       name=sgen.sgen_name)

    # --- Loads

    # HV
    hv_loads = pd.DataFrame()
    hv_loads['load_name'] = ['MV Net %s' % i for i in range(5)]
    hv_loads['bus'] = ['Bus SB 4', 'Bus HV1', 'Bus HV2', 'Bus HV3', 'Bus HV4']
    hv_loads['p'] = 38000
    hv_loads['q'] = 6000

    for _, load in hv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # MV
    mv_loads = pd.DataFrame()
    mv_loads['load_name'] = ['Further MV-Rings', 'Industry Load'
                             ] + ['LV Net %s' % i for i in [1, 2, 3, 5, 6, 7]]
    mv_loads['bus'] = ['Bus MV0', 'Bus MV0 20kV'
                       ] + ['Bus MV%s' % i for i in [1, 2, 3, 5, 6, 7]]
    mv_loads['p'] = [6000, 18000, 400, 400, 400, 400, 400, 400]
    mv_loads['q'] = [2000, 4000, 100, 60, 60, 60, 60, 60]

    for _, load in mv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # LV
    lv_loads = pd.DataFrame()
    idx = ['', '(1)', '(2)', '(3)', '(4)', '(5)']
    lv_loads['load_name'] = ['Further LV-Feeders Load'] + [
        'Residential Load%s' % i for i in idx[0:5]
    ] + ['Rural Load%s' % i for i in idx[0:6]]
    lv_loads['bus'] = [
        'Bus LV%s' % i for i in [
            '0', '1.1', '1.2', '1.3', '1.4', '1.5', '2.1', '2.2', '2.3', '2.4',
            '2.2.1', '2.2.2'
        ]
    ]
    lv_loads['p'] = [100] + [10] * 11
    lv_loads['q'] = [10] + [3] * 11

    for _, load in lv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # --- Other

    # Shunt
    pp.create_shunt(net,
                    pp.get_element_index(net, "bus", 'Bus HV1'),
                    p_kw=0,
                    q_kvar=-960,
                    name='Shunt')

    # ExtGrids
    pp.create_ext_grid(net,
                       pp.get_element_index(net, "bus", 'Double Busbar 1'),
                       vm_pu=1.03,
                       va_degree=0,
                       name='External grid',
                       s_sc_max_mva=10000,
                       rx_max=0.1,
                       rx_min=0.1)
    # Gen
    pp.create_gen(net,
                  pp.get_element_index(net, "bus", 'Bus HV4'),
                  vm_pu=1.03,
                  p_kw=-1e5,
                  name='Gas turbine')

    # Impedance
    pp.create_impedance(net,
                        pp.get_element_index(net, "bus", 'Bus HV3'),
                        pp.get_element_index(net, "bus", 'Bus HV1'),
                        rft_pu=0.074873,
                        xft_pu=0.198872,
                        sn_kva=100000,
                        name='Impedance')

    # xwards
    pp.create_xward(net,
                    pp.get_element_index(net, "bus", 'Bus HV3'),
                    ps_kw=23942,
                    qs_kvar=-12241.87,
                    pz_kw=2814.571,
                    qz_kvar=0,
                    r_ohm=0,
                    x_ohm=12.18951,
                    vm_pu=1.02616,
                    name='XWard 1')
    pp.create_xward(net,
                    pp.get_element_index(net, "bus", 'Bus HV1'),
                    ps_kw=3776,
                    qs_kvar=-7769.979,
                    pz_kw=9174.917,
                    qz_kvar=0,
                    r_ohm=0,
                    x_ohm=50.56217,
                    vm_pu=1.024001,
                    name='XWard 2')

    # --- Switches

    # HV
    # Bus-bus switches
    hv_bus_sw = pd.DataFrame()
    hv_bus_sw['bus_name'] = ['DB DS%s' % i for i in range(14)] + \
                            ['DB CB%s' % i for i in range(5)] + \
                            ['SB DS%s.%s' % (i, j) for i in range(1, 6) for j in range(1, 3)] + \
                            ['SB CB%s' % i for i in range(1, 6)]
    hv_bus_sw['from_bus'] = ['Double Busbar %s' % i for i in [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]] + \
                            ['Bus DB T%s' % i for i in [2, 4, 6, 8, 0, 3, 5, 7, 9]] + \
                            ['Bus SB T1.1', 'Single Busbar', 'Bus SB T2.1', 'Single Busbar',
                             'Bus SB T3.1', 'Single Busbar', 'Bus SB T4.1', 'Single Busbar',
                             'Bus SB T5.1', 'Single Busbar'] + \
                            ['Bus SB T%s.2' % i for i in range(1, 6)]
    hv_bus_sw['to_bus'] = ['Bus DB %s' % i for i in
                           ['T0', 'T1', 'T3', 'T3', 'T5', 'T5', 'T7', 'T7', 'T9', 'T9',
                            '1', '2', '3', '4', 'T1', 'T2', 'T4', 'T6', 'T8']] + \
                          ['Bus SB %s' % i for i in
                           ['1', 'T1.2', '2', 'T2.2', '3', 'T3.2', '4', 'T4.2', '5', 'T5.2']] + \
                          ['Bus SB T%s.1' % i for i in range(1, 6)]
    hv_bus_sw['type'] = ['DS'] * 14 + ['CB'] * 5 + ['DS'] * 10 + ['CB'] * 5
    hv_bus_sw['et'] = 'b'
    hv_bus_sw['closed'] = [
        bool(i)
        for i in [1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1] +
        [1] * 15
    ]

    for _, switch in hv_bus_sw.iterrows():
        from_bus = pp.get_element_index(net, "bus", switch.from_bus)
        to_bus = pp.get_element_index(net, "bus", switch.to_bus)
        pp.create_switch(net,
                         from_bus,
                         to_bus,
                         et=switch.et,
                         closed=switch.closed,
                         type=switch.type,
                         name=switch.bus_name)

    # Bus-Line switches
    hv_buses = net.bus[(net.bus.vn_kv == 380) | (net.bus.vn_kv == 110)].index
    hv_ls = net.line[(net.line.from_bus.isin(hv_buses))
                     & (net.line.to_bus.isin(hv_buses))]
    for _, line in hv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    # MV
    # Bus-line switches
    mv_buses = net.bus[(net.bus.vn_kv == 10) | (net.bus.vn_kv == 20)].index
    mv_ls = net.line[(net.line.from_bus.isin(mv_buses))
                     & (net.line.to_bus.isin(mv_buses))]
    for _, line in mv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    open_switch_id = net.switch[(
        net.switch.name == 'Switch Bus MV5 - MV Line5')].index
    net.switch.closed.loc[open_switch_id] = False

    # LV
    # Bus-line switches
    lv_buses = net.bus[net.bus.vn_kv == 0.4].index
    lv_ls = net.line[(net.line.from_bus.isin(lv_buses))
                     & (net.line.to_bus.isin(lv_buses))]
    for _, line in lv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    # Trafoswitches
    # HV
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus DB 2'),
                     pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch DB2 - EHV-HV-Trafo')
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus SB 1'),
                     pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch SB1 - EHV-HV-Trafo')
    # LV
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus MV4'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch MV4 - MV-LV-Trafo')
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus LV0'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch LV0 - MV-LV-Trafo')

    # --- Powerflow

    # run power flow and generate result tables
    pp.runpp(net, init='dc', calculate_voltage_angles=True, Numba=False)

    return net
Ejemplo n.º 3
0
def test_init_slack_with_multiple_transformers(angles=True):
    np.random.seed(123)
    net = pp.create_empty_network()
    pp.create_bus(net, 220, index=0)
    pp.create_bus(net, 110, index=1)
    pp.create_bus(net, 110, index=2)
    pp.create_bus(net, 110, index=3)
    pp.create_bus(net, 10, index=4)
    pp.create_bus(net, 10, index=5)
    pp.create_bus(net, 10, index=6)
    pp.create_bus(net, 10, index=7, in_service=False)
    pp.create_transformer(net,
                          3,
                          7,
                          std_type="63 MVA 110/10 kV",
                          in_service=False)
    pp.create_transformer(net, 3, 4, std_type="63 MVA 110/10 kV")
    pp.create_transformer(net, 0, 1, std_type="100 MVA 220/110 kV")
    pp.create_line(net, 1, 2, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV")
    pp.create_line(net, 1, 3, 2.0, std_type="N2XS(FL)2Y 1x120 RM/35 64/110 kV")
    pp.create_line(net, 4, 5, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV")
    pp.create_line(net, 5, 6, 2.0, std_type="NA2XS2Y 1x95 RM/25 12/20 kV")
    pp.create_load(net, 2, 5000, 3300)
    pp.create_load(net, 5, 900, 500)
    pp.create_load(net, 6, 700, 300)
    pp.create_ext_grid(net,
                       bus=0,
                       vm_pu=1.04,
                       va_degree=10.,
                       name="Slack 220 kV")
    pp.runpp(net, calculate_voltage_angles=angles)
    for bus, row in net.res_bus[net.bus.in_service == True].iterrows():
        pp.create_measurement(net, "v", "bus", row.vm_pu * r(0.01), 0.01, bus)
        if row.p_kw != 0.:
            continue
        pp.create_measurement(net, "p", "bus", -row.p_kw * r(),
                              max(1.0, abs(0.03 * row.p_kw)), bus)
        pp.create_measurement(net, "q", "bus", -row.q_kvar * r(),
                              max(1.0, abs(0.03 * row.q_kvar)), bus)
    pp.create_measurement(net,
                          "p",
                          "line",
                          net.res_line.p_from_kw[0],
                          10.,
                          bus=1,
                          element=0)
    pp.create_measurement(net,
                          "q",
                          "line",
                          net.res_line.q_from_kvar[0],
                          10.,
                          bus=1,
                          element=0)
    pp.create_measurement(net,
                          "p",
                          "line",
                          net.res_line.p_from_kw[2],
                          10.,
                          bus=4,
                          element=2)
    pp.create_measurement(net,
                          "q",
                          "line",
                          net.res_line.q_from_kvar[2],
                          10.,
                          bus=4,
                          element=2)
    pp.create_measurement(net,
                          "p",
                          "line",
                          net.res_line.p_from_kw[3],
                          10.,
                          bus=5,
                          element=3)
    pp.create_measurement(net,
                          "q",
                          "line",
                          net.res_line.q_from_kvar[3],
                          10.,
                          bus=5,
                          element=3)
    success = estimate(net, init='slack', calculate_voltage_angles=angles)

    # pretty high error for vm_pu (half percent!)
    assert success
    assert (np.nanmax(
        np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) <
            0.006)
    assert (np.nanmax(
        np.abs(net.res_bus.va_degree.values -
               net.res_bus_est.va_degree.values)) < 0.006)
Ejemplo n.º 4
0
def test_3bus_with_transformer():
    np.random.seed(12)

    # 1. Create network
    net = pp.create_empty_network()
    pp.create_bus(net, name="bus1", vn_kv=10.)
    pp.create_bus(net, name="bus2", vn_kv=10.)
    pp.create_bus(net, name="bus3", vn_kv=10.)
    pp.create_bus(net, name="bus4", vn_kv=110.)
    pp.create_ext_grid(net, bus=3, vm_pu=1.01)
    pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0.,
                                   max_i_ka=1)
    pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0.,
                                   max_i_ka=1)
    pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0.,
                                   max_i_ka=1)
    pp.create_transformer(net, 3, 0, std_type="25 MVA 110/10 kV")

    pp.create_load(net, 1, 450, 300)
    pp.create_load(net, 2, 350, 200)

    pp.runpp(net, calculate_voltage_angles=True)

    pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[0], .004), .004, bus=0)
    pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[1], .004), .004, bus=1)
    pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[3], .004), .004, bus=3)

    pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_kw.iloc[1], 10), 10, bus=1)
    pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_kvar.iloc[1], 10), 10, bus=1)

    pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_kw.iloc[2], 10), 10, bus=2)
    pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_kvar.iloc[2], 10), 10, bus=2)

    pp.create_measurement(net, "p", "bus", 0., 1.0, bus=0)
    pp.create_measurement(net, "q", "bus", 0., 1.0, bus=0)

    pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_kw.iloc[0], 8), 8, 0, 0)
    pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_kw.iloc[1], 8), 8, 0, 1)

    pp.create_measurement(net, "p", "transformer", r2(net.res_trafo.p_hv_kw.iloc[0], 10), 10,
                          bus=3, element=0)  # transformer meas.
    pp.create_measurement(net, "q", "transformer", r2(net.res_trafo.q_hv_kvar.iloc[0], 10), 10,
                          bus=3, element=0)  # at hv side


    # 2. Do state estimation
    success = estimate(net, init='slack', tolerance=5e-5, maximum_iterations=10, calculate_voltage_angles=True)
    v_result = net.res_bus_est.vm_pu.values
    delta_result = net.res_bus_est.va_degree.values

    diff_v = net.res_bus.vm_pu.values - v_result
    diff_delta = net.res_bus.va_degree.values - delta_result

    assert success
    assert (np.nanmax(abs(diff_v)) < 6e-4)
    assert (np.nanmax(abs(diff_delta)) < 1.4e-4)

    # Backwards check. Use state estimation results for power flow and check for equality
    net.load.drop(net.load.index, inplace=True)
    net.ext_grid.vm_pu = net.res_bus_est.vm_pu.iloc[net.ext_grid.bus.iloc[0]]
    pp.create_load(net, 0, net.res_bus_est.p_kw.iloc[0], net.res_bus_est.q_kvar.iloc[0])
    pp.create_load(net, 1, net.res_bus_est.p_kw.iloc[1], net.res_bus_est.q_kvar.iloc[1])
    pp.create_load(net, 2, net.res_bus_est.p_kw.iloc[2], net.res_bus_est.q_kvar.iloc[2])

    _compare_pf_and_se_results(net)
Ejemplo n.º 5
0
def assert_init_results(net):
    pp.runpp(net, init="auto")
    assert net._ppc["iterations"] > 0
    pp.runpp(net, init="results")
    assert net._ppc["iterations"] == 0
Ejemplo n.º 6
0
def test_zip_loads_gridcal():
    # Tests newton power flow considering zip loads against GridCal's pf result

    # Results used for benchmarking are obtained using GridCal with the following code:
    # from GridCal.grid.CalculationEngine import *
    #
    # np.set_printoptions(precision=4)
    # grid = MultiCircuit()
    #
    # # Add buses
    # bus1 = Bus('Bus 1', vnom=20)
    #
    # bus1.controlled_generators.append(ControlledGenerator('Slack Generator', voltage_module=1.0))
    # grid.add_bus(bus1)
    #
    # bus2 = Bus('Bus 2', vnom=20)
    # bus2.loads.append(Load('load 2',
    #                        power=0.2 * complex(40, 20),
    #                        impedance=1 / (0.40 * (40. - 20.j)),
    #                        current=np.conj(0.40 * (40. + 20.j)) / (20 * np.sqrt(3)),
    #                        ))
    # grid.add_bus(bus2)
    #
    # bus3 = Bus('Bus 3', vnom=20)
    # bus3.loads.append(Load('load 3', power=complex(25, 15)))
    # grid.add_bus(bus3)
    #
    # bus4 = Bus('Bus 4', vnom=20)
    # bus4.loads.append(Load('load 4', power=complex(40, 20)))
    # grid.add_bus(bus4)
    #
    # bus5 = Bus('Bus 5', vnom=20)
    # bus5.loads.append(Load('load 5', power=complex(50, 20)))
    # grid.add_bus(bus5)
    #
    # # add branches (Lines in this case)
    # grid.add_branch(Branch(bus1, bus2, 'line 1-2', r=0.05, x=0.11, b=0.02))
    #
    # grid.add_branch(Branch(bus1, bus3, 'line 1-3', r=0.05, x=0.11, b=0.02))
    #
    # grid.add_branch(Branch(bus1, bus5, 'line 1-5', r=0.03, x=0.08, b=0.02))
    #
    # grid.add_branch(Branch(bus2, bus3, 'line 2-3', r=0.04, x=0.09, b=0.02))
    #
    # grid.add_branch(Branch(bus2, bus5, 'line 2-5', r=0.04, x=0.09, b=0.02))
    #
    # grid.add_branch(Branch(bus3, bus4, 'line 3-4', r=0.06, x=0.13, b=0.03))
    #
    # grid.add_branch(Branch(bus4, bus5, 'line 4-5', r=0.04, x=0.09, b=0.02))
    #
    # grid.compile()
    #
    # print('Ybus:\n', grid.circuits[0].power_flow_input.Ybus.todense())
    #
    # options = PowerFlowOptions(SolverType.NR, robust=False)
    # power_flow = PowerFlow(grid, options)
    # power_flow.run()
    #
    # print('\n\n', grid.name)
    # print('\t|V|:', abs(grid.power_flow_results.voltage))
    # print('\tVang:', np.rad2deg(np.angle(grid.power_flow_results.voltage)))

    vm_pu_gridcal = np.array(
        [1., 0.9566486349, 0.9555640318, 0.9340468428, 0.9540542172])
    va_degree_gridcal = np.array(
        [0., -2.3717973886, -2.345654238, -3.6303651197, -2.6713716569])

    Ybus_gridcal = np.array(
        [[
            10.9589041096 - 25.9973972603j, -3.4246575342 + 7.5342465753j,
            -3.4246575342 + 7.5342465753j, 0.0000000000 + 0.j,
            -4.1095890411 + 10.9589041096j
        ],
         [
             -3.4246575342 + 7.5342465753j, 11.8320802147 - 26.1409476063j,
             -4.1237113402 + 9.2783505155j, 0.0000000000 + 0.j,
             -4.1237113402 + 9.2783505155j
         ],
         [
             -3.4246575342 + 7.5342465753j, -4.1237113402 + 9.2783505155j,
             10.4751981427 - 23.1190605054j, -2.9268292683 + 6.3414634146j,
             0.0000000000 + 0.j
         ],
         [
             0.0000000000 + 0.j, 0.0000000000 + 0.j,
             -2.9268292683 + 6.3414634146j, 7.0505406085 - 15.5948139301j,
             -4.1237113402 + 9.2783505155j
         ],
         [
             -4.1095890411 + 10.9589041096j, -4.1237113402 + 9.2783505155j,
             0.0000000000 + 0.j, -4.1237113402 + 9.2783505155j,
             12.3570117215 - 29.4856051405j
         ]])

    losses_gridcal = 4.69773448916 - 2.710430515j

    abs_path = os.path.join(pp.pp_dir, 'networks',
                            'power_system_test_case_jsons',
                            'case5_demo_gridcal.json')
    net = pp.from_json(abs_path)

    pp.runpp(net, voltage_depend_loads=True, recycle=None)

    # Test Ybus matrix
    Ybus_pp = net["_ppc"]['internal']['Ybus'].todense()
    bus_ord = net["_pd2ppc_lookups"]["bus"]
    Ybus_pp = Ybus_pp[bus_ord, :][:, bus_ord]

    assert np.allclose(Ybus_pp, Ybus_gridcal)

    # Test Results
    assert np.allclose(net.res_bus.vm_pu, vm_pu_gridcal)
    assert np.allclose(net.res_bus.va_degree, va_degree_gridcal)

    # Test losses
    losses_pp = net.res_bus.p_mw.sum() + 1.j * net.res_bus.q_mvar.sum()
    assert np.isclose(losses_gridcal, -losses_pp / 1.e3)

    # Test bfsw algorithm
    pp.runpp(net, voltage_depend_loads=True, algorithm='bfsw')
    assert np.allclose(net.res_bus.vm_pu, vm_pu_gridcal)
    assert np.allclose(net.res_bus.va_degree, va_degree_gridcal)
Ejemplo n.º 7
0
    # LV
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus MV4'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch MV4 - MV-LV-Trafo')
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus LV0'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch LV0 - MV-LV-Trafo')

    ###########################################################################
    # Powerflow
    ###########################################################################

    # run power flow and generate result tables
    pp.runpp(net, init='dc', calculate_voltage_angles=True, Numba=False)

    return net


if __name__ == '__main__':
    net = example_simple()
    pp.runpp(net, calculate_voltage_angles=True, init="dc")
    pp.runpp(net, calculate_voltage_angles=True, init="results")
Ejemplo n.º 8
0
              name="A",
              slack=True,
              in_service=True)
pp.create_gen(net,
              p_mw=150.0,
              max_q_mvar=9999.0,
              min_q_mvar=-9990.0,
              sn_mva=200.,
              bus=F,
              vm_pu=1.0,
              name="F",
              slack=False,
              in_service=True)

# List of Switches:

# List of controllers:

init_va_degree_list = []
init_vm_pu_list = []

# Run power flow
if len(init_va_degree_list) > 0 and len(init_vm_pu_list) > 0:
    pp.runpp(net,
             init_va_degree=init_va_degree_list,
             init_vm_pu=init_vm_pu_list)
else:
    pp.runpp(net)

print(net.res_bus)  # bus results
Ejemplo n.º 9
0
def test_convert_format():  # TODO what is this thing testing ?
    net = pp.from_pickle(os.path.join(pp.pp_dir, "test", "api", "old_net.p"))
    pp.runpp(net)
    assert net.converged
Ejemplo n.º 10
0
def run(loops=10):
    ''' Runs the Tabu Search

    Parameters
    ----------
    loops : int, optional
        The number of loops that the Tabu Search should execute. Default is 10.
    
    Returns
    -------
    list
        A list with dicts containing the results and the parameters for each
        step of the loop. The dicts has the following form:
        {'time': float, # The time elapsed
        'best': list, # The best solution found
        'total_i': int, # The total iterations
        'i_best': int, # The iteration of the best solution
        'fault': list, # The list with the fault points
        'i_local': int, # The amout of loops of the local search
        'itm': int, # The loops for reset the search with ITM
        'max_i': # The max loops for stop the search
        }
    '''

    results = list()

    for step in range(loops):

        print(
            color.yellow(
                '\n\nLOOP #%d ---------------------------------------------' %
                (step + 1), 'bold'))

        # Extra variables
        elapsed_time = 0

        # DEFINING GLOBAL VARIABLES AND PARAMETERS --------------

        # For single-sourced models, use the lines of code below:
        # -------------------------------------------------------
        # Getting the test model
        #net = models.network33bus()

        # Getting the power source name (it works only for one-sourced nets)
        #source = net.bus['name'][int(net.ext_grid['bus'])]

        # Getting the initial topology
        #top = tools.create_topology(net)
        # Getting the indexes of the bridge lines between the source (bus0) and
        # the first fork
        #bridges = tools.bridge_lines(top, source)

        # For multiple-sourced models, use the lines of code below:
        # ---------------------------------------------------------
        net = models.network10bus()

        # Defines the power source name
        source = 'bus1'

        # Creating a multi-sourced topology
        top = tools.create_multisourced_topology(net)

        # Adding the abstract edges to the topology
        top.add_abstract_edge('bus0', 'bus1')
        #top.add_abstract_edge('bus1', 'bus2')

        # Defining manually the bridge lines according to the model
        bridges = [0, 1]
        # ---------------------------------------------------------

        # The variable that controls the loop
        stop = False

        # Creating the tabu-list
        tabu = TabuList(max_length=int(
            0.2 * len(net.line)))  #int(20% of the number of lines)

        # Getting the probability vector for the initial state of the net
        prob_vector = tools.get_lines_probability(top, source)

        # Defining the fault points
        fault = [3]

        # Applying the fault points
        tools.set_faults(top, fault)

        # Limit for voltage variation
        #v_variation = 0.18
        v_variation = 0.05

        # Limit for current variation
        i_variation = 0.0

        # Best solution (starting with the initial solution)
        best = top.get_edge_states()

        # Number of solutions generated per iteration
        n_solutions = int(0.2 * len(net.line))

        # Iteration number (starting with 0)
        iteration = 1

        # The IT memory
        memory = [0 for _ in range(len(net.line))]

        # Stores the last iteration that improve the best solution
        improved = iteration

        # Limiar of frequence that determines if a component will stay in the
        # solution after the reset of the search by the ITM
        frequence = 0.6

        # A flag that indicates if the search was restarted once
        reset = False

        # The number of max iterations before reset the search with IT memory
        max_reset = 25

        # Maximum limit of iterations without improvement of the best solution
        # found (termination criteria)
        max_i = 50

        # Maximum iterations to local search
        max_local = 10
        # -------------------------------------------------------

        # MAIN LOOP ---------------------------------------------
        print('Starting loop...')
        print('Initial solution:', top.get_edge_states())
        # Stores the initial time
        begin = time.time()

        while not stop:

            # List of generated neighbors (solutions)
            neighbors = list()

            # The iteration-selected solution
            selected = top.get_edge_states()

            # Neighborhood generation ---------------------------
            print(color.blue('Iteration #%d' % iteration))
            print('Generating neighbors...')
            # Making `n_solutions` neihgbors
            for k in range(n_solutions):
                print('  Generating neighbor %d/%d' % (k + 1, n_solutions))
                # Generating the neighbor components
                sol = list()
                for i in range(len(net.line)):
                    c = selected[i]
                    if c == 1:
                        if tools.draw(prob_vector[i]):
                            c = 0
                    else:
                        if tools.draw(0.5):
                            c = 1
                    # Making solution
                    sol.append(c)

                # Local search
                #print('  Performing local search...')
                local_search = [sol] + [
                    tools.swap_1_0(sol.copy()) for _ in range(max_local)
                ]

                # Activating the bridge lines and removing fault points
                for i in range(len(local_search)):
                    local_search[i] = tools.set_value(local_search[i], bridges,
                                                      1)
                    local_search[i] = tools.set_value(local_search[i], fault,
                                                      0)

                #print('  Removing cycles...')
                # Removing cycles
                for i in range(len(local_search)):
                    top.set_edge_states(local_search[i])
                    for cycle in top.cycles(source, search='bfs'):
                        #print(color.magenta('    The topology has cycles. Fixing it...'))
                        top.deactivate_edge(
                            top.get_edge_index(cycle[0], cycle[1]))
                        # Update the solution removing its cycles
                        local_search[i] = top.get_edge_states()

                #print('  Running the power flow...')
                valid_solutions = list()
                for solution in local_search:
                    # Setting the solution in the network switching
                    top.set_edge_states(solution)
                    tools.make_switch_operations(top.get_edge_states(), net)
                    try:
                        # Running powerflow
                        pp.runpp(net)

                        # Checking voltage constraints
                        for index, voltage in enumerate(net.res_bus['vm_pu'],
                                                        start=0):
                            if abs(
                                    1 - voltage
                            ) > v_variation:  # out of the voltage constraints
                                #print(color.magenta('    Bus out of voltage contraints. Fixing it...'))
                                bus = top.get_vertex_name(index)
                                for adjacent in top.get_adjacent(bus):
                                    top.deactivate_edge(
                                        top.get_edge_index(bus, adjacent))

                        # Passing the topology alterations to the network
                        tools.make_switch_operations(top.get_edge_states(),
                                                     net)

                        # Running the power flow again
                        pp.runpp(net)

                        # Checking current constraints
                        for index, current in enumerate(
                                net.res_line['loading_percent'], start=0):
                            if current > 100 * (
                                    1 + i_variation
                            ):  # out of the current constraints
                                #print(color.magenta('    Line out of current limits. Fixing it...'))
                                top.deactivate_edge(index)

                        # Saving the generated solution in the valid solution list
                        valid_solutions.append(top.get_edge_states())

                    except (pp.powerflow.LoadflowNotConverged):
                        print(
                            color.red(
                                '  ### Power flow not converged. Ignoring the solution.'
                            ))
                        continue

                # Getting the best of local search
                if valid_solutions != []:
                    neighbors.append(
                        tools.best_of(valid_solutions, top, source))
            # ---------------------------------------------------

            # Neighbor selection --------------------------------
            print('Selecting the neighbor...')
            if neighbors != []:
                best_of_iteration = tools.best_of(neighbors, top, source)
                while len(neighbors) != 0:
                    selected = tools.best_of(neighbors, top, source)
                    neighbors.remove(selected)
                    if tabu.is_tabu(selected):
                        print(
                            '  TABU: This solution is in tabu list. Applying aspiration criteria...'
                        )
                        # Aspiration criteria
                        if not tools.draw(0.3):
                            print('  Result: REFUSED')
                            continue
                        print('  Result: ACCEPTED')
                        if len(neighbors) == 0:
                            print(
                                '  All solutions is in tabu list. Selecting the best found.'
                            )
                            selected = best_of_iteration.copy()
                            tabu.add(best_of_iteration)
                            top.set_edge_states(best_of_iteration)
                            break
                    tabu.add(selected.copy())
                    top.set_edge_states(selected)
                    print('  Solution selected.')
                    break
            else:
                # Case no valid solutions were generated, select the same
                # previous iteration solution
                top.set_edge_states(selected)

            # Comparing the selected solution with the best solution found
            #print('  Comparing the selected solution with the best solution found...')
            if best != []:
                sel = tools.best_of([selected, best], top, source)
                if sel != best and tools.value_of_solution(
                        selected, net) > tools.value_of_solution(best, net):
                    print(
                        color.green(
                            'IMPROVEMENT: Improving solution at iteration %d.'
                            % iteration, 'bold'))
                    best = sel.copy()
                    improved = iteration
            else:
                best = selected.copy()
            # ---------------------------------------------------

            # Intermediate-term memory --------------------------
            print('Saving the solution in the intermediate-term memory...')
            for i in range(len(selected)):
                memory[i] += selected[i]
            if not reset and iteration - improved >= max_reset:
                print(color.yellow('RESETING SEARCH -------------------'))
                print('Reseting the search with intermediate-term memory.')
                reset = True
                mcc = list()
                for value in memory:
                    if value / iteration > frequence:
                        mcc.append(1)
                    else:
                        mcc.append(0)
                # Activating the bridge lines and removing fault points
                mcc = tools.set_value(mcc, bridges, 1)
                mcc = tools.set_value(mcc, fault, 0)
                print('Most common components:', mcc)
                selected = mcc.copy()
                top.set_edge_states(selected)
            # ---------------------------------------------------

            # Checking termination criteria ---------------------
            #print('Selected:', selected)
            #print('Best:', best)
            iteration += 1
            # The TS stops whether it reaches the max iterarion or find a
            # optimal solution
            if iteration - improved > max_i or tools.value_of_solution(
                    best, net) == len(net.bus.values):
                stop = True
                elapsed_time = time.time() - begin
                print(color.yellow('Elapsed time: %f s' % elapsed_time))
                print(color.yellow('Best solution found: %s' % best, 'bold'))
            # ---------------------------------------------------

        # -------------------------------------------------------
        results.append({
            'time': elapsed_time,
            'best': best,
            'total_i': iteration,
            'i_best': improved,
            'fault': fault,
            'i_local': max_local,
            'itm': max_reset,
            'max_i': max_i,
        })

    return results
Ejemplo n.º 11
0
def test_repl_to_line_with_switch():
    """
    Same test as above, but this time in comparison to actual replacement
    """
    net = nw.example_multivoltage()
    pp.runpp(net)

    for testindex in net.line.index:
        if net.line.in_service.loc[testindex]:
            # todo print weg
            print("testing line " + str(testindex))
            line = net.line.loc[testindex]
            fbus = line.from_bus
            tbus = line.to_bus
            len = line.length_km

            if "184-AL1/30-ST1A" in net.line.std_type.loc[testindex]:
                std = "243-AL1/39-ST1A 110.0"
            elif "NA2XS2Y" in net.line.std_type.loc[testindex]:
                std = "NA2XS2Y 1x240 RM/25 6/10 kV"
            elif "NAYY" in net.line.std_type.loc[testindex]:
                std = "NAYY 4x150 SE"
            elif " 15-AL1/3-ST1A" in net.line.std_type.loc[testindex]:
                std = "24-AL1/4-ST1A 0.4"

            # create an oos line at the same buses
            REPL = pp.create_line(net, from_bus=fbus, to_bus=tbus, length_km=len, std_type=std)

            for bus in fbus, tbus:
                if bus in net.switch[(net.switch.closed == False) & (net.switch.element == testindex)].bus.values:
                    pp.create_switch(net, bus=bus, element=REPL, closed=False, et="l", type="LBS")

            # calculate runpp with REPL
            net.line.in_service[testindex] = False
            net.line.in_service[REPL] = True
            pp.runpp(net)

            fbus_repl = net.res_bus.loc[fbus]
            tbus_repl = net.res_bus.loc[tbus]

            ploss_repl = (net.res_line.loc[REPL].p_from_mw - net.res_line.loc[REPL].p_to_mw )
            qloss_repl =(net.res_line.loc[REPL].q_from_mvar - net.res_line.loc[REPL].q_to_mvar )

            # get ne line impedances
            new_idx = tb.repl_to_line(net, testindex, std, in_service=True)
            # activate new idx line
            net.line.in_service[REPL] = False
            net.line.in_service[testindex] = True
            net.line.in_service[new_idx] = True
            pp.runpp(net)
            # compare lf results
            fbus_ne = net.res_bus.loc[fbus]
            tbus_ne = net.res_bus.loc[tbus]
            ploss_ne = (net.res_line.loc[testindex].p_from_mw - net.res_line.loc[testindex].p_to_mw)+\
                  (net.res_line.loc[new_idx].p_from_mw - net.res_line.loc[new_idx].p_to_mw)
            qloss_ne = (net.res_line.loc[testindex].q_from_mvar - net.res_line.loc[testindex].q_to_mvar )+\
                  (net.res_line.loc[new_idx].q_from_mvar - net.res_line.loc[new_idx].q_to_mvar)


            assert_series_equal(fbus_repl, fbus_ne, atol=1e-2)
            assert_series_equal(tbus_repl, tbus_ne)
            assert np.isclose(ploss_repl,ploss_ne, atol=1e-5)
            assert np.isclose(qloss_repl,qloss_ne)

            # and reset to unreinforced state again
            net.line.in_service[testindex] = True
            net.line.in_service[new_idx] = False
            net.line.in_service[REPL] = False
Ejemplo n.º 12
0
import pandapower.networks as nw1
import pandapower as pp
from pandapower.plotting import simple_plot, simple_plotly, pf_res_plotly
net1 = nw1.mv_oberrhein()
pp.runpp(net1)
print(net1.res_bus)
highest = net1.res_bus.vm_pu.max()
print(highest)
highest_ones = net1.res_bus.loc[net1.res_bus.vm_pu > 1.02]
print(highest_ones)
lines = net1.res_line.loc[net1.res_line.loading_percent > 50.]
print(lines)
simple_plot(net1)
simple_plotly(net1)
print()
Ejemplo n.º 13
0
def test_convenience_create_functions():
    net = pp.create_empty_network()
    b1 = pp.create_bus(net, 110.)
    b2 = pp.create_bus(net, 110.)
    b3 = pp.create_bus(net, 20)
    pp.create_ext_grid(net, b1)
    pp.create_line_from_parameters(net,
                                   b1,
                                   b2,
                                   length_km=20.,
                                   r_ohm_per_km=0.0487,
                                   x_ohm_per_km=0.1382301,
                                   c_nf_per_km=160.,
                                   max_i_ka=0.664)

    l0 = pp.create_load_from_cosphi(net, b2, 10e3, 0.95, "ind", name="load")
    pp.runpp(net, init="flat")
    assert net.load.p_kw.at[l0] == 9.5e3
    assert net.load.q_kvar.at[l0] > 0
    assert np.sqrt(net.load.p_kw.at[l0]**2 + net.load.q_kvar.at[l0]**2) == 10e3
    assert np.isclose(net.res_bus.vm_pu.at[b2], 0.99990833838)
    assert net.load.name.at[l0] == "load"

    sh0 = pp.create_shunt_as_capacitor(net,
                                       b2,
                                       10e3,
                                       loss_factor=0.01,
                                       name="shunt")
    pp.runpp(net, init="flat")
    assert np.isclose(net.res_shunt.q_kvar.at[sh0], -10, 043934174e3)
    assert np.isclose(net.res_shunt.p_kw.at[sh0], 100.43933665)
    assert np.isclose(net.res_bus.vm_pu.at[b2], 1.0021942964)
    assert net.shunt.name.at[sh0] == "shunt"

    sg0 = pp.create_sgen_from_cosphi(net, b2, 5e3, 0.95, "cap", name="sgen")
    pp.runpp(net, init="flat")
    assert np.sqrt(net.sgen.p_kw.at[sg0]**2 +
                   net.sgen.q_kvar.at[sg0]**2) == 5e3
    assert net.sgen.p_kw.at[sg0] == -4.75e3
    assert net.sgen.q_kvar.at[sg0] < 0
    assert np.isclose(net.res_bus.vm_pu.at[b2], 1.0029376578)
    assert net.sgen.name.at[sg0] == "sgen"

    tol = 1e-6
    sind = pp.create_series_reactor_as_impedance(net,
                                                 b1,
                                                 b2,
                                                 r_ohm=100,
                                                 x_ohm=200,
                                                 sn_kva=100)
    assert net.impedance.at[sind, 'rft_pu'] - 8.264463e-04 < tol
    assert net.impedance.at[sind, 'xft_pu'] - 0.001653 < tol

    tid = pp.create_transformer_from_parameters(net,
                                                hv_bus=b2,
                                                lv_bus=b3,
                                                sn_kva=100,
                                                vn_hv_kv=110,
                                                vn_lv_kv=20,
                                                vscr_percent=5,
                                                vsc_percent=20,
                                                pfe_kw=1,
                                                i0_percent=1)
    pp.create_load(net, b3, 100)
    assert net.trafo.at[tid, 'df'] == 1
    pp.runpp(net)
    tr_l = net.res_trafo.at[tid, 'loading_percent']
    net.trafo.at[tid, 'df'] = 2
    pp.runpp(net)
    tr_l_2 = net.res_trafo.at[tid, 'loading_percent']
    assert tr_l == tr_l_2 * 2
    net.trafo.at[tid, 'df'] = 0
    with pytest.raises(UserWarning):
        pp.runpp(net)
Ejemplo n.º 14
0
    def load_grid(self, path=None, filename=None):
        """
        Demonstration on how you can load a powergrid and then initialize the proper grid2op attributes.

        The only thing we have to do here is to "order" the objects in each substation. Note that we don't even do it
        implicitly here (relying on default grid2op ordering).

        The only decision we had to make was concerning "grid2op powerlines" which represents both
        "pandapower transformers"
        and "pandapower powerlines".

        We decided that:

        - powerline are "before" trafo (so in the grid2op line id I will put first all powerlines, then all trafo)
        - grid2op "origin" side will be "from" side for pandapower powerline and "hv" side for pandapower trafo
        - grid2op "extremity" side will be "to" side for pandapower powerline and "lv" side for pandapower trafo


        .. note:: We use one "trick" here. Pandapower grid (as it will be the case for most format) will have one "bus"
            per substation. For grid2op, we want at least 2 busbar per substation. So we simply copy and paste the grid.

            And we will deactivate the busbar that are not connected (no element connected to it).

            This "coding" allows for easily mapping the bus id (each bus is represented with an id in pandapower)
            and whether its busbar 1 or busbar 2 (grid2op side). More precisely: busbar 1 of substation with
            id `sub_id` will have id `sub_id` and busbar 2 of the same substation will have id `sub_id + n_sub`
            (recall that n_sub is the number of substation on the grid).

            This "coding" is not optimal in the ram it takes. But we recommend you to adopt a similar one. It's
            pretty easy to change the topology using this trick, much easier than if you rely on "switches" for
            example. (But of course  you can still use switches if you really want to)

        """

        # first, handles different kind of path:
        if path is None and filename is None:
            raise RuntimeError(
                "You must provide at least one of path or file to load a powergrid."
            )
        if path is None:
            full_path = filename
        elif filename is None:
            full_path = path
        else:
            full_path = os.path.join(path, filename)
        if not os.path.exists(full_path):
            raise RuntimeError(
                "There is no powergrid at \"{}\"".format(full_path))

        # then load the grid located at the full path and store it in `self._grid`
        # raise an exception if it can't be loaded
        try:
            with warnings.catch_warnings():
                # remove deprecationg warnings for old version of pandapower
                warnings.filterwarnings("ignore", category=DeprecationWarning)
                self._grid = pp.from_json(full_path)
        except Exception as exc_:
            raise BackendError(
                f"Impossible to load the powergrid located at \"{full_path}\". Please "
                f"check the file exist and that the file represent a valid pandapower "
                f"grid. For your information, the error is:\n{exc_}")

        ######################################################################
        # this part is due to the "modeling" of the topology FOR THIS EXAMPLE
        # remember (see docstring of this function) that we "duplicate the buses" to code more easily the
        # topology modification (instead of relying on the `switches`)

        # first we remember the number of substation
        self.n_sub = self._grid.bus.shape[0]
        # and then we duplicate the bus
        add_topo = copy.deepcopy(self._grid.bus)
        add_topo.index += add_topo.shape[0]
        add_topo["in_service"] = False
        self._grid.bus = pd.concat((self._grid.bus, add_topo))
        self._nb_real_line_pandapower = self._grid.line.shape[0]
        # i do a powerflow to initialize the "results" dataframes
        # this last step is internal to pandapower
        pp.runpp(self._grid, check_connectivity=False)
        ######################################################################

        # and now we initialize the number of each of the elements
        self.n_line = self._grid.line.shape[0] + self._grid.trafo.shape[
            0]  # trafo are powerline for grid2op !
        self.n_gen = self._grid.gen.shape[0]
        self.n_load = self._grid.load.shape[0]
        # self.n_sub  # already initialize above

        # initialize the number of elements per substation
        # now export to grid2op the substation to which objects are connected
        self.load_to_subid = copy.deepcopy(self._grid.load["bus"])
        self.gen_to_subid = copy.deepcopy(self._grid.gen["bus"])
        # here we just decide (but that is a convention we could have done it differently)
        # that "origin side" (grid2op) corresponds to "from_bus" from pandapower line and "hv_bus" for
        # pandapower trafo.
        self.line_or_to_subid = np.concatenate(
            (copy.deepcopy(self._grid.line["from_bus"]),
             copy.deepcopy(self._grid.trafo["hv_bus"])))
        self.line_ex_to_subid = np.concatenate(
            (copy.deepcopy(self._grid.line["to_bus"]),
             copy.deepcopy(self._grid.trafo["lv_bus"])))

        # and now we don't forget to initialize the rest
        self._compute_pos_big_topo()  # we highly recommend you to call this !

        # and now the thermal limit
        self.thermal_limit_a = 1000 * np.concatenate(
            (self._grid.line["max_i_ka"].values,
             self._grid.trafo["sn_mva"].values /
             (np.sqrt(3) * self._grid.trafo["vn_hv_kv"].values)))
        self.thermal_limit_a = self.thermal_limit_a.astype(dt_float)

        # NB: this instance of backend is here for academic purpose only. For clarity, it does not handle
        # neither shunt nor storage unit.
        self.shunts_data_available = False
        self.set_no_storage()
Ejemplo n.º 15
0
# Copyright (c) 2020, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of PyKLU2Grid, PyKLU2Grid a implements a c++ backend targeting the Grid2Op platform.

import pandapower as pp
import pandapower.networks as pn

grid = pn.case30()
grid = pn.case118()
pp.runpp(grid, numba=False)
Ejemplo n.º 16
0
        
        if type(q2) is float or type(q2) is int:
            load_3 = pp.create_load(net = net, bus = bus_3, p_mw = p_load_2, q_mvar = q2*p_load_2, name = "load 3")
        elif q2:    
            load_3 = pp.create_load(net = net, bus = bus_3, p_mw = p_load_2, q_mvar = q_load_2, name = "load 3")
        else:
            load_3 = pp.create_load(net = net, bus = bus_3, p_mw = p_load_2, name = "load 3")
        #load_3 = pp.create_load(net = net, bus = bus_3, p_mw = p_tot - p_load_1, q_mvar = q_load_2, name = "load 3")

        if modus == 2:
            gen_1 = pp.create_gen(net = net, bus = bus_0, p_mw = p_gen_1, vm_pu = 1, slack = True)
        else:
            gen_1 = pp.create_gen(net = net, bus = bus_1, p_mw = p_gen_1, vm_pu = 1, slack = True)

        # Run the network
        pp.runpp(net, max_iteration = max_iteration, tolerance_mva = 1e-10)

        iterations[i] = net["_ppc"]["iterations"]

        vm_pu_res[:, i] = net["res_bus"].loc[:, "vm_pu"]
        va_degree_res[:, i] = net["res_bus"].loc[:, "va_degree"]
        p_mw_res[:, i] = net["res_bus"].loc[:, "p_mw"]
        q_mvar_res[:, i] = net["res_bus"].loc[:, "q_mvar"]
        i += 1

    
    if nr_of_nodes == 4:
        extra_index = 1
    else:
        extra_index = 0
Ejemplo n.º 17
0
for pq in pqs.itertuples(index=True, name='Pandas'):
    bus_num = getattr(pq, "bus_num")
    p_mw = getattr(pq, "active_power")
    q_mvar = getattr(pq, "reactive_power")
    pq_num = getattr(pq, "Index")
    pp.create_load(net, bus_num-1, p_mw=p_mw, q_mvar=q_mvar, name='Load %s' % pq_num)
print(net.load) # show loads table

### PQgen ###
pqgens = pd.read_csv('data/PQgen.csv',names=['bus_num','power_rating','voltage_rating','active_power','reactive_power',
                                            'v_max','v_min','conv_imp','area'],index_col=False)
for pqgen in pqgens.itertuples(index=True, name='Pandas'):
    bus_num = getattr(pqgen, "bus_num")
    try:
        mask=pqs[pqs['bus_num']==bus_num].index.tolist()[0]
        raise ValueError("Attention static gens and loads at the same bus. Manually modify database")
    except:
        p_mw = getattr(pqgen, "active_power")
        q_mvar = getattr(pqgen, "reactive_power")
        sn_mva = getattr(pqgen, "power_rating")
        pqgen_num = getattr(pqgen, "Index")
        pp.create_sgen(net, bus_num-1, p_mw=p_mw, q_mvar=q_mvar, sn_mva=sn_mva, name='StatGen %s' % pqgen_num)
        #pp.create_load(net, bus_num-1, p_mw=p_mw, q_mvar=q_mvar, name='StatGen %s' % pqgen_num)
print(net.sgen) # show static gen table

### Diagnosis ###
pp.diagnostic(net, report_style='detailed', warnings_only=False, return_result_dict=True, overload_scaling_factor=0.001, min_r_ohm=0.001, min_x_ohm=0.001, min_r_pu=1e-05, min_x_pu=1e-05, nom_voltage_tolerance=0.3, numba_tolerance=1e-05)

### Run Power Flow ###
pp.runpp(net, algorithm="iwamoto_nr", calculate_voltage_angles="auto", init="dc", check_connectivity=True, v_debug=True) #, init_vm_pu=True, init_va_degree=True
print(net)
Ejemplo n.º 18
0
def test_pp_initialization():
    net = pp.create_empty_network()

    b1 = pp.create_bus(net, vn_kv=0.4)
    b2 = pp.create_bus(net, vn_kv=0.4)

    pp.create_ext_grid(net, b1, vm_pu=0.7)
    pp.create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", index=4)
    pp.create_load(net, b2, p_mw=0.01)

    pp.runpp(net, init_va_degree="flat", init_vm_pu=1.02)
    assert net._ppc["iterations"] == 5

    pp.runpp(net, init_va_degree="dc", init_vm_pu=0.8)
    assert net._ppc["iterations"] == 4

    pp.runpp(net, init_va_degree="flat", init_vm_pu=np.array([0.75, 0.7]))
    assert net._ppc["iterations"] == 3

    pp.runpp(net, init_va_degree="dc", init_vm_pu=[0.75, 0.7])
    assert net._ppc["iterations"] == 3

    pp.runpp(net, init_va_degree="flat", init_vm_pu="auto")
    assert net._ppc["iterations"] == 3

    pp.runpp(net, init_va_degree="dc")
    assert net._ppc["iterations"] == 3
Ejemplo n.º 19
0
    def runpf(self, is_dc=False):
        """
        Run a power flow on the underlying _grid. This implements an optimization of the powerflow
        computation: if the number of
        buses has not changed between two calls, the previous results are re used. This speeds up the computation
        in case of "do nothing" action applied.
        """
        # print("I called runpf")
        conv = True
        nb_bus = self.get_nb_active_bus()
        try:
            with warnings.catch_warnings():
                # remove the warning if _grid non connex. And it that case load flow as not converged
                warnings.filterwarnings("ignore", category=scipy.sparse.linalg.MatrixRankWarning)
                warnings.filterwarnings("ignore", category=RuntimeWarning)
                if self._nb_bus_before is None:
                    self._pf_init = "dc"
                elif nb_bus == self._nb_bus_before:
                    self._pf_init = "results"
                else:
                    self._pf_init = "auto"
                if is_dc:
                    pp.rundcpp(self._grid, check_connectivity=False)
                    self._nb_bus_before = None  # if dc i start normally next time i call an ac powerflow
                else:
                    pp.runpp(self._grid, check_connectivity=False, init=self._pf_init, numba=numba_)

                if self._grid.res_gen.isnull().values.any():
                    # TODO see if there is a better way here
                    # sometimes pandapower does not detect divergence and put Nan.
                    raise pp.powerflow.LoadflowNotConverged

                self.load_p[:], self.load_q[:], self.load_v[:] = self._loads_info()
                if not is_dc:
                    if not np.all(np.isfinite(self.load_v)):
                        # TODO see if there is a better way here
                        # some loads are disconnected: it's a game over case!
                        raise pp.powerflow.LoadflowNotConverged

                self.line_status[:] = self._get_line_status()
                # I retrieve the data once for the flows, so has to not re read multiple dataFrame
                self.p_or[:] = self._aux_get_line_info("p_from_mw", "p_hv_mw")
                self.q_or[:] = self._aux_get_line_info("q_from_mvar", "q_hv_mvar")
                self.v_or[:] = self._aux_get_line_info("vm_from_pu", "vm_hv_pu")
                self.a_or[:] = self._aux_get_line_info("i_from_ka", "i_hv_ka") * 1000
                self.a_or[~np.isfinite(self.a_or)] = 0.
                self.v_or[~np.isfinite(self.v_or)] = 0.

                # it seems that pandapower does not take into account disconencted powerline for their voltage
                self.v_or[~self.line_status] = 0.
                self.v_ex[~self.line_status] = 0.

                self.p_ex[:] = self._aux_get_line_info("p_to_mw", "p_lv_mw")
                self.q_ex[:] = self._aux_get_line_info("q_to_mvar", "q_lv_mvar")
                self.v_ex[:] = self._aux_get_line_info("vm_to_pu", "vm_lv_pu")
                self.a_ex[:] = self._aux_get_line_info("i_to_ka", "i_lv_ka") * 1000
                self.a_ex[~np.isfinite(self.a_ex)] = 0.
                self.v_ex[~np.isfinite(self.v_ex)] = 0.

                self.v_or[:] *= self.lines_or_pu_to_kv
                self.v_ex[:] *= self.lines_ex_pu_to_kv

                self.prod_p[:], self.prod_q[:], self.prod_v[:] = self._gens_info()
                # for attr_nm in ["load_p", "load_q", "load_v", "p_or", "q_or", "v_or", "a_or", "p_ex", "q_ex",
                #                 "v_ex", "a_ex", "prod_p", "prod_q", "prod_v"]:
                #     setattr(self, attr_nm, getattr(self, attr_nm).astype(dt_float))

                self._nb_bus_before = None
                self._grid._ppc["gen"][self._iref_slack, 1] = 0.
                return self._grid.converged

        except pp.powerflow.LoadflowNotConverged:
            # of the powerflow has not converged, results are Nan
            self.p_or[:] = np.NaN
            self.q_or[:] = np.NaN
            self.v_or[:] = np.NaN
            self.a_or[:] = np.NaN
            self.p_ex[:] = np.NaN
            self.q_ex[:] = np.NaN
            self.v_ex[:] = np.NaN
            self.a_ex[:] = np.NaN
            self.prod_p[:] = np.NaN
            self.prod_q[:] = np.NaN
            self.prod_v[:] = np.NaN
            self.load_p[:] = np.NaN
            self.load_q[:] = np.NaN
            self.load_v[:] = np.NaN

            self._nb_bus_before = None
            return False
Ejemplo n.º 20
0
def test_line_temperature():
    net = four_loads_with_branches_out()
    r_init = net.line.r_ohm_per_km.values.copy()

    # r_ohm_per_km is not in line results by default
    pp.runpp(net)
    v_init = net.res_bus.vm_pu.values.copy()
    va_init = net.res_bus.va_degree.values.copy()
    assert "r_ohm_per_km" not in net.res_line.columns

    # no temperature adjustment performed if not explicitly set in options/arguments to runpp
    net.line["temperature_degree_celsius"] = 20
    pp.runpp(net)
    assert "r_ohm_per_km" not in net.res_line.columns
    assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16)
    assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16)

    # argument in runpp is considered
    pp.runpp(net, consider_line_temperature=True)
    assert "r_ohm_per_km" in net.res_line.columns
    assert np.allclose(net.res_line.r_ohm_per_km, r_init, rtol=0, atol=1e-16)
    assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16)
    assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16)

    # check results of r adjustment, check that user_pf_options works, alpha is 4e-3 by default
    t = np.arange(0, 80, 10)
    net.line.temperature_degree_celsius = t
    pp.set_user_pf_options(net, consider_line_temperature=True)
    pp.runpp(net)
    alpha = 4e-3
    r_temp = r_init * (1 + alpha * (t - 20))
    assert np.allclose(net.res_line.r_ohm_per_km, r_temp, rtol=0, atol=1e-16)
    assert not np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-4)
    assert not np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-2)

    # check reults with user-defined alpha
    alpha = np.arange(3e-3, 5e-3, 2.5e-4)
    net.line['alpha'] = alpha
    pp.runpp(net)
    r_temp = r_init * (1 + alpha * (t - 20))
    assert np.allclose(net.res_line.r_ohm_per_km, r_temp, rtol=0, atol=1e-16)
    assert not np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-4)
    assert not np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-2)

    # not anymore in net if not considered
    pp.set_user_pf_options(net, overwrite=True)
    pp.runpp(net)
    assert np.allclose(net.res_bus.vm_pu, v_init, rtol=0, atol=1e-16)
    assert np.allclose(net.res_bus.va_degree, va_init, rtol=0, atol=1e-16)
    assert "r_ohm_per_km" not in net.res_line.columns
Ejemplo n.º 21
0
    def load_grid(self, path=None, filename=None):
        """
        .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\

        Load the _grid, and initialize all the member of the class. Note that in order to perform topological
        modification of the substation of the underlying powergrid, some buses are added to the test case loaded. They
        are set as "out of service" unless a topological action acts on these specific substations.

        """

        if path is None and filename is None:
            raise RuntimeError(
                "You must provide at least one of path or file to load a powergrid."
            )
        if path is None:
            full_path = filename
        elif filename is None:
            full_path = path
        else:
            full_path = os.path.join(path, filename)
        if not os.path.exists(full_path):
            raise RuntimeError(
                "There is no powergrid at \"{}\"".format(full_path))

        with warnings.catch_warnings():
            # remove deprecationg warnings for old version of pandapower
            warnings.filterwarnings("ignore", category=DeprecationWarning)
            self._grid = pp.from_json(full_path)

        # add the slack bus that is often not modeled as a generator, but i need it for this backend to work
        bus_gen_added = None
        i_ref = None
        self._iref_slack = None
        self._id_bus_added = None
        pp.runpp(self._grid, numba=numba_)
        if np.all(~self._grid.gen["slack"]):
            # there are not defined slack bus on the data, i need to hack it up a little bit
            pd2ppc = self._grid._pd2ppc_lookups[
                "bus"]  # pd2ppc[pd_id] = ppc_id
            ppc2pd = np.argsort(pd2ppc)  # ppc2pd[ppc_id] = pd_id
            for i, el in enumerate(self._grid._ppc['gen'][:, 0]):
                if int(el) not in self._grid._pd2ppc_lookups["bus"][
                        self._grid.gen["bus"].values]:
                    if bus_gen_added is not None:
                        raise RuntimeError(
                            "Impossible to recognize the powergrid")
                    bus_gen_added = ppc2pd[int(el)]
                    i_ref = i
                    break
            self._iref_slack = i_ref
            self._id_bus_added = self._grid.gen.shape[0]
            # see https://matpower.org/docs/ref/matpower5.0/idx_gen.html for details on the comprehension of self._grid._ppc
            pp.create_gen(self._grid,
                          bus_gen_added,
                          p_mw=self._grid._ppc['gen'][i_ref, 1],
                          vm_pu=self._grid._ppc['gen'][i_ref, 5],
                          min_p_mw=self._grid._ppc['gen'][i_ref, 9],
                          max_p_mw=self._grid._ppc['gen'][i_ref, 8],
                          max_q_mvar=self._grid._ppc['gen'][i_ref, 3],
                          min_q_mvar=self._grid._ppc['gen'][i_ref, 4],
                          slack=True,
                          controllable=True)
        else:
            self.slack_id = np.where(self._grid.gen["slack"])[0]

        pp.runpp(self._grid, numba=numba_)
        self.__nb_bus_before = self._grid.bus.shape[0]
        self.__nb_powerline = self._grid.line.shape[0]
        self._init_bus_load = self.cst_1 * self._grid.load["bus"].values
        self._init_bus_gen = self.cst_1 * self._grid.gen["bus"].values
        self._init_bus_lor = self.cst_1 * self._grid.line["from_bus"].values
        self._init_bus_lex = self.cst_1 * self._grid.line["to_bus"].values

        t_for = self.cst_1 * self._grid.trafo["hv_bus"].values
        t_fex = self.cst_1 * self._grid.trafo["lv_bus"].values
        self._init_bus_lor = np.concatenate(
            (self._init_bus_lor, t_for)).astype(np.int)
        self._init_bus_lex = np.concatenate(
            (self._init_bus_lex, t_fex)).astype(np.int)

        self._grid["ext_grid"]["va_degree"] = 0.0

        # this has the effect to divide by 2 the active power in the added generator, if this generator and the "slack bus"
        # one are connected to the same bus.
        # if not, it must not be done. So basically, i create a vector for which p and q for generator must be multiply
        self._fact_mult_gen = np.ones(self._grid.gen.shape[0])
        # self._fact_mult_gen[-1] += 1

        # now extract the powergrid
        self.n_line = copy.deepcopy(self._grid.line.shape[0]) + copy.deepcopy(
            self._grid.trafo.shape[0])
        if "name" in self._grid.line.columns and not self._grid.line[
                "name"].isnull().values.any():
            self.name_line = [name for name in self._grid.line["name"]]
        else:
            self.name_line = [
                '{from_bus}_{to_bus}_{id_powerline_me}'.format(
                    **row, id_powerline_me=i)
                for i, (_, row) in enumerate(self._grid.line.iterrows())
            ]
        if "name" in self._grid.trafo.columns and not self._grid.trafo[
                "name"].isnull().values.any():
            self.name_line += [
                name_traf for name_traf in self._grid.trafo["name"]
            ]
        else:
            transfo = [('{hv_bus}'.format(**row), '{lv_bus}'.format(**row))
                       for i, (_,
                               row) in enumerate(self._grid.trafo.iterrows())]
            transfo = [sorted(el) for el in transfo]
            self.name_line += [
                '{}_{}_{}'.format(*el, i + self._grid.line.shape[0])
                for i, el in enumerate(transfo)
            ]
        self.name_line = np.array(self.name_line)

        self.n_gen = copy.deepcopy(self._grid.gen.shape[0])
        if "name" in self._grid.gen.columns and not self._grid.gen[
                "name"].isnull().values.any():
            self.name_gen = [name_g for name_g in self._grid.gen["name"]]
        else:
            self.name_gen = [
                "gen_{bus}_{index_gen}".format(**row, index_gen=i)
                for i, (_, row) in enumerate(self._grid.gen.iterrows())
            ]
        self.name_gen = np.array(self.name_gen)

        self.n_load = copy.deepcopy(self._grid.load.shape[0])
        if "name" in self._grid.load.columns and not self._grid.load[
                "name"].isnull().values.any():
            self.name_load = [nl for nl in self._grid.load["name"]]
        else:
            self.name_load = [
                "load_{bus}_{index_gen}".format(**row, index_gen=i)
                for i, (_, row) in enumerate(self._grid.load.iterrows())
            ]
        self.name_load = np.array(self.name_load)
        self.n_sub = copy.deepcopy(self._grid.bus.shape[0])
        self.name_sub = [
            "sub_{}".format(i) for i, row in self._grid.bus.iterrows()
        ]
        self.name_sub = np.array(self.name_sub)
        #  number of elements per substation
        self.sub_info = np.zeros(self.n_sub, dtype=dt_int)

        self.load_to_subid = np.zeros(self.n_load, dtype=dt_int)
        self.gen_to_subid = np.zeros(self.n_gen, dtype=dt_int)
        self.line_or_to_subid = np.zeros(self.n_line, dtype=dt_int)
        self.line_ex_to_subid = np.zeros(self.n_line, dtype=dt_int)

        self.load_to_sub_pos = np.zeros(self.n_load, dtype=dt_int)
        self.gen_to_sub_pos = np.zeros(self.n_gen, dtype=dt_int)
        self.line_or_to_sub_pos = np.zeros(self.n_line, dtype=dt_int)
        self.line_ex_to_sub_pos = np.zeros(self.n_line, dtype=dt_int)

        pos_already_used = np.zeros(self.n_sub, dtype=dt_int)
        self._what_object_where = [[] for _ in range(self.n_sub)]

        # self._grid.line.sort_index(inplace=True)
        # self._grid.trafo.sort_index(inplace=True)
        # self._grid.gen.sort_index(inplace=True)
        # self._grid.load.sort_index(inplace=True)

        for i, (_, row) in enumerate(self._grid.line.iterrows()):
            sub_or_id = int(row["from_bus"])
            sub_ex_id = int(row["to_bus"])
            self.sub_info[sub_or_id] += 1
            self.sub_info[sub_ex_id] += 1
            self.line_or_to_subid[i] = sub_or_id
            self.line_ex_to_subid[i] = sub_ex_id

            self.line_or_to_sub_pos[i] = pos_already_used[sub_or_id]
            pos_already_used[sub_or_id] += 1
            self.line_ex_to_sub_pos[i] = pos_already_used[sub_ex_id]
            pos_already_used[sub_ex_id] += 1

            self._what_object_where[sub_or_id].append(("line", "from_bus", i))
            self._what_object_where[sub_ex_id].append(("line", "to_bus", i))

        lag_transfo = self._grid.line.shape[0]
        self._number_true_line = copy.deepcopy(self._grid.line.shape[0])
        for i, (_, row) in enumerate(self._grid.trafo.iterrows()):
            sub_or_id = int(row["hv_bus"])
            sub_ex_id = int(row["lv_bus"])
            self.sub_info[sub_or_id] += 1
            self.sub_info[sub_ex_id] += 1
            self.line_or_to_subid[i + lag_transfo] = sub_or_id
            self.line_ex_to_subid[i + lag_transfo] = sub_ex_id

            self.line_or_to_sub_pos[i +
                                    lag_transfo] = pos_already_used[sub_or_id]
            pos_already_used[sub_or_id] += 1
            self.line_ex_to_sub_pos[i +
                                    lag_transfo] = pos_already_used[sub_ex_id]
            pos_already_used[sub_ex_id] += 1

            self._what_object_where[sub_or_id].append(("trafo", "hv_bus", i))
            self._what_object_where[sub_ex_id].append(("trafo", "lv_bus", i))

        for i, (_, row) in enumerate(self._grid.gen.iterrows()):
            sub_id = int(row["bus"])
            self.sub_info[sub_id] += 1
            self.gen_to_subid[i] = sub_id
            self.gen_to_sub_pos[i] = pos_already_used[sub_id]
            pos_already_used[sub_id] += 1

            self._what_object_where[sub_id].append(("gen", "bus", i))

        for i, (_, row) in enumerate(self._grid.load.iterrows()):
            sub_id = int(row["bus"])
            self.sub_info[sub_id] += 1
            self.load_to_subid[i] = sub_id
            self.load_to_sub_pos[i] = pos_already_used[sub_id]
            pos_already_used[sub_id] += 1

            self._what_object_where[sub_id].append(("load", "bus", i))

        self.dim_topo = np.sum(self.sub_info)
        self._compute_pos_big_topo()

        # utilities for imeplementing apply_action
        self._corresp_name_fun = {}

        self._get_vector_inj = {}
        self._get_vector_inj[
            "load_p"] = self._load_grid_load_p_mw  #lambda grid: grid.load["p_mw"]
        self._get_vector_inj[
            "load_q"] = self._load_grid_load_q_mvar  #lambda grid: grid.load["q_mvar"]
        self._get_vector_inj[
            "prod_p"] = self._load_grid_gen_p_mw  #lambda grid: grid.gen["p_mw"]
        self._get_vector_inj[
            "prod_v"] = self._load_grid_gen_vm_pu  #lambda grid: grid.gen["vm_pu"]

        # "hack" to handle topological changes, for now only 2 buses per substation
        add_topo = copy.deepcopy(self._grid.bus)
        add_topo.index += add_topo.shape[0]
        add_topo["in_service"] = False
        self._grid.bus = pd.concat((self._grid.bus, add_topo))

        self.load_pu_to_kv = self._grid.bus["vn_kv"][
            self.load_to_subid].values.astype(dt_float)
        self.prod_pu_to_kv = self._grid.bus["vn_kv"][
            self.gen_to_subid].values.astype(dt_float)
        self.lines_or_pu_to_kv = self._grid.bus["vn_kv"][
            self.line_or_to_subid].values.astype(dt_float)
        self.lines_ex_pu_to_kv = self._grid.bus["vn_kv"][
            self.line_ex_to_subid].values.astype(dt_float)

        self.thermal_limit_a = 1000 * np.concatenate(
            (self._grid.line["max_i_ka"].values,
             self._grid.trafo["sn_mva"].values /
             (np.sqrt(3) * self._grid.trafo["vn_hv_kv"].values)))
        self.thermal_limit_a = self.thermal_limit_a.astype(dt_float)

        self.p_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.q_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.v_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.a_or = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.p_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.q_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.v_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.a_ex = np.full(self.n_line, dtype=dt_float, fill_value=np.NaN)
        self.line_status = np.full(self.n_line,
                                   dtype=dt_bool,
                                   fill_value=np.NaN)
        self.load_p = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN)
        self.load_q = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN)
        self.load_v = np.full(self.n_load, dtype=dt_float, fill_value=np.NaN)
        self.prod_p = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN)
        self.prod_v = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN)
        self.prod_q = np.full(self.n_gen, dtype=dt_float, fill_value=np.NaN)
        self._nb_bus_before = None

        # shunts data
        self.n_shunt = self._grid.shunt.shape[0]
        self.shunt_to_subid = np.zeros(self.n_shunt, dtype=dt_int) - 1
        name_shunt = []
        for i, (_, row) in enumerate(self._grid.shunt.iterrows()):
            bus = int(row["bus"])
            name_shunt.append(
                "shunt_{bus}_{index_shunt}".format(**row, index_shunt=i))
            self.shunt_to_subid[i] = bus
        self.name_shunt = np.array(name_shunt)
        self._sh_vnkv = self._grid.bus["vn_kv"][
            self.shunt_to_subid].values.astype(dt_float)
        self.shunts_data_available = True

        # store the topoid -> objid
        self._big_topo_to_obj = [(None, None) for _ in range(self.dim_topo)]
        nm_ = "load"
        for load_id, pos_big_topo in enumerate(self.load_pos_topo_vect):
            self._big_topo_to_obj[pos_big_topo] = (load_id, nm_)
        nm_ = "gen"
        for gen_id, pos_big_topo in enumerate(self.gen_pos_topo_vect):
            self._big_topo_to_obj[pos_big_topo] = (gen_id, nm_)
        nm_ = "lineor"
        for l_id, pos_big_topo in enumerate(self.line_or_pos_topo_vect):
            self._big_topo_to_obj[pos_big_topo] = (l_id, nm_)
        nm_ = "lineex"
        for l_id, pos_big_topo in enumerate(self.line_ex_pos_topo_vect):
            self._big_topo_to_obj[pos_big_topo] = (l_id, nm_)

        # store the topoid -> objid
        self._big_topo_to_backend = [(None, None, None)
                                     for _ in range(self.dim_topo)]
        for load_id, pos_big_topo in enumerate(self.load_pos_topo_vect):
            self._big_topo_to_backend[pos_big_topo] = (load_id, load_id, 0)
        for gen_id, pos_big_topo in enumerate(self.gen_pos_topo_vect):
            self._big_topo_to_backend[pos_big_topo] = (gen_id, gen_id, 1)
        for l_id, pos_big_topo in enumerate(self.line_or_pos_topo_vect):
            if l_id < self.__nb_powerline:
                self._big_topo_to_backend[pos_big_topo] = (l_id, l_id, 2)
            else:
                self._big_topo_to_backend[pos_big_topo] = (l_id, l_id -
                                                           self.__nb_powerline,
                                                           3)
        for l_id, pos_big_topo in enumerate(self.line_ex_pos_topo_vect):
            if l_id < self.__nb_powerline:
                self._big_topo_to_backend[pos_big_topo] = (l_id, l_id, 4)
            else:
                self._big_topo_to_backend[pos_big_topo] = (l_id, l_id -
                                                           self.__nb_powerline,
                                                           5)

        self._topo_vect = self._get_topo_vect()
        # Create a deep copy of itself in the initial state
        pp_backend_initial_state = copy.deepcopy(self)
        # Store it under super private attribute
        self.__pp_backend_initial_state = pp_backend_initial_state
import pandapower as pp

#create empty net
net = pp.create_empty_network()

#create buses
bus1 = pp.create_bus(net, vn_kv=20., name="Bus 1")
bus2 = pp.create_bus(net, vn_kv=0.4, name="Bus 2")
bus3 = pp.create_bus(net, vn_kv=0.4, name="Bus 3")

#create bus elements
pp.create_ext_grid(net, bus=bus1, vm_pu=1.02, name="Grid Connection")
pp.create_load(net, bus=bus3, p_mw=0.100, q_mvar=0.05, name="Load")

#create branch elements
trafo = pp.create_transformer(net, hv_bus=bus1, lv_bus=bus2, std_type="0.4 MVA 20/0.4 kV", name="Trafo")
line = pp.create_line(net, from_bus=bus2, to_bus=bus3, length_km=0.1, std_type="NAYY 4x50 SE", name="Line")

pp.runpp(net) #Power Flow
print(net.res_bus)
print(net.res_line)
net.res_trafo
print(net.res_bus)
Ejemplo n.º 23
0
    def runpf(self, is_dc=False):
        """
        .. warning:: /!\\\\ Internal, do not use unless you know what you are doing /!\\\\

        Run a power flow on the underlying _grid. This implements an optimization of the powerflow
        computation: if the number of
        buses has not changed between two calls, the previous results are re used. This speeds up the computation
        in case of "do nothing" action applied.
        """
        conv = True
        nb_bus = self.get_nb_active_bus()
        try:
            with warnings.catch_warnings():
                # remove the warning if _grid non connex. And it that case load flow as not converged
                warnings.filterwarnings(
                    "ignore", category=scipy.sparse.linalg.MatrixRankWarning)
                warnings.filterwarnings("ignore", category=RuntimeWarning)
                if self._nb_bus_before is None:
                    self._pf_init = "dc"
                elif nb_bus == self._nb_bus_before:
                    self._pf_init = "results"
                else:
                    self._pf_init = "auto"

                if np.any(~self._grid.load["in_service"]):
                    # TODO see if there is a better way here -> do not handle this here, but rather in Backend._next_grid_state
                    raise pp.powerflow.LoadflowNotConverged("Isolated load")
                if np.any(~self._grid.gen["in_service"]):
                    # TODO see if there is a better way here -> do not handle this here, but rather in Backend._next_grid_state
                    raise pp.powerflow.LoadflowNotConverged("Isolated gen")

                if is_dc:
                    pp.rundcpp(self._grid, check_connectivity=False)
                    self._nb_bus_before = None  # if dc i start normally next time i call an ac powerflow
                else:
                    pp.runpp(self._grid,
                             check_connectivity=False,
                             init=self._pf_init,
                             numba=numba_)

                # stores the computation time
                if "_ppc" in self._grid:
                    if "et" in self._grid["_ppc"]:
                        self.comp_time += self._grid["_ppc"]["et"]
                if self._grid.res_gen.isnull().values.any():
                    # TODO see if there is a better way here -> do not handle this here, but rather in Backend._next_grid_state
                    # sometimes pandapower does not detect divergence and put Nan.
                    raise pp.powerflow.LoadflowNotConverged("Isolated gen")

                self.prod_p[:], self.prod_q[:], self.prod_v[:] = self._gens_info(
                )
                self.load_p[:], self.load_q[:], self.load_v[:] = self._loads_info(
                )
                if not is_dc:
                    if not np.all(np.isfinite(self.load_v)):
                        # TODO see if there is a better way here
                        # some loads are disconnected: it's a game over case!
                        raise pp.powerflow.LoadflowNotConverged(
                            "Isolated load")
                else:
                    # fix voltages magnitude that are always "nan" for dc case
                    # self._grid.res_bus["vm_pu"] is always nan when computed in DC
                    self.load_v[:] = self.load_pu_to_kv  # TODO
                    # need to assign the correct value when a generator is present at the same bus
                    # TODO optimize this ugly loop
                    for l_id in range(self.n_load):
                        if self.load_to_subid[l_id] in self.gen_to_subid:
                            ind_gens = np.where(self.gen_to_subid ==
                                                self.load_to_subid[l_id])[0]
                            for g_id in ind_gens:
                                if self._topo_vect[self.load_pos_topo_vect[
                                        l_id]] == self._topo_vect[
                                            self.load_pos_topo_vect[g_id]]:
                                    self.load_v[l_id] = self.prod_v[g_id]
                                    break

                self.line_status[:] = self._get_line_status()
                # I retrieve the data once for the flows, so has to not re read multiple dataFrame
                self.p_or[:] = self._aux_get_line_info("p_from_mw", "p_hv_mw")
                self.q_or[:] = self._aux_get_line_info("q_from_mvar",
                                                       "q_hv_mvar")
                self.v_or[:] = self._aux_get_line_info("vm_from_pu",
                                                       "vm_hv_pu")
                self.a_or[:] = self._aux_get_line_info("i_from_ka",
                                                       "i_hv_ka") * 1000
                self.a_or[~np.isfinite(self.a_or)] = 0.
                self.v_or[~np.isfinite(self.v_or)] = 0.

                self.p_ex[:] = self._aux_get_line_info("p_to_mw", "p_lv_mw")
                self.q_ex[:] = self._aux_get_line_info("q_to_mvar",
                                                       "q_lv_mvar")
                self.v_ex[:] = self._aux_get_line_info("vm_to_pu", "vm_lv_pu")
                self.a_ex[:] = self._aux_get_line_info("i_to_ka",
                                                       "i_lv_ka") * 1000
                self.a_ex[~np.isfinite(self.a_ex)] = 0.
                self.v_ex[~np.isfinite(self.v_ex)] = 0.

                # it seems that pandapower does not take into account disconencted powerline for their voltage
                self.v_or[~self.line_status] = 0.
                self.v_ex[~self.line_status] = 0.

                self.v_or[:] *= self.lines_or_pu_to_kv
                self.v_ex[:] *= self.lines_ex_pu_to_kv

                self._nb_bus_before = None
                self._grid._ppc["gen"][self._iref_slack, 1] = 0.
                self._topo_vect[:] = self._get_topo_vect()
                return self._grid.converged

        except pp.powerflow.LoadflowNotConverged as exc_:
            # of the powerflow has not converged, results are Nan
            self._reset_all_nan()
            return False
Ejemplo n.º 24
0
def validate_from_ppc(
        ppc_net,
        net,
        pf_type="runpp",
        max_diff_values={
            "bus_vm_pu": 1e-6,
            "bus_va_degree": 1e-5,
            "branch_p_mw": 1e-6,
            "branch_q_mvar": 1e-6,
            "gen_p_mw": 1e-6,
            "gen_q_mvar": 1e-6
        },
        run=True):
    """
    This function validates the pypower case files to pandapower net structure conversion via a \
    comparison of loadflow calculation results. (Hence the opf cost conversion is not validated.)

    INPUT:

        **ppc_net** - The pypower case file, which must already contain the pypower powerflow
            results or pypower must be importable.

        **net** - The pandapower network.

    OPTIONAL:

        **pf_type** ("runpp", string) - Type of validated power flow. Possible are ("runpp",
            "rundcpp", "runopp", "rundcopp")

        **max_diff_values** - Dict of maximal allowed difference values. The keys must be
        'vm_pu', 'va_degree', 'p_branch_mw', 'q_branch_mvar', 'p_gen_mw' and 'q_gen_mvar' and
        the values floats.

        **run** (True, bool or list of two bools) - changing the value to False avoids trying to run
            (optimal) loadflows. Giving a list of two bools addresses first pypower and second
            pandapower.

    OUTPUT:

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

    EXAMPLE:

        import pandapower.converter as pc

        net = cv.from_ppc(ppc_net, f_hz=50)

        conversion_success = cv.validate_from_ppc(ppc_net, net)

    NOTE:

        The user has to take care that the loadflow results already are included in the provided \
        ppc_net or pypower is importable.
    """
    # check in case of optimal powerflow comparison whether cost information exist
    if "opp" in pf_type:
        if not (len(net.polynomial_cost) | len(net.piecewise_linear_cost)):
            if "gencost" in ppc_net:
                if not len(ppc_net["gencost"]):
                    logger.debug(
                        'ppc and pandapower net do not include cost information.'
                    )
                    return True
                else:
                    logger.error(
                        'The pandapower net does not include cost information.'
                    )
                    return False
            else:
                logger.debug(
                    'ppc and pandapower net do not include cost information.')
                return True

    # guarantee run parameter as list, for pypower and pandapower (optimal) powerflow run
    run = [run, run] if isinstance(run, bool) else run

    # --- check pypower powerflow success, if possible
    if pypower_import and run[0]:
        try:
            if pf_type == "runpp":
                ppc_net = runpf.runpf(ppc_net, ppopt)[0]
            elif pf_type == "rundcpp":
                ppc_net = rundcpf.rundcpf(ppc_net, ppopt)[0]
            elif pf_type == "runopp":
                ppc_net = runopf.runopf(ppc_net, ppopt)
            elif pf_type == "rundcopp":
                ppc_net = rundcopf.rundcopf(ppc_net, ppopt)
            else:
                raise ValueError("The pf_type %s is unknown" % pf_type)
        except:
            logger.debug("The pypower run did not work.")
    ppc_success = True
    if 'success' in ppc_net.keys():
        if ppc_net['success'] != 1:
            ppc_success = False
            logger.error(
                "The given ppc data indicates an unsuccessful pypower powerflow: "
                + "'ppc_net['success'] != 1'")
    if (ppc_net['branch'].shape[1] < 17):
        ppc_success = False
        logger.error(
            "The shape of given ppc data indicates missing pypower powerflow results."
        )

    # --- try to run a pandapower powerflow
    if run[1]:
        if pf_type == "runpp":
            try:
                pp.runpp(net,
                         init="dc",
                         calculate_voltage_angles=True,
                         trafo_model="pi")
            except pp.LoadflowNotConverged:
                try:
                    pp.runpp(net,
                             calculate_voltage_angles=True,
                             init="flat",
                             trafo_model="pi")
                except pp.LoadflowNotConverged:
                    try:
                        pp.runpp(net,
                                 trafo_model="pi",
                                 calculate_voltage_angles=False)
                        if "bus_va_degree" in max_diff_values.keys():
                            max_diff_values[
                                "bus_va_degree"] = 1e2 if max_diff_values[
                                    "bus_va_degree"] < 1e2 else max_diff_values[
                                        "bus_va_degree"]
                        logger.info("voltage_angles could be calculated.")
                    except pp.LoadflowNotConverged:
                        logger.error(
                            'The pandapower powerflow does not converge.')
        elif pf_type == "rundcpp":
            try:
                pp.rundcpp(net, trafo_model="pi")
            except pp.LoadflowNotConverged:
                logger.error('The pandapower dc powerflow does not converge.')
        elif pf_type == "runopp":
            try:
                pp.runopp(net, init="flat", calculate_voltage_angles=True)
            except pp.OPFNotConverged:
                try:
                    pp.runopp(net, init="pf", calculate_voltage_angles=True)
                except (pp.OPFNotConverged, pp.LoadflowNotConverged, KeyError):
                    try:
                        pp.runopp(net,
                                  init="flat",
                                  calculate_voltage_angles=False)
                        logger.info("voltage_angles could be calculated.")
                        if "bus_va_degree" in max_diff_values.keys():
                            max_diff_values[
                                "bus_va_degree"] = 1e2 if max_diff_values[
                                    "bus_va_degree"] < 1e2 else max_diff_values[
                                        "bus_va_degree"]
                    except pp.OPFNotConverged:
                        try:
                            pp.runopp(net,
                                      init="pf",
                                      calculate_voltage_angles=False)
                            if "bus_va_degree" in max_diff_values.keys():
                                max_diff_values[
                                    "bus_va_degree"] = 1e2 if max_diff_values[
                                        "bus_va_degree"] < 1e2 else max_diff_values[
                                            "bus_va_degree"]
                            logger.info("voltage_angles could be calculated.")
                        except (pp.OPFNotConverged, pp.LoadflowNotConverged,
                                KeyError):
                            logger.error(
                                'The pandapower optimal powerflow does not converge.'
                            )
        elif pf_type == "rundcopp":
            try:
                pp.rundcopp(net)
            except pp.LoadflowNotConverged:
                logger.error(
                    'The pandapower dc optimal powerflow does not converge.')
        else:
            raise ValueError("The pf_type %s is unknown" % pf_type)

    # --- prepare powerflow result comparison by reordering pp results as they are in ppc results
    if not ppc_success:
        return False
    if "opp" in pf_type:
        if not net.OPF_converged:
            return
    elif not net.converged:
        return False

    # --- store pypower powerflow results
    ppc_res = dict.fromkeys(ppc_elms)
    ppc_res["branch"] = ppc_net['branch'][:, 13:17]
    ppc_res["bus"] = ppc_net['bus'][:, 7:9]
    ppc_res["gen"] = ppc_net['gen'][:, 1:3]

    # --- pandapower bus result table
    pp_res = dict.fromkeys(ppc_elms)
    pp_res["bus"] = array(net.res_bus.sort_index()[['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
    # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array
    if len(ppc_net["gen"].shape) == 1:
        ppc_net["gen"] = array(ppc_net["gen"], ndmin=2)
    GENS = DataFrame(ppc_net['gen'][:, [0]].astype(int))
    GEN_uniq = GENS.drop_duplicates()
    already_used_gen = Series(zeros(GEN_uniq.shape[0]).astype(int),
                              index=[int(v) for v in GEN_uniq.values])
    change_q_compare = []
    for i, j in GENS.iterrows():
        current_bus_type, current_bus_idx, same_bus_gen_idx, first_same_bus_in_service_gen_idx, \
            last_same_bus_in_service_gen_idx = _gen_bus_info(ppc_net, i)
        if current_bus_type == 3 and i == first_same_bus_in_service_gen_idx:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_ext_grid[net.ext_grid.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]]).reshape((1, 2)), 0)
        elif current_bus_type == 2 and i == first_same_bus_in_service_gen_idx:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_gen[net.gen.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]]).reshape((1, 2)), 0)
        else:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_sgen[net.sgen.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]])[already_used_gen.at[int(j)]].reshape((1, 2)), 0)
            already_used_gen.at[int(j)] += 1
            change_q_compare += [int(j)]
    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 often branches were considered
    # each node-to-node-connection
    try:
        init1 = concat([net.line.from_bus, net.line.to_bus], axis=1,
                       sort=True).drop_duplicates()
        init2 = concat([net.trafo.hv_bus, net.trafo.lv_bus], axis=1,
                       sort=True).drop_duplicates()
    except TypeError:
        # legacy pandas < 0.21
        init1 = concat([net.line.from_bus, net.line.to_bus],
                       axis=1).drop_duplicates()
        init2 = concat([net.trafo.hv_bus, net.trafo.lv_bus],
                       axis=1).drop_duplicates()
    init1['hv_bus'] = nan
    init1['lv_bus'] = nan
    init2['from_bus'] = nan
    init2['to_bus'] = nan
    try:
        already_used_branches = concat([init1, init2], axis=0, sort=True)
    except TypeError:
        # pandas < 0.21 legacy
        already_used_branches = concat([init1, init2], axis=0)
    already_used_branches['number'] = zeros(
        [already_used_branches.shape[0], 1]).astype(int)
    BRANCHES = DataFrame(ppc_net['branch'][:, [0, 1, 8, 9]])
    for i in BRANCHES.index:
        from_bus = pp.get_element_index(net,
                                        'bus',
                                        name=int(ppc_net['branch'][i, 0]))
        to_bus = pp.get_element_index(net,
                                      'bus',
                                      name=int(ppc_net['branch'][i, 1]))
        from_vn_kv = ppc_net['bus'][from_bus, 9]
        to_vn_kv = ppc_net['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(net.res_line[(net.line.from_bus == from_bus)
                                   & (net.line.to_bus == to_bus)][[
                                       'p_from_mw', 'q_from_mvar', 'p_to_mw',
                                       'q_to_mvar'
                                   ]])
                [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(net.res_trafo[(net.trafo.hv_bus == from_bus)
                                        & (net.trafo.lv_bus == to_bus)]
                          [['p_hv_mw', 'q_hv_mvar', 'p_lv_mw', 'q_lv_mvar'
                            ]])[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(net.res_trafo[(net.trafo.hv_bus == to_bus)
                                        & (net.trafo.lv_bus == from_bus)]
                          [['p_lv_mw', 'q_lv_mvar', 'p_hv_mw', 'q_hv_mvar'
                            ]])[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 powerflow result comparison
    diff_res = dict.fromkeys(ppc_elms)
    diff_res["bus"] = ppc_res["bus"] - pp_res["bus"]
    diff_res["bus"][:, 1] -= diff_res["bus"][0, 1]  # remove va_degree offset
    diff_res["branch"] = ppc_res["branch"] - pp_res["branch"]
    diff_res["gen"] = ppc_res["gen"] - pp_res["gen"]
    # comparison of buses with several generator units only as q sum
    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 MW" % max_(abs(diff_res["branch"][:, [0, 2]])))
    logger.debug(
        "Maximum branch flow reactive power difference between pypower and "
        "pandapower: %.2e MVAr" % max_(abs(diff_res["branch"][:, [1, 3]])))
    logger.debug(
        "Maximum active power generation difference between pypower and pandapower: "
        "%.2e MW" % max_(abs(diff_res["gen"][:, 0])))
    logger.debug(
        "Maximum reactive power generation difference between pypower and pandapower: "
        "%.2e MVAr" % max_(abs(diff_res["gen"][:, 1])))
    if _validate_diff_res(diff_res, {"bus_vm_pu": 1e-3, "bus_va_degree": 1e-3, "branch_p_mw": 1e-6,
                                     "branch_q_mvar": 1e-6}) and \
            (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 isinstance(max_diff_values, dict):
        return _validate_diff_res(diff_res, max_diff_values)
    else:
        logger.debug("'max_diff_values' must be a dict.")
Ejemplo n.º 25
0
def test_transformer3w_phase_shift():
    test_ref = ((0.9995, -31.003), (0.9996, -60.764))
    test_tap_pos = {
        'hv': ((0.9615, -31.466), (0.9617, -61.209)),
        'mv': ((1.0389, -30.620), (0.9996, -60.764)),
        'lv': ((0.9995, -31.003), (1.039, -60.381))
    }
    test_tap_neg = {
        'hv': ((1.0405, -30.511), (1.0406, -60.291)),
        'mv': ((0.9602, -31.417), (0.9996, -60.764)),
        'lv': ((0.9995, -31.003), (0.9603, -61.178))
    }
    for side in ["hv", "mv", "lv"]:
        net = pp.create_empty_network()
        b1 = pp.create_bus(net, vn_kv=110.)
        pp.create_ext_grid(net, b1)
        b2 = pp.create_bus(net, vn_kv=20.)
        pp.create_load(net, b2, 1e4)
        b3 = pp.create_bus(net, vn_kv=0.4)
        pp.create_load(net, b3, 1e3)
        pp.create_transformer3w_from_parameters(net,
                                                hv_bus=b1,
                                                mv_bus=b2,
                                                lv_bus=b3,
                                                vn_hv_kv=110,
                                                vn_mv_kv=20,
                                                vn_lv_kv=0.4,
                                                sn_hv_kva=40000,
                                                sn_mv_kva=30000,
                                                sn_lv_kva=10000,
                                                vsc_hv_percent=5,
                                                vsc_mv_percent=5,
                                                vsc_lv_percent=5,
                                                vscr_hv_percent=0.1,
                                                vscr_mv_percent=0.1,
                                                vscr_lv_percent=0.1,
                                                pfe_kw=0,
                                                i0_percent=0.1,
                                                shift_mv_degree=30,
                                                shift_lv_degree=60,
                                                tp_side=side,
                                                tp_st_percent=2,
                                                tp_st_degree=10,
                                                tp_pos=0,
                                                tp_mid=0,
                                                tp_min=-2,
                                                tp_max=2)
        pp.runpp(net, init="dc", calculate_voltage_angles=True)
        assert np.isclose(net.res_bus.vm_pu.at[b2], test_ref[0][0], rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b2],
                          test_ref[0][1],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.vm_pu.at[b3], test_ref[1][0], rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b3],
                          test_ref[1][1],
                          rtol=1e-4)

        net.trafo3w.tp_pos.at[0] = 2
        pp.runpp(net, init="dc", calculate_voltage_angles=True)
        assert np.isclose(net.res_bus.vm_pu.at[b2],
                          test_tap_pos[side][0][0],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b2],
                          test_tap_pos[side][0][1],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.vm_pu.at[b3],
                          test_tap_pos[side][1][0],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b3],
                          test_tap_pos[side][1][1],
                          rtol=1e-4)

        net.trafo3w.tp_pos.at[0] = -2
        pp.runpp(net, init="dc", calculate_voltage_angles=True)
        assert np.isclose(net.res_bus.vm_pu.at[b2],
                          test_tap_neg[side][0][0],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b2],
                          test_tap_neg[side][0][1],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.vm_pu.at[b3],
                          test_tap_neg[side][1][0],
                          rtol=1e-4)
        assert np.isclose(net.res_bus.va_degree.at[b3],
                          test_tap_neg[side][1][1],
                          rtol=1e-4)
Ejemplo n.º 26
0
def runpp_with_consistency_checks(net, **kwargs):
    pp.runpp(net, **kwargs)
    consistency_checks(net)
    return True
Ejemplo n.º 27
0
def result_test_network():
    for net in result_test_network_generator():
        pass
    pp.runpp(net, trafo_model="t", trafo_loading="current")
    return net
Ejemplo n.º 28
0
# -*- coding: utf-8 -*-

# Copyright (c) 2016-2021 by University of Kassel and Fraunhofer Institute for Energy Economics
# and Energy System Technology (IEE), Kassel. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

import pandapower.networks as nw
import pandapower as pp
import pandapower.control as control
import os

net = nw.example_multivoltage()
control.DiscreteTapControl(net, 1, 1.02, 1.03)
pp.runpp(net, run_control=True)
pp.to_json(net, os.path.join("old_versions",
                             "example_%s.json" % pp.__version__))
Ejemplo n.º 29
0
def test_pandapower_case():

    #more complicated examples like
    #net = pandapower.networks.example_simple()
    #can be used once the import of e.g. switches is perfected

    #create empty net
    net = pp.create_empty_network()

    #create buses
    b1 = pp.create_bus(net, vn_kv=20., name="Bus 1")
    b2 = pp.create_bus(net, vn_kv=0.4, name="Bus 2")
    b3 = pp.create_bus(net, vn_kv=0.4, name="Bus 3")

    #create bus elements
    pp.create_ext_grid(net, bus=b1, vm_pu=1.02, name="Grid Connection")
    pp.create_load(net, bus=b3, p_mw=0.1, q_mvar=0.05, name="Load")

    #create branch elements
    tid = pp.create_transformer(net,
                                hv_bus=b1,
                                lv_bus=b2,
                                std_type="0.4 MVA 20/0.4 kV",
                                name="Trafo")
    pp.create_line(net,
                   from_bus=b2,
                   to_bus=b3,
                   length_km=0.1,
                   name="Line",
                   std_type="NAYY 4x50 SE")

    #because of phase angles, need to init with DC
    pp.runpp(net, calculate_voltage_angles=True, init="dc")

    n = pypsa.Network()

    n.import_from_pandapower_net(net)

    #seed PF with LPF solution because of phase angle jumps
    n.lpf()
    n.pf(use_seed=True)

    #use same index for everything
    net.res_bus.index = net.bus.name.values
    net.res_line.index = net.line.name.values

    #compare bus angles
    np.testing.assert_array_almost_equal(
        n.buses_t.v_ang.loc["now"] * 180 / np.pi, net.res_bus.va_degree)

    #compare bus voltage magnitudes
    np.testing.assert_array_almost_equal(n.buses_t.v_mag_pu.loc["now"],
                                         net.res_bus.vm_pu)

    #compare bus active power (NB: pandapower uses load signs)
    np.testing.assert_array_almost_equal(n.buses_t.p.loc["now"],
                                         -net.res_bus.p_mw)

    #compare bus active power (NB: pandapower uses load signs)
    np.testing.assert_array_almost_equal(n.buses_t.q.loc["now"],
                                         -net.res_bus.q_mvar)

    #compare branch flows
    np.testing.assert_array_almost_equal(n.lines_t.p0.loc["now"],
                                         net.res_line.p_from_mw)
    np.testing.assert_array_almost_equal(n.lines_t.p1.loc["now"],
                                         net.res_line.p_to_mw)
    np.testing.assert_array_almost_equal(n.lines_t.q0.loc["now"],
                                         net.res_line.q_from_mvar)
    np.testing.assert_array_almost_equal(n.lines_t.q1.loc["now"],
                                         net.res_line.q_to_mvar)

    np.testing.assert_array_almost_equal(n.transformers_t.p0.loc["now"],
                                         net.res_trafo.p_hv_mw)
    np.testing.assert_array_almost_equal(n.transformers_t.p1.loc["now"],
                                         net.res_trafo.p_lv_mw)
    np.testing.assert_array_almost_equal(n.transformers_t.q0.loc["now"],
                                         net.res_trafo.q_hv_mvar)
    np.testing.assert_array_almost_equal(n.transformers_t.q1.loc["now"],
                                         net.res_trafo.q_lv_mvar)
Ejemplo n.º 30
0
def test_pandapower_case():

    #more complicated examples like
    #net = pandapower.networks.example_simple()
    #can be used once the import of e.g. switches is perfected

    #create empty net
    net = pp.create_empty_network()

    #create buses
    b1 = pp.create_bus(net, vn_kv=20., name="Bus 1")
    b2 = pp.create_bus(net, vn_kv=0.4, name="Bus 2")
    b3 = pp.create_bus(net, vn_kv=0.4, name="Bus 3")

    #create bus elements
    pp.create_ext_grid(net, bus=b1, vm_pu=1.02, name="Grid Connection")
    pp.create_load(net, bus=b3, p_kw=100, q_kvar=50, name="Load")

    #create branch elements
    tid = pp.create_transformer(net, hv_bus=b1, lv_bus=b2, std_type="0.4 MVA 20/0.4 kV",
                                                            name="Trafo")
    pp.create_line(net, from_bus=b2, to_bus=b3, length_km=0.1, name="Line",
                                  std_type="NAYY 4x50 SE")

    #because of phase angles, need to init with DC
    pp.runpp(net,calculate_voltage_angles=True,init="dc")

    n = pypsa.Network()

    n.import_from_pandapower_net(net)

    #seed PF with LPF solution because of phase angle jumps
    n.lpf()
    n.pf(use_seed=True)

    #use same index for everything
    net.res_bus.index = net.bus.name.values
    net.res_line.index = net.line.name.values

    #compare bus angles
    np.testing.assert_array_almost_equal(n.buses_t.v_ang.loc["now"]*180/np.pi,net.res_bus.va_degree)

    #compare bus voltage magnitudes
    np.testing.assert_array_almost_equal(n.buses_t.v_mag_pu.loc["now"],net.res_bus.vm_pu)

    #compare bus active power (NB: pandapower uses load signs)
    np.testing.assert_array_almost_equal(n.buses_t.p.loc["now"],-net.res_bus.p_kw/1e3)

    #compare bus active power (NB: pandapower uses load signs)
    np.testing.assert_array_almost_equal(n.buses_t.q.loc["now"],-net.res_bus.q_kvar/1e3)

    #compare branch flows
    np.testing.assert_array_almost_equal(n.lines_t.p0.loc["now"],net.res_line.p_from_kw/1e3)
    np.testing.assert_array_almost_equal(n.lines_t.p1.loc["now"],net.res_line.p_to_kw/1e3)
    np.testing.assert_array_almost_equal(n.lines_t.q0.loc["now"],net.res_line.q_from_kvar/1e3)
    np.testing.assert_array_almost_equal(n.lines_t.q1.loc["now"],net.res_line.q_to_kvar/1e3)

    np.testing.assert_array_almost_equal(n.transformers_t.p0.loc["now"],net.res_trafo.p_hv_kw/1e3)
    np.testing.assert_array_almost_equal(n.transformers_t.p1.loc["now"],net.res_trafo.p_lv_kw/1e3)
    np.testing.assert_array_almost_equal(n.transformers_t.q0.loc["now"],net.res_trafo.q_hv_kvar/1e3)
    np.testing.assert_array_almost_equal(n.transformers_t.q1.loc["now"],net.res_trafo.q_lv_kvar/1e3)
Ejemplo n.º 31
0
def test_convert_format():
    folder = os.path.abspath(os.path.dirname(pp.__file__))
    net =  pp.from_pickle(os.path.join(folder, "test", "api", "old_net.p"))
    pp.runpp(net)
    assert net.converged