Skip to main content

gdm-flow

CodeFactorcodecovCIDeploy DocsPublish to PyPIMCP ServerMCP ToolsGitHub issues

Utilities for OPF and power-flow style preprocessing on top of grid-data-models distribution systems.

GDM-Flow CLI

Current features

  • Y-Bus Construction — Phase-domain admittance matrices from GDM components (branches, transformers, switches) with matrix and sequence impedance support
  • Four Solvers — AC OPF (nonlinear least-squares), AC PF (Newton-Raphson power flow), DC OPF (quadratic programming), and LinDistFlow (backward/forward sweep)
  • Multi-Phase Support — Full three-phase and split-phase (center-tapped transformer) modeling
  • Component Integration — Direct integration with GDM loads, solar PV, batteries, capacitors, and regulators
  • Interactive Dashboards — Plotly-based HTML dashboards with voltage profiles, power flow, branch loading, losses, and equipment state
  • QSTS Simulation — Quasi-static time series with warm-starting across timesteps for any solver
  • Multi-Period OPF — Joint optimization across a time horizon with battery SOC coupling and ramp constraints (DC OPF and LinDistFlow)
  • Time Series Discovery — Inspect available load, solar, and battery time series profiles in GDM models
  • Modern CLI — Rich terminal interface with info, run, compare, plot, export, ts-info, qsts, multiperiod, plot-ts, and reporting commands
  • SQLite Export — Structured database output with voltage/loading limit tracking, violation reporting, and streaming time series results
  • MCP Server — Model Context Protocol server exposing all solvers as AI-callable tools

Install

pip install -e .

If you also want sparse matrix return support:

pip install -e .[sparse]

If you want optimization support:

pip install -e '.[optimization]'

If you want interactive plotting dashboards:

pip install -e '.[plotting]'

If you want to run the MCP server:

pip install -e '.[mcp,optimization]'
gdm-flow-mcp-server

Development checks

Install development dependencies and enable pre-commit hooks:

pip install -e '.[dev]'
pre-commit install

Run the same lint checks used in CI:

pre-commit run --all-files

Examples

An end-to-end examples folder is included at examples/ with a downloaded demo distribution model and runnable scripts for each optimization flavor:

  • examples/models/p5r.json
  • examples/run_ac_opf_example.py
  • examples/run_dc_opf_example.py
  • examples/run_lindistflow_example.py
  • examples/compare_plotly_results.py — interactive Plotly comparison across all solvers

Run from the repository root:

python examples/run_ac_opf_example.py
python examples/run_dc_opf_example.py
python examples/run_lindistflow_example.py
python examples/compare_plotly_results.py

Usage

from gdm.distribution import DistributionSystem
from gdm_flow import calculate_ybus

system = DistributionSystem.from_json("path/to/system.json")
result = calculate_ybus(system, include_shunt=False)

Y = result.ybus
labels = result.index_to_label

labels[k] is a (bus_name, phase) tuple for row/column k of Y.

Optimization usage

from gdm.distribution import DistributionSystem
from gdm_flow import optimize_ac_power_flow

system = DistributionSystem.from_json("path/to/system.json")

# Specify net nodal injections in SI units: +generation, -load
p_spec_w = {("bus_5", "A"): -20_000.0, ("bus_5", "B"): -20_000.0, ("bus_5", "C"): -20_000.0}
q_spec_var = {("bus_5", "A"): -5_000.0, ("bus_5", "B"): -5_000.0, ("bus_5", "C"): -5_000.0}

result = optimize_ac_power_flow(
  system,
  p_spec_w=p_spec_w,
  q_spec_var=q_spec_var,
)

print(result.success, result.final_objective)

Auto-build specs from components

If your model already contains DistributionLoad and DistributionSolar components, you can build nodal injections automatically:

from gdm.distribution import DistributionSystem
from gdm_flow import optimize_ac_power_flow_from_components

system = DistributionSystem.from_json("path/to/system.json")

result = optimize_ac_power_flow_from_components(
  system,
  include_loads=True,
  include_solar=True,
  include_capacitor=True,
  include_battery=False,
  include_regulator_targets=True,
  include_regulator_limits=True,
)

print(result.success, result.final_objective)

Notes:

  • include_capacitor=True adds capacitor reactive injections into nodal Q specs.
  • include_regulator_targets=True adds soft voltage-target constraints derived from regulator controllers.
  • include_regulator_limits=True adds hard voltage magnitude bounds from regulator min/max limits.

AC Power Flow (Newton-Raphson)

gdm-flow includes a classical Newton-Raphson AC power flow solver. Unlike the AC OPF which optimises voltage magnitudes within bounds, the AC PF solves for exact bus voltages given fixed P/Q injections and a slack bus:

from gdm.distribution import DistributionSystem
from gdm_flow import solve_ac_power_flow_from_components

system = DistributionSystem.from_json("path/to/system.json")

result = solve_ac_power_flow_from_components(
  system,
  include_loads=True,
  include_solar=True,
  include_capacitor=True,
)

print(result.success, result.iterations)
print(result.max_mismatch_pu)   # convergence metric
print(result.voltage_pu)        # per-unit voltage magnitudes

The solver uses sparse LU factorisation with a damped update and LinDistFlow warm-start for robust convergence on heavily loaded feeders.

DC OPF module

gdm-flow also includes a separate DC OPF module:

from gdm.distribution import DistributionSystem
from gdm_flow import solve_dc_opf_from_components

system = DistributionSystem.from_json("path/to/system.json")

result = solve_dc_opf_from_components(
  system,
  include_solar_generators=True,
  include_battery_generators=True,
  include_loads=True,
)

print(result.success, result.objective)
print(result.generator_dispatch_w)

LinDistFlow module

