-
Notifications
You must be signed in to change notification settings - Fork 12
Pandapower converter: fix 3-Ph transformer loading Calculation #320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
In case of trafo_loading="current", a value error is generated while calculating "ui" from "i" and "u" because "i" is (n,3) array while "u" is (n,) array. fixed it by converted "u" to (n,3) array. Moreover, for phase wise loading, since "u" is line-to-line voltage, it needs to be converted to "line-to-ground" before multiplying, moreover to calculated loading percent, phase_power is to be divided by "sn_ph" instead of "sn" where "sn_ph" = "sn" / 3. Signed-off-by: Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>
fix/ PandaPower Transformer Loading
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your contribution @furqan463 ! We greatly appreciate you proposing the fix to the bug you found.
This is just a code review. Still TODO:
- add some tests
- review electrical engineering correctness
- reproduce with a pandapower grid.
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com> Signed-off-by: Martijn Govers <martygovers@hotmail.com>
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com> Signed-off-by: Martijn Govers <martygovers@hotmail.com>
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
Signed-off-by: Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>
Aligned with PandaPower code. Signed-off-by: Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>
@mgovers I've updated the description above elaborating mathematics involved. Moreover, thanks to @nitbharambe proposed changes match with existing code in PandaPower. I'm attaching a small code to reproduce the errors as well as testing the proposed changes. I'm trying to create unit tests, but while working on it, I've found some bugs with existing validation data. |
Signed-off-by: Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>
@mgovers I've highlighted in relevant test code, why the unit test was not working for this function. |
@mgovers I've updated the validation unittest, now the test includes all components and since I loading pp_input to converter, all components are being converted and tested. |
cd0d3a7
to
73bf364
Compare
…and power and updating of validation tests Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
…and power and updating of validation tests DCO Remediation Commit for Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com> I, Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>, hereby add my Signed-off-by to this commit: 0e3f838 Signed-off-by: Engr. Ahmad Furqan <40142397+furqan463@users.noreply.github.com>
Hi @furqan463, Nice find again! I am thinking that maybe we can try to add your validation case as a validation case similar to import pandapower as pp
import numpy as np
from math import sqrt
def create_net():
net = pp.create_empty_network('test', f_hz=50)
pp.create_bus(net, 11, 'source')
pp.create_bus(net, 11, 'TF_HT')
pp.create_bus(net, 0.4, 'TF_LT')
pp.create_ext_grid(net, 0, 1.0, 0, s_sc_max_mva=100, rx_max = 0.1, x0x_max=1, r0x0_max=0.1)
pp.create_line_from_parameters(net, 0, 1, 2, 0.33, 0.34,
0.001, 600, r0_ohm_per_km=0.66, x0_ohm_per_km=0.65, c0_nf_per_km=0.001,
g_us_per_km=0, g0_us_per_km=0)
pp.create_transformer_from_parameters(net, 1,2, 1, 11, 0.415, 0,
4, 0, 0.01, -30, vector_group='Dyn',
vk0_percent=4, vkr0_percent=0, mag0_percent=100, mag0_rx=0, si0_hv_partial=0.9)
pp.create_asymmetric_load(net, 2, 0.2, 0.19, 0.195,
0.05, 0.045, 0.035, 0, type='wye')
return net
def check_result(net):
v_hv = net.trafo.vn_hv_kv
v_lv = net.trafo.vn_lv_kv
i_max_hv = np.divide(net.trafo.sn_mva, v_hv* np.sqrt(3)) * 1e3
i_max_lv = np.divide(net.trafo.sn_mva, v_lv* np.sqrt(3)) * 1e3
i_a_hv = net.res_trafo_3ph.loc[:, 'i_a_hv_ka'] * 1000
i_b_hv = net.res_trafo_3ph.loc[:, 'i_b_hv_ka'] * 1000
i_c_hv = net.res_trafo_3ph.loc[:, 'i_c_hv_ka'] * 1000
i_a_lv = net.res_trafo_3ph.loc[:, 'i_a_lv_ka'] * 1000
i_b_lv = net.res_trafo_3ph.loc[:, 'i_b_lv_ka'] * 1000
i_c_lv = net.res_trafo_3ph.loc[:, 'i_c_lv_ka'] * 1000
np.testing.assert_allclose(np.maximum(i_a_hv / i_max_hv, i_a_lv / i_max_lv)*100, net.res_trafo_3ph.loading_a_percent)
np.testing.assert_allclose(np.maximum(i_b_hv / i_max_hv, i_b_lv / i_max_lv)*100, net.res_trafo_3ph.loading_b_percent)
np.testing.assert_allclose(np.maximum(i_c_hv / i_max_hv, i_c_lv / i_max_lv)*100, net.res_trafo_3ph.loading_c_percent)
def compare_result(actual, expected, *, rtol):
np.testing.assert_allclose(actual.trafo.vn_hv_kv, expected.trafo.vn_hv_kv, rtol=rtol)
np.testing.assert_allclose(actual.trafo.vn_lv_kv, expected.trafo.vn_lv_kv, rtol=rtol)
np.testing.assert_allclose(actual.trafo.sn_mva, expected.trafo.sn_mva, rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_a_hv_ka'], expected.res_trafo_3ph.loc[:, 'i_a_hv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_b_hv_ka'], expected.res_trafo_3ph.loc[:, 'i_b_hv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_c_hv_ka'], expected.res_trafo_3ph.loc[:, 'i_c_hv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_a_lv_ka'], expected.res_trafo_3ph.loc[:, 'i_a_lv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_b_lv_ka'], expected.res_trafo_3ph.loc[:, 'i_b_lv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loc[:, 'i_c_lv_ka'], expected.res_trafo_3ph.loc[:, 'i_c_lv_ka'], rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loading_a_percent, expected.res_trafo_3ph.loading_a_percent, rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loading_b_percent, expected.res_trafo_3ph.loading_b_percent, rtol=rtol)
np.testing.assert_allclose(actual.res_trafo_3ph.loading_c_percent, expected.res_trafo_3ph.loading_c_percent, rtol=rtol)
def test_pgm_pp_converter():
pgm_net = create_net()
pp_net = create_net()
pp.runpp_pgm(pgm_net, symmetric=False)
pp.runpp_3ph(pp_net)
check_result(pgm_net)
check_result(pp_net)
compare_result(pgm_net, pp_net, rtol=0.04)
if __name__ == "__main__":
test_pgm_pp_converter() The current That said, I do still see some small differences between PGM and PP if I run that script (the |
So far, it seems like you're solving the issues nicely, so I don't think my help is needed as of now. If you do need some input from me, I'm happy to help. |
@furqan463 how is it going with the tests? Since you found a bug and have already resolved it, I'm also OK with merging in its current state without extensive tests (after a minor clean-up). The tests can then be added as a follow-up. The reasoning behind that is that users can already use the PGM-IO with the bugfix. What are your thoughts? |
@mgovers agreed. I couldn't find time to finalise the tests, but agreed we can merge without tests, as the changes are broadly conceptual. |
…ading of 3 phases to align with pandapower. corrected line input producing NaN with c_nf_per_km=0, tan value should be 0 in this case Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
Awesome! I've linked the issue in this PR, so it will automatically close that issue. Let's also add a separate test case for this
It's great to hear that you're switching to PGM as a result of this improved handling. It's a type of user story that really shows we're helping out the community with this project (c.c. @petersalemink95). Regarding the scope of the tests in this repo, I do agree with you, but I'm a little bit hesitant to completely remove the test as well.
The good thing is that we have both Regarding the unbalanced v.s. balanced load tests, I think both have their own places in the validation tests: One to prove that balanced works correctly, and one to prove that unbalanced works similarly between PGM and PP, but not exactly the same (to be added). They can be 2 separate tests with 2 separate fixtures. @nitbharambe do you maybe have any good ideas regarding this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @furqan463,
Since you are actively picking up this PR again, the team has decided to treat this as a regular external contribution PR again and only merge it once all testing is fully in place.
Please let me know if you need help - if not, I'll be on stand-by.
tests/validation/converters/test_pandapower_converter_output.py
Outdated
Show resolved
Hide resolved
tests/validation/converters/test_pandapower_converter_output.py
Outdated
Show resolved
Hide resolved
Agreed with these! The validation test here and rtols should not be used for modelling comparison. Hence, we should be less stringent on the rtol setting here if test fails because of it (Now or in future.) We had earlier also thought of having a default vs custom rtol for specific attribute, but that was ruled out. We can do it if more such cases occur (Not because it would enable finer validation, but to clean up code.). |
…rate test cases for balanced and un-balanced load for trafo_loading Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@furqan463 looks quite good. A couple small remarks left, but I think the main piece of the code is pretty much finished.
tests/validation/converters/test_pandapower_converter_output.py
Outdated
Show resolved
Hide resolved
tests/validation/converters/test_pandapower_converter_output.py
Outdated
Show resolved
Hide resolved
tests/validation/converters/test_pandapower_converter_output.py
Outdated
Show resolved
Hide resolved
Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
Functions pp_trafo_output and pp_switch_output not being tested for the same reason as was for pp_trafo_output_3ph, the functions are returning from first if because pp_data is not passed to converter. These two functions are also appearing missed in coverage, resulting in coverage of only 89% for this file. Now trying to fix this. |
… switch output, also corrected bugs in pp_trafo_output and pp_switch_output Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
@mgovers I'm done now. There's one unittest failing that I'm not sure how to resolve. As I understand the test check exactly how we calculate "tan1" in pgm_input_line, but I changed the formula to avoid Nan values. |
Awesome, @furqan463 , I'll have a look when i can 👍 |
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
Signed-off-by: Martijn Govers <Martijn.Govers@Alliander.com>
@nitbharambe looks like this PR is now in a good-to-go state. Since I've also contributed significantly, can you please review? |
OH apparently, CI is still failing; investigating. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
found the reason for the remaining validation tests.
To run the validation tests locally, please either use a test extension or run pytest tests/validation
rather than just pytest
, as the validation tests are excluded from pytest
by default.
Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
@mgovers please check now, I've updated the data file. |
Great! @nitbharambe and I will have a look on Monday.
|
Signed-off-by: furqan463 <ahmadfurqanc@gmail.com>
Fixes #319
Fixes #321
Changes proposed in this PR include:
Extended "u1" and "u2" arrays from (n,) dimensions to (n,3) dimensions to remove value error.
multiplied phase loading percent with sqrt(3), (i * v / sqrt(3)) / (sn / 3) --> sqrt(3) * (i * v) / sn
divided total loading percent with sqrt(3) as v_ph = v / sqrt(3).
Electrical Mathematics:
Power per Phase = V_n * I_line_to_line # Basic Definition
Capacity per Phase = Sn / 3
Loading per Phase = Power per Phase / Capacity per Phase
ui = i_line_to_line * V_line_to_line
Loading per Phase = [ui / sqrt(3)] / [Sn / 3]
= [3 / sqrt(3)] * [ui] / [Sn]
= sqrt(3) * ui / Sn
Total Power = sum[Power_Phase_a, Power_Phase_b, Power_Phase_c]
= sum[ ui_a / sqrt(3), ui_b / sqrt(3), ui_c / sqrt(3)]
= [ sum(ui_a, ui_b, ui_c) / sqrt(3) ]
Total Loading = [sum(ui_a, ui_b, ui_c) / sqrt(3)] / Sn
Looking at it from another perspective which is more relevant in case of trafo_loading="current"
loading_per_phase = phase_current(line_to_line) / rated_current
rated_current (I_rated) = Sn / (sqrt(3) x V_line_to_line) #As for 3-Ph power system S = sqrt(3) * V * I
loading_per_phase = I_ph / I_rated
= I_ph / [Sn / (sqrt(3) x V_line_to_line)]
= sqrt(3) * [I_ph * V_line_to_line] / Sn
Checks before merge