feat: pandapower interop — IEC 60909 short-circuit + AC validation of the optimiser#13
Open
harrysalmon wants to merge 4 commits into
Open
feat: pandapower interop — IEC 60909 short-circuit + AC validation of the optimiser#13harrysalmon wants to merge 4 commits into
harrysalmon wants to merge 4 commits into
Conversation
Survey of how pandapower could augment nopywer's power calculations. Six numbered docs cover the library overview, what nopywer's tree walk actually computes, the concept-by-concept intersection, three porting strategies with tradeoffs, references, and a wider opportunity menu. A seventh doc records what was built for opportunity §1 (AC validation of the optimiser) and what running it on the 2025 fixture revealed. REVIEWING.md is a reading-order guide for whoever picks up this branch. No code changes.
Optional feature, opt-in via `pip install nopywer[pandapower]`.
Adds a two-step pandapower interop module:
to_pandapower(grid) -> PandapowerGrid (the handle)
compute_short_circuit(pp_grid) -> {name: i_sc_ka}
PandapowerGrid bundles the pandapowerNet, name->bus_idx, and a back-ref
to the source PowerGrid for write-back. The same handle is reused
across calc functions; future ones (power flow, OPF, runpp_3ph) hang
off the same conversion.
PowerNode gains an `i_sc_ka` field (rounded, emitted in to_geojson).
All defaults and modelling assumptions live in pp_interop/config.py
(generator Sn/X''d, cable X, voltage convention, fault type).
A `modern` extra restores the original pandas>=3.0 / numpy>=2.4 floors
for users who don't want pandapower; declared as conflicting with the
pandapower extra in [tool.uv].
Adds two new entry points on top of the conversion layer: compute_power_flow(pp_grid) -> PowerFlowResults (V, I per bus/line) compare_with_tree_walk(grid) -> TreeWalkVsAcDiff (tree, ac, Δ) compute_power_flow runs pp.runpp (Newton-Raphson) and returns results in nopywer-native units (volts P-N, amps, percent). compare_with_tree_walk runs analyze() and the AC flow side-by-side and reports per-node / per-cable diffs, with helpers for the worst disagreement. to_pandapower now also creates net.load entries for every consumer (P from power_watts, Q from PF). Loads are required by runpp and are inert for IEC 60909 calc_sc max-case (which ignores prefault load). scripts/validate_optimiser_with_runpp.py runs the validator end-to-end on the 2025 event fixture. Findings are written up in research/pandapower/07_optimiser_validation_findings.md.
Pandapower 3.4.0 (released 2026-02-09) ships a bug that breaks runpp under pandas>=2.3 with read-only numpy buffers. The fix landed in e2nIEE/pandapower#2860 on 2026-02-10 — one day too late. No 3.4.1 yet. Without this pin compute_power_flow is unusable. compute_short_circuit is unaffected because calc_sc doesn't traverse the buggy code path. Switch back to a PyPI version constraint once 3.4.1 ships. Search the pyproject.toml comment for the PR link to find the spot.
harrysalmon
commented
May 10, 2026
Draft
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in pandapower interop layer (
src/nopywer/pp_interop/) that:PowerGridto apandapowerNetviato_pandapower(grid)— the conversion runs once and produces aPandapowerGridhandle that subsequent calc functions reuse.compute_short_circuit) — useful for sizing breaker breaking capacity and verifying RCD/breaker trip conditions.compute_power_flow) and a side-by-sidecompare_with_tree_walkhelper that diffs the existinganalyze.pytree walk against pandapower's Newton-Raphson AC truth.Pandapower is an optional dependency (
pip install nopywer[pandapower]);import nopywerworks without it. Amodernextra is added for users who want pandas≥3.0 / numpy≥2.4 without pandapower (the two extras are declared as conflicting in[tool.uv]because pandapower 3.4 caps both).Reading order for reviewers
research/pandapower/REVIEWING.mdis a 25-min reader's guide with reading order, run-it-yourself recipe, and a "decisions worth pushing back on" section that pre-empts the eight design choices most likely to provoke a comment (git pin, dep floors, module name, GeoJSON schema, etc.).The 7 numbered docs in
research/pandapower/cover background, intersection between the two domain models, porting tradeoffs, the wider opportunity menu, and the findings from running the validator on the 2025 fixture.Headline finding
Running the validator on
tests/fixtures/input_nodes.geojson(the 2025 event, 51 nodes / 50 cables) shows the tree-walk under-reports voltage drop by up to 12 percentage points at high-stress nodes:glitchoasis_playgroundbelly_townMean voltage Δ across all 51 buses: 7.8 V; max 28 V at
glitch.The gap is one-sided (tree walk always under-reports) and grows with drop magnitude. Cause: constant-power loads at low voltage draw more current → bigger drop → more current → … The tree walk computes I at nominal V₀ and never sees the feedback. AC iterates to the equilibrium.
This is exactly the validator that PR #5's MILP optimiser docstring asks for: "validate critical layouts with a detailed power-flow check". Full write-up in
research/pandapower/07_optimiser_validation_findings.md.Commits
docs(research)— 9 research docs (~1100 lines), no code.feat(pp_interop)— conversion layer + IEC 60909 short-circuit. Addsi_sc_kafield toPowerNode. SC tests.feat(pp_interop)— AC power flow + tree-walk validator. Loads into_pandapower. End-to-end script underscripts/. PF tests.chore(deps)— pins pandapower to the merge commit of e2nIEE/pandapower#2860 which fixes a CoW/read-only bug breakingrunppunder pandas≥2.3. Released 3.4.0 is one day too old; no 3.4.1 yet.Each commit leaves the tree in a working state.
Test plan
uv sync --extra pandapower && uv run pytest— 44/44 pass (33 existing untouched + 11 new)uv run python scripts/validate_optimiser_with_runpp.py— converges, reports the divergence aboveuv sync --extra modern— installs cleanly without pandapower, gives pandas 3.x / numpy 2.4+import nopywerworks without thepandapowerextra installed (lazy import insidepp_interop)What this PR does NOT do
nopywer-analyzeis a thin wrapper, deliberately deferred.i_sc_kafield (default 0.0) thatapp.jsignores.research/pandapower/06_extended_opportunities.md.runpp_3ph(per-phase asymmetric flow). Balancedrunppis enough to demonstrate the linearisation gap. Asymmetric is opportunity §3 in the same doc.🤖 Generated with Claude Code