def test_eg_voltage(): """ Testing a very simple network without transformer for voltage 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, vm_pu=1.01) 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) # run OPF for init in ["pf", "flat"]: pp.runopp(net, verbose=False, init=init) assert net["OPF_converged"] # check and assert result logger.debug("test_simplest_voltage") logger.debug("res_gen:\n%s" % net.res_gen) logger.debug("res_ext_grid:\n%s" % net.res_ext_grid) logger.debug("res_bus.vm_pu: \n%s" % net.res_bus.vm_pu) assert net.res_bus.vm_pu.at[0] == net.ext_grid.vm_pu.values
def test_result_index_unsorted(): net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=0.4, index=4) b2 = pp.create_bus(net, vn_kv=0.4, index=2) b3 = pp.create_bus(net, vn_kv=0.4, index=3) pp.create_gen(net, b1, p_kw=-10, vm_pu=0.4) pp.create_load(net, b2, p_kw=10) pp.create_ext_grid(net, b3) pp.create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") pp.create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") net_recycle = copy.deepcopy(net) pp.runpp(net_recycle) pp.runpp(net_recycle, recycle=dict(_is_elements=True, ppc=True, Ybus=True)) pp.runpp(net) assert nets_equal(net, net_recycle, tol=1e-12)
def base_net(): net = pp.create_empty_network() pp.create_bus(net, vn_kv=10) pp.create_bus(net, vn_kv=10) pp.create_ext_grid(net, 0) pp.create_load(net, 1, p_mw=0.2, controllable=False) pp.create_line_from_parameters(net, 0, 1, 50, name="line", 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.runpp(net) return net
def test_zip_loads_with_voltage_angles(): net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=1.) b2 = pp.create_bus(net, vn_kv=1.) pp.create_ext_grid(net, b1) pp.create_line_from_parameters(net, b1, b2, length_km=1, r_ohm_per_km=0.3, x_ohm_per_km=0.3, c_nf_per_km=10, max_i_ka=1) pp.create_load(net, b2, p_kw=2., const_z_percent=0, const_i_percent=100) pp.set_user_pf_options(net, calculate_voltage_angles=True, init='dc') pp.runpp(net) res_load = net.res_load.copy() net.ext_grid.va_degree = 100 pp.runpp(net) assert np.allclose(net.res_load.values, res_load.values)
def simple_two_bus(): net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=20.) b2 = pp.create_bus(net, vn_kv=20.) pp.create_line(net, from_bus=b1, to_bus=b2, length_km=2.5, std_type="NA2XS2Y 1x240 RM/25 12/20 kV") pp.create_ext_grid(net, bus=b2) pp.create_gen(net, bus=b1, p_kw=-1000, vn_kv=20, sn_kva=8000, controllable=True) pp.runpp(net) return net
def test_mixed_p_q_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_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, min_p_mw=0.005, max_p_mw=0.1, max_q_mvar=.05, 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_pwl_cost(net, 0, "gen", [[-150, 150, 1]]) pp.create_pwl_cost(net, 0, "gen", [[-150, 150, 1]], power_type="q") pp.runopp(net) assert net["OPF_converged"] assert np.allclose(net.res_cost, net.res_gen.p_mw.values + net.res_gen.q_mvar.values)
def test_3bus(): # 1. Create network net = pp.create_empty_network() pp.create_bus(net, name="bus1", vn_kv=1.) pp.create_bus(net, name="bus2", vn_kv=1.) pp.create_bus(net, name="bus3", vn_kv=1.) pp.create_ext_grid(net, 0) pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, max_i_ka=1) pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, max_i_ka=1) pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, max_i_ka=1) pp.create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 pp.create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 pp.create_measurement(net, "p", "bus", 0.018, 0.01, 2) # p3 pp.create_measurement(net, "q", "bus", -0.1, 0.01, 2) # q3 pp.create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 pp.create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 # 2. Do state estimation success = estimate(net, init='flat') v_result = net.res_bus_est.vm_pu.values delta_result = net.res_bus_est.va_degree.values target_v = np.array([1.0627, 1.0589, 1.0317]) diff_v = target_v - v_result target_delta = np.array([0., 0.8677, 3.1381]) diff_delta = target_delta - delta_result assert success assert (np.nanmax(abs(diff_v)) < 1e-4) assert (np.nanmax(abs(diff_delta)) < 1e-4) # Backwards check. Use state estimation results for power flow and check for equality net.ext_grid.vm_pu = net.res_bus_est.vm_pu.iloc[0] pp.create_load(net, 0, net.res_bus_est.p_mw.iloc[0], net.res_bus_est.q_mvar.iloc[0]) pp.create_load(net, 1, net.res_bus_est.p_mw.iloc[1], net.res_bus_est.q_mvar.iloc[1]) pp.create_load(net, 2, net.res_bus_est.p_mw.iloc[2], net.res_bus_est.q_mvar.iloc[2]) _compare_pf_and_se_results(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 test_net_with_zero_injection(): # @author: AndersLi net = pp.create_empty_network() b1 = pp.create_bus(net, name="Bus 1", vn_kv=220, index=1) b2 = pp.create_bus(net, name="Bus 2", vn_kv=220, index=2) b3 = pp.create_bus(net, name="Bus 3", vn_kv=220, index=3) b4 = pp.create_bus(net, name="Bus 4", vn_kv=220, index=4) pp.create_ext_grid(net, 1) # set the slack bus to bus 1 factor = 48.4 * 2 * np.pi * 50 * 1e-9 # capacity factor pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=.0221*48.4, x_ohm_per_km=.1603*48.4, c_nf_per_km=0.00274/factor, max_i_ka=1) pp.create_line_from_parameters(net, 2, 3, 1, r_ohm_per_km=.0428*48.4, x_ohm_per_km=.242*48.4, c_nf_per_km=0.00384/factor, max_i_ka=1) l3 = pp.create_line_from_parameters(net, 2, 4, 1, r_ohm_per_km=.002*48.4, x_ohm_per_km=.0111*48.4, c_nf_per_km=0.00018/factor, max_i_ka=1) pp.create_measurement(net, "v", "bus", 1.063548, .001, b1) # V at bus 1 pp.create_measurement(net, "v", "bus", 1.068342, .001, b3) # V at bus 3 pp.create_measurement(net, "v", "bus", 1.069861, .001, b4) # V at bus 4 pp.create_measurement(net, "p", "bus", -40.0, 1, b1) # P at bus 1 pp.create_measurement(net, "q", "bus", -9.2, 1, b1) # Q at bus 1 # pp.create_measurement(net, "p", "bus", 0, 0.01, b2) # P at bus 2 - not required anymore # pp.create_measurement(net, "q", "bus", 0, 0.01, b2) # Q at bus 2 - not required anymore pp.create_measurement(net, "p", "bus", 10.0, 1, b3) # P at bus 3 pp.create_measurement(net, "q", "bus", 1.0, 1, b3) # Q at bus 3 pp.create_measurement(net, "p", "bus", 30.0, 1, b4) # P at bus 4 pp.create_measurement(net, "q", "bus", -0.100, 1, b4) # Q at bus 4 pp.create_measurement(net, "p", "line", 30.100, 1, l3, side="to") # Pline (bus 2 -> bus 4) at bus 4 pp.create_measurement(net, "q", "line", -0.099, 1, l3, side="to") # Qline (bus 2 -> bus 4) at bus 4 success = estimate(net, tolerance=1e-10, zero_injection='auto', algorithm='wls_with_zero_constraint') assert success assert np.abs(net.res_bus_est.at[1, 'p_mw']) < 1e-8 assert np.abs(net.res_bus_est.at[1, 'q_mvar']) < 1e-8 net_given_bus = deepcopy(net) success = estimate(net, tolerance=1e-6, zero_injection="auto") success_given_bus = estimate(net, tolerance=1e-6, zero_injection=[b2]) assert success and success_given_bus assert np.allclose(net.res_bus_est.va_degree.values,net_given_bus.res_bus_est.va_degree.values, 1e-3) assert np.allclose(net.res_bus_est.vm_pu.values,net_given_bus.res_bus_est.vm_pu.values, 1e-3)
def test_two_gens_at_one_bus(): net = pp.create_empty_network() b1 = pp.create_bus(net, 380) b2 = pp.create_bus(net, 380) b3 = pp.create_bus(net, 380) pp.create_ext_grid(net, b1, 1.02, max_p_kw=0.) p1 = 800 p2 = 500 g1 = pp.create_gen(net, b3, vm_pu=1.018, p_kw=p1) g2 = pp.create_gen(net, b3, vm_pu=1.018, p_kw=p2) pp.create_line(net, b1, b2, 30, "490-AL1/64-ST1A 380.0") pp.create_line(net, b2, b3, 20, "490-AL1/64-ST1A 380.0") pp.runpp(net) assert net.res_gen.p_kw.at[g1] == p1 assert net.res_gen.p_kw.at[g2] == p2
def two_ext_grids_at_one_bus(): net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=110, index=3) b2 = pp.create_bus(net, vn_kv=110, index=5) pp.create_ext_grid(net, b1, vm_pu=1.01, index=2) pp.create_line(net, b1, b2, 1., std_type="305-AL1/39-ST1A 110.0") pp.create_load(net, bus=b2, p_mw=3.5, q_mvar=1) pp.create_gen(net, b1, vm_pu=1.01, p_mw=1) runpp_with_consistency_checks(net) assert net.converged # connect second ext_grid to b1 with different angle but out of service eg2 = pp.create_ext_grid(net, b1, vm_pu=1.01, va_degree=20, index=5, in_service=False) runpp_with_consistency_checks( net) # power flow still converges since eg2 is out of service assert net.converged # error is raised after eg2 is set in service net.ext_grid.in_service.at[eg2] = True with pytest.raises(UserWarning): pp.runpp(net) # error is also raised when eg2 is connected to first ext_grid through bus-bus switch b3 = pp.create_bus(net, vn_kv=110) pp.create_switch(net, b1, b3, et="b") net.ext_grid.bus.at[eg2] = b3 with pytest.raises(UserWarning): pp.runpp(net) # no error is raised when voltage angles are not calculated runpp_with_consistency_checks(net, calculate_voltage_angles=False) assert net.converged # same angle but different voltage magnitude also raises an error net.ext_grid.vm_pu.at[eg2] = 1.02 net.ext_grid.va_degree.at[eg2] = 0 with pytest.raises(UserWarning): pp.runpp(net)
def simple_four_bus_system(): """ This function creates a simple four bus system with two radial low voltage nodes connected to \ a medium valtage slack bus. At both low voltage nodes the a load and a static generator is \ connected. OUTPUT: **net** - Returns the required four bus system EXAMPLE: import pandapower.networks as pn net_simple_four_bus = pn.simple_four_bus_system() """ net = pp.create_empty_network() busnr1 = pp.create_bus(net, name="bus1ref", vn_kv=10) pp.create_ext_grid(net, busnr1) busnr2 = pp.create_bus(net, name="bus2", vn_kv=.4) pp.create_transformer(net, busnr1, busnr2, name="transformer", std_type="0.25 MVA 10/0.4 kV") busnr3 = pp.create_bus(net, name="bus3", vn_kv=.4) pp.create_line(net, busnr2, busnr3, name="line1", length_km=0.50000, std_type="NAYY 4x50 SE") busnr4 = pp.create_bus(net, name="bus4", vn_kv=.4) pp.create_line(net, busnr3, busnr4, name="line2", length_km=0.50000, std_type="NAYY 4x50 SE") pp.create_load(net, busnr3, 30, 10, name="load1") pp.create_load(net, busnr4, 30, 10, name="load2") pp.create_sgen(net, busnr3, p_kw=-20., q_kvar=-5., name="pv1", sn_kva=30) pp.create_sgen(net, busnr4, p_kw=-15., q_kvar=-2., name="pv2", sn_kva=20) return net
def test_drop_elements_at_buses(): net = pp.create_empty_network() bus0 = pp.create_bus(net, vn_kv=110) bus1 = pp.create_bus(net, vn_kv=20) bus2 = pp.create_bus(net, vn_kv=10) bus3 = pp.create_bus(net, vn_kv=0.4) bus4 = pp.create_bus(net, vn_kv=0.4) bus5 = pp.create_bus(net, vn_kv=20) pp.create_ext_grid(net, 0) trafo0 = pp.create_transformer3w(net, hv_bus=bus0, mv_bus=bus1, lv_bus=bus2, name='trafo0', std_type='63/25/38 MVA 110/20/10 kV') trafo1 = pp.create_transformer(net, hv_bus=bus2, lv_bus=bus3, std_type='0.4 MVA 10/0.4 kV') line1 = pp.create_line(net, from_bus=bus3, to_bus=bus4, length_km=20.1, std_type='24-AL1/4-ST1A 0.4', name='line1') pp.create_sgen(net, 1, 0) switch0a = pp.create_switch(net, bus=bus0, element=trafo0, et='t3') switch0b = pp.create_switch(net, bus=bus1, element=trafo0, et='t3') switch0c = pp.create_switch(net, bus=bus2, element=trafo0, et='t3') switch1 = pp.create_switch(net, bus=bus1, element=bus5, et='b') switch2a = pp.create_switch(net, bus=bus2, element=trafo1, et='t') switch2b = pp.create_switch(net, bus=bus3, element=trafo1, et='t') switch3a = pp.create_switch(net, bus=bus3, element=line1, et='l') switch3b = pp.create_switch(net, bus=bus4, element=line1, et='l') # bus id needs to be entered as iterable, not done in the function for b in net.bus.index.values: net1 = net.deepcopy() cd = tb.get_connected_elements_dict(net1, b, connected_buses=False) swt3w = set(net1.switch.loc[net1.switch.element.isin(cd.get('trafo3w', [1000])) & (net1.switch.et=='t3')].index) swt = set(net1.switch.loc[net1.switch.element.isin(cd.get('trafo', [1000])) & (net1.switch.et=='t')].index) swl = set(net1.switch.loc[net1.switch.element.isin(cd.get('line', [1000])) & (net1.switch.et=='l')].index) sw = swt3w | swt | swl tb.drop_elements_at_buses(net1, [b]) assert b not in net1.switch.bus.values assert b not in net1.switch.query("et=='b'").element.values assert sw.isdisjoint(set(net1.switch.index)) for elm, id in cd.items(): assert len(net1[elm].loc[net1[elm].index.isin(id)]) == 0
def test_unconstrained_line(): """ Testing a very simple network without transformer for voltage 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) 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) pp.create_polynomial_cost(net, 0, "gen", array([-1, 0])) # run OPF pp.runopp(net, verbose=False) assert net["OPF_converged"] # check and assert result logger.debug("test_simplest_voltage") logger.debug("res_gen:\n%s" % net.res_gen) logger.debug("res_ext_grid:\n%s" % net.res_ext_grid) logger.debug("res_bus.vm_pu: \n%s" % net.res_bus.vm_pu) assert max(net.res_bus.vm_pu) < vm_max assert min(net.res_bus.vm_pu) > vm_min
def test_3bus_with_bad_data(): net = pp.create_empty_network() pp.create_bus(net, name="bus1", vn_kv=1.) pp.create_bus(net, name="bus2", vn_kv=1.) pp.create_bus(net, name="bus3", vn_kv=1.) pp.create_ext_grid(net, 0) pp.create_line_from_parameters(net, 0, 1, 1, r_ohm_per_km=0.7, x_ohm_per_km=0.2, c_nf_per_km=0, max_i_ka=1) pp.create_line_from_parameters(net, 0, 2, 1, r_ohm_per_km=0.8, x_ohm_per_km=0.8, c_nf_per_km=0, max_i_ka=1) pp.create_line_from_parameters(net, 1, 2, 1, r_ohm_per_km=1, x_ohm_per_km=0.6, c_nf_per_km=0, max_i_ka=1) pp.create_measurement(net, "p", "line", -0.0011, 0.01, 0, 0) # p12 pp.create_measurement(net, "q", "line", 0.024, 0.01, 0, 0) # q12 pp.create_measurement(net, "p", "bus", 0.018, 0.01, 2) # p3 pp.create_measurement(net, "q", "bus", -0.1, 0.01, 2) # q3 pp.create_measurement(net, "v", "bus", 1.08, 0.05, 0) # u1 pp.create_measurement(net, "v", "bus", 1.015, 0.05, 2) # u3 # 1. Create false voltage measurement for testing bad data detection (-> should be removed) pp.create_measurement(net, "v", "bus", 1.3, 0.01, 1) # V at bus 2 # 2. Do chi2-test bad_data_detected = chi2_analysis(net, init='flat') # 3. Perform rn_max_test success_rn_max = remove_bad_data(net, init='flat') v_est_rn_max = net.res_bus_est.vm_pu.values delta_est_rn_max = net.res_bus_est.va_degree.values target_v = np.array([1.0627, 1.0589, 1.0317]) diff_v = target_v - v_est_rn_max target_delta = np.array([0., 0.8677, 3.1381]) diff_delta = target_delta - delta_est_rn_max assert bad_data_detected assert success_rn_max assert (np.nanmax(abs(diff_v)) < 1e-4) assert (np.nanmax(abs(diff_delta)) < 1e-4)
def test_drop_inactive_elements(): net = pp.create_empty_network() service = 0 bus0 = pp.create_bus(net, vn_kv=.4, in_service=service) pp.create_ext_grid(net, bus0, in_service=service) bus1 = pp.create_bus(net, vn_kv=.4, in_service=service) pp.create_transformer(net, bus0, bus1, in_service=service, std_type='63 MVA 110/20 kV') bus2 = pp.create_bus(net, vn_kv=.4, in_service=service) pp.create_line(net, bus1, bus2, length_km=1, in_service=service, std_type='149-AL1/24-ST1A 10.0') pp.create_load(net, bus2, p_kw=0., in_service=service) pp.create_sgen(net, bus2, p_kw=0., in_service=service) # drop them tb.drop_inactive_elements(net) sum_of_elements = 0 for element in net.keys(): # skip this one since we expect items here if element == "std_types" or element == "_pd2ppc_lookups" or element == "_ppc2pd_lookups": continue try: sum_of_elements += len(net[element]) except TypeError: # _ppc is initialized with None and clashes when checking continue assert sum_of_elements == 0
def test_net_unobserved_island(): net = pp.create_empty_network() bus1 = pp.create_bus(net, name="bus1", vn_kv=10.) bus2 = pp.create_bus(net, name="bus2", vn_kv=10.) bus3 = pp.create_bus(net, name="bus3", vn_kv=10.) bus4 = pp.create_bus(net, name="bus4", vn_kv=110.) pp.create_line_from_parameters(net, bus1, bus2, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, max_i_ka=1) pp.create_line_from_parameters(net, bus2, bus3, 10, r_ohm_per_km=.59, x_ohm_per_km=.35, c_nf_per_km=10.1, max_i_ka=1) pp.create_transformer(net, bus4, bus1, std_type="40 MVA 110/10 kV") pp.create_ext_grid(net, bus=bus4, vm_pu=1.0) pp.create_load(net, bus1, p_mw=.350, q_mvar=.100) pp.create_load(net, bus2, p_mw=.450, q_mvar=.100) pp.create_load(net, bus3, p_mw=.250, q_mvar=.100) # Created bb switch pp.runpp(net, calculate_voltage_angles=True) pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus1], .002), .002, element=bus1) pp.create_measurement(net, "v", "bus", r2(net.res_bus.vm_pu.iloc[bus4], .002), .002, element=bus4) pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_mw.iloc[bus4], .002), .002, element=bus4) pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_mvar.iloc[bus4], .002), .002, element=bus4) # IF pq of bus2 is not available makes bus3 an unobserved island # pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_mw.iloc[bus2], .001), .001, element=bus2) # pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_mvar.iloc[bus2], .001), .001, element=bus2) pp.create_measurement(net, "p", "bus", -r2(net.res_bus.p_mw.iloc[bus1], .001), .001, element=bus1) pp.create_measurement(net, "q", "bus", -r2(net.res_bus.q_mvar.iloc[bus1], .001), .001, element=bus1) pp.create_measurement(net, "p", "line", r2(net.res_line.p_from_mw.iloc[0], .002), .002, 0, side='from') pp.create_measurement(net, "q", "line", r2(net.res_line.q_from_mvar.iloc[0], .002), .002, 0, side='from') pp.create_measurement(net, "p", "trafo", r2(net.res_trafo.p_hv_mw.iloc[0], .001), .01, side="hv", element=0) pp.create_measurement(net, "q", "trafo", r2(net.res_trafo.q_hv_mvar.iloc[0], .001), .01, side="hv", element=0) success = estimate(net, tolerance=1e-6, zero_injection=None) assert success
def test_opf_sgen_voltage(): """ Testing a simple network with transformer for voltage constraints with OPF using a static generator """ # boundaries vm_max = 1.04 vm_min = 0.96 # 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_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) pp.create_bus(net, max_vm_pu=vm_max, min_vm_pu=vm_min, vn_kv=.4) pp.create_transformer_from_parameters(net, 0, 1, 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, max_loading_percent=1000000) pp.create_sgen(net, 3, p_kw=-10, controllable=True, max_p_kw=- 15, min_p_kw=-5, max_q_kvar=25, min_q_kvar=-25, cost_per_kw = -100) pp.create_ext_grid(net, 0) pp.create_line_from_parameters(net, 1, 2, 1, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, imax_ka=0.123, x_ohm_per_km=0.1159876, max_loading_percent=1000000) pp.create_line_from_parameters(net, 2, 3, 1, name="line2", r_ohm_per_km=0.876, c_nf_per_km=260.0, imax_ka=0.123, x_ohm_per_km=0.1159876, max_loading_percent=1000000) # run OPF pp.runopp(net, verbose=False) assert net["OPF_converged"] # assert and check result logger.debug("test_opf_sgen_voltage") logger.debug("res_sgen:\n%s" % net.res_sgen) logger.debug("res_bus.vm_pu: \n%s" % net.res_bus.vm_pu) assert max(net.res_bus.vm_pu) < vm_max assert net.OPF_converged
def test_mixed_p_q_pol(): 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.create_polynomial_cost(net, 0, "gen", np.array([0, -1, 0]), type="q") pp.runopp(net, verbose=False) assert net["OPF_converged"] assert net.res_cost == -net.res_gen.p_kw.values + net.res_gen.q_kvar.values
def test_cost_piecewise_linear_sgen_q(): """ 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_sgen(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) 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([[-50, 50], [50, -50]]), type="q") # run OPF pp.runopp(net, verbose=False) assert net["OPF_converged"] assert net.res_cost - net.res_sgen.q_kvar.values < 1e-3
def test_oos_buses_at_trafo3w(): net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=110.) b2 = pp.create_bus(net, vn_kv=110.) b3 = pp.create_bus(net, vn_kv=110., in_service=False) b4 = pp.create_bus(net, vn_kv=20., in_service=False) b5 = pp.create_bus(net, vn_kv=10., in_service=False) pp.create_ext_grid(net, b1) l1 = pp.create_line(net, b1, b2, 0.5, std_type="NAYY 4x50 SE", in_service=True) l2 = pp.create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", in_service=False) tidx = pp.create_transformer3w( net, b3, b4, b5, std_type='63/25/38 MVA 110/20/10 kV', in_service=True) pp.runpp(net, trafo3w_losses = 'star', trafo_model= 'pi', init='flat') assert net.res_line.loading_percent.at[l1] > 0 assert np.isnan(net.res_trafo3w.i_hv_ka.at[tidx])
def test_equal_indices_res(): # tests if res_bus indices of are the same as the ones in bus. # If this is not the case and you init from results, the PF will fail net = pp.create_empty_network() b1 = pp.create_bus(net, vn_kv=10., index=3) b2 = pp.create_bus(net, vn_kv=0.4, index=1) b3 = pp.create_bus(net, vn_kv=0.4, index=2) pp.create_ext_grid(net, b1) pp.create_transformer(net, b1, b2, std_type="0.63 MVA 20/0.4 kV") pp.create_line(net, b2, b3, 0.5, std_type="NAYY 4x50 SE", index=4) pp.create_load(net, b3, p_mw=0.010) pp.runpp(net) net["bus"] = net["bus"].sort_index() try: pp.runpp(net, init_vm_pu="results", init_va_degree="results") assert True except LoadflowNotConverged: assert False
def test_result_index_unsorted(): net = pp.create_empty_network() pp.set_user_pf_options(net, tolerance_mva=1e-9) b1 = pp.create_bus(net, vn_kv=0.4, index=4) b2 = pp.create_bus(net, vn_kv=0.4, index=2) b3 = pp.create_bus(net, vn_kv=0.4, index=3) pp.create_gen(net, b1, p_mw=0.01, vm_pu=0.4) pp.create_load(net, b2, p_mw=0.01) pp.create_ext_grid(net, b3) pp.create_line(net, from_bus=b1, to_bus=b2, length_km=0.5, std_type="NAYY 4x120 SE") pp.create_line(net, from_bus=b1, to_bus=b3, length_km=0.5, std_type="NAYY 4x120 SE") net_recycle = copy.deepcopy(net) pp.runpp(net_recycle) pp.runpp(net_recycle, recycle=dict(trafo=True, bus_pq=True, gen=True)) pp.runpp(net) assert nets_equal(net, net_recycle, atol=1e-12)
def simple_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)) b3 = pp.create_bus(net, name="bus3", geodata=(1, 3)) b4 = pp.create_bus(net, name="bus4", vn_kv=10.) pp.create_transformer(net, b4, b2, std_type="0.25 MVA 10/0.4 kV", name=None, in_service=True, index=None) pp.create_line(net, b2, b3, 1, name="line1", std_type="NAYY 4x150 SE", geodata=np.array([[1, 2], [3, 4]])) pp.create_line(net, b1, b4, 1, name="line2", std_type="NAYY 4x150 SE") pp.create_load(net, b2, p_mw=0.01, q_mvar=0, name="load1") pp.create_load(net, b3, p_mw=0.04, q_mvar=0.002, name="load2") pp.create_gen(net, 3, q_mvar=0.020, vm_pu=1.0) pp.create_sgen(net, 2, p_mw=0.050, sn_mva=0.1) 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 test_network_with_trafo3w_with_disabled_branch(): net = pp.create_empty_network() bus_slack = pp.create_bus(net, vn_kv=110) pp.create_ext_grid(net, bus=bus_slack) bus_20_1 = pp.create_bus(net, vn_kv=20,name="b") pp.create_sgen(net, bus=bus_20_1, p_mw=0.03, q_mvar=0.02) bus_10_1 = pp.create_bus(net, vn_kv=10) pp.create_sgen(net, bus=bus_10_1, p_mw=0.02, q_mvar=0.02) bus_10_2 = pp.create_bus(net, vn_kv=10) pp.create_load(net, bus=bus_10_2, p_mw=0.06, q_mvar=0.01) pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) disabled_line = pp.create_line(net, from_bus=bus_10_1, to_bus=bus_10_2, std_type="149-AL1/24-ST1A 10.0", length_km=2) net.line.at[disabled_line, 'in_service'] = False pp.create_transformer3w(net, bus_slack, bus_20_1, bus_10_1, std_type="63/25/38 MVA 110/20/10 kV") pp.runpp(net) pp.create_measurement(net, "p", "line", net.res_line.p_from_mw[0], 0.001, 0, 'from') pp.create_measurement(net, "q", "line", net.res_line.q_from_mvar[0], 0.001, 0, 'from') pp.create_measurement(net, "p", "line", net.res_line.p_to_mw[0], 0.001, 0, 'to') pp.create_measurement(net, "q", "line", net.res_line.q_to_mvar[0], 0.001, 0, 'to') pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_hv_mw[0], 0.001, 0, 'hv') pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_hv_mvar[0], 0.001, 0, 'hv') pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_mv_mw[0], 0.002, 0, 'mv') pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_mv_mvar[0], 0.002, 0, 'mv') pp.create_measurement(net, "p", "trafo3w", net.res_trafo3w.p_lv_mw[0], 0.001, 0, 'lv') pp.create_measurement(net, "q", "trafo3w", net.res_trafo3w.q_lv_mvar[0], 0.001, 0, 'lv') pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[0], 0.01, 0) pp.create_measurement(net, "v", "bus", net.res_bus.vm_pu[1], 0.01, 1) success = estimate(net) assert success assert (np.nanmax(np.abs(net.res_bus.vm_pu.values - net.res_bus_est.vm_pu.values)) < 0.006) assert (np.nanmax(np.abs(net.res_bus.va_degree.values- net.res_bus_est.va_degree.values)) < 0.006)
def test_3bus_with_2_slacks(): # load the net which already contains 3 buses net = load_3bus_network() # add the same net with different slack (no galvanic connection) # skip bus index 4 as further stability test pp.create_bus(net, name="bus5", vn_kv=1., index=5) pp.create_bus(net, name="bus6", vn_kv=1., index=6) pp.create_bus(net, name="bus7", vn_kv=1., index=7) pp.create_ext_grid(net, 5) pp.create_line_from_parameters(net, 5, 6, 1, r_ohm_per_km=.01, x_ohm_per_km=.03, c_nf_per_km=0., max_i_ka=1) pp.create_line_from_parameters(net, 5, 7, 1, r_ohm_per_km=.02, x_ohm_per_km=.05, c_nf_per_km=0., max_i_ka=1) pp.create_line_from_parameters(net, 6, 7, 1, r_ohm_per_km=.03, x_ohm_per_km=.08, c_nf_per_km=0., max_i_ka=1) pp.create_measurement(net, "v", "bus", 1.006, .004, element=5) # V at bus 5 pp.create_measurement(net, "v", "bus", .968, .004, element=6) # V at bus 6 pp.create_measurement(net, "p", "bus", -.501, .010, element=6) # P at bus 6 pp.create_measurement(net, "q", "bus", -.286, .010, element=6) # Q at bus 6 pp.create_measurement(net, "p", "line", .888, .008, 3, 5) # Pline (bus 5 -> bus 6) at bus 5 pp.create_measurement(net, "p", "line", 1.173, .008, 4, 5) # Pline (bus 5 -> bus 7) at bus 5 pp.create_measurement(net, "q", "line", .568, .008, 3, 5) # Qline (bus 5 -> bus 6) at bus 5 pp.create_measurement(net, "q", "line", .663, .008, 4, 5) # Qline (bus 5 -> bus 7) at bus 5 # 2. Do state estimation success = estimate(net, init='flat', maximum_iterations=10) v_result = net.res_bus_est.vm_pu.values delta_result = net.res_bus_est.va_degree.values target_v = np.array([0.9996, 0.9741, 0.9438, np.nan, 0.9996, 0.9741, 0.9438]) diff_v = target_v - v_result target_delta = np.array([0.0, -1.2475469989322963, -2.7457167371166862, np.nan, 0.0, -1.2475469989322963, -2.7457167371166862]) diff_delta = target_delta - delta_result assert success assert (np.nanmax(abs(diff_v)) < 1e-4) assert (np.nanmax(abs(diff_delta)) < 1e-4)
def test_cost_pwl_q_3point(): # We have a problem with the cost value after optimization of 3 point q cost functions! It returns the amount of q at the EG, but not the costs! # Also, the q result is not the optimum! 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, 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) 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([[-50, 50], [0, 0], [50, 50]]), type="q") # run OPF pp.runopp(net, verbose=False) assert net["OPF_converged"]
def test_overloaded_lines(): net = pp.create_empty_network() bus0 = pp.create_bus(net, vn_kv=.4) bus1 = pp.create_bus(net, vn_kv=.4) pp.create_ext_grid(net, bus0) line0 = pp.create_line(net, bus0, bus1, length_km=1, std_type="NAYY 4x50 SE") line1 = pp.create_line(net, bus0, bus1, length_km=1, std_type="NA2XS2Y 1x95 RM/25 12/20 kV") line2 = pp.create_line(net, bus0, bus1, length_km=1, std_type="15-AL1/3-ST1A 0.4") line3 = pp.create_line(net, bus0, bus1, length_km=10, std_type="149-AL1/24-ST1A 10.0") pp.create_load(net, bus1, p_kw=200, q_kvar=50) pp.runpp(net) # test the overloaded lines by default value of max_load=100 overloaded_lines = tb.overloaded_lines(net, max_load=100) assert set(overloaded_lines) == set([line0, line1]) # test the overloaded lines by a self defined value of max_load=50 overloaded_lines = tb.overloaded_lines(net, max_load=50) assert set(overloaded_lines) == set([line0, line1, line2])
def test_continuous_tap_control_vectorized_hv(): # --- load system and run power flow net = pp.create_empty_network() pp.create_buses(net, 6, 110) pp.create_buses(net, 5, 20) pp.create_ext_grid(net, 0) pp.create_lines(net, np.zeros(5), np.arange(1, 6), 10, "243-AL1/39-ST1A 110.0") for hv, lv in zip(np.arange(1, 6), np.arange(6, 11)): pp.create_transformer(net, hv, lv, "63 MVA 110/20 kV") pp.create_load(net, lv, 25 * (lv - 8), 25 * (lv - 8) * 0.4) pp.set_user_pf_options(net, init='dc', calculate_voltage_angles=True) # --- run loadflow pp.runpp(net) net_ref = net.deepcopy() # create with individual controllers for comparison tol = 1e-4 for tid in net.trafo.index.values: ContinuousTapControl(net_ref, tid=tid, side='hv', vm_set_pu=1.02, tol=tol) # run control reference pp.runpp(net_ref, run_control=True) # now create the vectorized version ContinuousTapControl(net, tid=net.trafo.index.values, side='hv', vm_set_pu=1.02, tol=tol) pp.runpp(net, run_control=True) assert np.allclose(net_ref.trafo.tap_pos, net.trafo.tap_pos, atol=1e-2, rtol=0)
def test_pandapower_case(): #more complicated examples like #net = pandapower.networks.example_simple() #can be used once the import of e.g. switches is perfected #create empty net net = pp.create_empty_network() #create buses b1 = pp.create_bus(net, vn_kv=20., name="Bus 1") b2 = pp.create_bus(net, vn_kv=0.4, name="Bus 2") b3 = pp.create_bus(net, vn_kv=0.4, name="Bus 3") #create bus elements pp.create_ext_grid(net, bus=b1, vm_pu=1.02, name="Grid Connection") pp.create_load(net, bus=b3, p_kw=100, q_kvar=50, name="Load") #create branch elements tid = pp.create_transformer(net, hv_bus=b1, lv_bus=b2, std_type="0.4 MVA 20/0.4 kV", name="Trafo") pp.create_line(net, from_bus=b2, to_bus=b3, length_km=0.1, name="Line", std_type="NAYY 4x50 SE") #because of phase angles, need to init with DC pp.runpp(net,calculate_voltage_angles=True,init="dc") n = pypsa.Network() n.import_from_pandapower_net(net) #seed PF with LPF solution because of phase angle jumps n.lpf() n.pf(use_seed=True) #use same index for everything net.res_bus.index = net.bus.name.values net.res_line.index = net.line.name.values #compare bus angles np.testing.assert_array_almost_equal(n.buses_t.v_ang.loc["now"]*180/np.pi,net.res_bus.va_degree) #compare bus voltage magnitudes np.testing.assert_array_almost_equal(n.buses_t.v_mag_pu.loc["now"],net.res_bus.vm_pu) #compare bus active power (NB: pandapower uses load signs) np.testing.assert_array_almost_equal(n.buses_t.p.loc["now"],-net.res_bus.p_kw/1e3) #compare bus active power (NB: pandapower uses load signs) np.testing.assert_array_almost_equal(n.buses_t.q.loc["now"],-net.res_bus.q_kvar/1e3) #compare branch flows np.testing.assert_array_almost_equal(n.lines_t.p0.loc["now"],net.res_line.p_from_kw/1e3) np.testing.assert_array_almost_equal(n.lines_t.p1.loc["now"],net.res_line.p_to_kw/1e3) np.testing.assert_array_almost_equal(n.lines_t.q0.loc["now"],net.res_line.q_from_kvar/1e3) np.testing.assert_array_almost_equal(n.lines_t.q1.loc["now"],net.res_line.q_to_kvar/1e3) np.testing.assert_array_almost_equal(n.transformers_t.p0.loc["now"],net.res_trafo.p_hv_kw/1e3) np.testing.assert_array_almost_equal(n.transformers_t.p1.loc["now"],net.res_trafo.p_lv_kw/1e3) np.testing.assert_array_almost_equal(n.transformers_t.q0.loc["now"],net.res_trafo.q_hv_kvar/1e3) np.testing.assert_array_almost_equal(n.transformers_t.q1.loc["now"],net.res_trafo.q_lv_kvar/1e3)