8.4.633-stable Switch to dev

GreyCat Powergrid Library

@library("powergrid", "0.0.0");

Power flow analysis for electrical networks:

  • PowerNetwork: AC load flow (Newton-Raphson) and short circuit, computing voltages, currents, power flows and losses.
  • DcNetwork: DC load flow, PTDF / LODF sensitivities and fast N-1 security screening, for planning studies that evaluate many topologies or many contingencies.

Quick Start

// Define a simple 3-bus network: external grid → line → load
var network = PowerNetwork {};
network.configure(3, 2, 1, 1);  // 3 buses, 2 lines, 1 ext grid, 1 load

// Create buses at 20 kV
network.createBus(0, 20.0);
network.createBus(1, 20.0);
network.createBus(2, 20.0);

// External grid (slack bus) at bus 0, voltage = 1.0 p.u.
network.createExtGrid(0, 1.0);

// Transmission lines
network.createLine(0, 0, 1, 10.0, 0.1, 0.4, 9.7, 0.5);  // bus 0 → bus 1, 10 km
network.createLine(1, 1, 2, 5.0, 0.1, 0.4, 9.7, 0.5);   // bus 1 → bus 2, 5 km

// Load at bus 2: 2 MW active, 0.5 MVar reactive
network.createLoad(2, 2.0, 0.5);

// Solve power flow
network.compute();

// Read results
var busResult = network.getBusResult(2);
info("Bus 2 voltage: ${busResult.abs} p.u., angle: ${busResult.angle_radians} rad");

var lineResult = network.getLineResult(0);
info("Line 0: ${lineResult.p_from_mw} MW, losses: ${lineResult.pl_mw} MW, loading: ${lineResult.loading_percent}%");

Workflow

  1. Configure — declare network dimensions with configure()
  2. Build topology — create buses, lines, loads, and external grids
  3. Solve — run Newton-Raphson power flow with compute()
  4. Read results — query bus and line results

API Reference

PowerNetwork

Electrical network model and power flow solver.

Constructor:

Field Type Description
tolerance float? Convergence tolerance for Newton-Raphson solver
max_iteration int? Maximum solver iterations

Methods:

Method Returns Description
configure(nb_bus, nb_lines, nb_ext_grids, nb_loads) void Set network dimensions. Must be called first.
createBus(bus_id, vn_kv) void Create a bus at given nominal voltage (kV)
createLine(line_id, from, to, length_km, r, x, c, max_i_ka) void Create a transmission line between two buses
createLoad(bus_id, p_mw, q_mvar) void Create a load at a bus
createExtGrid(bus_id, vm_pu) void Create an external grid (slack bus) with fixed voltage
compute() void Run Newton-Raphson power flow analysis
getBusResult(bus_id) PowerBusResult Get voltage/current results for a bus
getLineResult(line_id) PowerLineResult Get power flow results for a line
getCheckSum() Array<float> Get solver convergence metrics

createLine Parameters

Parameter Unit Description
line_id — Unique line identifier (0 to nb_lines-1)
from_bus_id — Starting bus ID
to_bus_id — Ending bus ID
lenght_km km Line length
r_ohm_per_km Ω/km Resistance per kilometer
x_ohm_per_km Ω/km Reactance per kilometer
c_n_f_per_km nF/km Capacitance per kilometer
max_i_ka kA Maximum current rating

PowerBusResult

Results for a single bus after power flow computation.

Field Type Unit Description
abs float p.u. Voltage magnitude
angle_radians float rad Voltage phase angle
voltage float — Real component of voltage
voltage_img float — Imaginary component of voltage
current float — Real component of current
current_img float — Imaginary component of current

PowerLineResult

Results for a transmission line after power flow computation.

