Slack types and short-circuit currents
Level: Advanced, companion of basic-tour chapter 3.
Note: This workshop was created with AI assistance and is reviewed and curated by the maintainer; it is not a fully machine-generated text.
Every AC power flow needs one bus that balances the network: the slack. But the real grid connection is not an infinitely stiff busbar; it is the superordinate network behind an impedance, and it also determines how much short-circuit current arrives at your buses. In this notebook you model one and the same grid connection three ways with Sparlectra.jl and compare the results, then reuse the connection's declared short-circuit power for an IEC 60909-0 short-circuit calculation:
- Ideal slack: the connection bus holds voltage magnitude and angle, no matter what.
- Non-ideal external-grid source: the reference voltage sits behind the feeder impedance $Z_Q = U_n^2 / S_k''$, so the connection-bus voltage droops under load.
- Distributed slack: the active-power imbalance is picked up by the generators according to participation factors, the primary-control picture.
The theory behind the comparison is on Slack Bus and External Grid Sources; the short-circuit method is documented in the Short-Circuit Compendium.
The test network is an eight-bus ring with two cross-ties (the middle verticals B2-B7 and B3-B6); the grid connection under study sits at B1:
(grid connection)
B1 ---- B2 ---- B3 ---- B4
| | | |
B8 ---- B7 ---- B6 ---- B5Note: On Google Colab the install cell takes a few minutes on a fresh session (package download and precompilation). Colab's Julia version may change over time; this notebook targets Julia ≥ 1.12.
Warm-up and shared helpers
Julia compiles each function on first use. This cell loads the package, collects the solve helper up top, and warms BOTH paths this notebook exercises: the power-flow solver and the IEC 60909 short-circuit engine, on a tiny throwaway feeder with declared short-circuit power.
using Sparlectra
# solve helper used by every scenario (25 iterations, tolerance 1e-8)
function solve!(net; kwargs...)
etime = @elapsed begin
ite, erg = runpf!(net, 25, 1e-8, 0; kwargs...)
end
erg == 0 || error("Power flow did not converge (status = $erg)")
calcNetLosses!(net)
return etime, ite
end
wnet = Net(name = "warmup", baseMVA = 100.0)
addBus!(net = wnet, busName = "A", vn_kV = 110.0)
addBus!(net = wnet, busName = "B", vn_kV = 110.0)
addExternalGrid!(net = wnet, busName = "A", vm_pu = 1.0, sk_max_MVA = 2000.0, sk_min_MVA = 1500.0, rx_max = 0.1, internal_impedance = false)
addProsumer!(net = wnet, busName = "B", type = "ENERGYCONSUMER", p = 10.0, q = 3.0)
addPIModelACLine!(net = wnet, fromBus = "A", toBus = "B", r_pu = 0.01, x_pu = 0.08, b_pu = 0.0, status = 1)
t_pf = @elapsed solve!(wnet)
t_sc = @elapsed runShortCircuit!(wnet; case = :max)
println("warm: power flow ", round(t_pf; digits = 2), " s, short circuit ", round(t_sc; digits = 2), " s (first calls compile)")warm: power flow 0.08 s, short circuit 1.79 s (first calls compile)The study network
A meshed 110 kV ring B1..B8 with two chords, the eight-bus ring drawn in the introduction above, two PV generators (60 MW at B3, 40 MW at B6) and 160 MW of load. Scheduled generation deliberately undershoots the load, so the grid connection at B1 has to import a visible amount of power: that import is what makes the three slack representations distinguishable.
addExternalGrid! models the connection as an IEC 60909-0 network feeder: it creates the load-flow side (ideal slack by default, non-ideal source with internal_impedance = true) and records the declared short-circuit power ($S_{k,\mathrm{max}}'' = 2000$ MVA, $S_{k,\mathrm{min}}'' = 1500$ MVA) for the short-circuit engine.
function build_grid(mode::Symbol)
net = Net(name = "workshop_eg8_$(mode)", baseMVA = 100.0)
for b in ("B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8")
addBus!(net = net, busName = b, vn_kV = 110.0)
end
addPIModelACLine!(net = net, fromBus = "B1", toBus = "B2", r_pu = 0.010, x_pu = 0.060, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B2", toBus = "B3", r_pu = 0.015, x_pu = 0.080, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B3", toBus = "B4", r_pu = 0.020, x_pu = 0.090, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B4", toBus = "B5", r_pu = 0.012, x_pu = 0.070, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B5", toBus = "B6", r_pu = 0.015, x_pu = 0.075, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B6", toBus = "B7", r_pu = 0.018, x_pu = 0.085, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B7", toBus = "B8", r_pu = 0.010, x_pu = 0.055, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B8", toBus = "B1", r_pu = 0.011, x_pu = 0.065, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B2", toBus = "B7", r_pu = 0.020, x_pu = 0.100, b_pu = 0.02, status = 1)
addPIModelACLine!(net = net, fromBus = "B3", toBus = "B6", r_pu = 0.022, x_pu = 0.110, b_pu = 0.02, status = 1)
addProsumer!(net = net, busName = "B3", type = "GENERATOR", p = 60.0, vm_pu = 1.01, qMin = -60.0, qMax = 60.0)
addProsumer!(net = net, busName = "B6", type = "GENERATOR", p = 40.0, vm_pu = 1.00, qMin = -40.0, qMax = 40.0)
addProsumer!(net = net, busName = "B2", type = "ENERGYCONSUMER", p = 45.0, q = 12.0)
addProsumer!(net = net, busName = "B4", type = "ENERGYCONSUMER", p = 50.0, q = 15.0)
addProsumer!(net = net, busName = "B7", type = "ENERGYCONSUMER", p = 40.0, q = 10.0)
addProsumer!(net = net, busName = "B8", type = "ENERGYCONSUMER", p = 25.0, q = 8.0)
addExternalGrid!(
net = net,
busName = "B1",
vm_pu = 1.02,
sk_max_MVA = 2000.0,
sk_min_MVA = 1500.0,
rx_max = 0.1,
internal_impedance = (mode === :source),
)
ok, msg = validate!(net = net)
ok || error("Network validation failed: $msg")
return net
endbuild_grid (generic function with 1 method)The solve! helper comes from the warm-up cell (shared helpers up top).
Scenario 1: ideal slack
Example 1: the ideal slack. The default: the connection bus B1 becomes the reference (REF) bus and holds exactly 1.02 pu at 0° while absorbing whatever active and reactive power the network is missing.
net_slack = build_grid(:slack)
etime, ite = solve!(net_slack)
printACPFlowResults(net_slack, etime, ite, 1e-8)================================================================================
| SPARLECTRA Version 0.9.19 - AC Power Flow Results |
================================================================================
Date : 25-Aug-26 16:19:4
Iterations : 4
Flatstart : No
Tolerance : 1.0e-08
Solver : NR
Total time : 0.007392 s
Case :workshop_eg8_slack
Cooldown iters : 0
Q-hysteresis : 0.0000 pu
Jacobian cond. : kappa1(J) = 310.0, attainable accuracy ~ 6.9e-14, well conditioned (tol 1.0e-8 reachable)
BaseMVA : 100
Nodes : 8 (PV: 2 PQ: 5 Slack: 1)
Grid connection: slack bus B1
Branches : 10
Links : 0
HVDC links : 0
Lines : 10
Trafos : 0
Generators : 3
Loads : 4
Shunts : 0
Controllers : 0 (Tap: 0, Q(U): 0, P(U): 0)
PV→PQ locks : 0
PV→PQ events : 0
total network power balance (Σ S_branch): P = 0.821 [MW], Q = -15.938 [MVar]
==========================================================================================================================================================================================================================
| Nr | Bus | Vn [kV] | V [kV] | V [pu] | phi [deg] | Pg [MW] | Qg [MVar] | Pl [MW] | Ql [MVar] | Ps [MW] | Qs [MVar] | Type | Control | Tap Vm tgt |
==========================================================================================================================================================================================================================
| 1 | B1 | 110.0 | 112.200 | 1.020 | 0.000 | 60.821 | 30.126 | | | | | SLACK | - | |
| 2 | B2 | 110.0 | 110.839 | 1.008 | -0.871 | | | 45.000 | 12.000 | | | PQ | - | |
| 3 | B3 | 110.0 | 111.100 | 1.010 | 0.208 | 60.000 | 16.114 | | | | | PV | - | |
| 4 | B4 | 110.0 | 109.258 | 0.993 | -1.342 | | | 50.000 | 15.000 | | | PQ | - | |
| 5 | B5 | 110.0 | 109.667 | 0.997 | -0.651 | | | | | | | PQ | - | |
| 6 | B6 | 110.0 | 110.000 | 1.000 | 0.098 | 40.000 | -17.177 | | | | | PV | - | |
| 7 | B7 | 110.0 | 110.117 | 1.001 | -1.229 | | | 40.000 | 10.000 | | | PQ | - | |
| 8 | B8 | 110.0 | 110.733 | 1.007 | -1.065 | | | 25.000 | 8.000 | | | PQ | - | |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
==========================================================================================================================================================================================================================
| Branch | Type | Connection | P [MW] | Q [MVar] | P [MW] | Q [MVar] | Pv [MW] | Qv [MVar] | Ctrl | P_tgt | TapPos | Ctrl status |
==========================================================================================================================================================================================================================
| B_ACL_110_1_2 | Line | B1 -> B2 | 28.790 | 15.390 | -28.685 | -16.812 | 0.106 | -1.422 | - | - | - | - |
| B_ACL_110_2_3 | Line | B2 -> B3 | -23.652 | 0.659 | 23.735 | -2.252 | 0.083 | -1.592 | - | - | - | - |
| B_ACL_110_3_4 | Line | B3 -> B4 | 32.805 | 10.894 | -32.566 | -11.826 | 0.239 | -0.932 | - | - | - | - |
| B_ACL_110_4_5 | Line | B4 -> B5 | -17.434 | -3.174 | 17.471 | 1.412 | 0.038 | -1.761 | - | - | - | - |
| B_ACL_110_5_6 | Line | B5 -> B6 | -17.471 | -1.412 | 17.517 | -0.351 | 0.046 | -1.763 | - | - | - | - |
| B_ACL_110_6_7 | Line | B6 -> B7 | 25.925 | -7.426 | -25.796 | 6.030 | 0.128 | -1.396 | - | - | - | - |
| B_ACL_110_7_8 | Line | B7 -> B8 | -6.883 | -9.939 | 6.896 | 7.993 | 0.013 | -1.946 | - | - | - | - |
| B_ACL_110_8_1 | Line | B8 -> B1 | -31.896 | -15.993 | 32.031 | 14.736 | 0.135 | -1.257 | - | - | - | - |
| B_ACL_110_2_7 | Line | B2 -> B7 | 7.336 | 4.152 | -7.320 | -6.091 | 0.016 | -1.938 | - | - | - | - |
| B_ACL_110_3_6 | Line | B3 -> B6 | 3.460 | 7.471 | -3.442 | -9.401 | 0.018 | -1.929 | - | - | - | - |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Control
-------
Transformer controls: noneReading aid (Example 1): the SLACK row at B1 imports the scheduled 60 MW imbalance plus all network losses, and B1 sits at exactly 1.02 pu / 0.000°: the ideal, infinitely stiff busbar.
Scenario 2: non-ideal external-grid source
Example 2: the non-ideal external-grid source. With internal_impedance = true the reference voltage moves to a hidden internal bus B1__extgrid_int behind the feeder impedance $z_{pu} = \mathrm{baseMVA} / S_k'' = 100/2000 = 0.05$ (split by the declared $R/X = 0.1$). The terminal bus B1 becomes an ordinary solved bus.
net_source = build_grid(:source)
etime, ite = solve!(net_source)
printACPFlowResults(net_source, etime, ite, 1e-8)================================================================================
| SPARLECTRA Version 0.9.19 - AC Power Flow Results |
================================================================================
Date : 25-Aug-26 16:19:4
Iterations : 4
Flatstart : No
Tolerance : 1.0e-08
Solver : NR
Total time : 0.000455 s
Case :workshop_eg8_source
Cooldown iters : 0
Q-hysteresis : 0.0000 pu
Jacobian cond. : kappa1(J) = 378.0, attainable accuracy ~ 8.4e-14, well conditioned (tol 1.0e-8 reachable)
BaseMVA : 100
Nodes : 9 (PV: 2 PQ: 6 Slack: 0 Source: 1)
Grid connection: external-grid source at B1 (Sk'' = 2000.0 MVA, R/X = 0.1; internal slack: B1__extgrid_int)
Branches : 11
Links : 0
HVDC links : 0
Lines : 11
Trafos : 0
Generators : 3
Loads : 4
Shunts : 0
Controllers : 0 (Tap: 0, Q(U): 0, P(U): 0)
PV→PQ locks : 0
PV→PQ events : 0
total network power balance (Σ S_branch): P = 0.974 [MW], Q = -14.086 [MVar]
==========================================================================================================================================================================================================================
| Nr | Bus | Vn [kV] | V [kV] | V [pu] | phi [deg] | Pg [MW] | Qg [MVar] | Pl [MW] | Ql [MVar] | Ps [MW] | Qs [MVar] | Type | Control | Tap Vm tgt |
==========================================================================================================================================================================================================================
| 1 | B1 | 110.0 | 110.952 | 1.009 | -1.640 | | | | | | | PQ | - | |
| 2 | B2 | 110.0 | 110.156 | 1.001 | -2.578 | | | 45.000 | 12.000 | | | PQ | - | |
| 3 | B3 | 110.0 | 111.100 | 1.010 | -1.562 | 60.000 | 23.923 | | | | | PV | - | |
| 4 | B4 | 110.0 | 109.258 | 0.993 | -3.114 | | | 50.000 | 15.000 | | | PQ | - | |
| 5 | B5 | 110.0 | 109.667 | 0.997 | -2.424 | | | | | | | PQ | - | |
| 6 | B6 | 110.0 | 110.000 | 1.000 | -1.675 | 40.000 | -11.017 | | | | | PV | - | |
| 7 | B7 | 110.0 | 109.538 | 0.996 | -2.950 | | | 40.000 | 10.000 | | | PQ | - | |
| 8 | B8 | 110.0 | 109.843 | 0.999 | -2.755 | | | 25.000 | 8.000 | | | PQ | - | |
| 9 | B1__extgrid_int | 110.0 | 112.200 | 1.020 | 0.000 | 60.974 | 18.008 | | | | | SOURCE | - | |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
==========================================================================================================================================================================================================================
| Branch | Type | Connection | P [MW] | Q [MVar] | P [MW] | Q [MVar] | Pv [MW] | Qv [MVar] | Ctrl | P_tgt | TapPos | Ctrl status |
==========================================================================================================================================================================================================================
| B_ACL_110_1_2 | Line | B1 -> B2 | 28.829 | 6.563 | -28.742 | -8.060 | 0.087 | -1.496 | - | - | - | - |
| B_ACL_110_2_3 | Line | B2 -> B3 | -23.568 | -7.122 | 23.657 | 5.572 | 0.089 | -1.550 | - | - | - | - |
| B_ACL_110_3_4 | Line | B3 -> B4 | 32.830 | 10.890 | -32.591 | -11.821 | 0.239 | -0.931 | - | - | - | - |
| B_ACL_110_4_5 | Line | B4 -> B5 | -17.409 | -3.179 | 17.447 | 1.417 | 0.037 | -1.762 | - | - | - | - |
| B_ACL_110_5_6 | Line | B5 -> B6 | -17.447 | -1.417 | 17.493 | -0.347 | 0.046 | -1.764 | - | - | - | - |
| B_ACL_110_6_7 | Line | B6 -> B7 | 26.002 | -1.280 | -25.880 | -0.137 | 0.122 | -1.417 | - | - | - | - |
| B_ACL_110_7_8 | Line | B7 -> B8 | -6.823 | -4.758 | 6.829 | 2.803 | 0.006 | -1.955 | - | - | - | - |
| B_ACL_110_8_1 | Line | B8 -> B1 | -31.829 | -10.803 | 31.952 | 9.511 | 0.122 | -1.291 | - | - | - | - |
| B_ACL_110_2_7 | Line | B2 -> B7 | 7.310 | 3.182 | -7.296 | -5.106 | 0.014 | -1.924 | - | - | - | - |
| B_ACL_110_3_6 | Line | B3 -> B6 | 3.513 | 7.461 | -3.495 | -9.390 | 0.018 | -1.929 | - | - | - | - |
| B_ACL_110_9_1 | Line | B1__extgrid_int -> B1 | 60.974 | 18.008 | -60.781 | -16.075 | 0.193 | 1.933 | - | - | - | - |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Control
-------
Transformer controls: noneReading aid (Example 2): look at the first row. The terminal bus B1 is now an ordinary PQ bus at about 1.009 pu and -1.6°, below the 1.02 pu setpoint. The setpoint itself is held by the hidden internal bus B1__extgrid_int in the last row (type SOURCE, exactly 1.020 pu at 0°, the actual angle reference): the import current drops the difference between those two rows across the feeder impedance. The stiffer the declared $S_k''$, the smaller the droop; for $S_k'' \to \infty$ this variant degenerates to Example 1.
Scenario 3: distributed slack
Example 3: the distributed slack. Examples 1 and 2 answer the question "who supplies the missing power?" the same way: one dedicated bus absorbs the whole imbalance plus all losses. That is an accounting fiction; in a real interconnection, primary control raises the output of many machines at once. The distributed slack models exactly that. The solver gains one unknown, the total correction lambda_P, and every participating generator covers its share alpha * lambda_P. The weights come from the scheduled output (:pg_weighted: 60 MW gives α = 0.6 for B3, 40 MW gives α = 0.4 for B6). The reference bus keeps the angle reference and the reactive balance, but its active import drops to zero.
net_dist = build_grid(:slack)
etime, ite = solve!(net_dist; distributed_slack_enabled = true, distributed_slack_p_mode = :pg_weighted)
printACPFlowResults(net_dist, etime, ite, 1e-8)================================================================================
| SPARLECTRA Version 0.9.19 - AC Power Flow Results |
================================================================================
Date : 25-Aug-26 16:19:5
Iterations : 4
Flatstart : No
Tolerance : 1.0e-08
Solver : NR
Total time : 0.000533 s
Case :workshop_eg8_slack
Cooldown iters : 0
Q-hysteresis : 0.0000 pu
Jacobian cond. : kappa1(J) = 306.0, attainable accuracy ~ 6.8e-14, well conditioned (tol 1.0e-8 reachable)
BaseMVA : 100
Nodes : 8 (PV: 2 PQ: 5 Slack: 1)
Grid connection: slack bus B1
Branches : 10
Links : 0
HVDC links : 0
Lines : 10
Trafos : 0
Generators : 3
Loads : 4
Shunts : 0
Controllers : 0 (Tap: 0, Q(U): 0, P(U): 0)
PV→PQ locks : 0
PV→PQ events : 0
Dist. slack : mode pg_weighted, lambda_P = +61.537 MW (imbalance + losses picked up by 2 participant(s), see the dSl alpha column)
total network power balance (Σ S_branch): P = 1.537 [MW], Q = -12.415 [MVar]
====================================================================================================================================================================================================================================================
| Nr | Bus | Vn [kV] | V [kV] | V [pu] | phi [deg] | Pg [MW] | Qg [MVar] | Pl [MW] | Ql [MVar] | Ps [MW] | Qs [MVar] | Type | Control | Tap Vm tgt | dSl alpha | Pg eff MW |
====================================================================================================================================================================================================================================================
| 1 | B1 | 110.0 | 112.200 | 1.020 | 0.000 | | 41.841 | | | | | SLACK | - | | | |
| 2 | B2 | 110.0 | 110.763 | 1.007 | 0.460 | | | 45.000 | 12.000 | | | PQ | - | | | |
| 3 | B3 | 110.0 | 111.100 | 1.010 | 3.164 | 60.000 | 11.252 | | | | | PV | - | | 0.6000 | 96.922 |
| 4 | B4 | 110.0 | 109.256 | 0.993 | 1.584 | | | 50.000 | 15.000 | | | PQ | - | | | |
| 5 | B5 | 110.0 | 109.667 | 0.997 | 2.252 | | | | | | | PQ | - | | | |
| 6 | B6 | 110.0 | 110.000 | 1.000 | 2.977 | 40.000 | -20.508 | | | | | PV | - | | 0.4000 | 64.615 |
| 7 | B7 | 110.0 | 110.026 | 1.000 | 0.326 | | | 40.000 | 10.000 | | | PQ | - | | | |
| 8 | B8 | 110.0 | 110.681 | 1.006 | -0.231 | | | 25.000 | 8.000 | | | PQ | - | | | |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
==========================================================================================================================================================================================================================
| Branch | Type | Connection | P [MW] | Q [MVar] | P [MW] | Q [MVar] | Pv [MW] | Qv [MVar] | Ctrl | P_tgt | TapPos | Ctrl status |
==========================================================================================================================================================================================================================
| B_ACL_110_1_2 | Line | B1 -> B2 | -9.761 | 22.847 | 9.825 | -24.517 | 0.064 | -1.670 | - | - | - | - |
| B_ACL_110_2_3 | Line | B2 -> B3 | -58.389 | 7.496 | 58.904 | -6.783 | 0.515 | 0.713 | - | - | - | - |
| B_ACL_110_3_4 | Line | B3 -> B4 | 33.362 | 10.800 | -33.116 | -11.701 | 0.246 | -0.901 | - | - | - | - |
| B_ACL_110_4_5 | Line | B4 -> B5 | -16.884 | -3.299 | 16.919 | 1.524 | 0.035 | -1.774 | - | - | - | - |
| B_ACL_110_5_6 | Line | B5 -> B6 | -16.919 | -1.524 | 16.963 | -0.254 | 0.043 | -1.778 | - | - | - | - |
| B_ACL_110_6_7 | Line | B6 -> B7 | 52.290 | -11.096 | -51.779 | 11.506 | 0.511 | 0.410 | - | - | - | - |
| B_ACL_110_7_8 | Line | B7 -> B8 | 15.333 | -14.520 | -15.291 | 12.737 | 0.042 | -1.783 | - | - | - | - |
| B_ACL_110_8_1 | Line | B8 -> B1 | -9.709 | -20.737 | 9.761 | 18.994 | 0.053 | -1.743 | - | - | - | - |
| B_ACL_110_2_7 | Line | B2 -> B7 | 3.564 | 5.021 | -3.554 | -6.987 | 0.010 | -1.966 | - | - | - | - |
| B_ACL_110_3_6 | Line | B3 -> B6 | 4.657 | 7.235 | -4.637 | -9.159 | 0.019 | -1.923 | - | - | - | - |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Control
-------
Transformer controls: noneReading aid (Example 3): the bus table now carries the participation directly in the columns dSl alpha and Pg eff MW: B3 picks up α = 0.6 of the 61.5 MW correction (60 to 96.9 MW effective), B6 the remaining α = 0.4 (40 to 64.6 MW). The Pg column keeps showing the schedule, the header line above the table sums it up (mode and lambda_P), and the slack row at B1 no longer imports active power; only the reactive balance stays with the reference bus. The branch flows confirm the pickup: summing them around B3 yields exactly the effective 96.9 MW.
The three scenarios side by side
Same network, three grid-connection models: Examples 1 to 3 in one table. The losses differ because the flow pattern differs: in Example 3 the extra power from B3 and B6 travels longer paths through the ring, and in Example 2 the feeder branch itself dissipates a share. (A negative Q loss means the line charging produces more reactive power than the flows consume.)
println(rpad("scenario", 20), lpad("Vm(B1) pu", 11), lpad("P loss MW", 11), lpad("Q loss MVAr", 13), " balanced by")
for (label, net, by) in (
("ideal slack", net_slack, "slack bus B1"),
("non-ideal source", net_source, "hidden source bus"),
("distributed slack", net_dist, "B3 (α=0.6) + B6 (α=0.4)"),
)
pl, ql = getTotalLosses(net = net)
println(rpad(label, 20), lpad(string(round(get_bus_vm_pu(net, "B1"); digits = 4)), 11), lpad(string(round(pl; digits = 3)), 11), lpad(string(round(ql; digits = 3)), 13), " ", by)
endscenario Vm(B1) pu P loss MW Q loss MVAr balanced by
ideal slack 1.02 0.821 -15.938 slack bus B1
non-ideal source 1.0087 0.974 -14.086 hidden source bus
distributed slack 1.02 1.537 -12.415 B3 (α=0.6) + B6 (α=0.4)Short-circuit currents (IEC 60909-0)
Example 4: the IEC 60909-0 short-circuit sweep. The external grid is more than a voltage boundary condition: its declared short-circuit power says how much fault current the superordinate network can deliver. The sweep runs on the Example 1 network (net_slack), the same eight-bus ring. runShortCircuit! replaces the operating state by the equivalent voltage source at the fault location and computes the initial symmetrical short-circuit current $I_k''$, power $S_k''$, and peak current $i_p$ per fault bus. Only sources with declared short-circuit data contribute; here that is the feeder at B1. The two generators carry no short-circuit attributes, so they are simply not short-circuit sources in this sweep; near those machines the real fault level would be somewhat higher than the feeder-only result below.
sc_max = runShortCircuit!(net_slack; case = :max)
printShortCircuitResult(sc_max)Balanced 3-phase short circuit (IEC 60909-0) — case: max, c per IEC Table 1
bus Un[kV] Ik''[kA] Sk''[MVA] kappa ip[kA] status flagged
B1 110.0 10.497 2000.0 2.0 29.691 ok no
B2 110.0 5.703 1086.6 1.931 15.574 ok no
B3 110.0 3.8549 734.47 1.8862 10.283 ok no
B4 110.0 2.9546 562.94 1.8565 7.7573 ok no
B5 110.0 2.978 567.39 1.8597 7.8324 ok no
B6 110.0 3.6897 702.97 1.8749 9.7832 ok no
B7 110.0 4.8744 928.69 1.908 13.153 ok no
B8 110.0 5.5627 1059.8 1.9266 15.156 ok noThe minimum case (protection sensitivity) uses the declared $S_{k,\mathrm{min}}'' = 1500$ MVA and the lower IEC 60909-0 voltage factor $c_\mathrm{min}$:
sc_min = runShortCircuit!(net_slack; case = :min)
printShortCircuitResult(sc_min)Balanced 3-phase short circuit (IEC 60909-0) — case: min, c per IEC Table 1
bus Un[kV] Ik''[kA] Sk''[MVA] kappa ip[kA] status flagged
B1 110.0 7.873 1500.0 2.0 22.268 ok no
B2 110.0 4.649 885.76 1.9386 12.746 ok no
B3 110.0 3.2515 619.5 1.8944 8.7112 ok no
B4 110.0 2.535 482.98 1.8643 6.6835 ok no
B5 110.0 2.5539 486.58 1.8675 6.7448 ok no
B6 110.0 3.1218 594.79 1.8835 8.3154 ok no
B7 110.0 4.0342 768.62 1.9165 10.934 ok no
B8 110.0 4.5462 866.17 1.9344 12.437 ok noReading aid (Example 4): $I_k''$ is largest at the connection bus B1, whose short-circuit level is exactly the declared feeder strength (2000 MVA resp. 1500 MVA), and decays with electrical distance as line impedance accumulates in the fault loop; B4, the electrically farthest bus, sees less than a third of the connection-bus current.
Where to go next
- New to Sparlectra? Chapter 1 of the workshop tour builds a network from scratch step by step, directly in Colab.
- Slack Bus and External Grid Sources: the full theory: why the load flow needs a slack, the source model, and how the equation system changes.
- Distributed slack notebook: where the participation weights come from (schedule, headroom, imported APF/normalPF, explicit) and the fallback when no participant is valid.
- Short-Circuit Compendium: method, c-factors, safety flagging, and CGMES-fed short circuits.
examples/powerflow/exp_external_grid_comparison.jlin the repository: the same comparison as a script, tabulated bus by bus.