diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp index f5257c4f59..daf30c9006 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/common/common.hpp @@ -84,6 +84,8 @@ constexpr DoubleComplex y_link{g_link, g_link}; constexpr double default_source_sk = 1e10; // 10 GVA 10^10 constexpr double default_source_rx_ratio = 0.1; constexpr double default_source_z01_ratio = 1.0; +// transformer low susceptance ratio for floating zero sequence +constexpr double transformer_low_susceptance_ratio = 1e-8; // some usual vector using DoubleVector = std::vector; diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/component/transformer.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/component/transformer.hpp index 9c7c297bcb..381a03516e 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/component/transformer.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/component/transformer.hpp @@ -258,6 +258,27 @@ class Transformer : public Branch { param0.ytt() = y0_series; } + auto const low_susceptance = -transformer_low_susceptance_ratio * sn_ / base_power_3p / uk_; + auto const zero_seq_available = [](WindingType this_side, WindingType other_side) { + using enum WindingType; + switch (this_side) { + case wye_n: + return other_side == wye_n || other_side == delta; + case zigzag_n: + return true; + default: + return false; + } + }; + bool const zero_seq_available_from = zero_seq_available(winding_from_, winding_to_); + bool const zero_seq_available_to = zero_seq_available(winding_to_, winding_from_); + if (!zero_seq_available_from && from_status()) { + param0.yff() += DoubleComplex{0.0, low_susceptance}; + } + if (!zero_seq_available_to && to_status()) { + param0.ytt() += DoubleComplex{0.0, low_susceptance}; + } + // for the rest param0 is zero // calculate yabc ComplexTensor const sym_matrix = get_sym_matrix(); @@ -269,6 +290,7 @@ class Transformer : public Branch { y012 << param0.value[i], 0.0, 0.0, 0.0, param1.value[i], 0.0, 0.0, 0.0, param2.value[i]; param.value[i] = dot(sym_matrix, y012, sym_matrix_inv); } + return param; } }; diff --git a/tests/cpp_unit_tests/test_transformer.cpp b/tests/cpp_unit_tests/test_transformer.cpp index ce6f6f5fba..6b6417911b 100644 --- a/tests/cpp_unit_tests/test_transformer.cpp +++ b/tests/cpp_unit_tests/test_transformer.cpp @@ -92,6 +92,11 @@ TEST_CASE("Test transformer") { double const r_series = 100e3 * 10e3 * 10e3 / 30e6 / 30e6; DoubleComplex const z_series = r_series + 1.0i * std::sqrt(z_series_abs * z_series_abs - r_series * r_series); DoubleComplex const y = 1.0 / z_series / base_y; + auto const low_susceptance = -transformer_low_susceptance_ratio * input.sn / base_power_3p / input.uk; + DoubleComplex const low_admittance = 1.0i * low_susceptance; + ComplexTensor y012; + y012 << low_admittance, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0; + ComplexTensor const low_admittance_asym = dot(get_a(), y012, get_a_inv()); // sym std::vector> vec_sym; @@ -125,10 +130,15 @@ TEST_CASE("Test transformer") { vec_asym.push_back({{y1, -y1, -y1, y1}}); // Dyn11 vec_asym.push_back({{y2, y3t, y3, y1}}); + vec_asym.back().yff() += low_admittance_asym; // Yd1 vec_asym.push_back({{y2, y3, y3t, y2}}); + vec_asym.back().yff() += low_admittance_asym; + vec_asym.back().ytt() += low_admittance_asym; // Yy12 vec_asym.push_back({{y2, -y2, -y2, y2}}); + vec_asym.back().yff() += low_admittance_asym; + vec_asym.back().ytt() += low_admittance_asym; // YNyn2 vec_asym.push_back({{y1, y4, y4t, y1}}); @@ -469,8 +479,10 @@ TEST_CASE("Test Transfomer - Test grounding - Dyn11") { // Zero sequence DoubleComplex const z_grounding_to = (input.r_grounding_to + 1i * input.x_grounding_to) * base_y_to; + auto const low_susceptance = -transformer_low_susceptance_ratio * input.sn / base_power_3p / input.uk; + DoubleComplex const low_admittance = 1.0i * low_susceptance; - DoubleComplex const y_0_ff = 0.0; + DoubleComplex const y_0_ff = low_admittance; DoubleComplex const y_0_ft = 0.0; DoubleComplex const y_0_tf = 0.0; DoubleComplex const y_0_tt = (1.0 / (z_1_series + 3.0 * z_grounding_to)) + y_1_shunt; @@ -578,8 +590,10 @@ TEST_CASE("Test Transfomer - Test grounding - Yzn11") { // Zero sequence DoubleComplex const z_grounding_to = (input.r_grounding_to + 1i * input.x_grounding_to) * base_y_to; + auto const low_susceptance = -transformer_low_susceptance_ratio * input.sn / base_power_3p / input.uk; + DoubleComplex const low_admittance = 1.0i * low_susceptance; - DoubleComplex const y_0_ff = 0.0; + DoubleComplex const y_0_ff = low_admittance; DoubleComplex const y_0_ft = 0.0; DoubleComplex const y_0_tf = 0.0; DoubleComplex const y_0_tt = (1.0 / (z_1_series * 0.1 + 3.0 * z_grounding_to)); @@ -687,8 +701,10 @@ TEST_CASE("Test Transformer - Dyn11 - tap_max and tap_min flipped") { // Zero sequence DoubleComplex const z_grounding_to = (input.r_grounding_to + 1i * input.x_grounding_to) * base_y_to; + auto const low_susceptance = -transformer_low_susceptance_ratio * input.sn / base_power_3p / input.uk; + DoubleComplex const low_admittance = 1.0i * low_susceptance; - DoubleComplex const y_0_ff = 0.0; + DoubleComplex const y_0_ff = low_admittance; DoubleComplex const y_0_ft = 0.0; DoubleComplex const y_0_tf = 0.0; DoubleComplex const y_0_tt = (1.0 / (z_1_series + 3.0 * z_grounding_to)) + y_1_shunt; diff --git a/tests/data/power_flow/floating_zero_sequence/asym_output.json b/tests/data/power_flow/floating_zero_sequence/asym_output.json new file mode 100644 index 0000000000..7b5b8e752c --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/asym_output.json @@ -0,0 +1,23 @@ +{ + "version": "1.0", + "type": "asym_output", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "energized": 1, "u_pu": [0.96852205547155257, 1.0206083148508613, 0.98784175476403047], "u": [5591.764694425905, 5892.4848531631515, 5703.307030297653], "u_angle": [-0.040742566360496869, -2.1441345251331376, 2.0033567593816968], "p": [1314971.9340071543, 1691451.3014948303, 2993576.7644979917], "q": [989444.74610297778, -743175.16349568975, 263988.08450858196]}, + {"id": 2, "energized": 1, "u_pu": [0.94750841657660867, 0.99621887552137245, 1.0263746319452911], "u": [5470.4423936994108, 5751.6723595405065, 5925.7767004301686], "u_angle": [2.5081331635193447, 0.47812215756400461, -1.688791344148733], "p": [1.2548582932767838e-08, 1.302774370913572e-08, 2.5285099200928076e-08], "q": [1.9214234326283912e-09, -2.5139098505749905e-08, 6.7944203835937232e-09]}, + {"id": 3, "energized": 1, "u_pu": [0.95328569878941172, 1.0317279231128014, 0.98298950273421282], "u": [5503.7975481068734, 5956.6839413962934, 5675.2925401417415], "u_angle": [-0.07860954164747154, -2.1823201253199591, 1.8951713864745763], "p": [-999999.99999999907, -1000000.0000000133, -4000000.0000000075], "q": [8.0491169285323849e-10, 2.3166653780511599e-08, 7.1054273576010019e-09]} + ], + "transformer": [ + {"id": 4, "energized": 1, "loading": 0.6498356896389379, "p_from": [1314971.9340071543, 1691451.3014948303, 2993576.7644979917], "q_from": [989444.74610297778, -743175.16349568975, 263988.08450858196], "i_from": [294.29822170602006, 313.53774185504125, 526.92132474738628], "s_from": [1645646.4057680501, 1847516.3947758083, 3005194.0958455205], "p_to": [-2308548.6844076109, -1006423.2333675779, -2685028.0822247765], "q_to": [-978312.09287856543, -60818.915340574335, 760155.06177346141], "i_to": [458.33362520409179, 175.29844576248311, 470.91844756917072], "s_to": [2507287.6937744003, 1008259.2251624847, 2790557.5644081375]}, + {"id": 5, "energized": 1, "loading": 0.63061044833450686, "p_from": [2308548.684407624, 1006423.2333675909, 2685028.0822248021], "q_from": [978312.0928785674, 60818.915340549247, -760155.06177345454], "i_from": [458.33362520409406, 175.29844576248513, 470.91844756917453], "s_from": [2507287.6937744129, 1008259.2251624962, 2790557.5644081603], "p_to": [-999999.99999999907, -1000000.0000000133, -4000000.0000000075], "q_to": [8.0491169285323849e-10, 2.3166653780511599e-08, 7.1054273576010019e-09], "i_to": [181.69272965790074, 167.87864016931633, 704.80948280775453], "s_to": [999999.99999999907, 1000000.0000000133, 4000000.0000000075]} + ], + "asym_load": [ + {"id": 6, "energized": 1, "p": [1000000, 1000000, 4000000], "q": [0, 0, 0], "i": [181.69272965790091, 167.87864016931411, 704.80948280775306], "s": [1000000, 1000000, 4000000], "pf": [1, 1, 1]} + ], + "source": [ + {"id": 7, "energized": 1, "p": [1314971.9340071541, 1691451.3014948303, 2993576.7644979917], "q": [989444.74610297778, -743175.16349568986, 263988.08450858208], "i": [294.29822170602, 313.53774185504125, 526.92132474738628], "s": [1645646.4057680501, 1847516.3947758083, 3005194.0958455205], "pf": [0.79906104336759709, 0.91552708613450973, 0.99613424924413729]} + ] + } +} \ No newline at end of file diff --git a/tests/data/power_flow/floating_zero_sequence/asym_output.json.license b/tests/data/power_flow/floating_zero_sequence/asym_output.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/asym_output.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/power_flow/floating_zero_sequence/input.json b/tests/data/power_flow/floating_zero_sequence/input.json new file mode 100644 index 0000000000..5aa2d5ccdf --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/input.json @@ -0,0 +1,26 @@ +{ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000}, + {"id": 3, "u_rated": 10000} + ], + "transformer": [ + {"id": 4, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 10000000, "uk": 0.050000000000000003, "pk": 0, "i0": 0, "p0": 0, "winding_from": 1, "winding_to": 2, "clock": 7, "tap_side": 0, "tap_pos": 0, "tap_min": 0, "tap_max": 0, "tap_nom": 0, "tap_size": 0}, + {"id": 5, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 10000000, "uk": 0.050000000000000003, "pk": 0, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": 0, "tap_max": 0, "tap_nom": 0, "tap_size": 0} + ], + "asym_load": [ + {"id": 6, "node": 3, "status": 1, "type": 0, "p_specified": [1000000, 1000000, 4000000], "q_specified": [0, 0, 0]} + ], + "source": [ + {"id": 7, "node": 1, "status": 1, "u_ref": 1, "sk": 100000000, "rx_ratio": 0, "z01_ratio": 1} + ], + "fault": [ + {"id": 8, "status": 1, "fault_type": 2, "fault_phase": 6, "fault_object": 3} + ] + } +} \ No newline at end of file diff --git a/tests/data/power_flow/floating_zero_sequence/input.json.license b/tests/data/power_flow/floating_zero_sequence/input.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/input.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/power_flow/floating_zero_sequence/params.json b/tests/data/power_flow/floating_zero_sequence/params.json new file mode 100644 index 0000000000..aedf0ff451 --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/params.json @@ -0,0 +1,7 @@ +{ + "calculation_method": [ + "newton_raphson" + ], + "rtol": 3e-07, + "atol": 1e-07 +} \ No newline at end of file diff --git a/tests/data/power_flow/floating_zero_sequence/params.json.license b/tests/data/power_flow/floating_zero_sequence/params.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/power_flow/floating_zero_sequence/params.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json new file mode 100644 index 0000000000..5aa2d5ccdf --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json @@ -0,0 +1,26 @@ +{ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000}, + {"id": 3, "u_rated": 10000} + ], + "transformer": [ + {"id": 4, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 10000000, "uk": 0.050000000000000003, "pk": 0, "i0": 0, "p0": 0, "winding_from": 1, "winding_to": 2, "clock": 7, "tap_side": 0, "tap_pos": 0, "tap_min": 0, "tap_max": 0, "tap_nom": 0, "tap_size": 0}, + {"id": 5, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1, "u1": 10000, "u2": 10000, "sn": 10000000, "uk": 0.050000000000000003, "pk": 0, "i0": 0, "p0": 0, "winding_from": 2, "winding_to": 1, "clock": 5, "tap_side": 0, "tap_pos": 0, "tap_min": 0, "tap_max": 0, "tap_nom": 0, "tap_size": 0} + ], + "asym_load": [ + {"id": 6, "node": 3, "status": 1, "type": 0, "p_specified": [1000000, 1000000, 4000000], "q_specified": [0, 0, 0]} + ], + "source": [ + {"id": 7, "node": 1, "status": 1, "u_ref": 1, "sk": 100000000, "rx_ratio": 0, "z01_ratio": 1} + ], + "fault": [ + {"id": 8, "status": 1, "fault_type": 2, "fault_phase": 6, "fault_object": 3} + ] + } +} \ No newline at end of file diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json.license b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/input.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json new file mode 100644 index 0000000000..22f97d9a3d --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json @@ -0,0 +1,8 @@ +{ + "calculation_method": [ + "iec60909" + ], + "rtol": 1e-07, + "atol": 1e-07, + "short_circuit_voltage_scaling": "maximum" +} \ No newline at end of file diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json.license b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/params.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json new file mode 100644 index 0000000000..b2fa895e9d --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json @@ -0,0 +1,26 @@ +{ + "version": "1.0", + "type": "sc_output", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "energized": 1, "u_pu": [1.0999999999999999, 0.72758161054276271, 0.72758161054276194], "u": [6350.8529610858823, 4200.6943870428549, 4200.6943870428504], "u_angle": [2.512019772889243e-16, -2.4278682746450277, 2.4278682746450273]}, + {"id": 2, "energized": 1, "u_pu": [0.96250000511909928, 0.96249999477409609, 0.27500000037381495], "u": [5556.9963705052814, 5556.9963107783778, 1587.7132424296924], "u_angle": [2.998245085844498, 0.14334756929664444, -1.5707963457989134]}, + {"id": 3, "energized": 1, "u_pu": [1.0999999999999994, 0.5499999999999996, 0.5499999999999996], "u": [6350.8529610858805, 3175.4264805429393, 3175.4264805429393], "u_angle": [5.6520444890008018e-16, -3.1415926535897927, -3.1415926535897927]} + ], + "transformer": [ + {"id": 4, "energized": 1, "i_from": [1.6705560276655585e-12, 2749.9999999999986, 2750.0000000000005], "i_from_angle": [3.1415926535897931, -3.1415926535897931, 5.9670114874447551e-16], "i_to": [1587.7132402714715, 1587.7132402714694, 3175.426480542942], "i_to_angle": [3.1415926535897931, 3.1415926535897922, 7.7513752992010926e-16]}, + {"id": 5, "energized": 1, "i_from": [1587.7132402714719, 1587.7132402714703, 3175.426480542942], "i_from_angle": [4.1340668262405803e-15, -1.0335167065601461e-15, -3.1415926535897927], "i_to": [1.6412165780830384e-12, 2750.0000000000009, 2750.0000000000005], "i_to_angle": [1.552048524251098, -2.9835057437223771e-16, -3.1415926535897913]} + ], + "asym_load": [ + {"id": 6, "energized": 0, "i": [0, 0, 0], "i_angle": [0, 0, 0]} + ], + "source": [ + {"id": 7, "energized": 1, "i": [2.2886189511086415e-12, 2749.9999999999995, 2750.0000000000014], "i_angle": [-2.3421109143694845, -3.1415926535897927, 1.1934022974889508e-15]} + ], + "fault": [ + {"id": 8, "energized": 1, "i_f": [0, 2750.0000000000009, 2750.0000000000009], "i_f_angle": [0, -3.1415926535897927, 4.4752586155835661e-16]} + ] + } +} \ No newline at end of file diff --git a/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json.license b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json.license new file mode 100644 index 0000000000..7601059167 --- /dev/null +++ b/tests/data/short_circuit/floating_zero_sequence_two_phase_short_circuit/sc_output.json.license @@ -0,0 +1,3 @@ +SPDX-FileCopyrightText: Contributors to the Power Grid Model project + +SPDX-License-Identifier: MPL-2.0 diff --git a/tests/data/short_circuit/single_phase_to_ground_c_maximum/params.json b/tests/data/short_circuit/single_phase_to_ground_c_maximum/params.json index 71db2d5f8e..c5858d76db 100644 --- a/tests/data/short_circuit/single_phase_to_ground_c_maximum/params.json +++ b/tests/data/short_circuit/single_phase_to_ground_c_maximum/params.json @@ -1,6 +1,6 @@ { "calculation_method": "iec60909", - "rtol": 1e-08, - "atol": 1e-08, + "rtol": 2e-06, + "atol": 1e-03, "short_circuit_voltage_scaling": "maximum" } \ No newline at end of file diff --git a/tests/data/short_circuit/single_phase_to_ground_c_minimum/params.json b/tests/data/short_circuit/single_phase_to_ground_c_minimum/params.json index fe50f74cf4..b6ce9acf9b 100644 --- a/tests/data/short_circuit/single_phase_to_ground_c_minimum/params.json +++ b/tests/data/short_circuit/single_phase_to_ground_c_minimum/params.json @@ -1,6 +1,6 @@ { "calculation_method": "iec60909", - "rtol": 1e-08, - "atol": 1e-08, + "rtol": 2e-06, + "atol": 1e-03, "short_circuit_voltage_scaling": "minimum" } \ No newline at end of file diff --git a/tests/data/short_circuit/two_phase_to_ground_c_maximum/params.json b/tests/data/short_circuit/two_phase_to_ground_c_maximum/params.json index 71db2d5f8e..c5858d76db 100644 --- a/tests/data/short_circuit/two_phase_to_ground_c_maximum/params.json +++ b/tests/data/short_circuit/two_phase_to_ground_c_maximum/params.json @@ -1,6 +1,6 @@ { "calculation_method": "iec60909", - "rtol": 1e-08, - "atol": 1e-08, + "rtol": 2e-06, + "atol": 1e-03, "short_circuit_voltage_scaling": "maximum" } \ No newline at end of file diff --git a/tests/data/short_circuit/two_phase_to_ground_c_minimum/params.json b/tests/data/short_circuit/two_phase_to_ground_c_minimum/params.json index fe50f74cf4..b6ce9acf9b 100644 --- a/tests/data/short_circuit/two_phase_to_ground_c_minimum/params.json +++ b/tests/data/short_circuit/two_phase_to_ground_c_minimum/params.json @@ -1,6 +1,6 @@ { "calculation_method": "iec60909", - "rtol": 1e-08, - "atol": 1e-08, + "rtol": 2e-06, + "atol": 1e-03, "short_circuit_voltage_scaling": "minimum" } \ No newline at end of file