@@ -99,7 +99,7 @@ def _parse_data(
9999 self .idx_lookup = {}
100100 self .next_idx = 0
101101
102- # Set pandas data
102+ # Set pandapower data
103103 self .pp_input_data = data
104104
105105 # Convert
@@ -360,6 +360,9 @@ def _create_output_data_3ph(self):
360360 Furthermore, creates a global node lookup table, which stores nodes' voltage magnitude per unit and the voltage
361361 angle in degrees
362362 """
363+ # TODO create output_data_3ph for remaining components
364+ # Although Pandapower itself did not implmenet res_shunt_3ph
365+ # Since results are avaiable in PGM output, these should be converted.
363366 self ._pp_buses_output_3ph ()
364367 self ._pp_lines_output_3ph ()
365368 self ._pp_ext_grids_output_3ph ()
@@ -376,6 +379,7 @@ def _create_pgm_input_nodes(self):
376379 Returns:
377380 a power-grid-model structured array for the Node component
378381 """
382+ # TODO handle out-of-service buses, either here or in get_switch_states
379383 pp_busses = self .pp_input_data ["bus" ]
380384
381385 if pp_busses .empty :
@@ -422,11 +426,12 @@ def _create_pgm_input_lines(self):
422426 pgm_lines ["x1" ] = self ._get_pp_attr ("line" , "x_ohm_per_km" , expected_type = "f8" ) * multiplier
423427 pgm_lines ["c1" ] = c_nf_per_km * length_km * parallel * 1e-9
424428 # The formula for tan1 = R_1 / Xc_1 = (g * 1e-6) / (2 * pi * f * c * 1e-9) = g / (2 * pi * f * c * 1e-3)
425- pgm_lines ["tan1" ] = (
426- self ._get_pp_attr ("line" , "g_us_per_km" , expected_type = "f8" , default = 0 )
427- / c_nf_per_km
428- / ( 2 * np . pi * self . system_frequency * 1e-3 )
429+ pgm_lines ["tan1" ] = np . divide (
430+ self ._get_pp_attr ("line" , "g_us_per_km" , expected_type = "f8" , default = 0 ),
431+ c_nf_per_km * ( 2 * np . pi * self . system_frequency * 1e-3 ),
432+ where = c_nf_per_km != 0.0 ,
429433 )
434+ pgm_lines ["tan1" ][np .equal (c_nf_per_km , 0.0 )] = 0.0
430435 pgm_lines ["i_n" ] = (
431436 (self ._get_pp_attr ("line" , "max_i_ka" , expected_type = "f8" , default = np .nan ) * 1e3 )
432437 * self ._get_pp_attr ("line" , "df" , expected_type = "f8" , default = 1 )
@@ -435,11 +440,12 @@ def _create_pgm_input_lines(self):
435440 pgm_lines ["r0" ] = self ._get_pp_attr ("line" , "r0_ohm_per_km" , expected_type = "f8" , default = np .nan ) * multiplier
436441 pgm_lines ["x0" ] = self ._get_pp_attr ("line" , "x0_ohm_per_km" , expected_type = "f8" , default = np .nan ) * multiplier
437442 pgm_lines ["c0" ] = c0_nf_per_km * length_km * parallel * 1e-9
438- pgm_lines ["tan0" ] = (
439- self ._get_pp_attr ("line" , "g0_us_per_km" , expected_type = "f8" , default = 0 )
440- / c0_nf_per_km
441- / ( 2 * np . pi * self . system_frequency * 1e-3 )
443+ pgm_lines ["tan0" ] = np . divide (
444+ self ._get_pp_attr ("line" , "g0_us_per_km" , expected_type = "f8" , default = 0 ),
445+ c0_nf_per_km * ( 2 * np . pi * self . system_frequency * 1e-3 ),
446+ where = c0_nf_per_km != 0.0 ,
442447 )
448+ pgm_lines ["tan0" ][np .equal (c0_nf_per_km , 0.0 )] = 0.0
443449 assert ComponentType .line not in self .pgm_input_data
444450 self .pgm_input_data [ComponentType .line ] = pgm_lines
445451
@@ -755,7 +761,10 @@ def _create_pgm_input_transformers(self): # pylint: disable=too-many-statements
755761 valid = np .logical_and (np .not_equal (sn_mva , 0.0 ), np .isfinite (sn_mva ))
756762 mag_g = np .divide (pfe , sn_mva * 1000 , where = valid )
757763 mag_g [np .logical_not (valid )] = np .nan
758- rx_mag = mag_g / np .sqrt (i_no_load * i_no_load * 1e-4 - mag_g * mag_g )
764+ z_squared = i_no_load * i_no_load * 1e-4 - mag_g * mag_g
765+ valid = np .logical_and (np .greater (z_squared , 0 ), np .isfinite (z_squared ))
766+ rx_mag = np .divide (mag_g , np .sqrt (z_squared , where = valid ), where = valid )
767+ rx_mag [np .logical_not (valid )] = np .inf
759768 # positive and zero sequence magnetising impedance must be equal.
760769 # mag0_percent = z0mag / z0.
761770 checks = {
@@ -1382,7 +1391,9 @@ def _pp_trafos_output(self):
13821391 if self .trafo_loading == "current" :
13831392 ui_from = pgm_output_transformers ["i_from" ] * pgm_input_transformers ["u1" ]
13841393 ui_to = pgm_output_transformers ["i_to" ] * pgm_input_transformers ["u2" ]
1385- loading = np .maximum (ui_from , ui_to ) / pgm_input_transformers ["sn" ] * loading_multiplier * 1e2
1394+ loading = (
1395+ (np .sqrt (3 ) * np .maximum (ui_from , ui_to ) / pgm_input_transformers ["sn" ]) * loading_multiplier * 1e2
1396+ )
13861397 elif self .trafo_loading == "power" :
13871398 loading = pgm_output_transformers ["loading" ] * loading_multiplier * 1e2
13881399 else :
@@ -1704,14 +1715,16 @@ def join_currents(table: str, bus_name: str, i_name: str) -> pd.DataFrame:
17041715 )
17051716 pp_switches_output = pp_switches_output [["i_ka" ]]
17061717 pp_switches_output .set_index (pp_switches_output_index , inplace = True )
1707- pp_switches_output ["loading_percent" ] = np .nan
17081718
17091719 # For et=b, ie bus to bus switches, links are created. get result from them
17101720 if not links_absent :
17111721 links = self .pgm_output_data [ComponentType .link ]
17121722 # For links, i_from = i_to = i_ka / 1e3
17131723 link_ids = self ._get_pp_ids ("switch" , links ["id" ], "b2b_switches" )
17141724 pp_switches_output .loc [link_ids , "i_ka" ] = links ["i_from" ] * 1e-3
1725+ in_ka = self .pp_input_data ["switch" ]["in_ka" ].values
1726+ pp_switches_output ["loading_percent" ] = np .nan
1727+ pp_switches_output ["loading_percent" ] = np .divide (pp_switches_output ["i_ka" ], in_ka , where = in_ka != 0 )
17151728
17161729 assert "res_switch" not in self .pp_output_data
17171730 self .pp_output_data ["res_switch" ] = pp_switches_output
@@ -1942,7 +1955,10 @@ def _pp_lines_output_3ph(self):
19421955 pp_output_lines_3ph ["loading_c_percent" ] = (
19431956 np .maximum (pp_output_lines_3ph ["i_c_from_ka" ], pp_output_lines_3ph ["i_c_to_ka" ]) / pgm_input_lines ["i_n" ]
19441957 ) * 1e5
1945- pp_output_lines_3ph ["loading_percent" ] = pgm_output_lines ["loading" ] * 1e2
1958+ pp_output_lines_3ph ["loading_percent" ] = np .maximum (
1959+ np .maximum (pp_output_lines_3ph ["loading_a_percent" ], pp_output_lines_3ph ["loading_b_percent" ]),
1960+ pp_output_lines_3ph ["loading_c_percent" ],
1961+ )
19461962
19471963 assert "res_line_3ph" not in self .pp_output_data
19481964 self .pp_output_data ["res_line_3ph" ] = pp_output_lines_3ph
@@ -2017,38 +2033,29 @@ def _pp_trafos_output_3ph(self): # pylint: disable=too-many-statements
20172033 # Only derating factor used here. Sn is already being multiplied by parallel
20182034 loading_multiplier = pp_input_transformers ["df" ] * 1e2
20192035 if self .trafo_loading == "current" :
2020- ui_from = pgm_output_transformers ["i_from" ] * pgm_input_transformers ["u1" ]
2021- ui_to = pgm_output_transformers ["i_to" ] * pgm_input_transformers ["u2" ]
2022- loading_a_percent = np .maximum (ui_from [:, 0 ], ui_to [:, 0 ]) / pgm_input_transformers ["sn" ]
2023- loading_b_percent = np .maximum (ui_from [:, 1 ], ui_to [:, 1 ]) / pgm_input_transformers ["sn" ]
2024- loading_c_percent = np .maximum (ui_from [:, 2 ], ui_to [:, 2 ]) / pgm_input_transformers ["sn" ]
2025- loading = np .maximum (np .sum (ui_from , axis = 1 ), np .sum (ui_to , axis = 1 )) / pgm_input_transformers ["sn" ]
2036+ ui_from = pgm_output_transformers ["i_from" ] * pgm_input_transformers ["u1" ][:, None ]
2037+ ui_to = pgm_output_transformers ["i_to" ] * pgm_input_transformers ["u2" ][:, None ]
2038+ loading_a_percent = np .sqrt (3 ) * np .maximum (ui_from [:, 0 ], ui_to [:, 0 ]) / pgm_input_transformers ["sn" ]
2039+ loading_b_percent = np .sqrt (3 ) * np .maximum (ui_from [:, 1 ], ui_to [:, 1 ]) / pgm_input_transformers ["sn" ]
2040+ loading_c_percent = np .sqrt (3 ) * np .maximum (ui_from [:, 2 ], ui_to [:, 2 ]) / pgm_input_transformers ["sn" ]
20262041 elif self .trafo_loading == "power" :
2027- loading_a_percent = (
2028- np .maximum (
2029- pgm_output_transformers ["s_from" ][:, 0 ],
2030- pgm_output_transformers ["s_to" ][:, 0 ],
2031- )
2032- / pgm_output_transformers ["s_n" ]
2033- )
2034- loading_b_percent = (
2035- np .maximum (
2036- pgm_output_transformers ["s_from" ][:, 1 ],
2037- pgm_output_transformers ["s_to" ][:, 1 ],
2038- )
2039- / pgm_output_transformers ["s_n" ]
2040- )
2041- loading_c_percent = (
2042- np .maximum (
2043- pgm_output_transformers ["s_from" ][:, 2 ],
2044- pgm_output_transformers ["s_to" ][:, 2 ],
2045- )
2046- / pgm_output_transformers ["s_n" ]
2047- )
2048- loading = pgm_output_transformers ["loading" ]
2042+ loading_a_percent = np .maximum (
2043+ pgm_output_transformers ["s_from" ][:, 0 ],
2044+ pgm_output_transformers ["s_to" ][:, 0 ],
2045+ ) / (pgm_input_transformers ["sn" ] / 3 )
2046+ loading_b_percent = np .maximum (
2047+ pgm_output_transformers ["s_from" ][:, 1 ],
2048+ pgm_output_transformers ["s_to" ][:, 1 ],
2049+ ) / (pgm_input_transformers ["sn" ] / 3 )
2050+ loading_c_percent = np .maximum (
2051+ pgm_output_transformers ["s_from" ][:, 2 ],
2052+ pgm_output_transformers ["s_to" ][:, 2 ],
2053+ ) / (pgm_input_transformers ["sn" ] / 3 )
20492054 else :
20502055 raise ValueError (f"Invalid transformer loading type: { str (self .trafo_loading )} " )
20512056
2057+ loading = np .maximum (np .maximum (loading_a_percent , loading_b_percent ), loading_c_percent )
2058+
20522059 pp_output_trafos_3ph = pd .DataFrame (
20532060 columns = [
20542061 "p_a_hv_mw" ,
0 commit comments