powergrid_synth.transmission.capacity_allocator
Assigns generation capacities to generator buses using a statistical approach based on Elyas et al. (2017), “On the Statistical Settings of Generation and Load in a Synthetic Grid Modeling” (https://arxiv.org/abs/1706.09294).
The methodology uses the exponential distribution of individual generation
capacities and the non-trivial correlation between generation capacity and
nodal degree observed in realistic grids. An analogous approach for load
allocation is implemented in load_allocator.
Ported from the MATLAB SynGrid toolbox (sg_refsys_stat.m).
Module Contents
- class powergrid_synth.transmission.capacity_allocator.CapacityAllocator(graph, ref_sys_id=1)[source]
Assigns generation capacities (PgMax) to generator buses in the grid.
Implements the three-stage methodology from Elyas et al. (2017):
Total generation: Compute the aggregate generation capacity from a scaling law fitted to realistic grids:
log Pg_tot(N) = -0.21 * log^2(N) + 2.06 * log(N) + 0.66.Individual capacities: Sample N_g individual capacities from an exponential distribution (with ~1% super-large outliers to capture the observed heavy tail).
Correlated assignment: Assign capacities to generator buses using a 14x14 empirical 2D probability table (
Tab_2D_Pgmax) that encodes the joint distribution of normalized capacity and normalized nodal degree. This preserves the observed Pearson correlation rho(P_bar, k_bar) in [0.25, 0.5] between capacity and degree.
Reference systems with pre-computed
Tab_2D_Pgmaxtables are available for NYISO-2935 (id=1), WECC-16944 (id=2), and a third system (id=3). A heuristic diagonal-bias table (id=0) is provided as a fallback.- Parameters:
graph (nx.Graph) – NetworkX graph with
'bus_type'node attributes already set (byBusTypeAllocator).ref_sys_id (int) – Reference system for statistical tables (0=heuristic, 1=NYISO-2935, 2=WECC-16944, 3=additional reference).
References
- _assignment_logic(norm_deg_pairs, norm_caps, tab_2d)[source]
Assign normalized capacities to buses via 2D-binning (Stage 3).
This implements the correlated assignment algorithm from Elyas et al. (2017) that preserves the empirical joint distribution of normalized capacity and normalized nodal degree. The steps are:
Scale 2D table to counts: multiply
tab_2dbyN_gand round to integer targetsn_rcfor each (capacity-class r, degree-class c) cell. Adjust rounding so that the total equalsN_gexactly.Compute marginals: column sums give degree-bin targets; row sums give capacity-bin targets.
Bin by degree: sort generators by normalized degree, partition into 14 degree bins according to column-sum targets.
Bin by capacity: sort normalized capacities, partition into 14 capacity bins according to row-sum targets.
Nested assignment loop: for each degree bin c = 1..14 and each capacity bin r = 14..1 (high to low): randomly sample
n_rccapacities from capacity bin r (without replacement) and assign them to unassigned generators in degree bin c.Reassemble all bins into the output array.
- Parameters:
norm_deg_pairs (np.ndarray) – Shape
(N_g, 2)— columns are[NodeID, NormalizedDegree].norm_caps (np.ndarray) – Shape
(N_g,)— normalized capacity values in [0, 1].tab_2d (np.ndarray) – A 14x14 joint-probability matrix (rows=capacity classes, columns=degree classes).
- Returns:
Shape
(N_g, 3)— columns are[NodeID, NormalizedDegree, NormalizedCapacity].- Return type:
np.ndarray
- _generate_heuristic_tab_2d()[source]
Generate a heuristic 14x14 joint-probability table as a fallback.
When no reference system data is selected (
ref_sys_id=0), this method produces a synthetic table using a Gaussian-decay diagonal bias:weight(r, c) = exp(-0.5 * |r - c|), where rows represent capacity classes and columns represent degree classes (both ordered low-to-high). The matrix is normalized to sum to 1.This simulates the positive correlation between nodal degree and generation capacity observed in realistic grids, without relying on empirical data from a specific reference system.
- Returns:
A 14x14 probability matrix (sums to 1).
- Return type:
np.ndarray
- _get_default_tab_2d()[source]
Return the
Tab_2D_Pgmaxtable for the selected reference system.The table is a 14x14 matrix representing the empirical joint PDF
Pr((P_bar_gn_max, k_bar_n) in A)discretized into 14 capacity classes (rows, low-to-high) and 14 nodal-degree classes (columns, low-to-high). Tables for real reference systems are loaded fromreference_data.get_reference_stats()(ported from the MATLAB SynGrid filesg_refsys_stat.m).- Returns:
A 14x14 probability matrix.
- Return type:
np.ndarray
- _initial_generation_distribution(total_gen)[source]
Sample individual generation capacities from the empirical distribution.
Following Elyas et al. (2017), more than 99% of generation units in realistic grids follow an exponential distribution. About 1% have extremely large capacities that fall outside the exponential range.
The procedure is:
Draw
N_gsamples fromExp(mu)wheremu = total_gen / N_g.Replace ~1% of the samples with “super-large” values drawn uniformly from
[max(P), 3 * max(P)].If the sum deviates more than 5% above or 10% below
total_gen, rescale all values proportionally.Normalize by the maximum capacity.
- Parameters:
total_gen (float) – Target total generation capacity (MW).
- Returns:
p_caps (np.ndarray) – Raw (possibly rescaled) capacity values, shape
(N_g,).max_r_pgmax (float) – Maximum capacity value, used for normalization.
normalized_r_pgmax (np.ndarray) – Capacities normalized to [0, 1] by dividing by
max_r_pgmax.
- Return type:
Tuple[numpy.ndarray, float, numpy.ndarray]
- allocate(tab_2d=None)[source]
Run the full generation-capacity allocation pipeline.
Executes the three-stage methodology from Elyas et al. (2017):
Compute total generation capacity from the scaling law:
Pg_tot = 10^(-0.21 * log10(N)^2 + 2.06 * log10(N) + 0.66).Sample individual capacities, normalize them and the generator nodal degrees by their respective maxima so that both lie in [0, 1]:
P_bar = P / max(P),k_bar = k / max(k).Assign normalized capacities to generator buses via 2D binning using
Tab_2D_Pgmax.Denormalize:
Pg_max = P_bar * max(P).
- Parameters:
tab_2d (np.ndarray or None, optional) – Custom 14x14 probability matrix. If None, the default table for the selected
ref_sys_idis used.- Returns:
Mapping from generator node ID to its assigned capacity
Pg_max(MW).- Return type:
dict[int, float]