Work with per-unit (pu) representation of network quantities
Per-unit representation normalizes network quantities to dimensionless values, making it easier to compare values across different voltage levels and simplifying calculations.
For elements with one nominal voltage:Rpu=Vnom2Sn⋅RFor lines (two voltage levels):Rpu=Vnom1⋅Vnom2Sn⋅RFor two-winding transformers, use Vnom2 (secondary side).
For elements with one nominal voltage:Bpu=SnVnom2⋅BFor lines (side 1):Bpu=SnVnom12⋅B+(Vnom1−Vnom2)⋅Vnom1⋅Im(Y)where Y is the admittance and Im() is the imaginary part.
For elements with one nominal voltage:Gpu=SnVnom2⋅GFor lines (side 1):Gpu=SnVnom12⋅G+(Vnom1−Vnom2)⋅Vnom1⋅Re(Y)where Y is the admittance and Re() is the real part.For side 2, swap Vnom1 and Vnom2.
Per-unit makes it easy to compare values across voltage levels:
import pypowsybl as ppnet = pp.network.create_eurostag_tutorial_example1_network()net.per_unit = True# Get generators at different voltage levelsgens = net.get_generators()print(gens[['voltage_level_id', 'target_p', 'target_v', 'p', 'q']])# All values are normalized, easy to compare# regardless of voltage level
import pypowsybl as ppimport pypowsybl.loadflow as lfnet = pp.network.create_ieee14()net.per_unit = Truenet.nominal_apparent_power = 100 # MVA# Run load flowresult = lf.run_ac(net)# Get per-unit resultsbuses = net.get_buses()print(buses[['v_mag', 'v_angle']]) # Voltage in pu, angle in radianslines = net.get_lines()print(lines[['p1', 'q1', 'i1']]) # Power and current in pu
Per-unit values allow direct comparison across different voltage levels:
net.per_unit = True# Compare loading across all voltage levelslines = net.get_lines()lines['loading'] = lines['i1'] # Already normalizedprint(lines[['voltage_level1_id', 'loading']].sort_values('loading'))
Benchmark Networks
Compare different networks on the same scale:
# Both networks use same base powernet1.per_unit = Truenet1.nominal_apparent_power = 100net2.per_unit = Truenet2.nominal_apparent_power = 100# Now directly comparable