Static calculations like power flow (or load flow as it’s called in PowerFactory ) or short circuit analysis are not the main focus of powfacpy . However, powfacpy provides a convenient interface to perform these calculations and to access the results.
We first activate the IEEE 39 Bus example system and create a study case for this tutorial.
# If you use IPython/Jupyter:
import sys
sys.path.append(
r"C: \ Program Files \D IgSILENT \ PowerFactory 2025 SP3 \ Python \3 . 13"
) # you may use a different directory
# Get the PF app
import powerfactory
from powfacpy.base.active_project import ActiveProject
app = powerfactory.GetApplication()
app.Show()
app.ActivateProject(
r"powfacpy \3 9_bus_new_england_copy_where_tests_run"
) # You may change the project path.
act_prj = ActiveProject(app)
study_case = act_prj.copy_single_obj("Study Cases \\ 2.3 Simulation Fault Bus 31 Stable" , "Study Cases" , new_name= "Load flow tutorial" )
study_case.Activate()
Load Flow
Execute
powfacpy provides an interface class for static calculations, which we import and use to execute the load flow calculation.
from powfacpy.applications.static_calc import StaticCalc
pfstat = StaticCalc(app)
pfstat.execute_load_flow()
We can check the results for validity. If the results are invalid, an exception is raised by default (see docstring for more options).
pfstat.check_load_flow_results()
Results
Export to Pandas DataFrame
We can easily access results of static calculations using the get_result_dataframe method. For example, we can get the voltage magnitudes and angles for all terminals with a nominal voltage above 300 kV. We use the ResVar class to specify the result variables we want to access.
from powfacpy.result_variables import ResVar
LF_Bal = ResVar.LF_Bal
terminals = act_prj.get_calc_relevant_obj("ElmTerm" , condition = lambda x: x.uknom > 300 )
df_voltage_res = pfstat.get_result_dataframe(terminals, [LF_Bal.ElmTerm.m_u.value, LF_Bal.ElmTerm.m_phiu.value])
df_voltage_res
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 01.ElmTerm</l3>
1.047356
-8.438685
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 02.ElmTerm</l3>
1.048736
-5.753762
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 03.ElmTerm</l3>
1.030173
-8.598549
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 04.ElmTerm</l3>
1.003863
-9.606667
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 05.ElmTerm</l3>
1.005311
-8.611863
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 06.ElmTerm</l3>
1.007672
-7.949683
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 07.ElmTerm</l3>
0.997001
-10.123823
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 08.ElmTerm</l3>
0.996020
-10.615381
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 09.ElmTerm</l3>
1.028226
-10.321987
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 10.ElmTerm</l3>
1.017151
-5.427126
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 11.ElmTerm</l3>
1.012694
-6.284262
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 13.ElmTerm</l3>
1.014307
-6.097718
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 14.ElmTerm</l3>
1.011733
-7.656411
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 15.ElmTerm</l3>
1.015384
-7.736092
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 16.ElmTerm</l3>
1.031774
-6.187509
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 17.ElmTerm</l3>
1.033555
-7.301285
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 18.ElmTerm</l3>
1.030931
-8.223858
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 19.ElmTerm</l3>
1.049861
-1.022768
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 21.ElmTerm</l3>
1.031760
-3.780534
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 22.ElmTerm</l3>
1.049795
0.668306
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 23.ElmTerm</l3>
1.044789
0.470028
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 24.ElmTerm</l3>
1.037311
-6.067907
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 25.ElmTerm</l3>
1.057568
-4.363391
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 26.ElmTerm</l3>
1.052075
-5.526725
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 27.ElmTerm</l3>
1.037741
-7.495423
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 28.ElmTerm</l3>
1.050122
-2.014886
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 29.ElmTerm</l3>
1.049942
0.744355
<l3>\seberlein.IntUser\powfacpy\39_bus_new_england_copy_where_tests_run.IntPrj\Network Model.IntPrjfolder\Network Data.IntPrjfolder\Grid.ElmNet\Bus 39.ElmTerm</l3>
1.030000
-10.052961
While the above dataframe is useful for further processing, it is not very readable. We can use the replace_obj_with_loc_name_and_add_variable_desc method to replace object references with their names and add variable descriptions.
df_voltage_res_readable = pfstat.replace_obj_with_loc_name_and_add_variable_desc(df_voltage_res)
df_voltage_res_readable
p.u., Voltage, Magnitude
deg, Voltage, Angle
Bus 01
1.047356
-8.438685
Bus 02
1.048736
-5.753762
Bus 03
1.030173
-8.598549
Bus 04
1.003863
-9.606667
Bus 05
1.005311
-8.611863
Bus 06
1.007672
-7.949683
Bus 07
0.997001
-10.123823
Bus 08
0.996020
-10.615381
Bus 09
1.028226
-10.321987
Bus 10
1.017151
-5.427126
Bus 11
1.012694
-6.284262
Bus 13
1.014307
-6.097718
Bus 14
1.011733
-7.656411
Bus 15
1.015384
-7.736092
Bus 16
1.031774
-6.187509
Bus 17
1.033555
-7.301285
Bus 18
1.030931
-8.223858
Bus 19
1.049861
-1.022768
Bus 21
1.031760
-3.780534
Bus 22
1.049795
0.668306
Bus 23
1.044789
0.470028
Bus 24
1.037311
-6.067907
Bus 25
1.057568
-4.363391
Bus 26
1.052075
-5.526725
Bus 27
1.037741
-7.495423
Bus 28
1.050122
-2.014886
Bus 29
1.049942
0.744355
Bus 39
1.030000
-10.052961
Export to .csv
From the dataframe format, we can easily export the results to a .csv file for further analysis or reporting.
df_voltage_res_readable.to_csv(r" . \t ests \t ests_output \s tatic_calc_results . csv" , index= True )
Back to top