From 842b05db21d39a3cc5263d3e256d9b4cf0994e8d Mon Sep 17 00:00:00 2001 From: Roman Bolgaryn Date: Wed, 8 Nov 2023 16:44:37 +0100 Subject: [PATCH] use csr_matrix for J_m_vsc to allow for parallel configurations for VSC HVDC systems --- pandapower/pf/create_jacobian_facts.py | 23 ++++++++- pandapower/test/loadflow/test_facts.py | 65 ++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/pandapower/pf/create_jacobian_facts.py b/pandapower/pf/create_jacobian_facts.py index bedda1b4c..107374c4b 100644 --- a/pandapower/pf/create_jacobian_facts.py +++ b/pandapower/pf/create_jacobian_facts.py @@ -244,6 +244,10 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo t_in_pq = np.isin(t, pq) t_in_pvpq = np.isin(t, pvpq) + rows = np.array([], dtype=np.float64) + cols = np.array([], dtype=np.float64) + data = np.array([], dtype=np.float64) + # todo: use _sum_by_group what multiple elements start (or end) at the same bus? # J_C_P_d = np.zeros(shape=(len(pvpq) + len(x_control), len(pvpq) + len(x_control)), dtype=np.float64) # J_C_P_d = np.zeros(shape=(len(pvpq), len(pvpq)), dtype=np.float64) @@ -266,6 +270,10 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo if np.any(t_in_pvpq): J_m[pvpq_lookup[t[t_in_pvpq]], pvpq_lookup[t[t_in_pvpq]]] = -S_Fki.imag + rows = np.r_[rows, pvpq_lookup[f[f_in_pvpq]], pvpq_lookup[f[f_in_pvpq & t_in_pvpq]], pvpq_lookup[t[f_in_pvpq & t_in_pvpq]], pvpq_lookup[t[t_in_pvpq]]] + cols = np.r_[cols, pvpq_lookup[f[f_in_pvpq]], pvpq_lookup[t[f_in_pvpq & t_in_pvpq]], pvpq_lookup[f[f_in_pvpq & t_in_pvpq]], pvpq_lookup[t[t_in_pvpq]]] + data = np.r_[data, -S_Fik.imag, S_Fik.imag, S_Fki.imag, -S_Fki.imag] + # J_C_P_u = np.zeros(shape=(len(pvpq), len(pq)), dtype=np.float64) # J_C_P_u = np.zeros(shape=(len(pvpq)+ len(x_control), len(pq)+ len(x_control)), dtype=np.float64) @@ -285,6 +293,10 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo if np.any(t_in_pvpq & t_in_pq): J_m[pvpq_lookup[t[t_in_pvpq & t_in_pq]], len(pvpq)+pq_lookup[t[t_in_pvpq & t_in_pq]]] = (2 * S_Fkk.real + S_Fki.real) / Vmt + rows = np.r_[rows, pvpq_lookup[f[f_in_pvpq]], pvpq_lookup[f[f_in_pvpq & t_in_pq]], pvpq_lookup[t[f_in_pvpq & t_in_pq]], pvpq_lookup[t[t_in_pvpq & t_in_pq]]] + cols = np.r_[cols, len(pvpq)+pq_lookup[f[f_in_pq]], len(pvpq)+pq_lookup[t[f_in_pvpq & t_in_pq]], len(pvpq)+pq_lookup[f[f_in_pvpq & t_in_pq]], len(pvpq)+pq_lookup[t[t_in_pvpq & t_in_pq]]] + data = np.r_[data, (2 * S_Fii.real + S_Fik.real) / Vmf, S_Fik.real/Vmt, S_Fki.real/Vmf, (2 * S_Fkk.real + S_Fki.real) / Vmt] + # J_C_Q_d = np.zeros(shape=(len(pq), len(pvpq)), dtype=np.float64) # J_C_Q_d = np.zeros(shape=(len(pq)+ len(x_control), len(pvpq)+ len(x_control)), dtype=np.float64) @@ -303,6 +315,10 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo if np.any(t_in_pq & t_in_pvpq): J_m[len(pvpq) + pq_lookup[t[t_in_pq]], pvpq_lookup[t[t_in_pvpq]]] = np.where(control_mode_v, SMALL_NUMBER, -S_Fik.real) # control mode V or Q + rows = np.r_[rows, len(pvpq) + pq_lookup[f[f_in_pq]], len(pvpq) + pq_lookup[f[f_in_pq & t_in_pvpq]], len(pvpq) + pq_lookup[t[f_in_pvpq & t_in_pq]], len(pvpq) + pq_lookup[t[t_in_pq]]] + cols = np.r_[cols, pvpq_lookup[f[f_in_pvpq]], pvpq_lookup[t[f_in_pq & t_in_pvpq]], pvpq_lookup[f[f_in_pvpq & t_in_pq]], pvpq_lookup[t[t_in_pvpq]]] + data = np.r_[data, S_Fik.real, -S_Fik.real, np.where(control_mode_v, SMALL_NUMBER, S_Fik.real), np.where(control_mode_v, SMALL_NUMBER, -S_Fik.real)] + # J_C_Q_u = np.zeros(shape=(len(pq), len(pq)), dtype=np.float64) @@ -324,6 +340,10 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo # J_C_Q_u[pq_lookup[t[f_in_pq]]+ len(x_control), pq_lookup[f[f_in_pq]]] = 1 # J_C_Q_u[pq_lookup[t[f_in_pq]]+ len(x_control), pq_lookup[t[f_in_pq]]+ len(x_control)] = 0 + rows = np.r_[rows, len(pvpq)+pq_lookup[f[f_in_pq]], len(pvpq)+pq_lookup[f[f_in_pq & t_in_pq]], len(pvpq)+pq_lookup[t[f_in_pq & t_in_pq]], len(pvpq)+pq_lookup[t[t_in_pq]]] + cols = np.r_[cols, len(pvpq)+pq_lookup[f[f_in_pq]], len(pvpq)+pq_lookup[t[f_in_pq & t_in_pq]], len(pvpq)+pq_lookup[f[f_in_pq & t_in_pq]], len(pvpq)+pq_lookup[t[t_in_pq]]] + data = np.r_[data, (2 * S_Fii.imag + S_Fik.imag) / Vmf, S_Fik.imag / Vmt, np.where(control_mode_v, 1, (2 * S_Fii.imag + S_Fik.imag) / Vmf), np.where(control_mode_v, SMALL_NUMBER, S_Fik.imag / Vmt)] + # J_C_P_c = np.zeros(shape=(len(pvpq), nsvc + ntcsc), dtype=np.float64) # J_C_Q_c = np.zeros(shape=(len(pq), nsvc + ntcsc + 2 * nssc), dtype=np.float64) # J_C_C_d = np.zeros(shape=(nsvc + ntcsc + 2 * nssc, len(pvpq)), dtype=np.float64) @@ -342,7 +362,8 @@ def create_J_modification_ssc(J, V, Ybus_ssc, f, t, pvpq, pq, pvpq_lookup, pq_lo # J_m = np.vstack([np.hstack([J_C_P_d, J_C_P_u]), # np.hstack([J_C_Q_d, J_C_Q_u])]) - J_m = csr_matrix(J_m) + #J_m = csr_matrix(J_m) + J_m = csr_matrix((data, (rows, cols)), shape=J.shape, dtype=np.float64) return J_m diff --git a/pandapower/test/loadflow/test_facts.py b/pandapower/test/loadflow/test_facts.py index c8e354693..b04e2d7e6 100644 --- a/pandapower/test/loadflow/test_facts.py +++ b/pandapower/test/loadflow/test_facts.py @@ -1650,6 +1650,71 @@ def test_simple_vsc_hvdc(): runpp_with_consistency_checks(net) +def test_simple_2vsc_hvdc1(): + np.set_printoptions(linewidth=1000, suppress=True, precision=3) + net = pp.create_empty_network() + # AC part + pp.create_buses(net, 3, 110, geodata=((0, 0), (100, 0), (200, 0))) + pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 1, 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', geodata=(100, 10)) + pp.create_bus_dc(net, 110, 'B', geodata=(200, 10)) + + pp.create_bus_dc(net, 110, 'C', geodata=(100, -10)) + pp.create_bus_dc(net, 110, 'D', geodata=(200, -10)) + + pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + pp.create_line_dc(net, 2, 3, 100, std_type="2400-CU") + + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + pp.create_vsc(net, 2, 1, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + + pp.create_vsc(net, 1, 2, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + pp.create_vsc(net, 2, 3, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + + runpp_with_consistency_checks(net) + + +def test_simple_2vsc_hvdc2(): + np.set_printoptions(linewidth=1000, suppress=True, precision=3) + net = pp.create_empty_network() + # AC part + pp.create_buses(net, 3, 110, geodata=((0, 0), (100, 0), (200, 0))) + pp.create_line_from_parameters(net, 0, 1, 30, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 1, 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', geodata=(100, 10)) + pp.create_bus_dc(net, 110, 'B', geodata=(200, 10)) + + pp.create_bus_dc(net, 110, 'C', geodata=(100, -10)) + pp.create_bus_dc(net, 110, 'D', geodata=(200, -10)) + + pp.create_line_dc(net, 0, 1, 100, std_type="2400-CU") + pp.create_line_dc(net, 2, 3, 100, std_type="2400-CU") + + pp.create_vsc(net, 1, 0, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + pp.create_vsc(net, 2, 1, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + + #pp.create_vsc(net, 1, 2, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + #pp.create_vsc(net, 2, 3, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + + pp.create_buses(net, 2, 110, geodata=((100, -5), (200, -5))) + pp.create_line_from_parameters(net, 1, 3, 30, 0.0487, 0.13823, 160, 0.664) + pp.create_line_from_parameters(net, 2, 4, 30, 0.0487, 0.13823, 160, 0.664) + + pp.create_vsc(net, 3, 2, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="p_mw", control_value_dc=10) + pp.create_vsc(net, 4, 3, 0.1, 5, control_mode_ac='vm_pu', control_value_ac=1, control_mode_dc="vm_pu", control_value_dc=1.02) + + runpp_with_consistency_checks(net) + + def test_b2b_vsc_1(): net = pp.create_empty_network() # AC part