mambo_power.contingency¶
N-1 branch-contingency screening. See the manual page for the screen/confirm split, the agreement guarantee and rating data.
mambo_power.contingency
¶
N-1 branch-contingency screening (epic Design §2 contingency/).
The public entry point (n1) takes a Network and returns a
typed N1Result; the array-level split
(mambo_power.contingency.n1.screen_n1, mambo_power.contingency.n1.confirm_n1)
mirrors mambo_power.pf.dc.solve vs mambo_power.pf.solve_dc. Branch outages only
this wave — generator-outage contingencies are an explicit carry-over (wave spec Not Doing).
Note: this module deliberately binds the name n1 twice — the submodule
mambo_power.contingency.n1 (imported below for its array-level functions) and the network-
level function defined at the end of this file, which rebinds the package attribute n1 to
itself. After import, mambo_power.contingency.n1 is the function; code that wants the
submodule imports it directly (from mambo_power.contingency.n1 import screen_n1), as this
module itself does.
N1Options
¶
Bases: BaseModel
Options for mambo_power.contingency.n1. Empty today; reserved for future knobs
(e.g. a screening tolerance) so the public signature does not need to change to add one.
LODF screen and confirming re-solve over arrays¶
mambo_power.contingency.n1
¶
N-1 branch-contingency screening: LODF fast screen -> confirming DC re-solve.
Two stages, mirroring pf.ac_newton/pf.dc's array-level split. screen_n1 is the
estimate: for every non-bridge branch outage k (mambo_power.numerics.bridges
skips the rest — a bridge outage disconnects the network, LODF is undefined for it, the same
skip rule _brute_force_lodf.py uses), it estimates every other branch l's post-outage
flow from the base-case DC dispatch and mambo_power.numerics.lodf::
estimated[l] = |base_flow[l] + lodf[l, k] * base_flow[k]|
— the exact form S1's fixture-wide rating-margin sanity sweep used (record/m3-s1-report.md) —
and flags k if any l's estimate exceeds l's rating_mva. confirm_n1 is
the ground truth: for each flagged outage, it rebuilds the network with that branch out of
service (the same deep-copy-once/flip/rebuild pattern _brute_force_lodf.py uses) and runs a
real mambo_power.pf.dc.solve — a single right-hand-side DC re-solve, cheap even at
case300 scale (record/m3-research.md §4) — confirming whether each flagged branch's flow
genuinely exceeds its rating. An outage the screen does not flag is never re-solved; AC-6's
brute-force agreement test (tests/unit/test_contingency_n1_brute_force.py) proves that is
safe: the confirmed-violation set this pipeline produces equals a full brute-force sweep's.
VIOLATION_TOL_MVA
module-attribute
¶
Absolute slack against float noise when comparing an estimated or confirmed flow to a
rating — matches tests._rated's own base-case-never-violates check.
N1Options
¶
Bases: BaseModel
Options for mambo_power.contingency.n1. Empty today; reserved for future knobs
(e.g. a screening tolerance) so the public signature does not need to change to add one.
N1Screen
dataclass
¶
N1Screen(
flagged_positions: dict[int, list[int]],
estimated_flow_mw: dict[int, FloatArray],
bridge_positions: list[int],
)
Array-level LODF fast-screen verdict (screen_n1).
flagged_positions[k] lists the positions of branches whose LODF-estimated post-outage
flow exceeds their rating when branch k is taken out; only outages with at least one
flagged branch appear as a key. estimated_flow_mw[k] is the full n_branch-length
estimated-flow array for that outage (every branch, not only the flagged ones), kept so
confirm_n1 can report the estimate alongside the confirmed value.
bridge_positions lists the branches skipped because their outage would disconnect the
network (mambo_power.numerics.bridges) — LODF is undefined for them.
screen_n1
¶
screen_n1(
arr: NetworkArrays, options: N1Options
) -> N1Screen
LODF fast screen: which branch outages would push another branch over its rating.
Solves the base case once (mambo_power.pf.dc.solve), then for every non-bridge
branch k, estimates every other branch's post-outage flow and flags k if any
estimate exceeds that branch's rating_mva (inf on an unrated branch, so it is never
flagged). options is accepted for symmetry with confirm_n1 and future
extensibility; nothing in it is read yet.
Source code in src/mambo_power/contingency/n1.py
confirm_n1
¶
confirm_n1(
net: Network, arr: NetworkArrays, screen: N1Screen
) -> list[N1OutageResult]
Confirming DC re-solve for every outage screen flagged; ground truth, not estimate.
Rebuilds the network with each flagged branch out of service and runs a real
mambo_power.pf.dc.solve, recording both the LODF-estimated and the confirmed flow
for every branch the screen flagged for that outage. net is not modified.
Mirrors _brute_force_lodf.py's deep-copy-once/flip/rebuild/restore pattern: net is
deep-copied exactly once up front, not once per outage — flipping in_service on that one
copy and restoring it after each re-solve is what keeps this cheap at case300 scale (record/
m3-research.md §4); a fresh model_copy(deep=True) per outage was measured ~20x slower.