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)
def create_net(state='NS'): net = pp.create_empty_network() pp.set_user_pf_options(net, init_vm_pu="flat", init_va_degree="dc", calculate_voltage_angles=True) b0 = pp.create_bus(net, 110) b1 = pp.create_bus(net, 110) b2 = pp.create_bus(net, 110) b3 = pp.create_bus(net, 110) b4 = pp.create_bus(net, 110) b5 = pp.create_bus(net, 110) b6 = pp.create_bus(net, 110) b7 = pp.create_bus(net, 110) b8 = pp.create_bus(net, 110) pp.create_ext_grid(net, b0) pp.create_line(net, b0, b3, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b3, b4, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b3, b8, 10, "149-AL1/24-ST1A 110.0") if state in ['NS', 'HL', 'LL', 'GD']: pp.create_line(net, b4, b5, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b5, b2, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b8, b7, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b5, b6, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b1, b7, 10, "149-AL1/24-ST1A 110.0") pp.create_line(net, b7, b6, 10, "149-AL1/24-ST1A 110.0") if state == 'HL': pp.create_load(net, b4, p_mw=90 * 1.1, q_mvar=30 * 1.1, name='load1') pp.create_load(net, b6, p_mw=100 * 1.1, q_mvar=35 * 1.1, name='load2') pp.create_load(net, b8, p_mw=125 * 1.1, q_mvar=50 * 1.1, name='load3') if state == 'LL': pp.create_load(net, b4, p_mw=90 * 0.9, q_mvar=30 * 0.9, name='load1') pp.create_load(net, b6, p_mw=100 * 0.9, q_mvar=35 * 0.9, name='load2') pp.create_load(net, b8, p_mw=125 * 0.9, q_mvar=50 * 0.9, name='load3') else: pp.create_load(net, b4, p_mw=90, q_mvar=30, name='load1') pp.create_load(net, b6, p_mw=100, q_mvar=35, name='load2') pp.create_load(net, b8, p_mw=125, q_mvar=50, name='load3') pp.create_gen(net, b0, p_mw=0, vm_pu=1.0, name='gen1', slack=True) pp.create_sgen(net, b1, p_mw=163, q_mvar=0, name='sgen1') if state in ['NS', 'HL', 'LL', 'LD']: pp.create_sgen(net, b2, p_mw=85, q_mvar=0, name='sgen2') return net
def create_test_network(): """Creates a simple pandapower test network """ net = pp.create_empty_network() b1 = pp.create_bus(net, name="bus1", vn_kv=10.) pp.create_ext_grid(net, b1) b2 = pp.create_bus(net, name="bus2", geodata=(1, 2), vn_kv=.4) b3 = pp.create_bus(net, name="bus3", geodata=(1, 3), vn_kv=.4, index=7) b4 = pp.create_bus(net, name="bus4", vn_kv=10.) pp.create_transformer_from_parameters(net, b4, b2, vsc_percent=3.75, tp_max=2, vn_lv_kv=0.4, shift_degree=150, tp_mid=0, vn_hv_kv=10.0, vscr_percent=2.8125, tp_pos=0, tp_side="hv", tp_min=-2, tp_st_percent=2.5, i0_percent=0.68751, sn_kva=16.0, pfe_kw=0.11, name=None, in_service=True, index=None) # 0.016 MVA 10/0.4 kV ET 16/23 SGB pp.create_line_from_parameters(net, b2, b3, 1, name="line1", r_ohm_per_km=0.2067, ices=0.389985, c_nf_per_km=720.0, max_i_ka=0.328, x_ohm_per_km=0.1897522, geodata=np.array([[1, 2], [3, 4]])) # NAYY 1x150RM 0.6/1kV ir pp.create_line_from_parameters(net, b1, b4, 1, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876) # NAYSEY 3x35rm/16 6/10kV pp.create_load(net, b2, p_kw=10, q_kvar=0, name="load1") pp.create_load(net, b3, p_kw=40, q_kvar=2, name="load2") pp.create_gen(net, b4, p_kw=-200., vm_pu=1.0) pp.create_sgen(net, b3, p_kw=-50, sn_kva=100) return net
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") net.bus net.line net.trafo net.load pp.runpp(net) net.res_bus
type='b', index=coll_idx[i], geodata=(df.at[intrC_idx[i], "X"], df.at[intrC_idx[i], "Y"])) for i in intrC.index: pp.create_line(net, from_bus=intrC.at[i, 'ID1'], to_bus=intrC.at[i, 'ID2'], length_km=1, std_type="NAYY 4x150 SE") ############################################## #Creating Load for i in loads.index: pp.create_load(net, loads.at[i, 'ID'], p_mw=0.1) ############################################## #creating External Grid (Slack Bus) pp.create_bus(net, vn_kv=110, type='b', index=0, geodata=(df.at[6276, "X"], df.at[6276, "Y"])) pp.create_ext_grid(net, 0, vm_pu=1) pp.create_transformer(net, hv_bus=0, lv_bus=6276, tap_pos="0.175", std_type="25 MVA 110/20 kV")
def add_test_oos_bus_with_is_element(net): b1, b2, ln = add_grid_connection(net, zone="test_oos_bus_with_is_element") pl = 1200 ql = 1100 ps = -500 u_set = 1.0 pz = 1200 qz = 1100 qs = 200 vm_pu = 1.06 r_ohm = 50 x_ohm = 70 # OOS buses b3 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) b4 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) b5 = pp.create_bus(net, zone="test_oos_bus_with_is_element", vn_kv=0.4, in_service=False) pp.create_line_from_parameters(net, b2, b3, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, c_nf_per_km=300, imax_ka=.2, df=.8) pp.create_line_from_parameters(net, b2, b4, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, c_nf_per_km=300, imax_ka=.2, df=.8) pp.create_line_from_parameters(net, b2, b5, 12.2, r_ohm_per_km=0.08, x_ohm_per_km=0.12, c_nf_per_km=300, imax_ka=.2, df=.8) # in service elements pp.create_load(net, b3, p_kw=pl, q_kvar=ql) pp.create_gen(net, b4, p_kw=ps, vm_pu=u_set) pp.create_sgen(net, b5, p_kw=ps, q_kvar=ql) pp.create_ward(net, b3, pz_kw=pz, qz_kvar=qz, ps_kw=ps, qs_kvar=qs) pp.create_xward(net, b4, pz_kw=0.5 * pz, qz_kvar=0.5 * qz, ps_kw=0.5 * ps, qs_kvar=0.5 * qs, vm_pu=vm_pu, x_ohm=x_ohm, r_ohm=r_ohm) pp.create_shunt(net, b5, q_kvar=-800, p_kw=0) net.last_added_case = "test_oos_bus_with_is_element" return net
def test_3ph_isolated_nodes(): v_base = 110 # 110kV Base Voltage mva_base = 100 # 100 MVA net = pp.create_empty_network(sn_mva=mva_base) busn = pp.create_bus(net, vn_kv=v_base, name="busn", index=1) pp.create_bus(net, vn_kv=20., in_service=True, index=2, name="busx") busk = pp.create_bus(net, vn_kv=v_base, name="busk", index=5) busl = pp.create_bus(net, vn_kv=v_base, name="busl", index=6) pp.create_bus(net, vn_kv=20., in_service=False, index=3) busy = pp.create_bus(net, vn_kv=20., in_service=True, index=0, name="busy") pp.create_ext_grid(net, bus=busn, vm_pu=1.0, name="Grid Connection", s_sc_max_mva=5000, rx_max=0.1) net.ext_grid["r0x0_max"] = 0.1 net.ext_grid["x0x_max"] = 1.0 pp.create_std_type( net, { "r0_ohm_per_km": 0.0848, "x0_ohm_per_km": 0.4649556, "c0_nf_per_km": 230.6, "max_i_ka": 0.963, "r_ohm_per_km": 0.0212, "x_ohm_per_km": 0.1162389, "c_nf_per_km": 230 }, "example_type") # Loads on supplied buses pp.create_asymmetric_load(net, busk, p_a_mw=50, q_a_mvar=50, p_b_mw=10, q_b_mvar=15, p_c_mw=10, q_c_mvar=5) pp.create_load(net, bus=busl, p_mw=7, q_mvar=0.070, name="Load 1") # Loads on unsupplied buses pp.create_load(net, bus=busy, p_mw=70, q_mvar=70, name="Load Y") pp.create_line(net, from_bus=busn, to_bus=busk, length_km=50.0, std_type="example_type") pp.create_line(net, from_bus=busl, to_bus=busk, length_km=50.0, std_type="example_type") pp.add_zero_impedance_parameters(net) runpp_3ph_with_consistency_checks(net) assert net['converged'] assert np.allclose(net.res_bus_3ph.T[[0, 2, 3]].T[[ "vm_a_pu", "va_a_degree", "vm_b_pu", "va_b_degree", "vm_c_pu", "va_c_degree" ]], np.nan, equal_nan=True) assert np.allclose( net.res_bus_3ph.T[[0, 2, 3]].T[[ "p_a_mw", "q_a_mvar", "p_b_mw", "q_b_mvar", "p_c_mw", "q_c_mvar" ]], 0.0)
pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') #create loads load1 = pp.create_load(net, bus2, p_mw=60, min_p_mw=30, max_p_mw=60, min_q_mvar=0, max_q_mvar=10, controllable=True) load2 = pp.create_load(net, bus3, p_mw=70, controllable=False) load3 = pp.create_load(net, bus4, p_mw=10, controllable=False) #create generators eg = pp.create_ext_grid(net, bus1, min_p_mw=-1000, max_p_mw=1000) g0 = pp.create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01, controllable=True)
pp.create_line_from_parameters(net, b2, b3, length_km=0.5, r_ohm_per_km=0.1941, x_ohm_per_km=0.07476991, c_nf_per_km=1160., max_i_ka=0.421, endtemp_degree=70.0, r0_ohm_per_km=0.7766, x0_ohm_per_km=0.2990796, c0_nf_per_km=496.2, index=pp.get_free_id(net.line) + 1) if case == "bal_wye": # Symmetric Load pp.create_load(net, b3, 0.08, 0.012, type='wye') elif case == "delta_wye": # Unsymmetric Light Load pp.create_asymmetric_load(net, b3, p_a_mw=0.0044, q_a_mvar=0.0013, p_b_mw=0.0044, q_b_mvar=0.0013, p_c_mw=0.0032, q_c_mvar=0.0013, type='wye') pp.create_asymmetric_load(net, b3, p_a_mw=0.0300, q_a_mvar=0.0048,
def test_3ph_two_bus_line_powerfactory(): 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=1.0, s_sc_max_mva=10, rx_max=0.1) net.ext_grid["x0x_max"] = 1. net.ext_grid["r0x0_max"] = 0.1 pp.create_std_type( net, { "r_ohm_per_km": 0.1013, "x_ohm_per_km": 0.06911504, "c_nf_per_km": 690, "g_us_per_km": 0, "max_i_ka": 0.44, "c0_nf_per_km": 312.4, "r0_ohm_per_km": 0.4053, "x0_ohm_per_km": 0.2764602 }, "N2XRY 3x185sm 0.6/1kV") pp.create_line(net, b1, b2, 0.4, std_type="N2XRY 3x185sm 0.6/1kV") pp.add_zero_impedance_parameters(net) pp.create_load(net, b2, p_mw=0.010, q_mvar=0.010) pp.create_asymmetric_load(net, b2, p_a_mw=0.020, q_a_mvar=0.010, p_b_mw=0.015, q_b_mvar=0.005, p_c_mw=0.025, q_c_mvar=0.010) runpp_3ph_with_consistency_checks(net) assert net['converged'] bus_pp = np.abs(net.res_bus_3ph[['vm_a_pu', 'vm_b_pu', 'vm_c_pu']].values) bus_pf = np.abs( np.array([[0.99939853552, 1.0013885141, 0.99921580141], [0.97401782343, 0.98945593737, 0.96329605983]])) assert np.max(np.abs(bus_pp - bus_pf)) < 4e-6 line_pp = np.abs(net.res_line_3ph[[ 'i_a_from_ka', 'i_b_from_ka', 'i_c_from_ka', 'i_a_to_ka', 'i_b_to_ka', 'i_c_to_ka', 'p_a_from_mw', 'p_b_from_mw', 'p_c_from_mw', 'q_a_from_mvar', 'q_b_from_mvar', 'q_c_from_mvar', 'p_a_to_mw', 'p_b_to_mw', 'p_c_to_mw', 'q_a_to_mvar', 'q_b_to_mvar', 'q_c_to_mvar' ]].values) line_pf = np.abs( np.array([[ 0.11946088987, 0.08812337783, 0.14074226065, 0.1194708224, 0.088131567331, 0.14075063601, 0.023810539354, 0.01855791658, 0.029375192747, 0.013901720672, 0.008421814704, 0.013852398586, -0.023333142958, -0.018333405987, -0.028331643666, -0.013332756527, -0.008333413919, -0.013332422725 ]])) assert np.max(np.abs(line_pp - line_pf)) < 1e-5 line_load_pp = np.abs(net.res_line_3ph[[ 'loading_a_percent', 'loading_b_percent', 'loading_c_percent', 'loading_percent' ]].values) line_load_pf = np.abs(np.array([[27.1525, 20.0299, 31.98878, 31.98878]])) assert np.max(np.abs(line_load_pp - line_load_pf)) < 1e-2
def test_minimize_active_power_curtailment(): net = pp.create_empty_network() # create buses bus1 = pp.create_bus(net, vn_kv=220.) bus2 = pp.create_bus(net, vn_kv=110.) bus3 = pp.create_bus(net, vn_kv=110.) bus4 = pp.create_bus(net, vn_kv=110.) # create 220/110 kV transformer pp.create_transformer(net, bus1, bus2, std_type="100 MVA 220/110 kV") # create 110 kV lines pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') # create loads pp.create_load(net, bus2, p_mw=60, controllable=False) pp.create_load(net, bus3, p_mw=70, controllable=False) pp.create_load(net, bus4, p_mw=10, controllable=False) # create generators pp.create_ext_grid(net, bus1) pp.create_gen(net, bus3, p_mw=80., max_p_mw=80., min_p_mw=0., vm_pu=1.01, controllable=True) pp.create_gen(net, bus4, p_mw=0.1, max_p_mw=100., min_p_mw=0., vm_pu=1.01, controllable=True) net.trafo["max_loading_percent"] = 50. net.line["max_loading_percent"] = 50. net.bus["min_vm_pu"] = 1.0 net.bus["max_vm_pu"] = 1.02 # use cheapest gen first, avoid ext_grid as much as possible (until vm_pu max is reached for gens) pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=0.02) pp.create_poly_cost(net, 1, "gen", cp1_eur_per_mw=0.0) pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=0.3) pp.runopp(net, calculate_voltage_angles=True) assert net["OPF_converged"] # checks limits in general assert all(net.res_line.loading_percent < 50.01) assert all(net.res_bus.vm_pu < 1.02) assert all(net.res_bus.vm_pu > 1.0) # checks if the cheaper gen is rather used then the more expensive one to cover the load assert net.res_gen.at[1, "p_mw"] > net.res_gen.at[0, "p_mw"] # check if they use their maximum voltage assert allclose(net.res_gen.loc[:, "vm_pu"], 1.02)
def test_without_ext_grid(): net = pp.create_empty_network() min_vm_pu = 0.95 max_vm_pu = 1.05 # create buses bus1 = pp.create_bus(net, vn_kv=220., geodata=(5, 9)) bus2 = pp.create_bus(net, vn_kv=110., geodata=(6, 10), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) bus3 = pp.create_bus(net, vn_kv=110., geodata=(10, 9), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) bus4 = pp.create_bus(net, vn_kv=110., geodata=(8, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) bus5 = pp.create_bus(net, vn_kv=110., geodata=(6, 8), min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) # create 220/110/110 kV 3W-transformer pp.create_transformer3w_from_parameters(net, bus1, bus2, bus5, vn_hv_kv=220, vn_mv_kv=110, vn_lv_kv=110, vk_hv_percent=10., vk_mv_percent=10., vk_lv_percent=10., vkr_hv_percent=0.5, vkr_mv_percent=0.5, vkr_lv_percent=0.5, pfe_kw=100, i0_percent=0.1, shift_mv_degree=0, shift_lv_degree=0, sn_hv_mva=100, sn_mv_mva=50, sn_lv_mva=50) # create 110 kV lines pp.create_line(net, bus2, bus3, length_km=70., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus3, bus4, length_km=50., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus4, bus2, length_km=40., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus4, bus5, length_km=30., std_type='149-AL1/24-ST1A 110.0') # create loads pp.create_load(net, bus2, p_mw=60, controllable=False) pp.create_load(net, bus3, p_mw=70, controllable=False) pp.create_load(net, bus4, p_mw=10, controllable=False) # create generators g1 = pp.create_gen(net, bus1, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, slack=True, min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu) pp.create_poly_cost(net, g1, 'gen', cp1_eur_per_mw=1000) g2 = pp.create_gen(net, bus3, p_mw=40, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, max_p_mw=40.) pp.create_poly_cost(net, g2, 'gen', cp1_eur_per_mw=2000) g3 = pp.create_gen(net, bus4, p_mw=0.050, min_p_mw=0, min_q_mvar=-20, max_q_mvar=20, vm_pu=1.01, min_vm_pu=min_vm_pu, max_vm_pu=max_vm_pu, max_p_mw=0.05) pp.create_poly_cost(net, g3, 'gen', cp1_eur_per_mw=3000) pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g2], 0, atol=1e-5, rtol=1e-5) assert np.isclose(net.res_gen.p_mw.at[g3], 0, atol=1e-5, rtol=1e-5) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3) net.trafo3w["max_loading_percent"] = 150. pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert 149. < net.res_trafo3w.loading_percent.values[0] < 150.01 assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3 + net.res_gen.p_mw.at[g2] * 2e3) pp.runpm_dc_opf(net) consistency_checks(net, rtol=1e-3, test_q=False) assert 149. < net.res_trafo3w.loading_percent.values[0] < 150.01 assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] * 1e3 + net.res_gen.p_mw.at[g2] * 2e3)
def creer_reseau(): net = pp.create_empty_network() bus1 = pp.create_bus(net, name="HTB noeud", vn_kv=110, type="b") bus2 = pp.create_bus(net, name="HTB transfo", vn_kv=110, type="n") bus3 = pp.create_bus(net, name="HTA transfo", vn_kv=20, type="n") bus4 = pp.create_bus(net, name="barre HTA", vn_kv=20, type="b") bus5 = pp.create_bus(net, name="noeud 1 HTA", vn_kv=20, type="b") bus6 = pp.create_bus(net, name="noeud 2 HTA", vn_kv=20, type="b") bus7 = pp.create_bus(net, name="noeud 3 HTA", vn_kv=20, type="b") bus8 = pp.create_bus(net, name="noeud 4 HTA", vn_kv=20, type="b") bus9 = pp.create_bus(net, name="noeud 5 HTA", vn_kv=20, type="b") bus10 = pp.create_bus(net, name="noeud 6 HTA", vn_kv=20, type="b") bus11 = pp.create_bus(net, name="noeud 7 HTA", vn_kv=20, type="b") bus12 = pp.create_bus(net, name="noeud 8 HTA", vn_kv=20, type="b") bus13 = pp.create_bus(net, name="noeud 9 HTA", vn_kv=20, type="b") pp.create_ext_grid(net, bus1, vm_pu=1, va_degree=50) trafo1 = pp.create_transformer(net, bus2, bus3, name="HTB/HTA transfo", std_type="40 MVA 110/20 kV") line1 = pp.create_line(net, bus4, bus5, length_km=1, std_type="NAYY 4x150 SE", name="Line 1") line2 = pp.create_line(net, bus5, bus6, length_km=1, std_type="NAYY 4x150 SE", name="Line 2") line3 = pp.create_line(net, bus6, bus7, length_km=1, std_type="NAYY 4x150 SE", name="Line 3") line4 = pp.create_line(net, bus7, bus8, length_km=1, std_type="NAYY 4x150 SE", name="Line 4") line5 = pp.create_line(net, bus4, bus9, length_km=1, std_type="NAYY 4x150 SE", name="Line 5") line6 = pp.create_line(net, bus9, bus10, length_km=1, std_type="NAYY 4x150 SE", name="Line 6") line7 = pp.create_line(net, bus10, bus11, length_km=1, std_type="NAYY 4x150 SE", name="Line 7") line8 = pp.create_line(net, bus11, bus12, length_km=1, std_type="NAYY 4x150 SE", name="Line 8") line9 = pp.create_line(net, bus12, bus13, length_km=1, std_type="NAYY 4x150 SE", name="Line 9") sw1 = pp.create_switch(net, bus1, bus2, et="b", type="CB", closed=True) sw2 = pp.create_switch(net, bus3, bus4, et="b", type="CB", closed=True) pp.create_load(net, bus5, p_mw=3, q_mvar=0.5, name="load1") pp.create_load(net, bus6, p_mw=3, q_mvar=0.5, scaling=1, name="load2") pp.create_load(net, bus7, p_mw=3, q_mvar=0.5, scaling=1, name="load3") pp.create_load(net, bus8, p_mw=3, q_mvar=0.5, scaling=1, name="load4") pp.create_load(net, bus9, p_mw=3, q_mvar=0.5, scaling=1, name="load5") pp.create_load(net, bus10, p_mw=3, q_mvar=0.5, scaling=1, name="load6") pp.create_load(net, bus11, p_mw=3, q_mvar=0.5, scaling=1, name="load7") pp.create_load(net, bus12, p_mw=3, q_mvar=0.5, scaling=1, name="load8") pp.create_load(net, bus13, p_mw=3, q_mvar=0.5, scaling=1, name="load9") pp.create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator", type="wind") return net
def test_in_service_controllables(): """ Testing controllable but out of service elements behaviour """ # boundaries vm_max = 1.1 vm_min = 0.9 max_line_loading_percent = 100 # create network net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) b2 = pp.create_bus(net, vn_kv=0.4, max_vm_pu=vm_max, min_vm_pu=vm_min) pp.create_line(net, b1, b2, length_km=5, std_type="NAYY 4x50 SE", max_loading_percent=max_line_loading_percent) # test elements static pp.create_ext_grid(net, b2) pp.create_load(net, b1, p_mw=7.5, controllable=True, max_p_mw=0.010, min_p_mw=0, max_q_mvar=2.5, min_q_mvar=-2.5) pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0.01, max_p_mw=0.025, max_q_mvar=0.025, min_q_mvar=-0.025) # test elements pp.create_sgen(net, b1, p_mw=0.025, controllable=True, min_p_mw=0, max_p_mw=0.025, max_q_mvar=0.025, min_q_mvar=-0.025) pp.create_load(net, b1, p_mw=0.025, controllable=True, max_p_mw=0.0025, min_p_mw=0, max_q_mvar=2.5, min_q_mvar=-2.5) # costs pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=3) pp.create_poly_cost(net, 0, "load", cp1_eur_per_mw=-1) pp.create_poly_cost(net, 0, "sgen", cp1_eur_per_mw=2) pp.create_poly_cost(net, 1, "sgen", cp1_eur_per_mw=1) pp.create_poly_cost(net, 1, "load", cp1_eur_per_mw=-1) net["sgen"].in_service.iloc[1] = False net["load"].in_service.iloc[1] = False pp.runopp(net) assert net["OPF_converged"]
def example_simple(): """ Returns the simple example network from the pandapower tutorials. OUTPUT: net - simple example network EXAMPLE: >>> import pandapower.networks >>> net = pandapower.networks.example_simple() """ net = pp.create_empty_network() # create buses bus1 = pp.create_bus(net, name="HV Busbar", vn_kv=110., type="b") bus2 = pp.create_bus(net, name="HV Busbar 2", vn_kv=110., type="b") bus3 = pp.create_bus(net, name="HV Transformer Bus", vn_kv=110., type="n") bus4 = pp.create_bus(net, name="MV Transformer Bus", vn_kv=20., type="n") bus5 = pp.create_bus(net, name="MV Main Bus", vn_kv=20., type="b") bus6 = pp.create_bus(net, name="MV Bus 1", vn_kv=20., type="b") bus7 = pp.create_bus(net, name="MV Bus 2", vn_kv=20., type="b") # create external grid pp.create_ext_grid(net, bus1, vm_pu=1.02, va_degree=50) # create transformer pp.create_transformer(net, bus3, bus4, name="110kV/20kV transformer", std_type="25 MVA 110/20 kV") # create lines pp.create_line(net, bus1, bus2, length_km=10, std_type="N2XS(FL)2Y 1x300 RM/35 64/110 kV", name="Line 1") line2 = pp.create_line(net, bus5, bus6, length_km=2.0, std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 2") line3 = pp.create_line(net, bus6, bus7, length_km=3.5, std_type="48-AL1/8-ST1A 20.0", name="Line 3") line4 = pp.create_line(net, bus7, bus5, length_km=2.5, std_type="NA2XS2Y 1x240 RM/25 12/20 kV", name="Line 4") # create bus-bus switches pp.create_switch(net, bus2, bus3, et="b", type="CB") pp.create_switch(net, bus4, bus5, et="b", type="CB") # create bus-line switches pp.create_switch(net, bus5, line2, et="l", type="LBS", closed=True) pp.create_switch(net, bus6, line2, et="l", type="LBS", closed=True) pp.create_switch(net, bus6, line3, et="l", type="LBS", closed=True) pp.create_switch(net, bus7, line3, et="l", type="LBS", closed=False) pp.create_switch(net, bus7, line4, et="l", type="LBS", closed=True) pp.create_switch(net, bus5, line4, et="l", type="LBS", closed=True) # create load pp.create_load(net, bus7, p_mw=2, q_mvar=4, scaling=0.6, name="load") # create generator pp.create_gen(net, bus6, p_mw=6, max_q_mvar=3, min_q_mvar=-3, vm_pu=1.03, name="generator") # create static generator pp.create_sgen(net, bus7, p_mw=2, q_mvar=-0.5, name="static generator") # create shunt pp.create_shunt(net, bus3, q_mvar=-0.96, p_mw=0, name='Shunt') return net
def test_cost_mixed(): """ Testing a very simple network for the resulting cost value constraints with OPF """ # boundaries: vm_max = 1.05 vm_min = 0.95 # create net net = pp.create_empty_network() pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) pp.create_gen(net, 1, p_kw=-100, controllable=True, max_p_kw=-5, min_p_kw=-150, max_q_kvar=50, min_q_kvar=-50) pp.create_ext_grid(net, 0) pp.create_load(net, 1, p_kw=20, controllable=False, max_q_kvar=50, max_p_kw=100, min_p_kw=50, min_q_kvar=-50) pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, max_loading_percent=100 * 690) # testing some combinations pp.create_polynomial_cost(net, 0, "gen", np.array([0, 1, 0])) pp.runopp(net, verbose=False) assert net["OPF_converged"] assert net.res_cost == -net.res_gen.p_kw.values net.polynomial_cost.c.at[0] = np.array([[1, 0, 0]]) pp.runopp(net, verbose=False) assert net["OPF_converged"] assert net.res_cost - net.res_gen.p_kw.values**2 < 1e-5 net.polynomial_cost.c.at[0] = np.array([[1, 0, 1]]) pp.runopp(net, verbose=False) assert net["OPF_converged"] assert net.res_cost - net.res_gen.p_kw.values**2 - 1 < 1e-5 net.load.controllable.at[0] = True pp.runopp(net, verbose=False) assert net.res_cost - net.res_gen.p_kw.values**2 - 1 < 1e-5 pp.create_piecewise_linear_cost(net, 0, "load", np.array([[0, 0], [100, 100]]), type="p") pp.runopp(net, verbose=False) assert net.res_cost - net.res_gen.p_kw.values**2 - 1 - net.res_load.p_kw.values < 1e-5
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_mva=300, vn_hv_kv=380, vn_lv_kv=110, vkr_percent=0.06, vk_percent=8, pfe_kw=0, i0_percent=0, tap_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_mva=0.4, vn_hv_kv=10, vn_lv_kv=0.4, vkr_percent=1.325, vk_percent=4, pfe_kw=0.95, i0_percent=0.2375, tap_side="hv", tap_neutral=0, tap_min=-2, tap_max=2, tap_step_percent=2.5, tap_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_mva=40, sn_mv_mva=15, sn_lv_mva=25, vk_hv_percent=10.1, vk_mv_percent=10.1, vk_lv_percent=10.1, vkr_hv_percent=0.266667, vkr_mv_percent=0.033333, vkr_lv_percent=0.04, pfe_kw=0, i0_percent=0, shift_mv_degree=30, shift_lv_degree=30, tap_side="hv", tap_neutral=0, tap_min=-8, tap_max=8, tap_step_percent=1.25, tap_pos=0, name='HV-MV-MV-Trafo') # --- Static generators # HV pp.create_sgen(net, pp.get_element_index(net, "bus", 'Bus SB 5'), p_mw=20, q_mvar=4, sn_mva=45, 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'] = [0.5, 0.5, 15, 2] mv_sgens['q'] = [0, 0.05, 3, 0.1] mv_sgens['sn'] = [0.75, 1, 20, 5] 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_mw=sgen.p, q_mvar=sgen.q, sn_mva=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'] = [0.006, 0.005, 0.005, 0.005, 0.005, 0.005] lv_sgens['q'] = 0 lv_sgens['sn'] = [0.012, 0.01, 0.01, 0.01, 0.01, 0.01] 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_mw=sgen.p, q_mvar=sgen.q, sn_mva=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'] = 38 hv_loads['q'] = 6 for _, load in hv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=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'] = [6, 18, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4] mv_loads['q'] = [2, 4, 0.1, 0.06, 0.06, 0.06, 0.06, 0.06] for _, load in mv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=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'] = [0.1] + [0.01] * 11 lv_loads['q'] = [0.01] + [0.03] * 11 for _, load in lv_loads.iterrows(): bus_idx = pp.get_element_index(net, "bus", load.bus) pp.create_load(net, bus_idx, p_mw=load.p, q_mvar=load.q, name=load.load_name) # --- Other # Shunt pp.create_shunt(net, pp.get_element_index(net, "bus", 'Bus HV1'), p_mw=0, q_mvar=-0.96, 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_mw=100, 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_mva=100, name='Impedance') # xwards pp.create_xward(net, pp.get_element_index(net, "bus", 'Bus HV3'), ps_mw=23.942, qs_mvar=-12.24187, pz_mw=2.814571, qz_mvar=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_mw=3.776, qs_mvar=-7.769979, pz_mw=9.174917, qz_mvar=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
def from_ppc(ppc, f_hz=50, validate_conversion=False, **kwargs): """ This function converts pypower case files to pandapower net structure. INPUT: **ppc** : The pypower case file. OPTIONAL: **f_hz** (float, 50) - The frequency of the network. **validate_conversion** (bool, False) - If True, validate_from_ppc is run after conversion. For running the validation, the ppc must already contain the pypower powerflow results or pypower must be importable. ****kwargs** keyword arguments for validate_from_ppc if validate_conversion is True OUTPUT: **net** : pandapower net. EXAMPLE: import pandapower.converter as pc from pypower import case4gs ppc_net = case4gs.case4gs() net = pc.from_ppc(ppc_net, f_hz=60) """ # --- catch common failures if Series(ppc['bus'][:, BASE_KV] <= 0).any(): logger.info('There are false baseKV given in the pypower case file.') # --- general_parameters baseMVA = ppc['baseMVA'] # MVA omega = pi * f_hz # 1/s MAX_VAL = 99999. net = pp.create_empty_network(f_hz=f_hz, sn_mva=baseMVA) # --- bus data -> create buses, sgen, load, shunt for i in range(len(ppc['bus'])): # create buses pp.create_bus(net, name=int(ppc['bus'][i, 0]), vn_kv=ppc['bus'][i, 9], type="b", zone=ppc['bus'][i, 6], in_service=bool(ppc['bus'][i, 1] != 4), max_vm_pu=ppc['bus'][i, 11], min_vm_pu=ppc['bus'][i, 12]) # create sgen, load if ppc['bus'][i, 2] > 0: pp.create_load(net, i, p_mw=ppc['bus'][i, 2], q_mvar=ppc['bus'][i, 3], controllable=False) elif ppc['bus'][i, 2] < 0: pp.create_sgen(net, i, p_mw=-ppc['bus'][i, 2], q_mvar=-ppc['bus'][i, 3], type="", controllable=False) elif ppc['bus'][i, 3] != 0: pp.create_load(net, i, p_mw=ppc['bus'][i, 2], q_mvar=ppc['bus'][i, 3], controllable=False) # create shunt if ppc['bus'][i, 4] != 0 or ppc['bus'][i, 5] != 0: pp.create_shunt(net, i, p_mw=ppc['bus'][i, 4], q_mvar=-ppc['bus'][i, 5]) # unused data of ppc: Vm, Va (partwise: in ext_grid), zone # --- gen data -> create ext_grid, gen, sgen gen_lookup = DataFrame(nan, columns=['element', 'element_type'], index=range(len(ppc['gen'][:, 0]))) # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array if len(ppc["gen"].shape) == 1: ppc["gen"] = array(ppc["gen"], ndmin=2) for i in range(len(ppc['gen'][:, 0])): 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, i) # create ext_grid if current_bus_type == 3: if i == first_same_bus_in_service_gen_idx: gen_lookup.element.loc[i] = pp.create_ext_grid( net, bus=current_bus_idx, vm_pu=ppc['gen'][last_same_bus_in_service_gen_idx, 5], va_degree=ppc['bus'][current_bus_idx, 8], in_service=bool(ppc['gen'][i, 7] > 0), max_p_mw=ppc['gen'][i, PMAX], min_p_mw=ppc['gen'][i, PMIN], max_q_mvar=ppc['gen'][i, QMAX], min_q_mvar=ppc['gen'][i, QMIN]) gen_lookup.element_type.loc[i] = 'ext_grid' if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_mvar of gen %d must be less than max_q_mvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_mw of gen %d must be less than min_p_mw but is not.' % i) else: current_bus_type = 1 # create gen elif current_bus_type == 2: if i == first_same_bus_in_service_gen_idx: gen_lookup.element.loc[i] = pp.create_gen( net, bus=current_bus_idx, vm_pu=ppc['gen'][last_same_bus_in_service_gen_idx, 5], p_mw=ppc['gen'][i, 1], in_service=bool(ppc['gen'][i, 7] > 0), controllable=True, max_p_mw=ppc['gen'][i, PMAX], min_p_mw=ppc['gen'][i, PMIN], max_q_mvar=ppc['gen'][i, QMAX], min_q_mvar=ppc['gen'][i, QMIN]) gen_lookup.element_type.loc[i] = 'gen' if ppc['gen'][i, 1] < 0: logger.info( 'p_mw of gen %d must be less than zero but is not.' % i) if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_mvar of gen %d must be less than max_q_mvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_mw of gen %d must be less than min_p_mw but is not.' % i) else: current_bus_type = 1 # create sgen if current_bus_type == 1: gen_lookup.element.loc[i] = pp.create_sgen( net, bus=current_bus_idx, p_mw=ppc['gen'][i, 1], q_mvar=ppc['gen'][i, 2], type="", in_service=bool(ppc['gen'][i, 7] > 0), max_p_mw=ppc['gen'][i, PMAX], min_p_mw=ppc['gen'][i, PMIN], max_q_mvar=ppc['gen'][i, QMAX], min_q_mvar=ppc['gen'][i, QMIN], controllable=True) gen_lookup.element_type.loc[i] = 'sgen' if ppc['gen'][i, 1] < 0: logger.info( 'p_mw of sgen %d must be less than zero but is not.' % i) if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_mvar of gen %d must be less than max_q_mvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_mw of gen %d must be less than min_p_mw but is not.' % i) # unused data of ppc: Vg (partwise: in ext_grid and gen), mBase, Pc1, Pc2, Qc1min, Qc1max, # Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30,ramp_q, apf # --- branch data -> create line, trafo for i in range(len(ppc['branch'])): from_bus = pp.get_element_index(net, 'bus', name=int(ppc['branch'][i, 0])) to_bus = pp.get_element_index(net, 'bus', name=int(ppc['branch'][i, 1])) from_vn_kv = ppc['bus'][from_bus, 9] to_vn_kv = ppc['bus'][to_bus, 9] if (from_vn_kv == to_vn_kv) & ((ppc['branch'][i, 8] == 0) | (ppc['branch'][i, 8] == 1)) & \ (ppc['branch'][i, 9] == 0): # create line Zni = ppc['bus'][to_bus, 9]**2 / baseMVA # ohm max_i_ka = ppc['branch'][i, 5] / ppc['bus'][to_bus, 9] / sqrt(3) if max_i_ka == 0.0: max_i_ka = MAX_VAL logger.debug( "ppc branch rateA is zero -> Using MAX_VAL instead to calculate " + "maximum branch flow") pp.create_line_from_parameters( net, from_bus=from_bus, to_bus=to_bus, length_km=1, r_ohm_per_km=ppc['branch'][i, 2] * Zni, x_ohm_per_km=ppc['branch'][i, 3] * Zni, c_nf_per_km=ppc['branch'][i, 4] / Zni / omega * 1e9 / 2, max_i_ka=max_i_ka, type='ol', max_loading_percent=100, in_service=bool(ppc['branch'][i, 10])) else: # create transformer if from_vn_kv >= to_vn_kv: hv_bus = from_bus vn_hv_kv = from_vn_kv lv_bus = to_bus vn_lv_kv = to_vn_kv tap_side = 'hv' else: hv_bus = to_bus vn_hv_kv = to_vn_kv lv_bus = from_bus vn_lv_kv = from_vn_kv tap_side = 'lv' if from_vn_kv == to_vn_kv: logger.warning( 'The pypower branch %d (from_bus, to_bus)=(%d, %d) is considered' ' as a transformer because of a ratio != 0 | 1 but it connects ' 'the same voltage level', i, ppc['branch'][i, 0], ppc['branch'][i, 1]) rk = ppc['branch'][i, 2] xk = ppc['branch'][i, 3] zk = (rk**2 + xk**2)**0.5 sn = ppc['branch'][i, 5] if sn == 0.0: sn = MAX_VAL logger.debug( "ppc branch rateA is zero -> Using MAX_VAL instead to calculate " + "apparent power") ratio_1 = 0 if ppc['branch'][i, 8] == 0 else (ppc['branch'][i, 8] - 1) * 100 i0_percent = -ppc['branch'][i, 4] * 100 * baseMVA / sn if i0_percent < 0: logger.info( 'A transformer always behaves inductive consumpting but the ' 'susceptance of pypower branch %d (from_bus, to_bus)=(%d, %d) is ' 'positive.', i, ppc['branch'][i, 0], ppc['branch'][i, 1]) pp.create_transformer_from_parameters( net, hv_bus=hv_bus, lv_bus=lv_bus, sn_mva=sn, vn_hv_kv=vn_hv_kv, vn_lv_kv=vn_lv_kv, vk_percent=sign(xk) * zk * sn * 100 / baseMVA, vkr_percent=rk * sn * 100 / baseMVA, max_loading_percent=100, pfe_kw=0, i0_percent=i0_percent, shift_degree=ppc['branch'][i, 9], tap_step_percent=abs(ratio_1) if ratio_1 else nan, tap_pos=sign(ratio_1) if ratio_1 else nan, tap_side=tap_side if ratio_1 else None, tap_neutral=0 if ratio_1 else nan) # unused data of ppc: rateB, rateC # --- gencost -> create polynomial_cost, piecewise_cost if 'gencost' in ppc: if len(ppc['gencost'].shape) == 1: # reshape gencost if only one gencost is given -> no indexError ppc['gencost'] = ppc['gencost'].reshape((1, -1)) if ppc['gencost'].shape[0] <= gen_lookup.shape[0]: idx_p = range(ppc['gencost'].shape[0]) idx_q = [] elif ppc['gencost'].shape[0] > gen_lookup.shape[0]: idx_p = range(gen_lookup.shape[0]) idx_q = range(gen_lookup.shape[0], ppc['gencost'].shape[0]) if ppc['gencost'].shape[0] >= 2 * gen_lookup.shape[0]: idx_p = range(gen_lookup.shape[0]) idx_q = range(gen_lookup.shape[0], 2 * gen_lookup.shape[0]) for idx in idx_p: _create_costs(net, ppc, gen_lookup, 'p', idx) for idx in idx_q: _create_costs(net, ppc, gen_lookup, 'q', idx) # areas are unconverted if validate_conversion: logger.setLevel(logging.DEBUG) if not validate_from_ppc(ppc, net, **kwargs): logger.error("Validation failed.") return net
def from_ppc(ppc, f_hz=50, validate_conversion=False): """ This function converts pypower case files to pandapower net structure. INPUT: **ppc** : The pypower case file. OPTIONAL: **f_hz** (float, 50) - The frequency of the network. **validate_conversion** (bool, False) - If True, validate_from_ppc is run after conversion. OUTPUT: **net** : pandapower net. EXAMPLE: import pandapower.converter as pc from pypower import case4gs ppc_net = case4gs.case4gs() pp_net = cv.from_ppc(ppc_net, f_hz=60) """ # --- catch common failures if Series(ppc['bus'][:, 9] <= 0).any(): logger.info('There are false baseKV given in the pypower case file.') # --- general_parameters baseMVA = ppc['baseMVA'] # MVA omega = pi * f_hz # 1/s MAX_VAL = 99999. net = pp.create_empty_network(f_hz=f_hz) # --- bus data -> create buses, sgen, load, shunt for i in range(len(ppc['bus'])): # create buses pp.create_bus(net, name=int(ppc['bus'][i, 0]), vn_kv=ppc['bus'][i, 9], type="b", zone=ppc['bus'][i, 6], in_service=bool(ppc['bus'][i, 1] != 4), max_vm_pu=ppc['bus'][i, 11], min_vm_pu=ppc['bus'][i, 12]) # create sgen, load if ppc['bus'][i, 2] > 0: pp.create_load(net, i, p_kw=ppc['bus'][i, 2] * 1e3, q_kvar=ppc['bus'][i, 3] * 1e3) elif ppc['bus'][i, 2] < 0: pp.create_sgen(net, i, p_kw=ppc['bus'][i, 2] * 1e3, q_kvar=ppc['bus'][i, 3] * 1e3, type="") elif ppc['bus'][i, 3] != 0: pp.create_load(net, i, p_kw=ppc['bus'][i, 2] * 1e3, q_kvar=ppc['bus'][i, 3] * 1e3) # create shunt if ppc['bus'][i, 4] != 0 or ppc['bus'][i, 5] != 0: pp.create_shunt(net, i, p_kw=ppc['bus'][i, 4] * 1e3, q_kvar=-ppc['bus'][i, 5] * 1e3) # unused data of ppc: Vm, Va (partwise: in ext_grid), zone # --- gen data -> create ext_grid, gen, sgen for i in range(len(ppc['gen'])): # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array if len(ppc["gen"].shape) == 1: ppc["gen"] = array(ppc["gen"], ndmin=2) current_bus_idx = pp.get_element_index(net, 'bus', name=int(ppc['gen'][i, 0])) current_bus_type = int(ppc['bus'][current_bus_idx, 1]) # create ext_grid if current_bus_type == 3: if len(pp.get_connected_elements(net, 'ext_grid', current_bus_idx)) > 0: logger.info('At bus %d an ext_grid already exists. ' % current_bus_idx + 'Because of that generator %d ' % i + 'is converted not as an ext_grid but as a sgen') current_bus_type = 1 else: pp.create_ext_grid(net, bus=current_bus_idx, vm_pu=ppc['gen'][i, 5], va_degree=ppc['bus'][current_bus_idx, 8], in_service=bool(ppc['gen'][i, 7] > 0), max_p_kw=-ppc['gen'][i, 9] * 1e3, min_p_kw=-ppc['gen'][i, 8] * 1e3, max_q_kvar=ppc['gen'][i, 3] * 1e3, min_q_kvar=ppc['gen'][i, 4] * 1e3) if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_kvar of gen %d must be less than max_q_kvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_kw of gen %d must be less than min_p_kw but is not.' % i) # create gen elif current_bus_type == 2: pp.create_gen(net, bus=current_bus_idx, vm_pu=ppc['gen'][i, 5], p_kw=-ppc['gen'][i, 1] * 1e3, in_service=bool(ppc['gen'][i, 7] > 0), max_p_kw=-ppc['gen'][i, 9] * 1e3, min_p_kw=-ppc['gen'][i, 8] * 1e3, max_q_kvar=ppc['gen'][i, 3] * 1e3, min_q_kvar=ppc['gen'][i, 4] * 1e3, controllable=True) if ppc['gen'][i, 1] < 0: logger.info( 'p_kw of gen %d must be less than zero but is not.' % i) if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_kvar of gen %d must be less than max_q_kvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_kw of gen %d must be less than min_p_kw but is not.' % i) # create sgen if current_bus_type == 1: pp.create_sgen(net, bus=current_bus_idx, p_kw=-ppc['gen'][i, 1] * 1e3, q_kvar=-ppc['gen'][i, 2] * 1e3, type="", in_service=bool(ppc['gen'][i, 7] > 0), max_p_kw=-ppc['gen'][i, 9] * 1e3, min_p_kw=-ppc['gen'][i, 8] * 1e3, max_q_kvar=ppc['gen'][i, 3] * 1e3, min_q_kvar=ppc['gen'][i, 4] * 1e3, controllable=True) if ppc['gen'][i, 1] < 0: logger.info( 'p_kw of sgen %d must be less than zero but is not.' % i) if ppc['gen'][i, 4] > ppc['gen'][i, 3]: logger.info( 'min_q_kvar of gen %d must be less than max_q_kvar but is not.' % i) if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]: logger.info( 'max_p_kw of gen %d must be less than min_p_kw but is not.' % i) # unused data of ppc: Vg (partwise: in ext_grid and gen), mBase, Pc1, Pc2, Qc1min, Qc1max, # Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30,ramp_q, apf # --- branch data -> create line, trafo for i in range(len(ppc['branch'])): from_bus = pp.get_element_index(net, 'bus', name=int(ppc['branch'][i, 0])) to_bus = pp.get_element_index(net, 'bus', name=int(ppc['branch'][i, 1])) from_vn_kv = ppc['bus'][from_bus, 9] to_vn_kv = ppc['bus'][to_bus, 9] if (from_vn_kv == to_vn_kv) & ((ppc['branch'][i, 8] == 0) | (ppc['branch'][i, 8] == 1)) & \ (ppc['branch'][i, 9] == 0): Zni = ppc['bus'][to_bus, 9]**2 / baseMVA # ohm max_i_ka = ppc['branch'][i, 5] / ppc['bus'][to_bus, 9] if max_i_ka == 0.0: max_i_ka = MAX_VAL logger.debug( "ppc branch rateA is zero -> Using MAX_VAL instead to calculate " + "maximum branch flow") pp.create_line_from_parameters( net, from_bus=from_bus, to_bus=to_bus, length_km=1, r_ohm_per_km=ppc['branch'][i, 2] * Zni, x_ohm_per_km=ppc['branch'][i, 3] * Zni, c_nf_per_km=ppc['branch'][i, 4] / Zni / omega * 1e9 / 2, max_i_ka=max_i_ka, type='ol', in_service=bool(ppc['branch'][i, 10])) else: if from_vn_kv >= to_vn_kv: hv_bus = from_bus vn_hv_kv = from_vn_kv lv_bus = to_bus vn_lv_kv = to_vn_kv tp_side = 'hv' else: hv_bus = to_bus vn_hv_kv = to_vn_kv lv_bus = from_bus vn_lv_kv = from_vn_kv tp_side = 'lv' if from_vn_kv == to_vn_kv: logger.warning( 'The pypower branch %d (from_bus, to_bus)=(%d, %d) is considered' ' as a transformer because of a ratio != 0 | 1 but it connects ' 'the same voltage level', i, ppc['branch'][i, 0], ppc['branch'][i, 1]) rk = ppc['branch'][i, 2] xk = ppc['branch'][i, 3] zk = (rk**2 + xk**2)**0.5 sn = ppc['branch'][i, 5] * 1e3 if sn == 0.0: sn = MAX_VAL logger.debug( "ppc branch rateA is zero -> Using MAX_VAL instead to calculate " + "apparent power") ratio_1 = 0 if ppc['branch'][i, 8] == 0 else (ppc['branch'][i, 8] - 1) * 100 i0_percent = -ppc['branch'][i, 4] * 100 * baseMVA * 1e3 / sn if i0_percent < 0: logger.info( 'A transformer always behaves inductive consumpting but the ' 'susceptance of pypower branch %d (from_bus, to_bus)=(%d, %d) is ' 'positive.', i, ppc['branch'][i, 0], ppc['branch'][i, 1]) pp.create_transformer_from_parameters( net, hv_bus=hv_bus, lv_bus=lv_bus, sn_kva=sn, vn_hv_kv=vn_hv_kv, vn_lv_kv=vn_lv_kv, vsc_percent=sign(xk) * zk * sn / 1e3, vscr_percent=rk * sn / 1e3, pfe_kw=0, i0_percent=i0_percent, shift_degree=ppc['branch'][i, 9], tp_st_percent=abs(ratio_1) if ratio_1 else nan, tp_pos=sign(ratio_1) if ratio_1 else nan, tp_side=tp_side if ratio_1 else None, tp_mid=0 if ratio_1 else nan) # unused data of ppc: rateB, rateC # gencost and areas are currently unconverted if validate_conversion: logger.setLevel(logging.DEBUG) if not validate_from_ppc(ppc, net): logger.error("Validation failed.") return net
def add_test_single_load_single_eg(net): b1 = pp.create_bus(net, vn_kv=20., zone="test_single_load_single_eg") pp.create_ext_grid(net, b1) pp.create_load(net, b1, p_kw=100, q_kvar=100) net.last_added_case = "test_single_load_single_eg" return net
def add_load_device(self, area, avg_power_w): return pp.create_load(self.network, bus=area.parent.bus, p_mw=convert_unit_to_mega(avg_power_w), name=area.name)
def test_cost_mixed(): """ Testing a very simple network for the resulting cost value constraints with OPF """ vm_max = 1.05 vm_min = 0.95 # create net net = pp.create_empty_network() pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) pp.create_gen(net, 1, p_mw=-0.1, controllable=True, min_p_mw=0.005, max_p_mw=0.15, max_q_mvar=.05, min_q_mvar=-.05) pp.create_ext_grid(net, 0) pp.create_load(net, 1, p_mw=0.02, controllable=False, max_q_mvar=.05, max_p_mw=0.1, min_p_mw=0.0050, min_q_mvar=-.05) pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, max_loading_percent=100 * 690) # testing some combinations pp.create_poly_cost(net, 0, "gen", cp1_eur_per_mw=1) pp.runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values[0]) net.poly_cost.cp1_eur_per_mw.at[0] = 0 net.poly_cost.cp2_eur_per_mw2.at[0] = 1 pp.runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2) net.poly_cost.cp0_eur.at[0] = 1 pp.runopp(net) assert net["OPF_converged"] assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2 + 1) net.load.controllable.at[0] = True pp.runopp(net) assert np.isclose(net.res_cost, net.res_gen.p_mw.values**2 + 1) net.load.controllable.at[0] = False net.pwl_cost.drop(net.pwl_cost.index, inplace=True) pp.create_pwl_cost(net, 0, "ext_grid", [[-1000, 0, -2000], [0, 1000, 2000]], power_type="p") net.poly_cost.cp1_eur_per_mw.at[0] = 1000 net.poly_cost.cp2_eur_per_mw2.at[0] = 0 pp.runopp(net) assert np.isclose(net.res_ext_grid.p_mw.values[0], 0, atol=1e-4) assert np.isclose(net.res_cost, net.res_gen.p_mw.values[0] * 1000, atol=1e-3)
import pandapower as pp net = pp.create_empty_network("mini") pp.create_buses(net, 3, 20, index=[0, 1, 2]) pp.create_line(net, 0, 1, 0.01, std_type="NAYY 4x50 SE") pp.create_line(net, 1, 2, 0.01, std_type="NAYY 4x50 SE") pp.create_line(net, 2, 0, 0.01, std_type="NAYY 4x50 SE") pp.create_load(net, bus=0, p_mw=100, q_mvar=100) pp.create_gen(net, bus=1, p_mw=-100, slack=True) #pp.runpp(net) net.res_bus
def create_synthetic_voltage_control_lv_network(network_class="rural_1"): """ This function creates a LV network from M. Lindner, C. Aigner, R. Witzmann, F. Wirtz, \ I. Berber, M. Gödde and R. Frings. "Aktuelle Musternetze zur Untersuchung von \ Spannungsproblemen in der Niederspannung". 14. Symposium Energieinnovation TU Graz. 2014 which are representative, synthetic grids for voltage control analysis. Neccessary assumptions, in addition to the paper above: According to Lindner, the household loads are 5.1 kw and the special loads are 7.9 kW. \ The user is suggested to assume load distribution and load profile generation. The line parameters according to the given types are received from pandapower standard types and literatur (as stated in the code). Transformer parameters, except the given 'vk_percent', 'sn_mva' and voltage levels, are based the pandapower standard type data. OPTIONAL: **network_class** (str, 'rural_1') - specify which type of network will be created. Must \ be in ['rural_1', 'rural_2', 'village_1', 'village_2', 'suburb_1']. OUTPUT: **net** - returns the required synthetic voltage control lv network EXAMPLE: import pandapower.networks as pn net = pn.create_synthetic_voltage_control_lv_network() """ # process network choosing input data if network_class not in [ 'rural_1', 'rural_2', 'village_1', 'village_2', 'suburb_1' ]: raise ValueError( "network_class is not in ['rural_1', 'rural_2', 'village_1', 'village_2'," " 'suburb_1']") n_feeder = { 'rural_1': [1, 4, 7], 'rural_2': [1, 3, 3, 1], 'village_1': [9, 16, 5, 9], 'village_2': [9, 12, 5, 10], 'suburb_1': [9, 17, 5, 13, 8, 1, 9, 17, 5, 13, 4] } l_lines = { 'rural_1': [0.26, 0.133, 0.068], 'rural_2': [3e-3, 0.076, 0.076, 0.076], 'village_1': [0.053, 0.034, 0.08, 0.04], 'village_2': [0.021, 0.033, 0.023, 0.052], 'suburb_1': [ 0.041, 0.017, 0.056, 0.018, 0.035, 0.103, 0.046, 0.019, 0.065, 0.026, 0.031 ] } line_types = { 'rural_1': ['NAYY 4x150 SE'] * 2 + [('NAYY 4x150 SE', 'NAYY 4x120 SE')], 'rural_2': ['NAYY 4x35'] + ['NF 4x70'] * 3, 'village_1': ['NAYY 4x150 SE'] * 4, 'village_2': [('NAYY 4x70', 'NF 4x50'), ('NAYY 4x120 SE', 'NF 4x95'), ('NAYY 4x95', 'NF 4x70'), ('NAYY 4x150 SE', 'NF 4x120')], 'suburb_1': [('NAYY 4x150 SE', 'NAYY 4x120 SE')] * 3 + [('NAYY 4x120 SE', 'NAYY 4x95'), 'NAYY 4x150 SE', 'NAYY 4x95'] + ['NAYY 4x150 SE'] * 5 } line_type_change_at = { 'rural_1': [nan] * 2 + [5], 'rural_2': [nan] * 4, 'village_1': [nan] * 4, 'village_2': [8, 3, 4, 5], 'suburb_1': [5, 10, 3, 6] + [nan] * 7 } trafo_type = { 'rural_1': '0.16 MVA 20/0.4 kV vc', 'rural_2': '0.25 MVA 20/0.4 kV vc', 'village_1': '0.25 MVA 20/0.4 kV vc', 'village_2': '0.4 MVA 20/0.4 kV vc', 'suburb_1': '0.4 MVA 20/0.4 kV vc' } house_connection_length = { 'rural_1': 29e-3, 'rural_2': 4e-3, 'village_1': 21e-3, 'village_2': 17e-3, 'suburb_1': 18e-3 } house_connection_type = { 'rural_1': 'NAYY 4x50 SE', 'rural_2': 'NAYY 4x35', 'village_1': 'NAYY 4x50 SE', 'village_2': 'NAYY 4x35', 'suburb_1': 'NAYY 4x35' } # create network net = pp.create_empty_network( name='synthetic_voltage_control_lv_network: ' + network_class) # create std_types # cable data (r, x, i_max) from www.faberkabel.de if network_class in ["rural_2", "village_2", "suburb_1"]: pp.create_std_type(net, { "c_nf_per_km": 202, "r_ohm_per_km": 0.869, "x_ohm_per_km": 0.085, "max_i_ka": 0.123, "type": "cs", "q_mm2": 35 }, name="NAYY 4x35", element="line") if network_class != "suburb_1": pp.create_std_type(net, { "c_nf_per_km": 17.8, "r_ohm_per_km": 0.439, "x_ohm_per_km": 0.295, "max_i_ka": 0.28, "type": "ol", "q_mm2": 70 }, name="NF 4x70", element="line") if network_class == "village_2": pp.create_std_type(net, { "c_nf_per_km": 230, "r_ohm_per_km": 0.443, "x_ohm_per_km": 0.0823, "max_i_ka": 0.179, "type": "cs", "q_mm2": 70 }, name="NAYY 4x70", element="line") data = net.std_types['line']['48-AL1/8-ST1A 0.4'] data['q_mm2'] = 50 pp.create_std_type(net, data, name="NF 4x50", element="line") data = net.std_types['line']['94-AL1/15-ST1A 0.4'] data['q_mm2'] = 95 pp.create_std_type(net, data, name="NF 4x95", element="line") pp.create_std_type(net, { "c_nf_per_km": 16.2, "r_ohm_per_km": 0.274, "x_ohm_per_km": 0.31, "max_i_ka": 0.4, "type": "ol", "q_mm2": 120 }, name="NF 4x120", element="line") if network_class != "rural_2": pp.create_std_type(net, { "c_nf_per_km": 240, "r_ohm_per_km": 0.32, "x_ohm_per_km": 0.082, "max_i_ka": 0.215, "type": "cs", "q_mm2": 95 }, name="NAYY 4x95", element="line") # trafos if network_class == "rural_1": data = net.std_types['trafo']['0.25 MVA 20/0.4 kV'] data['sn_mva'] = 0.16 data['pfe_kw'] = 0.62 data['i0_percent'] = 0.31 data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") elif network_class in ["rural_2", "village_1"]: data = net.std_types['trafo']['0.25 MVA 20/0.4 kV'] data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") elif network_class in ["suburb_1", "village_2"]: data = net.std_types['trafo']['0.4 MVA 20/0.4 kV'] data['vkr_percent'] = data['vkr_percent'] * 4 / data['vk_percent'] data['vk_percent'] = 4 pp.create_std_type(net, data, name=trafo_type[network_class], element="trafo") # create mv connection mv_bus = pp.create_bus(net, 20, name='mv bus') bb = pp.create_bus(net, 0.4, name='busbar') pp.create_ext_grid(net, mv_bus) pp.create_transformer(net, mv_bus, bb, std_type=trafo_type[network_class]) # create lv network idx_feeder = range(len(n_feeder[network_class])) lv_buses = {} house_buses = {} for i in idx_feeder: # buses lv_buses[i] = pp.create_buses(net, n_feeder[network_class][i], 0.4, zone='Feeder' + str(i + 1), type='m') house_buses[i] = pp.create_buses(net, n_feeder[network_class][i], 0.4, zone='Feeder' + str(i + 1), type='n') # lines lines = pd.DataFrame() lines['from_bus'] = append(bb, append(lv_buses[i][:-1], lv_buses[i])) lines['to_bus'] = append(lv_buses[i], house_buses[i]) if line_type_change_at[network_class][i] is nan: lines['std_type'] = [line_types[network_class][i]]*n_feeder[network_class][i] + \ [house_connection_type[network_class]]*n_feeder[network_class][i] else: lines['std_type'] = \ [line_types[network_class][i][0]]*line_type_change_at[network_class][i] + \ [line_types[network_class][i][1]]*(n_feeder[network_class][i] - line_type_change_at[network_class][i]) + \ [house_connection_type[network_class]]*n_feeder[network_class][i] lines['length'] = [l_lines[network_class][i]]*n_feeder[network_class][i] + \ [house_connection_length[network_class]]*n_feeder[network_class][i] for _, lines in lines.iterrows(): pp.create_line(net, lines.from_bus, lines.to_bus, length_km=lines.length, std_type=lines.std_type) # load for i in house_buses[i]: pp.create_load(net, i, p_mw=5.1e-3) # direct loads and DEA if network_class == "rural_1": special_load = [(2, 4), (3, 2)] DER = [(2, 1, 6.9), (2, 2, 15.3), (2, 4, 29.6), (3, 4, 15.8), (3, 5, 25.3)] elif network_class == "rural_2": special_load = [(1, 1), (2, 3), (3, 2)] DER = [(1, 1, 29.6), (2, 3, 25.4), (3, 2, 25), (3, 3, 10)] elif network_class == "village_1": special_load = [(2, 9), (2, 12), (2, 14), (2, 16), (3, 5), (4, 3), (4, 6), (4, 8)] DER = [(1, 6, 29.8), (1, 8, 22.8), (2, 3, 7.9), (2, 5, 4.2), (2, 11, 16.7), (2, 15, 7.3), (3, 1, 31.9), (3, 3, 17.4), (3, 5, 15), (4, 1, 8.8), (4, 3, 19.6), (4, 5, 9.3), (4, 6, 13)] elif network_class == "village_2": special_load = [] DER = [(1, 6, 29.8), (1, 2, 16), (1, 3, 4.6), (1, 6, 19), (1, 8, 29), (2, 1, 16), (2, 2, 5.2), (2, 3, 19), (2, 5, 12), (2, 10, 10), (2, 12, 8), (3, 1, 12.63), (3, 2, 30), (4, 3, 10), (4, 4, 33), (4, 10, 8)] elif network_class == "suburb_1": special_load = [(6, 1), (1, 4), (2, 17), (3, 5), (4, 5), (6, 1), (7, 7), (8, 17)] DER = [(1, 1, 9.36), (1, 2, 79.12), (7, 7, 30), (8, 7, 18.47), (8, 15, 9.54), (10, 10, 14.4)] for i in special_load: pp.create_load(net, lv_buses[i[0] - 1][i[1] - 1], p_mw=7.9e-3) for i in DER: pp.create_sgen(net, house_buses[i[0] - 1][i[1] - 1], p_mw=i[2] * 1e-3) # set bus geo data bus_geo = { "rural_1": '{"x":{"0":0.0,"1":0.0,"2":-1.6666666667,"3":-1.6666666667,"4":-0.1666666667,"5":-0.6666666667,"6":-1.1666666667,"7":-1.6666666667,"8":0.3333333333,"9":-0.1666666667,"10":-0.6666666667,"11":-1.6666666667,"12":1.8333333333,"13":1.3333333333,"14":0.8333333333,"15":0.3333333333,"16":-0.1666666667,"17":-0.6666666667,"18":-1.1666666667,"19":2.3333333333,"20":1.8333333333,"21":1.3333333333,"22":0.8333333333,"23":0.3333333333,"24":-0.1666666667,"25":-1.1666666667},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":2.0,"5":3.0,"6":4.0,"7":5.0,"8":3.0,"9":4.0,"10":5.0,"11":6.0,"12":2.0,"13":3.0,"14":4.0,"15":5.0,"16":6.0,"17":7.0,"18":8.0,"19":3.0,"20":4.0,"21":5.0,"22":6.0,"23":7.0,"24":8.0,"25":9.0}}', "rural_2": '{"x":{"0":0.0,"1":0.0,"2":-2.5,"3":-2.5,"4":-1.0,"5":-1.5,"6":-2.0,"7":-0.5,"8":-1.0,"9":-2.0,"10":1.0,"11":0.5,"12":0.0,"13":1.5,"14":1.0,"15":0.0,"16":2.5,"17":2.5},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":2.0,"5":3.0,"6":4.0,"7":3.0,"8":4.0,"9":5.0,"10":2.0,"11":3.0,"12":4.0,"13":3.0,"14":4.0,"15":5.0,"16":2.0,"17":3.0}}', "village_1": '{"x":{"0":0.0,"1":0.0,"2":-3.0,"3":-3.5,"4":-4.0,"5":-4.5,"6":-5.0,"7":-5.5,"8":-6.0,"9":-6.5,"10":-7.0,"11":-2.5,"12":-3.0,"13":-3.5,"14":-4.0,"15":-4.5,"16":-5.0,"17":-5.5,"18":-6.0,"19":-7.0,"20":-1.0,"21":-1.5,"22":-2.0,"23":-2.5,"24":-3.0,"25":-3.5,"26":-4.0,"27":-4.5,"28":-5.0,"29":-5.5,"30":-6.0,"31":-6.5,"32":-7.0,"33":-7.5,"34":-8.0,"35":-8.5,"36":-0.5,"37":-1.0,"38":-1.5,"39":-2.0,"40":-2.5,"41":-3.0,"42":-3.5,"43":-4.0,"44":-4.5,"45":-5.0,"46":-5.5,"47":-6.0,"48":-6.5,"49":-7.0,"50":-7.5,"51":-8.5,"52":1.0,"53":0.5,"54":0.0,"55":-0.5,"56":-1.0,"57":1.5,"58":1.0,"59":0.5,"60":0.0,"61":-1.0,"62":3.0,"63":2.5,"64":2.0,"65":1.5,"66":1.0,"67":0.5,"68":0.0,"69":-0.5,"70":-1.0,"71":3.5,"72":3.0,"73":2.5,"74":2.0,"75":1.5,"76":1.0,"77":0.5,"78":0.0,"79":-1.0},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":14.0,"33":15.0,"34":16.0,"35":17.0,"36":3.0,"37":4.0,"38":5.0,"39":6.0,"40":7.0,"41":8.0,"42":9.0,"43":10.0,"44":11.0,"45":12.0,"46":13.0,"47":14.0,"48":15.0,"49":16.0,"50":17.0,"51":18.0,"52":2.0,"53":3.0,"54":4.0,"55":5.0,"56":6.0,"57":3.0,"58":4.0,"59":5.0,"60":6.0,"61":7.0,"62":2.0,"63":3.0,"64":4.0,"65":5.0,"66":6.0,"67":7.0,"68":8.0,"69":9.0,"70":10.0,"71":3.0,"72":4.0,"73":5.0,"74":6.0,"75":7.0,"76":8.0,"77":9.0,"78":10.0,"79":11.0}}', "village_2": '{"x":{"0":0.0,"1":0.0,"2":-3.0,"3":-3.5,"4":-4.0,"5":-4.5,"6":-5.0,"7":-5.5,"8":-6.0,"9":-6.5,"10":-7.0,"11":-2.5,"12":-3.0,"13":-3.5,"14":-4.0,"15":-4.5,"16":-5.0,"17":-5.5,"18":-6.0,"19":-7.0,"20":-1.0,"21":-1.5,"22":-2.0,"23":-2.5,"24":-3.0,"25":-3.5,"26":-4.0,"27":-4.5,"28":-5.0,"29":-5.5,"30":-6.0,"31":-6.5,"32":-0.5,"33":-1.0,"34":-1.5,"35":-2.0,"36":-2.5,"37":-3.0,"38":-3.5,"39":-4.0,"40":-4.5,"41":-5.0,"42":-5.5,"43":-6.5,"44":1.0,"45":0.5,"46":0.0,"47":-0.5,"48":-1.0,"49":1.5,"50":1.0,"51":0.5,"52":0.0,"53":-1.0,"54":3.0,"55":2.5,"56":2.0,"57":1.5,"58":1.0,"59":0.5,"60":0.0,"61":-0.5,"62":-1.0,"63":-1.5,"64":3.5,"65":3.0,"66":2.5,"67":2.0,"68":1.5,"69":1.0,"70":0.5,"71":0.0,"72":-0.5,"73":-1.5},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":3.0,"33":4.0,"34":5.0,"35":6.0,"36":7.0,"37":8.0,"38":9.0,"39":10.0,"40":11.0,"41":12.0,"42":13.0,"43":14.0,"44":2.0,"45":3.0,"46":4.0,"47":5.0,"48":6.0,"49":3.0,"50":4.0,"51":5.0,"52":6.0,"53":7.0,"54":2.0,"55":3.0,"56":4.0,"57":5.0,"58":6.0,"59":7.0,"60":8.0,"61":9.0,"62":10.0,"63":11.0,"64":3.0,"65":4.0,"66":5.0,"67":6.0,"68":7.0,"69":8.0,"70":9.0,"71":10.0,"72":11.0,"73":12.0}}', "suburb_1": '{"x":{"0":0.0,"1":0.0,"2":-9.5,"3":-10.0,"4":-10.5,"5":-11.0,"6":-11.5,"7":-12.0,"8":-12.5,"9":-13.0,"10":-13.5,"11":-9.0,"12":-9.5,"13":-10.0,"14":-10.5,"15":-11.0,"16":-11.5,"17":-12.0,"18":-12.5,"19":-13.5,"20":-7.5,"21":-8.0,"22":-8.5,"23":-9.0,"24":-9.5,"25":-10.0,"26":-10.5,"27":-11.0,"28":-11.5,"29":-12.0,"30":-12.5,"31":-13.0,"32":-13.5,"33":-14.0,"34":-14.5,"35":-15.0,"36":-15.5,"37":-7.0,"38":-7.5,"39":-8.0,"40":-8.5,"41":-9.0,"42":-9.5,"43":-10.0,"44":-10.5,"45":-11.0,"46":-11.5,"47":-12.0,"48":-12.5,"49":-13.0,"50":-13.5,"51":-14.0,"52":-14.5,"53":-15.5,"54":-5.5,"55":-6.0,"56":-6.5,"57":-7.0,"58":-7.5,"59":-5.0,"60":-5.5,"61":-6.0,"62":-6.5,"63":-7.5,"64":-3.5,"65":-4.0,"66":-4.5,"67":-5.0,"68":-5.5,"69":-6.0,"70":-6.5,"71":-7.0,"72":-7.5,"73":-8.0,"74":-8.5,"75":-9.0,"76":-9.5,"77":-3.0,"78":-3.5,"79":-4.0,"80":-4.5,"81":-5.0,"82":-5.5,"83":-6.0,"84":-6.5,"85":-7.0,"86":-7.5,"87":-8.0,"88":-8.5,"89":-9.5,"90":-1.5,"91":-2.0,"92":-2.5,"93":-3.0,"94":-3.5,"95":-4.0,"96":-4.5,"97":-5.0,"98":-1.0,"99":-1.5,"100":-2.0,"101":-2.5,"102":-3.0,"103":-3.5,"104":-4.0,"105":-5.0,"106":0.0,"107":0.0,"108":1.5,"109":1.0,"110":0.5,"111":0.0,"112":-0.5,"113":-1.0,"114":-1.5,"115":-2.0,"116":-2.5,"117":2.0,"118":1.5,"119":1.0,"120":0.5,"121":0.0,"122":-0.5,"123":-1.0,"124":-1.5,"125":-2.5,"126":3.5,"127":3.0,"128":2.5,"129":2.0,"130":1.5,"131":1.0,"132":0.5,"133":0.0,"134":-0.5,"135":-1.0,"136":-1.5,"137":-2.0,"138":-2.5,"139":-3.0,"140":-3.5,"141":-4.0,"142":-4.5,"143":4.0,"144":3.5,"145":3.0,"146":2.5,"147":2.0,"148":1.5,"149":1.0,"150":0.5,"151":0.0,"152":-0.5,"153":-1.0,"154":-1.5,"155":-2.0,"156":-2.5,"157":-3.0,"158":-3.5,"159":-4.5,"160":5.5,"161":5.0,"162":4.5,"163":4.0,"164":3.5,"165":6.0,"166":5.5,"167":5.0,"168":4.5,"169":3.5,"170":7.5,"171":7.0,"172":6.5,"173":6.0,"174":5.5,"175":5.0,"176":4.5,"177":4.0,"178":3.5,"179":3.0,"180":2.5,"181":2.0,"182":1.5,"183":8.0,"184":7.5,"185":7.0,"186":6.5,"187":6.0,"188":5.5,"189":5.0,"190":4.5,"191":4.0,"192":3.5,"193":3.0,"194":2.5,"195":1.5,"196":9.5,"197":9.0,"198":8.5,"199":8.0,"200":10.0,"201":9.5,"202":9.0,"203":8.0},"y":{"0":0.0,"1":1.0,"2":2.0,"3":3.0,"4":4.0,"5":5.0,"6":6.0,"7":7.0,"8":8.0,"9":9.0,"10":10.0,"11":3.0,"12":4.0,"13":5.0,"14":6.0,"15":7.0,"16":8.0,"17":9.0,"18":10.0,"19":11.0,"20":2.0,"21":3.0,"22":4.0,"23":5.0,"24":6.0,"25":7.0,"26":8.0,"27":9.0,"28":10.0,"29":11.0,"30":12.0,"31":13.0,"32":14.0,"33":15.0,"34":16.0,"35":17.0,"36":18.0,"37":3.0,"38":4.0,"39":5.0,"40":6.0,"41":7.0,"42":8.0,"43":9.0,"44":10.0,"45":11.0,"46":12.0,"47":13.0,"48":14.0,"49":15.0,"50":16.0,"51":17.0,"52":18.0,"53":19.0,"54":2.0,"55":3.0,"56":4.0,"57":5.0,"58":6.0,"59":3.0,"60":4.0,"61":5.0,"62":6.0,"63":7.0,"64":2.0,"65":3.0,"66":4.0,"67":5.0,"68":6.0,"69":7.0,"70":8.0,"71":9.0,"72":10.0,"73":11.0,"74":12.0,"75":13.0,"76":14.0,"77":3.0,"78":4.0,"79":5.0,"80":6.0,"81":7.0,"82":8.0,"83":9.0,"84":10.0,"85":11.0,"86":12.0,"87":13.0,"88":14.0,"89":15.0,"90":2.0,"91":3.0,"92":4.0,"93":5.0,"94":6.0,"95":7.0,"96":8.0,"97":9.0,"98":3.0,"99":4.0,"100":5.0,"101":6.0,"102":7.0,"103":8.0,"104":9.0,"105":10.0,"106":2.0,"107":3.0,"108":2.0,"109":3.0,"110":4.0,"111":5.0,"112":6.0,"113":7.0,"114":8.0,"115":9.0,"116":10.0,"117":3.0,"118":4.0,"119":5.0,"120":6.0,"121":7.0,"122":8.0,"123":9.0,"124":10.0,"125":11.0,"126":2.0,"127":3.0,"128":4.0,"129":5.0,"130":6.0,"131":7.0,"132":8.0,"133":9.0,"134":10.0,"135":11.0,"136":12.0,"137":13.0,"138":14.0,"139":15.0,"140":16.0,"141":17.0,"142":18.0,"143":3.0,"144":4.0,"145":5.0,"146":6.0,"147":7.0,"148":8.0,"149":9.0,"150":10.0,"151":11.0,"152":12.0,"153":13.0,"154":14.0,"155":15.0,"156":16.0,"157":17.0,"158":18.0,"159":19.0,"160":2.0,"161":3.0,"162":4.0,"163":5.0,"164":6.0,"165":3.0,"166":4.0,"167":5.0,"168":6.0,"169":7.0,"170":2.0,"171":3.0,"172":4.0,"173":5.0,"174":6.0,"175":7.0,"176":8.0,"177":9.0,"178":10.0,"179":11.0,"180":12.0,"181":13.0,"182":14.0,"183":3.0,"184":4.0,"185":5.0,"186":6.0,"187":7.0,"188":8.0,"189":9.0,"190":10.0,"191":11.0,"192":12.0,"193":13.0,"194":14.0,"195":15.0,"196":2.0,"197":3.0,"198":4.0,"199":5.0,"200":3.0,"201":4.0,"202":5.0,"203":6.0}}' } net.bus_geodata = pd.read_json(bus_geo[network_class]) # Match bus.index net.bus_geodata = net.bus_geodata.loc[net.bus.index] return net
def execute_my_script(EQ_file, SSH_file): #Next step is to create a tree by parsing the XML file referenced # We are here using ENTSO-E model files used in Interoperability testing EQ_tree = ET.parse(EQ_file) SSH_tree = ET.parse(SSH_file) # We can access the root (raiz) of the tree and print it EQ_microgrid = EQ_tree.getroot() SSH_microgrid = SSH_tree.getroot() # To make working with the file easier, it may be useful to store the # namespace identifiers in strings and reuse when you search for tags ns = {'cim':'http://iec.ch/TC57/2013/CIM-schema-cim16#', 'entsoe':'http://entsoe.eu/CIM/SchemaExtension/3/1#', 'rdf':'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}'} #create an empty network net = pp.create_empty_network() #to see al the elements in our system: EQ_tag=[] for eq in EQ_microgrid: if (ns['cim'] in eq.tag): equipment = eq.tag.replace("{"+ns['cim']+"}","") if equipment not in EQ_tag : EQ_tag.append(equipment) print(EQ_tag) print("---------------------------------------------------------") # My goal here it's to create a dictionary that links voltage level with their respective ID # I want to to avoid repetition in the loop when finding the match voltage level of the equipment voltage_levels_dic = {} for voltage_level in EQ_microgrid.findall('cim:VoltageLevel', ns): voltage_name = float(voltage_level.find('cim:IdentifiedObject.name', ns).text) voltage_levels_dic[voltage_level.attrib.get(ns['rdf']+'ID')] = voltage_name print(voltage_levels_dic) # Create buses in the pandapower system from the XML file data adquired for bus in EQ_microgrid.findall('cim:BusbarSection', ns): # Extracting the name from the BusbarSection element bus_name = bus.find('cim:IdentifiedObject.name', ns).text # I the next line of code we want to obtain the Equipment.EquipmentContainer ID of each busbar section and take with it the corresponding bus # voltage level relation that we have previously determined in the dictionary bus_voltage_level = voltage_levels_dic[bus.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')] pp.create_bus(net, bus_voltage_level, name=bus_name) print(net.bus) print("---------------------------------------------------------") # Create lines in the pandapower system from the XML file data adquired for line in EQ_microgrid.findall('cim:ACLineSegment', ns): #I want to get the ID of each line line_id = line.attrib.get(ns['rdf'] + 'ID') print (line_id) # next step will be retrieving the name of the line line_name = line.find('cim:IdentifiedObject.name', ns).text print (line_name) # Now I want to get the length of the line line_length = float(line.find('cim:Conductor.length', ns).text) print (line_length) # get the resistance of the line line_resistance_per_km = float(line.find('cim:ACLineSegment.r', ns).text)/line_length # get the reactance of the line line_rectance_per_km = float(line.find('cim:ACLineSegment.x', ns).text)/line_length # I want to find the ID of the terminals where the line is connected to # Basically we want to know to wich 2 terminals each line is connected to in order to later define # from/to which buses the lines are connected to for terminal in EQ_microgrid.findall('cim:Terminal', ns): line_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') line_sequence_number = terminal.find('cim:ACDCTerminal.sequenceNumber', ns).text if line_id == line_Te_CE: # We do this in order to select the terminals related to the lines if line_sequence_number == '1': #This is because for each line we have 2 terminals, the one with sequence number 1 and the other with seq number 2 # Gets the connectivity node ID from the terminals line_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN: CN_id = CN.attrib.get(ns['rdf'] + 'ID') CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: Line_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text elif line_sequence_number == '2': # Gets the connectivity node ID from the terminals line_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN: CN_id = CN.attrib.get(ns['rdf'] + 'ID') CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: Line_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text Line_from_Bus = pp.get_element_index(net, "bus", Line_Te1) Line_to_Bus = pp.get_element_index(net, "bus", Line_Te2) pp.create_line(net, Line_from_Bus, Line_to_Bus, length_km=line_length,std_type='NAYY 4x50 SE', name=line_name)# parallel=hv_line.parallel) # show line table print(net.line) print("---------------------------------------------------------") # Create transformers in the pandapower system from the XML file data adquired for transformers in EQ_microgrid.findall('cim:PowerTransformer', ns): #I want to get the ID of each transformer transformer_id = transformers.attrib.get(ns['rdf'] + 'ID') # next step will be retrieving the name of the transformer transformers_name = transformers.find('cim:IdentifiedObject.name', ns).text print(transformers_name) # I want to find the ID of the terminals where the transformer is connected to for transformer_end in EQ_microgrid.findall('cim:PowerTransformerEnd', ns): transformer_end_id = transformer_end.find('cim:PowerTransformerEnd.PowerTransformer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # Find the side of the power transformer if transformer_id == transformer_end_id: transformer_end_number = transformer_end.find('cim:TransformerEnd.endNumber', ns).text # I want to find the value of the TransformerEnd.endNumber because it will give you the information about if # it is the HV(=1) or LV(=2) print(transformer_end_number) if transformer_end_number == '1': # As we did previously for the lines we use did if in order to create 2 paths, one will define the # parameters of HV side and the other the parameters of the LV side # I am taking the information of the transformer, Power rating of the transformer # The parameters are taking on the HV(=1) side because is where the data about r,x is stored at the XML file transformer_S = float(transformer_end.find('cim:PowerTransformerEnd.ratedS', ns).text) transformer_hv_kv = float(transformer_end.find('cim:PowerTransformerEnd.ratedU', ns).text) transformer_r = float(transformer_end.find('cim:PowerTransformerEnd.r', ns).text) transformer_x = float(transformer_end.find('cim:PowerTransformerEnd.x', ns).text) transformer_z = (transformer_r ** 2 + transformer_x ** 2) ** (1/2) # I am going to neglect the iron losses, the open loop losses, shift degree # Find the terminal the transformer end is connected to transformer_end_terminal = transformer_end.find('cim:TransformerEnd.Terminal', ns).attrib.get(ns['rdf'] + 'resource').replace('#','') for terminal in EQ_microgrid.findall('cim:Terminal', ns): terminal_id = terminal.attrib.get(ns['rdf'] + 'ID') if terminal_id == transformer_end_terminal: # Take the connectivity node's ID from the terminal transformer_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN: transformer_CN_id = CN.attrib.get(ns['rdf'] + 'ID') transformer_CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: transformer_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text # Now we want to do the same for the LV side elif transformer_end_number == '2': transformer_lv_kv = float(transformer_end.find('cim:PowerTransformerEnd.ratedU', ns).text) # Find the terminal the transformer end is connected to transformer_end_terminal = transformer_end.find('cim:TransformerEnd.Terminal', ns).attrib.get(ns['rdf'] + 'resource').replace('#','') for terminal in EQ_microgrid.findall('cim:Terminal', ns): terminal_id = terminal.attrib.get(ns['rdf'] + 'ID') if terminal_id == transformer_end_terminal: # Take the connectivity node's ID from the terminal transformer_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN: transformer_CN_id = CN.attrib.get(ns['rdf'] + 'ID') transformer_CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: transformer_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text hv_bus = pp.get_element_index(net, "bus", transformer_Te1) lv_bus = pp.get_element_index(net, "bus", transformer_Te2) pp.create_transformer_from_parameters(net, hv_bus, lv_bus, sn_mva=transformer_S, vn_hv_kv=transformer_hv_kv, vn_lv_kv=transformer_lv_kv, vkr_percent=0.06, vk_percent=8, pfe_kw=0, i0_percent=0, tp_pos=0, shift_degree=0, name=transformers_name) print(net.trafo) # show trafo table print("---------------------------------------------------------") # Create Loads in the pandapower system from the XML file (SSH) data adquired # In order to do this, firs we will take the name and ID of the loads from the EQ file, afterwards we will use this # Id that we have obtained before to look for its corresponding P & Q data stored in the SSH file for load in EQ_microgrid.findall('cim:EnergyConsumer', ns): #I want to get the ID of each load eq_load_id = load.attrib.get(ns['rdf'] + 'ID') # next step will be retrieving the name of the load load_name = load.find('cim:IdentifiedObject.name', ns).text print(load_name) for ssh_load in SSH_microgrid.findall('cim:EnergyConsumer', ns): ssh_load_id = ssh_load.attrib.get(ns['rdf'] + 'about').replace('#', '') print(ssh_load_id) if ssh_load_id == eq_load_id: P_load = float(ssh_load.find('cim:EnergyConsumer.p', ns).text) Q_load = float(ssh_load.find('cim:EnergyConsumer.q', ns).text) # After we got the P & Q for each load, now I want to find the terminal associated to each load (from the EQ file again) for terminal in EQ_microgrid.findall('cim:Terminal', ns): load_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') if eq_load_id == load_Te_CE: # We do this in order to select the terminals related to the loads load_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == load_Te_CN: CN_id = CN.attrib.get(ns['rdf'] + 'ID') CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: Load_Te = BusBar.find('cim:IdentifiedObject.name', ns).text bus_idx = pp.get_element_index(net, "bus", Load_Te) pp.create_load(net, bus_idx, p_mw=P_load, q_mvar=Q_load, name=load_name) # show load table print(net.load) print("---------------------------------------------------------") # Create generators in pandapower, for generator in EQ_microgrid.findall('cim:GeneratingUnit', ns): generator_id = generator.attrib.get(ns['rdf'] + 'ID') generator_name = generator.find('cim:IdentifiedObject.name', ns).text generator_initial_P = float(generator.find('cim:GeneratingUnit.initialP', ns).text) # Looking for the SynchronousMachine related to the generator unit for synch_machine in EQ_microgrid.findall('cim:SynchronousMachine', ns): synch_machine_id = synch_machine.attrib.get(ns['rdf'] + 'ID') if synch_machine.find('cim:RotatingMachine.GeneratingUnit', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == generator_id: synch_machine_ratedU = float(synch_machine.find('cim:RotatingMachine.ratedU', ns).text) # print(synch_machine_ratedU) synch_machine_id = synch_machine.attrib.get(ns['rdf'] + 'ID') synch_machine_equip_cont = synch_machine.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): BusBar_equip_cont = BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') if BusBar_equip_cont == synch_machine_equip_cont: generator_busbar = BusBar.find('cim:IdentifiedObject.name', ns).text bus_voltage = voltage_levels_dic[BusBar_equip_cont] # print(bus_voltage) vm_pu = synch_machine_ratedU / bus_voltage print(vm_pu) pp.create_gen(net, pp.get_element_index(net, "bus", generator_busbar), generator_initial_P, vm_pu, name=generator_name) # vm_pu=1.0 this is because there is no extra info about vm_pu in the xml file. Thus, as the rated voltage # of the synch.machine is exactly the same as the bus which it is connected # Find the terminal the generator is connected to print(net.gen) print("---------------------------------------------------------") # Create shunt capacitors in pandapower. # To define shunt in pandapower we need: the bus that is connected to, p_mw=0, q_mvar, name. for shunt in EQ_microgrid.findall('cim:LinearShuntCompensator', ns): shunt_id = shunt.attrib.get(ns['rdf'] + 'ID') shunt_name = shunt.find('cim:IdentifiedObject.name', ns).text shunt_b = float(shunt.find('cim:LinearShuntCompensator.bPerSection', ns).text) shunt_nom_U = float(shunt.find('cim:ShuntCompensator.nomU', ns).text) # In a shunt capacitor, Q = b*(Unom^2) because g = 0 shunt_Q = shunt_b*(shunt_nom_U**2) shunt_equip_cont = shunt.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): BusBar_equip_cont = BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') if BusBar_equip_cont == shunt_equip_cont: shunt_busbar = BusBar.find('cim:IdentifiedObject.name', ns).text pp.create_shunt(net, pp.get_element_index(net, "bus", shunt_busbar), p_mw=0, q_mvar=shunt_Q, name=shunt_name) print(net.shunt) print("---------------------------------------------------------") # Create breakers in pandapower. for breaker in EQ_microgrid.findall('cim:Breaker', ns): breaker_id = breaker.attrib.get(ns['rdf'] + 'ID') breaker_name = breaker.find('cim:IdentifiedObject.name', ns).text breaker_position = breaker.find('cim:Switch.normalOpen', ns).text # Breaker position in the EQ.xml file determines if the sitch is open(=TRUE), but for pandapower # the parameteres examines if the switch is closed(=FALSE), thi is why we need to create # an if condition to readjust this as we want if breaker_position == 'false': breaker_position = True elif breaker_position == 'true': breaker_position = False # I want to find the ID of the terminals where the breaker is connected to # Basically we want to know to wich 2 terminals each breaker is connected to in order to later define # from/to which buses the breaker are connected to for terminal in EQ_microgrid.findall('cim:Terminal', ns): breaker_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') breaker_sequence_number = terminal.find('cim:ACDCTerminal.sequenceNumber', ns).text if breaker_id == breaker_Te_CE: if breaker_sequence_number == '1': # Take the connectivity node's ID from the terminal breaker_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == breaker_Te_CN: CN_id = CN.attrib.get(ns['rdf'] + 'ID') CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: breaker_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text print(breaker_Te1) elif breaker_sequence_number == '2': # Gets the connectivity node ID from the terminals breaker_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # With this new for loop the objective is to find the ConnectivityNode associaton, in other words # I want to obtain for each connectivitynode their corresponding id and container association for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns): if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN: CN_id = CN.attrib.get(ns['rdf'] + 'ID') CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer # and the corresponding busbarsection for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns): if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container: breaker_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text print(breaker_Te2) print("---------------------------------------------------------") from_bus = pp.get_element_index(net, "bus", breaker_Te1) to_bus = pp.get_element_index(net, "bus", breaker_Te2) pp.create_switch(net, from_bus, to_bus, et='b', closed=breaker_position, type='CB', name=breaker_name) print(net.switch) plot.to_html(net, 'plot_system.html') #plot.simple_plot(net, respect_switches=False, line_width=1.0, bus_size=1.0, ext_grid_size=1.0, trafo_size=1.0, plot_loads=False, plot_sgens=False, load_size=1.0, sgen_size=1.0, switch_size=2.0, # switch_distance=1.0, plot_line_switches=False, scale_size=True, bus_color='b', line_color='grey', trafo_color='k', ext_grid_color='y', switch_color='k', library='igraph', show_plot=True, ax=None) #execute_my_script('MicroGridTestConfiguration_T1_BE_EQ_V2.xml', 'MicroGridTestConfiguration_T1_BE_SSH_V2.xml')
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, p_mw=10) b3 = pp.create_bus(net, vn_kv=0.4) pp.create_load(net, b3, p_mw=1) 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_mva=40, sn_mv_mva=30, sn_lv_mva=10, vk_hv_percent=5, vk_mv_percent=5, vk_lv_percent=5, vkr_hv_percent=0.1, vkr_mv_percent=0.1, vkr_lv_percent=0.1, pfe_kw=0, i0_percent=0.1, shift_mv_degree=30, shift_lv_degree=60, tap_side=side, tap_step_percent=2, tap_step_degree=10, tap_pos=0, tap_neutral=0, tap_min=-2, tap_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.tap_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.tap_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)
def test_3point_pwl(): vm_max = 1.05 vm_min = 0.95 # create net net = pp.create_empty_network() pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=10.) pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) pp.create_sgen(net, 1, p_kw=-100, q_kvar=0, controllable=True, max_p_kw=-100, min_p_kw=-100.5, max_q_kvar=50, min_q_kvar=-50) pp.create_ext_grid(net, 0) pp.create_load(net, 1, p_kw=20, controllable=False) pp.create_line_from_parameters(net, 0, 1, 50, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, max_i_ka=0.123, x_ohm_per_km=0.1159876, max_loading_percent=100 * 690) pp.create_piecewise_linear_cost(net, 0, "sgen", np.array([ [-100, -1], [0, 0], [100, -1], ]), type="q") # creating a pwl cost function that actually is realistic: The absolute value of the reactive power has costs. pp.runopp(net, verbose=False) # assert abs( net.res_sgen.q_kvar.values ) < 1e-5 # this is not the expected result. the reactive power should be at zero to minimze the costs. # checkout the dirty workaround: # the first sgen is only representing the positive segment of the function: net.piecewise_linear_cost.p.at[0] = np.array([[0, 1]]) net.piecewise_linear_cost.f.at[0] = np.array([[0, -1]]) net.sgen.min_q_kvar.at[0] = 0 # what we can do instead is modelling a second sgen on the same bus representing the negative segment of the function: pp.create_sgen(net, 1, p_kw=0, q_kvar=0, controllable=True, max_p_kw=0.01, min_p_kw=-0.01, max_q_kvar=0, min_q_kvar=-10) pp.create_piecewise_linear_cost(net, 1, "sgen", np.array([ [-100, -100], [0, 0], ]), type="q") # runOPF pp.runopp(net, verbose=False) assert abs(sum(net.res_sgen.q_kvar.values)) < 1e-5 # et voila, we have the q at zero. sure, we do have two seperate sgens now and this is very dirty. but it's working. # let's check if we can handle overvoltage net.bus.max_vm_pu = 1.041 pp.runopp(net, verbose=False) assert abs(max(net.res_bus.vm_pu.values) - 1.041) < 1e-5
N1 = pp.create_bus(net, vn_kv=20.0, name="N1", in_service=True) N2 = pp.create_bus(net, vn_kv=20.0, name="N2", in_service=True) N30 = pp.create_bus(net, vn_kv=20.0, name="N30", in_service=True) N6 = pp.create_bus(net, vn_kv=20.0, name="N6", in_service=True) N9 = pp.create_bus(net, vn_kv=20.0, name="N9", in_service=True) N12 = pp.create_bus(net, vn_kv=20.0, name="N12", in_service=True) N15 = pp.create_bus(net, vn_kv=20.0, name="N15", in_service=True) N18 = pp.create_bus(net, vn_kv=20.0, name="N18", in_service=True) N22 = pp.create_bus(net, vn_kv=20.0, name="N22", in_service=True) N21 = pp.create_bus(net, vn_kv=20.0, name="N21", in_service=True) N27 = pp.create_bus(net, vn_kv=20.0, name="N27", in_service=True) N16 = pp.create_bus(net, vn_kv=20.0, name="N16", in_service=True) # list of Loads: pp.create_load(net, bus=N4, p_mw=-4.5, q_mvar=-1.5, name="N4", in_service=True) pp.create_load(net, bus=N10, p_mw=-4.5, q_mvar=-2.0, name="N10", in_service=True) pp.create_load(net, bus=N25, p_mw=-4.5, q_mvar=-2.0, name="N25", in_service=True) pp.create_load(net, bus=N5, p_mw=0.7, q_mvar=0.21, name="N5", in_service=True) pp.create_load(net, bus=N7, p_mw=0.22, q_mvar=0.09, name="N7", in_service=True) pp.create_load(net, bus=N8, p_mw=0.33, q_mvar=0.11, name="N8", in_service=True) pp.create_load(net, bus=N11, p_mw=0.9, q_mvar=0.45, name="N11", in_service=True) pp.create_load(net, bus=N13, p_mw=0.35, q_mvar=0.15, name="N13", in_service=True) pp.create_load(net, bus=N14, p_mw=1.26, q_mvar=0.64, name="N14", in_service=True) pp.create_load(net, bus=N17, p_mw=0.76, q_mvar=0.43, name="N17", in_service=True) pp.create_load(net, bus=N19, p_mw=1.22, q_mvar=0.46, name="N19", in_service=True) pp.create_load(net, bus=N20, p_mw=0.95, q_mvar=0.43, name="N20", in_service=True) pp.create_load(net, bus=N23, p_mw=0.4, q_mvar=0.17, name="N23", in_service=True) pp.create_load(net, bus=N24, p_mw=0.44, q_mvar=0.205, name="N24", in_service=True) pp.create_load(net, bus=N26, p_mw=0.9, q_mvar=0.45, name="N26", in_service=True) pp.create_load(net, bus=N28, p_mw=1.05, q_mvar=0.625, name="N28", in_service=True)
def _add_lines_with_branched_loads(net, n_lines, startbus, length_per_line, std_type="NAYY 4x150 SE", p_load_mw=0, q_load_mvar=0, length_branchout_line_1=0.022, length_branchout_line_2=0, std_type_branchout_line_1="NAYY 4x50 SE", std_type_branchout_line_2="NAYY 4x50 SE", prob_branchout_line_1=0.5, branchnr=1): """ Creates a single unsplitted branch on the startbus. each bus on the main \ line is connected to a branch out line which connects \ the loadbus (households). If there are two std_types given for the branch_out_lin. The cable_types \ interchange with the given probability If there are two lengths of branchoutlines are given, the \ lengths interchange. It begins with length 1 and switches to length 2. The cable with length 1 \ is named as "MUF_" and length 2 becomes "KV_". Loads will only be added if p_load_mw or q_load_mvar \ is assigned The branch number could be assigned with branchnr. It will be added to the\ name ti keep track on the node position """ # support function startpoint_bus = 1 startpoint_line = 1 bus_before = startbus length_branchout_line = length_branchout_line_1 # destinct between Muffe und Kabelverteiler if length_branchout_line_2: bustype = "MUF" else: bustype = "bus" std_type_branchout_line = std_type_branchout_line_1 for i in range(n_lines): buscounter = startpoint_bus + i linecounter = startpoint_line + i created_bus_nr = pp.create_bus(net, name="%s_%d_%d" % (bustype, branchnr, buscounter), type="b" if bustype == "KV" else "n", vn_kv=.4) pp.create_line(net, bus_before, created_bus_nr, length_km=length_per_line, name="line_%d_%d" % (branchnr, linecounter), std_type=std_type) loadbusnr = pp.create_bus(net, name="loadbus_%d_%d" % (branchnr, buscounter), vn_kv=.4) pp.create_line(net, created_bus_nr, loadbusnr, length_km=length_branchout_line, name="branchout_line_%d_%d" % (branchnr, linecounter), std_type=std_type_branchout_line) if p_load_mw or q_load_mvar: pp.create_load(net, loadbusnr, p_mw=p_load_mw, q_mvar=q_load_mvar) bus_before = created_bus_nr # rueckgefuehrter Wert in der Schleife # alternates the length of the branch out lines if needed if length_branchout_line_2: if length_branchout_line == length_branchout_line_1: length_branchout_line = length_branchout_line_2 bustype = "KV" else: length_branchout_line = length_branchout_line_1 bustype = "MUF" # changes branch out lines according to the probabillity if needed if std_type_branchout_line_2: if rd.random() > prob_branchout_line_1: std_type_branchout_line = std_type_branchout_line_2 else: std_type_branchout_line = std_type_branchout_line_1 return net
def simple_mv_open_ring_net(): """ This function creates a simple medium voltage open ring network with loads at every medium \ voltage node. As an example this function is used in the topology and diagnostic docu. OUTPUT: **net** - Returns the required simple medium voltage open ring network EXAMPLE: import pandapower.networks as pn net_simple_open_ring = pn.simple_mv_open_ring_net() """ net = pp.create_empty_network() pp.create_bus(net, name="110 kV bar", vn_kv=110, type='b') pp.create_bus(net, name="20 kV bar", vn_kv=20, type='b') pp.create_bus(net, name="bus 2", vn_kv=20, type='b') pp.create_bus(net, name="bus 3", vn_kv=20, type='b') pp.create_bus(net, name="bus 4", vn_kv=20, type='b') pp.create_bus(net, name="bus 5", vn_kv=20, type='b') pp.create_bus(net, name="bus 6", vn_kv=20, type='b') pp.create_ext_grid(net, 0, vm_pu=1) pp.create_line(net, name="line 0", from_bus=1, to_bus=2, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_line(net, name="line 1", from_bus=2, to_bus=3, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_line(net, name="line 2", from_bus=3, to_bus=4, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_line(net, name="line 3", from_bus=4, to_bus=5, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_line(net, name="line 4", from_bus=5, to_bus=6, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_line(net, name="line 5", from_bus=6, to_bus=1, length_km=1, std_type="NA2XS2Y 1x185 RM/25 12/20 kV") pp.create_transformer(net, hv_bus=0, lv_bus=1, std_type="25 MVA 110/20 kV") pp.create_load(net, 2, p_kw=1000, q_kvar=200, name="load 0") pp.create_load(net, 3, p_kw=1000, q_kvar=200, name="load 1") pp.create_load(net, 4, p_kw=1000, q_kvar=200, name="load 2") pp.create_load(net, 5, p_kw=1000, q_kvar=200, name="load 3") pp.create_load(net, 6, p_kw=1000, q_kvar=200, name="load 4") pp.create_switch(net, bus=1, element=0, et='l') pp.create_switch(net, bus=2, element=0, et='l') pp.create_switch(net, bus=2, element=1, et='l') pp.create_switch(net, bus=3, element=1, et='l') pp.create_switch(net, bus=3, element=2, et='l') pp.create_switch(net, bus=4, element=2, et='l') pp.create_switch(net, bus=4, element=3, et='l', closed=0) pp.create_switch(net, bus=5, element=3, et='l') pp.create_switch(net, bus=5, element=4, et='l') pp.create_switch(net, bus=6, element=4, et='l') pp.create_switch(net, bus=6, element=5, et='l') pp.create_switch(net, bus=1, element=5, et='l') return net
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)