Topology pre-processing#
- merge_zero_z(case, threshold, *, xfmr_threshold=None)#
Consolidate electrically equivalent network nodes in place.
The merged case stays a valid case: record ids that collide at a representative bus are renamed. The lowering calls
merge_topologyinstead, because it keys nothing on merged identities.- Parameters:
case -- Parsed case to update in place.
threshold -- Branch impedance-magnitude limit in per unit on the system base. A nonpositive value disables branch consolidation.
xfmr_threshold -- Optional separate impedance-magnitude limit for two-winding transformers. Zero disables transformer consolidation.
- Returns:
Counts of affected buses, branches, transformers, and device records.
- class gpf.MergeZeroZStats#
Summarize the network records affected by bus consolidation.
- scale_loads(case, *, areas=None, zones=None, owners=None, buses=None, bus_type=None, interruptible='both', target_load_mw=None, multiplier=None, percent=None, increment_mw=None, q_mode='scale', q_target_mvar=None, q_percent=None, q_target_pf=None, q_increment_mvar=None)#
Scale selected in-service loads in place.
Supply exactly one active-power method. All supplied selectors intersect. The function does not change out-of-service loads. Loads with
SCALE=0and loads excluded byinterruptibleremain fixed, but their demand counts towardtarget_load_mw.- Parameters:
case -- Case to modify.
areas -- Optional area numbers.
zones -- Optional zone numbers.
owners -- Optional owner numbers.
buses -- Optional bus numbers.
bus_type --
Noneselects all bus types."pq"selects type 1."pv_slack"selects types 2 and 3.interruptible --
"both"selects all loads."non_interruptible"or"interruptible"selects one class.target_load_mw -- Target total active load in MW for the selected group.
multiplier -- Active-load multiplier. For example,
1.05adds 5 percent.percent -- Active-load percentage change. For example,
5adds 5 percent.increment_mw -- Active-load change in MW for the selected group.
q_mode -- Reactive-load treatment.
"scale"uses the active-load multiplier."preserve"keeps reactive load unchanged."zero"sets it to zero."target","percent","pf", and"increment"use their matching argument.q_target_mvar -- Target total reactive load in Mvar for
"target".q_percent -- Reactive-load percentage change for
"percent".q_target_pf -- Target power-factor magnitude in
(0, 1]for"pf". The original reactive-load sign determines leading or lagging sign.q_increment_mvar -- Reactive-load change in Mvar for
"increment".
- Returns:
The multiplier that the function applied to active load.
- Raises:
ValueError -- The caller supplies an invalid option combination, a selector matches no load, or the requested change is undefined.
Examples
Increase active and reactive load in area 2 by 5 percent:
>>> alpha = gpf.scale_loads(case, areas=[2], percent=5.0)
Set active load at two buses to 500 MW and preserve reactive load:
>>> alpha = gpf.scale_loads( ... case, ... buses=[101, 205], ... target_load_mw=500.0, ... q_mode="preserve", ... )
- curtail_loads(case, *, loads)#
Curtail named constant-power loads in place.
- Parameters:
case -- Case to modify.
loads --
(bus, load_id, curtailment_mw)rows. The function limits each curtailment to the load's positive constant-powerPL.
- Returns:
Total active load curtailed in MW.
- Raises:
ValueError -- A named load is absent, out of service, or has no positive constant-power active demand.
Notes
The function reduces
PLwithout crossing zero and scalesQLby the same factor. It does not change current or admittance load terms.
- dispatch_generators(case, *, machines, delta_mw, enforce_pt_pb=False)#
Shift active generation across named machines in place.
- Parameters:
case -- Case to modify.
machines --
(bus, generator_id, participation_factor)rows. The function normalizes the factors by their sum.delta_mw -- Total active-generation change in MW. A positive value raises output. A negative value lowers output.
enforce_pt_pb -- Clamp each resulting output to
[PB, PT]when true.
- Returns:
The total MW change that the function applied. This value can differ from
delta_mwwhen generator limits bind.- Raises:
ValueError -- A named generator is absent or out of service, or the participation factors sum to zero.
Examples
Share a 100 MW increase between two generators in a 60:40 ratio:
>>> applied_mw = gpf.dispatch_generators( ... case, ... machines=[(101, "1", 0.6), (205, "2", 0.4)], ... delta_mw=100.0, ... enforce_pt_pb=True, ... )
- scale_generators(case, *, areas=None, zones=None, owners=None, buses=None, target_pg_mw=None, multiplier=None, enforce_pt_pb=False)#
Scale selected in-service generator active output in place.
Supply exactly one of
target_pg_mwandmultiplier. All supplied selectors intersect. The function does not change reactive output or reactive limits.- Parameters:
case -- Case to modify.
areas -- Optional bus-area numbers.
zones -- Optional bus-zone numbers.
owners -- Optional generator-owner numbers.
buses -- Optional generator bus numbers.
target_pg_mw -- Target total active generation in MW for the selected machines.
multiplier -- Active-output multiplier for each selected machine.
enforce_pt_pb -- Enforce each non-slack generator's
PBandPTlimits when true. This option requirestarget_pg_mw. Selected slack generators receive the remaining target in proportion to their original active output.
- Returns:
The active-output multiplier calculated from the target or supplied by the caller.
- Raises:
ValueError -- The caller does not supply exactly one scaling method, a selector matches no in-service generator, or limit enforcement is requested without a target.
Examples
Set total in-service generation in area 2 to 1,500 MW:
>>> alpha = gpf.scale_generators( ... case, areas=[2], target_pg_mw=1500.0, enforce_pt_pb=True ... )
- scale_shunts(case, *, areas=None, zones=None, owners=None, buses=None, target_g_mw=None, multiplier_g=None, target_cap_mvar=None, target_reactor_mvar=None)#
Scale in-service FIXED SHUNT records in place.
All supplied selectors intersect. The function does not change out-of-service shunts.
- Parameters:
case -- Case to modify.
areas -- Optional bus-area numbers.
zones -- Optional bus-zone numbers.
owners -- Optional bus-owner numbers.
buses -- Optional shunt bus numbers.
target_g_mw -- Target total active shunt conductance in MW. Do not supply this argument with
multiplier_g.multiplier_g -- Multiplier for active shunt conductance.
target_cap_mvar -- Capacitor target parameter in Mvar. Supply this argument together with
target_reactor_mvar.target_reactor_mvar -- Reactor target parameter in Mvar. Supply this argument together with
target_cap_mvar.
- Returns:
None.- Raises:
ValueError -- A selector matches no in-service fixed shunt, active-shunt scaling is ambiguous, only one reactive target is supplied, or a requested target has no applicable shunt records.
Notes
Active-shunt scaling applies one common multiplier. Reactive-shunt scaling preserves each record's share within its original capacitor or reactor group. Let
ctandrtbe the two target parameters. LetS_candS_rbe the sums of the original positive and absolute negativeBLvalues. A capacitor receivesct * ct * BL / (S_c * (ct + rt)). A reactor receivesct * rt * abs(BL) / (S_r * (ct + rt))and becomes nonnegative. A zeroBLremains unchanged.
- start_generators(case, *, machines)#
Bring named out-of-service generators online in place.
- Parameters:
case -- Case to modify.
machines --
(bus, generator_id, output_mw)rows. The function clamps each requested output to[0, PT].
- Returns:
Total active output in MW assigned to the started generators.
- Raises:
ValueError -- A named generator is absent or already in service.
Notes
The function sets
QG,QT, andQBto zero. The started generators therefore supply no reactive-power support. The function can start a generator belowPBbecause it does not perform unit commitment.
- apply_substation_topology(case)#
Apply node-breaker topology to a copy of a case.
- Parameters:
case -- Case with substation topology records.
- Returns:
The updated case and a report of topology changes.
- class TopologyApplyReport(splits=<factory>, boundary_branches=<factory>, deenergized=<factory>, unmoved=<factory>)#
Describe changes from applying substation topology.
- splits#
Substation, source bus, new bus, and node numbers for each split.
- Type:
list[tuple[int, int, int, tuple[int, ...]]]
- boundary_branches#
End buses, circuit identifier, and switch state for each generated boundary branch.
- Type:
list[tuple[int, int, str, bool]]
- deenergized#
Bus numbers that became isolated.
- Type:
list[int]
- unmoved#
Equipment types and identifiers that could not be relocated.
- Type:
list[tuple[str, str]]
- is_noop()#
Return true when topology application changed nothing.
- summary()#
Return a one-line summary of the topology changes.