gridsolve: pandapower-Beschleuniger

Schnellere Lastflussberechnung bei konstanter Netztopologie.

Keine Migration. Kein neues API. Keine neuen Abhängigkeiten.

Auf eine schnellere Bibliothek umzusteigen bedeutet: Datenmodell neu schreiben, neues API lernen, Ergebnisse neu validieren. gridsolve geht einen anderen Weg: Es beschleunigt pandapower mathematisch von innen heraus. Ihre bestehenden pp.runpp()-Aufrufe bleiben unverändert.

Ein Wheel installieren.

Installieren

pip install gridsolve_eval-0.1.1-cp312-cp312-manylinux_2_38_x86_64.whl

Option A: globaler Patch (am einfachsten)

Ein Import, ein Aufruf. pp.runpp() bleibt überall unverändert.

import gridsolve

# call once at startup
gridsolve.patch()
# unchanged from here on
pp.runpp(net)
...
# restore original behaviour
gridsolve.unpatch()

Option B: expliziter Context-Manager

Beschleunigung auf einen bestimmten Block beschränken. Im Benchmark unten verwendet, um beide Ansätze isoliert zu vergleichen.

from gridsolve import Solver, solver_context

solver = Solver()

with solver_context(solver):
    # accelerated inside this block
    pp.runpp(net)

Benchmark-Ergebnisse

Median aus 100 Durchläufen auf Standard-IEEE/PEGASE-Testnetzen

NetzBussepandapowerpandapower + gridsolveGesamtzeit
case118118128 µs/Bus119 µs/Bus+7%
case30030064 µs/Bus66 µs/Bus−3%
case1354pegase1.35424,3 µs/Bus16,7 µs/Bus−31%
case2869pegase2.86918,7 µs/Bus9,8 µs/Bus−48%
case9241pegase9.24120,8 µs/Bus8,1 µs/Bus−61%

Der lineare Gleichungslöser ist in allen Großnetz-Fällen ca. 10× schneller. Die Gesamtzeitgewinne werden durch den Jacobi-Aufbau und weiteren pandapower-Overhead außerhalb des Solvers begrenzt.

P/Q-Einspeisungs-Benchmark

96 Durchläufe auf dem 9.241-Bus-Netz mit ±10 % zufälliger Variation der Wirk- und Blindleistungseinspeisung: 60 % Reduktion der Gesamtrechenzeit. Schwankungen der Einspeisungswerte beeinflussen den Speedup nicht, nur Topologieänderungen tun es.

So funktioniert es

Standard-pandapower wiederholt bei jedem Solve-Aufruf aufwändige Initialisierungsarbeit, selbst wenn sich die Netztopologie nicht geändert hat. gridsolve erkennt automatisch, ob die Topologie unverändert ist, und überspringt diese Schritte.

Topologieänderungen (Schalthandlungen) lösen eine einmalige Neuinitialisierung aus. Alles andere (Wirkleistung, Blindleistung, Laständerungen) nicht.

Am effektivsten bei

  • Zeitreihenlastfluss, bei dem der Schaltzustand zwischen den Intervallen stabil bleibt
  • Szenario- und Sensitivitätsanalysen mit variierenden Einspeisungen auf festem Netz
  • Wiederholten Dispatch-Berechnungen auf derselben Topologie

Die Ergebnisse sind numerisch identisch mit pandapowers Standard-Solver. Maximale Abweichung: 2×10⁻¹³ p.u. in der Spannungsamplitude, fünf Größenordnungen unterhalb der Newton-Raphson-Konvergenztoleranz von 10⁻⁸ p.u.

Selbst ausprobieren

Das folgende Skript führt zuerst einen Korrektheitsprüfung durch, dann einen Geschwindigkeitsvergleich. Wheel installieren, kopieren, ausführen.

Testnetz herunterladen (oder eigenes Netz einsetzen): case1354pegase.json

from timeit import timeit
import numpy as np
import pandapower as pp
from gridsolve import Solver, solver_context

NETWORK = "case1354pegase.json"
N = 96

net = pp.from_json(NETWORK)
base_p = net.load["p_mw"].values.copy()
base_q = net.load["q_mvar"].values.copy()
rng = np.random.default_rng(42)
scenarios = [
    (base_p * (1 + rng.uniform(-0.10, 0.10, size=len(base_p))),
     base_q * (1 + rng.uniform(-0.10, 0.10, size=len(base_q))))
    for _ in range(N)
]
solver = Solver()

def run_normal():
    for p, q in scenarios:
        net.load["p_mw"]   = p
        net.load["q_mvar"] = q
        pp.runpp(net)

def run_accelerated():
    with solver_context(solver):
        for p, q in scenarios:
            net.load["p_mw"]   = p
            net.load["q_mvar"] = q
            pp.runpp(net)

# 1. Correctness
run_normal()
ref = net.res_bus[["vm_pu", "va_degree"]].copy()
run_accelerated()
acc = net.res_bus[["vm_pu", "va_degree"]]
max_vm = np.abs(acc["vm_pu"]     - ref["vm_pu"]).max()
max_va = np.abs(acc["va_degree"] - ref["va_degree"]).max()
print(f"  Max |ΔVm|:    {max_vm:.2e} p.u.  (NR tolerance: 1e-8 p.u.)")
print(f"  Max |Δangle|: {max_va:.2e} deg")

# 2. Speed
t_normal = timeit(run_normal,      number=1)
t_accel  = timeit(run_accelerated, number=1)
speedup  = (t_normal - t_accel) / t_normal * 100
print(f"  pandapower:  {t_normal:.3f} s")
print(f"  gridsolve:   {t_accel:.3f} s  ({speedup:.0f}% faster)")

Output

  Max |ΔVm|:    2.25e-13 p.u.  (NR tolerance: 1e-8 p.u.)
  Max |Δangle|: 4.08e-11 deg
  pandapower:  3.162 s
  gridsolve:   2.181 s  (31% faster)

Testen Sie es an Ihrem Netz.

gridsolve wird als eigenständiges Python-Wheel ausgeliefert. Keine Systemabhängigkeiten über pandapower hinaus. Das Evaluierungs-Wheel unterstützt Netze bis zu 2.000 Bussen. Für eine Volllizenz nehmen Sie Kontakt auf.