Field Type Unit Description
p_from_mw float MW Active power at “from” bus
q_from_mvar float MVar Reactive power at “from” bus
p_to_mw float MW Active power at “to” bus
q_to_mvar float MVar Reactive power at “to” bus
pl_mw float MW Active power losses
ql_mvar float MVar Reactive power consumption
i_from_ka float kA Current at “from” bus
i_to_ka float kA Current at “to” bus
i_ka float kA Maximum current (max of from/to)
vm_from_pu float p.u. Voltage magnitude at “from” bus
vm_to_pu float p.u. Voltage magnitude at “to” bus
va_from_radians float rad Voltage angle at “from” bus
va_to_radians float rad Voltage angle at “to” bus
loading_percent float % Line loading percentage

Example — Analyzing Line Loading

var network = PowerNetwork { tolerance: 1e-8, max_iteration: 50 };
network.configure(2, 1, 1, 1);

network.createBus(0, 110.0);  // 110 kV bus
network.createBus(1, 110.0);
network.createExtGrid(0, 1.0);
network.createLine(0, 0, 1, 20.0, 0.05, 0.3, 11.0, 0.6);
network.createLoad(1, 10.0, 3.0);  // 10 MW, 3 MVar

network.compute();

var line = network.getLineResult(0);
info("Power flow: ${line.p_from_mw} MW → ${line.p_to_mw} MW");
info("Losses: ${line.pl_mw} MW + ${line.ql_mvar} MVar");
info("Current: ${line.i_ka} kA");
info("Loading: ${line.loading_percent}%");

if (line.loading_percent > 80.0) {
    warn("Line 0 is heavily loaded!");
}

DC load flow — DcNetwork

The DC approximation keeps only active power: |V| = 1 p.u., r ≪ x and small angle differences, so P = B·θ and the flow of a branch is (θ_from − θ_to) / x. It is linear, lossless and never diverges, which makes it the standard model for transmission expansion planning and contingency screening.

The susceptance matrix is factorized once (sparse LDLT, AMD ordering). N-1 flows then use line outage distribution factors (f_l + LODF[l][k]·f_k): one extra solve per outage, no refactorization, O(branches) memory. Bridges (outages that split the network) are found with Tarjan’s algorithm.

var dc = DcNetwork {};
dc.configure(3, 3, 0);          // 3 buses, 3 branches, slack = bus 0
dc.setBranch(0, 0, 1, 0.1);     // x in p.u.
dc.setBranch(1, 0, 2, 0.1);
dc.setBranch(2, 1, 2, 0.1);
dc.factorize();

var f = dc.flows([100.0, -50.0, -50.0]);   // MW: [50, 50, 0]

// N and N-1 screening over several snapshots
var snapshots = Array<Array<float>> { [100.0, -50.0, -50.0], [60.0, -30.0, -30.0] };
var s = dc.screen(snapshots, [60.0, 60.0, 60.0], true, 10);
info("max N-1 loading ${s.max_loading_n1}, overload ${s.overload_mw} MW, islandings ${s.islanding_cases}");
Method Returns Description
configure(nb_bus, nb_branches, slack_bus_id) void Set network size and reference bus. Must be called first.
setBranch(branch_id, from_bus_id, to_bus_id, x_pu) void Create or replace a branch (x > 0).
factorize() void Factorize the susceptance matrix of the part connected to the slack.
connected() Array<bool> Whether each bus is connected to the slack.
bridges() Array<bool> Whether the outage of each branch splits the network.
flows(injections) Array<float> N state branch flows [MW] for net injections per bus [MW].
ptdf() Array<float> Branches × buses PTDF, row-major (dense: small networks).
lodf() Array<float> Branches × branches LODF, row-major (dense: small networks).
screen(injections, ratings, n1, max_violations) DcScreening N (and N-1) screening of one injection array per snapshot.

Buses not connected to the slack get a zero angle. In screen, a state that cuts a bus with a non-zero injection from the slack counts as an islanding (islanding_cases, disconnected_mw) and its flows are not checked.

DcScreening: max_loading_n, max_loading_n1, overload_mw (sum of MW above rating), islanding_cases, disconnected_mw, and violations (the first max_violations DcViolation { snapshot, outage, branch, loading }; outage = -1 for the N state, branch = -1 for an islanding).