From f56c0f3b3cf67c2745aecd898dbbe04495ae11d4 Mon Sep 17 00:00:00 2001 From: Baraa Alfakhouri Date: Sat, 4 Nov 2023 08:24:44 +0100 Subject: [PATCH 1/2] add test for tcsc slack --- pandapower/create.py | 2 +- pandapower/test/loadflow/test_facts.py | 36 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pandapower/create.py b/pandapower/create.py index 92aadbead..66eadd82d 100644 --- a/pandapower/create.py +++ b/pandapower/create.py @@ -4849,7 +4849,7 @@ def create_tcsc(net, from_bus, to_bus, x_l_ohm, x_cvar_ohm, set_p_to_mw, min_angle_degree=90, max_angle_degree=180, **kwargs): """ Creates a TCSC element - series impedance compensator to control series reactance. - The TCSC device allows controlling the active power flow throgh the path it is connected in. + The TCSC device allows controlling the active power flow through the path it is connected in. Multiple TCSC elements in net are possible. Unfortunately, TCSC is not implemented for the case when multiple TCSC elements diff --git a/pandapower/test/loadflow/test_facts.py b/pandapower/test/loadflow/test_facts.py index c8e354693..4af9e26ec 100644 --- a/pandapower/test/loadflow/test_facts.py +++ b/pandapower/test/loadflow/test_facts.py @@ -418,6 +418,42 @@ def test_tcsc_simple3(): # test results by comparing impedance result to formula; p, q, i by comparing to line results; vm, va by comparing to bus results +def test_tcsc_simple3_slack(): + baseMVA = 100 # MVA + baseV = 110 # kV + baseI = baseMVA / (baseV * np.sqrt(3)) + baseZ = baseV ** 2 / baseMVA + xl = 0.2 + xc = -20 + # plot_z(baseZ, xl, xc) + + # (0)-------------(1)-----------------(3)-> + # |-----(TCSC)--(2)-------------------| + + net = pp.create_empty_network(sn_mva=baseMVA) + pp.create_buses(net, 4, baseV) + pp.create_ext_grid(net, 0) + pp.create_line_from_parameters(net, 0, 1, 20, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 1, 3, 20, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 2, 3, 20, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 1, 2, 20, 0.0487, 0.13823, 160, 0.664) + + pp.create_load(net, 2, 100, 40) + + pp.plotting.simple_plot(net) + pp.create_tcsc(net, 2,0, xl, xc, 5, 170, "Test", controllable=True, min_angle_degree=90, max_angle_degree=180) + + runpp_with_consistency_checks(net, init="dc") + + net_ref = copy_with_impedance(net) + pp.runpp(net_ref) + compare_tcsc_impedance(net, net_ref, net.tcsc.index, net_ref.impedance.index) + + # todo: + # test with distributed slack + # test results by comparing impedance result to formula; p, q, i by comparing to line results; vm, va by comparing to bus results + + def test_compare_to_impedance(): baseMVA = 100 # MVA baseV = 110 # kV From e87003e063aab58fa317c5f498b24ed5df1e7d64 Mon Sep 17 00:00:00 2001 From: Baraa Alfakhouri Date: Thu, 9 Nov 2023 18:56:13 +0100 Subject: [PATCH 2/2] add test_simple_2vsc_hvdc --- pandapower/test/loadflow/test_facts.py | 265 +++++++++++++++++++++++++ 1 file changed, 265 insertions(+) diff --git a/pandapower/test/loadflow/test_facts.py b/pandapower/test/loadflow/test_facts.py index 15ed1869e..732fa7bad 100644 --- a/pandapower/test/loadflow/test_facts.py +++ b/pandapower/test/loadflow/test_facts.py @@ -1987,6 +1987,271 @@ def test_line_dc_and_2_vsc2(): runpp_with_consistency_checks(net) +def test_multi_VSCs(): + + net = pp.from_json(r"C:\Users\malfakhouri\Downloads\20191120_testnetz_DC_small_2.json") + + pp.drop_elements(net,element_type='line_dc',element_index=[0,1]) + pp.drop_elements(net,element_type='vsc',element_index=[0,1,2,3]) + + + pp.create_line_dc_from_parameters(net,0,2,100.0,0.01,1.4,alpha=0.00403,temperature_degree_celsius=80.0) + pp.create_line_dc_from_parameters(net,1,3,100.0,0.01,1.4,alpha=0.00403,temperature_degree_celsius=80.0) + + pp.create_vsc(net,1,0,0.0968,24.199806,'vm_pu',1.0,'p_mw',10.000863,controllable=True,in_service=True) + pp.create_vsc(net,1,1,0.0968,24.199806,'vm_pu',1.0,'p_mw',10.000863,controllable=True,in_service=True) + pp.create_vsc(net,0,2,0.0968,36.299871,'q_mvar',-5.0,'p_mw',10.000863,controllable=True,in_service=True) + pp.create_vsc(net,0,3,0.0968,36.299871,'q_mvar',-5.0,'vm_pu',1,controllable=True,in_service=True) + + # net.bus_dc.loc[[0, 2], "in_service"] = False + # net.line_dc.loc[0, "in_service"] = False + + # net.vsc.control_mode_dc[net.vsc.index.isin([2,3])] = 'p_mw' + # net.vsc.control_value_dc[net.vsc.index.isin([2,3])] = 10.000863 + # + # net.vsc.control_mode_dc[net.vsc.index.isin([0,1])] = 'vm_pu' + # net.vsc.control_value_dc[net.vsc.index.isin([0,1])] = 1 + # + # + # net.vsc.control_mode_ac[net.vsc.index.isin([2,3])] = 'vm_pu' + # net.vsc.control_value_ac[net.vsc.index.isin([2,3])] = 1 + # + # net.vsc.control_mode_ac[net.vsc.index.isin([0,1])] = 'q_mvar' + # net.vsc.control_value_ac[net.vsc.index.isin([0,1])] = -5.0 + # + + + # net.vsc.in_service[net.vsc.index.isin([0, 2])] = False + + # + # net.vsc.control_mode_dc[net.vsc.index.isin([1])] = 'vm_pu' + # net.vsc.control_value_dc[net.vsc.index.isin([1])] = 1 + # + # net.vsc.control_mode_dc[net.vsc.index.isin([3])] = 'p_mw' + # net.vsc.control_value_dc[net.vsc.index.isin([3])] = 10.000863 + # + + pd.set_option('display.max_rows', 500) + pd.set_option('display.max_columns', 500) + pd.set_option('display.width', 1000) + + pp.runpp(net) + + + # pp.plotting.simple_plot(net) + + +def test_simple_2vsc_hvdc(): + + import itertools + + def net_2vsc_1ac_2dc_buses(): + + net = pp.create_empty_network() + # AC part + pp.create_buses(net, 2, 110) + pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + pp.create_ext_grid(net, 0) + pp.create_load(net, 1, 10) + + # DC part + pp.create_bus_dc(net, 110, 'A') + pp.create_bus_dc(net, 110, 'B') + + pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + + return net + + def net_2vsc_2ac_1dc_buses(): + + net = pp.create_empty_network() + # AC part + pp.create_buses(net, 3, 110) + pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 0, 2, 30, 0.0487, 0.13823, 160, 0.664) + + pp.create_ext_grid(net, 0) + pp.create_load(net, 1, 10) + + # DC part + pp.create_bus_dc(net, 110, 'A') + pp.create_bus_dc(net, 110, 'A') + + pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + + return net + + def net_2vsc_1ac_1dc_buses(): + + net = pp.create_empty_network() + # AC part + pp.create_buses(net, 2, 110) + pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + + pp.create_ext_grid(net, 0) + pp.create_load(net, 1, 10) + + # DC part + pp.create_bus_dc(net, 110, 'A') + pp.create_bus_dc(net, 110, 'A') + + pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + + return net + + + + + dict1 = {'work':[],"don't work":[],'error':[]} + dict2 = {'work':[],"don't work":[],'error':[]} + dict3 = {'work':[],"don't work":[],'error':[]} + + + + control_mode_ac = ['vm_pu','q_mvar'] + control_mode_dc = ['vm_pu','p_mw',] + + control_value_ac = [1,-5.0] + control_value_dc = [1,10] + + mode = itertools.product(control_mode_ac,control_mode_dc , repeat=2) + + value = itertools.product(control_value_ac,control_value_dc , repeat=2) + + for idx,((i,j,m,n),(q,w,e,r)) in enumerate(zip(mode,value)): + + net = net_2vsc_1ac_2dc_buses() + + if j == n == 'p_mw': ### because there must be a slack for dc + continue + + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac=i, control_value_ac=q, control_mode_dc=j, control_value_dc=w) + pp.create_vsc(net, 1, 1, 0.1, 5, control_mode_ac=m, control_value_ac=e, control_mode_dc=n, control_value_dc=r) + + try: + + pp.runpp(net) + + dict1['work'].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict1['work'].append(f"pp.create_vsc(net, 1, 1, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + + + except Exception as x: + dict1["error"].append(x) + dict1["error"].append(None) + # dict1["don't work"].append(e) + + print(f"Error occurred: {x}") + print(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + print(f"pp.create_vsc(net, 1, 1, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + dict1["don't work"].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict1["don't work"].append(f"pp.create_vsc(net, 1, 1, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + continue + + + + + mode = itertools.product(control_mode_ac,control_mode_dc , repeat=2) + + value = itertools.product(control_value_ac,control_value_dc , repeat=2) + + for idx, ((i, j, m, n), (q, w, e, r)) in enumerate(zip(mode, value)): + + net = net_2vsc_2ac_1dc_buses() + + if j == n == 'p_mw': ### because there must be a slack for dc + continue + + # if j != n == 'vm_pu': + # + # + # continue + + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac=i, control_value_ac=q, control_mode_dc=j, control_value_dc=w) + pp.create_vsc(net, 2, 0, 0.1, 5, control_mode_ac=m, control_value_ac=e, control_mode_dc=n, control_value_dc=r) + + + try: + + pp.runpp(net) + + dict2['work'].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict2['work'].append(f"pp.create_vsc(net, 2, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + + + except Exception as x: + dict2["error"].append(x) + dict2["error"].append(None) + # dict2["don't work"].append(e) + + # print(f"Error occurred: {x}") + # print(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + # print(f"pp.create_vsc(net, 2, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + dict2["don't work"].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict2["don't work"].append(f"pp.create_vsc(net, 2, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + continue + + + + mode = itertools.product(control_mode_ac,control_mode_dc , repeat=2) + + value = itertools.product(control_value_ac,control_value_dc , repeat=2) + + for idx, ((i, j, m, n), (q, w, e, r)) in enumerate(zip(mode, value)): + + net = net_2vsc_1ac_1dc_buses() + + if j == n == 'p_mw': ### because there must be a slack for dc + continue + + # if j != n == 'vm_pu': + # + # + # continue + + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac=i, control_value_ac=q, control_mode_dc=j, control_value_dc=w) + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac=m, control_value_ac=e, control_mode_dc=n, control_value_dc=r) + + + try: + + pp.runpp(net) + + dict3['work'].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict3['work'].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + + + except Exception as x: + dict3["error"].append(x) + dict3["error"].append(None) + # dict2["don't work"].append(e) + + print(f"Error occurred: {x}") + print(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + print(f"pp.create_vsc(net, 2, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + dict3["don't work"].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={i}, control_value_ac={q}, control_mode_dc={j}, control_value_dc={w})") + dict3["don't work"].append(f"pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac={m}, control_value_ac={e}, control_mode_dc={n}, control_value_dc={r})") + + continue + + + df1 = pd.DataFrame.from_dict(dict1,orient='index') + df2 = pd.DataFrame.from_dict(dict2,orient='index') + df3 = pd.DataFrame.from_dict(dict3,orient='index') + + + df1.transpose().to_csv(r"C:\Users\malfakhouri\Desktop\VSC\net_2vsc_1ac_2dc_buses.csv", index=False) + df2.transpose().to_csv(r"C:\Users\malfakhouri\Desktop\VSC\net_2vsc_2ac_1dc_buses.csv", index=False) + df3.transpose().to_csv(r"C:\Users\malfakhouri\Desktop\VSC\net_2vsc_1ac_1dc_buses.csv", index=False) + + + + # TODO VSC as slack - cannot work because slack is a Vm-Va bus, # and the VSC is a Vm bus? One way to implement this is to declare