gdm-flow includes a separate radial LinDistFlow approximation module:

from gdm.distribution import DistributionSystem
from gdm_flow import solve_lindistflow

system = DistributionSystem.from_json("path/to/system.json")

result = solve_lindistflow(system)

print(result.success)
print(result.voltage_v)     # {(bus, phase): voltage_in_volts}
print(result.p_flow_w)      # {(branch_name, phase): active_flow_w}

SQLite export module

You can export results from AC OPF, DC OPF, and LinDistFlow into one SQLite database:

from gdm_flow import export_all_results_to_sqlite

run_ids = export_all_results_to_sqlite(
  "results.sqlite",
  ac_result=ac_result,
  dc_result=dc_result,
  lindistflow_result=lindistflow_result,
)

print(run_ids)

Or export each result type separately:

  • export_ac_opf_result_to_sqlite(...)
  • export_dc_opf_result_to_sqlite(...)
  • export_lindistflow_result_to_sqlite(...)

Interactive dashboards

Generate interactive Plotly HTML dashboards from the CLI:

# Generate dashboard with all four solvers
gdm-flow plot examples/models/p5r.json

# Select specific solvers
gdm-flow plot examples/models/p5r.json -s ac -s pf

# Custom output path
gdm-flow plot examples/models/p5r.json -o my_dashboard.html

Time series simulation

GDM-Flow supports time series simulation for models with time-varying load and solar profiles. Two modes are available:

QSTS (Quasi-Static Time Series)

Sequential snapshot solves at each timestep with automatic warm-starting:

from gdm.distribution import DistributionSystem
from gdm_flow import run_qsts

system = DistributionSystem.from_json("model.json")

summary = run_qsts(
    system,
    solver="ldf",              # any solver: ac, pf, dc, ldf
    timestep_range=range(96),  # 24 hours at 15-min resolution
    db_path="qsts_results.db", # stream results to SQLite
)

print(f"Converged: {summary.num_converged}/{summary.num_timesteps}")

Multi-Period OPF

Joint optimization across the time horizon with battery SOC coupling:

from gdm_flow import solve_multiperiod_dc_opf
from gdm_flow.dc_opf import build_dc_generators_from_components

generators = build_dc_generators_from_components(system)

result = solve_multiperiod_dc_opf(
    system,
    generators=generators,
    timestep_range=range(96),
    ramp_limit_w=5000.0,
    db_path="multiperiod.db",
)

print(f"Objective: {result.objective:.2f}")

CLI commands

# Check available time series
gdm-flow ts-info model.json

# QSTS simulation
gdm-flow qsts model.json --solver ldf --end 96 --db results.db

# Multi-period DC OPF
gdm-flow multiperiod model.json --solver dc --end 96 --ramp 5000 --db results.db

# Plot time series results
gdm-flow plot-ts results.db -o timeseries.html

The dashboard includes:

  • Voltage-distance profiles along feeder paths
  • Per-phase voltage comparison across solvers
  • Branch power flow and loading analysis
  • Line loss breakdown
  • Equipment state (capacitors, regulators, transformers)

Requires the plotting extra: pip install -e '.[plotting]'

CLI export from JSON

Use the CLI to load saved result JSON files and export to SQLite in one command:

gdm-flow-export --db results.sqlite --ac-json ac_result.json --dc-json dc_result.json --lindistflow-json ldf_result.json

Generate starter JSON templates:

gdm-flow-export --write-templates ./templates

This creates:

  • templates/ac_result.template.json
  • templates/dc_result.template.json
  • templates/lindistflow_result.template.json

Expected JSON fields:

  • AC JSON:
    • success, message, iterations, initial_objective, final_objective
    • index_to_label: [["bus", "phase"], ...]
    • voltage: [{"real": ..., "imag": ...}, ...]
    • power_injection: [{"real": ..., "imag": ...}, ...]
  • DC JSON:
    • success, message, objective, iterations, slack_injection_w
    • generator_dispatch_w: {name: value}
    • theta_rad: {"bus|phase": value, ...}
    • nodal_balance_w: {"bus|phase": value, ...}
  • LinDistFlow JSON:
    • success, message, source_bus
    • voltage_v, p_flow_w, q_flow_var, p_net_w, q_net_var
    • All series use {"name|phase": value, ...} format.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gdm_flow-0.4.0.tar.gz (144.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gdm_flow-0.4.0-py3-none-any.whl (108.1 kB view details)

Uploaded Python 3

File details

Details for the file gdm_flow-0.4.0.tar.gz.

File metadata

  • Download URL: gdm_flow-0.4.0.tar.gz
  • Upload date:
  • Size: 144.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gdm_flow-0.4.0.tar.gz
Algorithm Hash digest
SHA256 c7bafa3c8992aa69d5121b39c712912dee6d12ecb1f2d864c144ec455d10fc0f
MD5 fd18f71cab18ffe1e2628278d845f11e
BLAKE2b-256 e22f33815ab1f467b4e1b95226713d389887fc3e301ad1dc3f5335add4cee18a

See more details on using hashes here.

Provenance

The following attestation bundles were made for gdm_flow-0.4.0.tar.gz:

Publisher: publish.yml on NLR-Distribution-Suite/gdm-flow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gdm_flow-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: gdm_flow-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 108.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for gdm_flow-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c9646ba25472ede64084535defcfc3528f58ca6e295d89936f079ec5dae48ec4
MD5 f8c975522568de2230758e7650892961
BLAKE2b-256 ad3439797d7bde17c76775d3094e332ad09581ff1c2ab1cfe7760885a7caab74

See more details on using hashes here.

Provenance

The following attestation bundles were made for gdm_flow-0.4.0-py3-none-any.whl:

Publisher: publish.yml on NLR-Distribution-Suite/gdm-flow

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.2

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page