def test_opf_ext_grid_controllable_pm(): # load net net = case5_pm_matfile_I() net_old = copy.deepcopy(net) pp.runpp(net_old) pp.runpm_ac_opf(net_old, calculate_voltage_angles=True, correct_pm_network_data=False, opf_flow_lim="I") net_new = copy.deepcopy(net) net_new.ext_grid["controllable"] = True pp.runpp(net_new) pp.runpm_ac_opf(net_new, calculate_voltage_angles=True, correct_pm_network_data=False, opf_flow_lim="I") assert np.isclose(net_new.res_bus.vm_pu[net.ext_grid.bus[0]], 1.0586551789267864) assert np.isclose(net_old.res_bus.vm_pu[net.ext_grid.bus[0]], 1.06414000007302) assert np.isclose(net_old.res_cost, 17082.8) assert np.isclose(net_new.res_cost, 17015.5635)
def test_compare_pwl_and_poly(net_3w_trafo_opf): net = net_3w_trafo_opf pp.create_pwl_cost(net, 0, 'ext_grid', [[0, 1, 1]]) pp.create_pwl_cost(net, 0, 'gen', [[0, 30, 3], [30, 80, 3]]) pp.create_pwl_cost(net, 1, 'gen', [[0, 100, 2]]) pp.runpm_ac_opf(net) consistency_checks(net) p_gen = net.res_gen.p_mw.values q_gen = net.res_gen.q_mvar.values vm_bus = net.res_bus.vm_pu.values va_bus = net.res_bus.va_degree.values net.pwl_cost.drop(net.pwl_cost.index, inplace=True) pp.create_poly_cost(net, 0, 'ext_grid', cp1_eur_per_mw=1) pp.create_poly_cost(net, 0, 'gen', cp1_eur_per_mw=3) pp.create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=2) pp.runpm_ac_opf(net) consistency_checks(net) np.allclose(p_gen, net.res_gen.p_mw.values) np.allclose(q_gen, net.res_gen.q_mvar.values) np.allclose(vm_bus, net.res_bus.vm_pu.values) np.allclose(va_bus, net.res_bus.va_degree.values) pp.runpm_dc_opf(net) consistency_checks(net) np.allclose(p_gen, net.res_gen.p_mw.values) np.allclose(va_bus, net.res_bus.va_degree.values)
def test_multiple_ext_grids(): net = pp.create_empty_network() # generate three ext grids b11, b12, l11 = add_grid_connection(net, vn_kv=110.) b21, b22, l21 = add_grid_connection(net, vn_kv=110.) b31, b32, l31 = add_grid_connection(net, vn_kv=110.) # connect them l12_22 = create_test_line(net, b12, b22) l22_32 = create_test_line(net, b22, b32) # create load and sgen to optimize pp.create_load(net, b12, p_mw=60) g3 = pp.create_sgen(net, b12, p_mw=50, min_p_mw=20, max_p_mw=200, controllable=True) pp.create_poly_cost(net, g3, 'sgen', cp1_eur_per_mw=10.) # set positive costs for ext_grid -> minimize ext_grid usage ext_grids = net.ext_grid.index net["ext_grid"].loc[0, "vm_pu"] = .99 net["ext_grid"].loc[1, "vm_pu"] = 1.0 net["ext_grid"].loc[2, "vm_pu"] = 1.01 for idx in ext_grids: # eg = net["ext_grid"].loc[idx] pp.create_poly_cost(net, idx, 'ext_grid', cp1_eur_per_mw=10.) pp.runpm_ac_opf(net) assert np.allclose(net.res_sgen.loc[0, "p_mw"], 60.)
def test_pwl(): net = pp.create_empty_network() # create buses bus1 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) bus2 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) bus3 = pp.create_bus(net, vn_kv=110., min_vm_pu=0.9, max_vm_pu=1.1) # create 110 kV lines pp.create_line(net, bus1, bus2, length_km=50., std_type='149-AL1/24-ST1A 110.0') pp.create_line(net, bus2, bus3, length_km=50., std_type='149-AL1/24-ST1A 110.0') # create loads pp.create_load(net, bus2, p_mw=80, controllable=False) # create generators g1 = pp.create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01, slack=True) g2 = pp.create_gen(net, bus3, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) # net.gen["controllable"] = False pp.create_pwl_cost(net, g1, 'gen', [[0, 2, 2], [2, 80, 5]]) pp.create_pwl_cost(net, g2, 'gen', [[0, 2, 2], [2, 80, 5]]) pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.iloc[0], net.res_gen.p_mw.iloc[1]) assert np.isclose(net.res_gen.q_mvar.iloc[0], net.res_gen.q_mvar.iloc[1]) net.pwl_cost.drop(net.pwl_cost.index, inplace=True) g3 = pp.create_gen(net, bus1, p_mw=80, min_p_mw=0, max_p_mw=80, vm_pu=1.01) pp.create_pwl_cost(net, g1, 'gen', [[0, 2, 1.], [2, 80, 8.]]) pp.create_pwl_cost(net, g2, 'gen', [[0, 3, 2.], [3, 80, 14]]) pp.create_pwl_cost(net, g3, 'gen', [[0, 1, 3.], [1, 80, 10.]]) net.load.p_mw = 1 pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g2], 0) assert np.isclose(net.res_gen.p_mw.at[g3], 0) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1], atol=1e-4) net.load.p_mw = 3 pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g3], 0) assert np.isclose(net.res_gen.p_mw.at[g1], 2) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] + net.res_gen.p_mw.at[g2] * 2, atol=1e-4) net.load.p_mw = 5 pp.runpm_ac_opf(net) consistency_checks(net, rtol=1e-3) assert np.isclose(net.res_gen.p_mw.at[g1], 2) assert np.isclose(net.res_gen.p_mw.at[g2], 3) assert np.isclose(net.res_cost, net.res_gen.p_mw.at[g1] + net.res_gen.p_mw.at[g2] * 2 + net.res_gen.p_mw.at[g3] * 3, atol=1e-4)
def optimal_ac(self, powermodels=True): """ Run optimal power flow. :return: A tuple of bus, generator, and external grid results as numpy arrays. Each column represents a different value. Returns None if not converged. Bus columns: [|V| angle(V) Re(S) Im(S)]. Generator columns: [Re(S) Im(S)] External grid columns: [Re(S) Im(S)] """ try: if powermodels: pp.runpm_ac_opf(self.net, calculate_voltage_angles=True, trafo_model="pi") else: pp.runopp(self.net, calculate_voltage_angles=True) except pp.OPFNotConverged: return None return self._results()
def test_compare_pwl_and_poly(net_3w_trafo_opf): net = net_3w_trafo_opf net.ext_grid.loc[:, "min_p_mw"] = -999. net.ext_grid.loc[:, "max_p_mw"] = 999. net.ext_grid.loc[:, "max_q_mvar"] = 999. net.ext_grid.loc[:, "min_q_mvar"] = -999. pp.create_pwl_cost(net, 0, 'ext_grid', [[0, 1, 1]]) pp.create_pwl_cost(net, 0, 'gen', [[0, 30, 3], [30, 80, 3]]) pp.create_pwl_cost(net, 1, 'gen', [[0, 80, 2]]) net.bus.loc[:, "max_vm_pu"] = 1.1 net.bus.loc[:, "min_vm_pu"] = .9 pp.runpm_ac_opf(net) consistency_checks(net) p_gen = net.res_gen.p_mw.values q_gen = net.res_gen.q_mvar.values vm_bus = net.res_bus.vm_pu.values va_bus = net.res_bus.va_degree.values net.pwl_cost.drop(net.pwl_cost.index, inplace=True) pp.create_poly_cost(net, 0, 'ext_grid', cp1_eur_per_mw=1) pp.create_poly_cost(net, 0, 'gen', cp1_eur_per_mw=3) pp.create_poly_cost(net, 1, 'gen', cp1_eur_per_mw=2) # pp.runopp(net) pp.runpm_ac_opf(net, correct_pm_network_data=False) consistency_checks(net) np.allclose(p_gen, net.res_gen.p_mw.values) np.allclose(q_gen, net.res_gen.q_mvar.values) np.allclose(vm_bus, net.res_bus.vm_pu.values) np.allclose(va_bus, net.res_bus.va_degree.values) # pp.rundcopp(net) pp.runpm_dc_opf(net, correct_pm_network_data=False) consistency_checks(net, test_q=False) np.allclose(p_gen, net.res_gen.p_mw.values) np.allclose(va_bus, net.res_bus.va_degree.values)
def test_voltage_angles(): net = pp.create_empty_network() b1, b2, l1 = add_grid_connection(net, vn_kv=110.) b3 = pp.create_bus(net, vn_kv=20.) b4 = pp.create_bus(net, vn_kv=10.) b5 = pp.create_bus(net, vn_kv=10., in_service=False) tidx = pp.create_transformer3w( net, b2, b3, b4, std_type='63/25/38 MVA 110/20/10 kV', max_loading_percent=120) pp.create_load(net, b3, p_mw=5, controllable=False) load_id = pp.create_load(net, b4, p_mw=5, controllable=True, max_p_mw=25, min_p_mw=0, min_q_mvar=-1e-6, max_q_mvar=1e-6) pp.create_poly_cost(net, 0, "ext_grid", cp1_eur_per_mw=1) pp.create_poly_cost(net, load_id, "load", cp1_eur_per_mw=1000) net.trafo3w.shift_lv_degree.at[tidx] = 10 net.trafo3w.shift_mv_degree.at[tidx] = 30 net.bus.loc[:, "max_vm_pu"] = 1.1 net.bus.loc[:, "min_vm_pu"] = .9 # load is zero since costs are high. PF results should be the same as OPF net.load.loc[1, "p_mw"] = 0. pp.runpp(net, calculate_voltage_angles=True) va_degree = net.res_bus.loc[:, "va_degree"].values vm_pu = net.res_bus.loc[:, "vm_pu"].values loading3w = net.res_trafo3w.loc[:, "loading_percent"].values net_opf = copy.deepcopy(net) pp.runpm_ac_opf(net_opf) assert 30. < (net_opf.res_bus.va_degree.at[b1] - net_opf.res_bus.va_degree.at[b3]) % 360 < 32. assert 10. < (net_opf.res_bus.va_degree.at[b1] - net_opf.res_bus.va_degree.at[b4]) % 360 < 11. assert np.isnan(net_opf.res_bus.va_degree.at[b5]) assert np.allclose(net_opf.res_bus.va_degree.values, va_degree, atol=1e-6, rtol=1e-6, equal_nan=True) assert np.allclose(net_opf.res_bus.vm_pu.values, vm_pu, atol=1e-6, rtol=1e-6, equal_nan=True) assert np.allclose(net_opf.res_trafo3w.loading_percent, loading3w, atol=1e-2, rtol=1e-2, equal_nan=True)
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)