Static Calculations

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\DIgSILENT\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\39_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()
0

1 Load Flow

1.1 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()
0

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()
True

2 Results

2.1 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
m:u m:phiu
<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
m:u m:phiu
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

2.2 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".\tests\tests_output\static_calc_results.csv", index=True)
Back to top