Releases: amptimal/surge
v0.1.9 — Datacenter Operator market + SCUC primitives
New Datacenter Operator market — behind-the-meter SCUC for a
microgridded datacenter — and three SCUC primitives that support it.
Added (markets, dashboards)
markets/datacenter/+dashboards/datacenter/: optimises
commitment + dispatch + AS awards across IT-load tiers (must-serve +
curtailable VOLL), BESS, solar, wind, fuel cell, gas CT, diesel,
optional must-run nuclear, and (optional) coincident-peak
transmission charges, against an exogenous LMP forecast and AS price
forecasts. Forecasts and asset specs editable live; re-solves in
seconds.
Added (surge-dispatch)
peak_demand_charges: SCUC primitive for coincident-peak demand
charges (e.g. ERCOT 4-CP). Adds an auxiliarypeak_mwvariable
bounded below by the resource's dispatch on the flagged periods,
with a linearcharge_per_mw × peak_mwobjective term.
Added (surge.market)
generator_dispatch_bounds: pin a resource's per-period dispatch
window directly in MW (setp_min == p_maxfor must-take fixed
output).must_run_units: forceu[t]=1for the listed resources. Paired
withgenerator_dispatch_boundsthis removes both commitment and
dispatch freedom — the canonical pin for baseload nuclear /
must-take PPAs / fixed-output IPP contracts.ECRScanonical reserve product.
Changed (defaults)
markets.go_c3defaultlp_solverflipped fromgurobi→highs.
Default runs no longer require a commercial license.
v0.1.8
`surge-dispatch` SCUC security loop: lower memory, faster solves, and
adjoint loss sensitivities. Default policy retuned.
Added (`surge-dispatch`)
- Lazy PTDF caching on the SCUC security path — caches build only
when a contingency actually binds, rather than eagerly per period. - Adjoint-based DC loss sensitivities replace the explicit per-branch
Jacobian build in `surge-opf`/`surge-dispatch`, simplifying the
loss-factor pipeline.
Fixed
- `surge-dispatch`: SCUC security loop now defers early exit by one
iteration when sys-row loss treatment is active but no solve has
yet consumed realized loss factors. Previously both
`ScalarFeedback` and `PenaltyFactors` could silently no-op on
scenarios with a clean contingency profile.
Performance (`surge-dispatch`)
- Lower SCUC security memory footprint at scale: per-period state is
released after use rather than retained for the full horizon. - Faster security wall time via tightened PTDF tolerance, lazy cache
construction, and adapter-side request reuse.
Changed (defaults)
- `scuc_loss_treatment` defaulted to `penalty_factors` (was
`scalar_feedback`), paired with the security-loop fix above. - `scuc_thermal_penalty_multiplier` defaulted to `1.25` (was `10.0`)
to keep SCUC thermal penalties closer to the configured slack rate.
v0.1.7
surge-dispatch polish release: end-to-end shadow prices, Q-LMPs,
faster N-1 screening, and SCUC correctness fixes. New in-process
Rust→Python tracing broadcast on surge-py. GO C3 defaults updated.
Added (surge-dispatch)
- Per-branch and per-contingency shadow prices flow from AC SCED
through toBranchThermalconstraint results; security-loop
flowgates retain theirN1_t{period}_…names. SCUC pricing
extraction emits per-constraint duals whenever the dual vector is
full-length, while LMPs still gate on optimal pricing-LP status. - Per-bus Q-LMP on AC SCED dispatch results.
- Per-iteration security SCUC timings in
run-report.json. - Optional per-iteration scalar loss-feedback pass in SCUC.
Added (surge-py)
- In-process Rust→Python tracing broadcast (replaces fd-tee, which
deadlocked under load); typed.pyistubs.
Fixed
surge-dispatch: PTDF-form security cuts now bind dispatch when
scuc_disable_bus_power_balance=true(previously absorbed by free
per-bus slacks).surge-dispatch: AC SCED no-storage path now threadsdt_hours
(was hard-coded to 1 h, miscosting sub-hourly markets).surge-dispatch: SCUC PF system-row RHS sign — drop the loss
double-count that hung AC SCED on loss-feedback runs.surge-dispatch: sparse-aware reserve extraction preserves
storage SoC coupling across the SCUC/SCED handoff.surge-dispatch: zonal / system reserve duals preserved through
the pricing LP so AS clearing prices match.surge-opf: AC-OPF Ipoptconstr_viol_tolbound totolso
unscaled bus balance tracks the requested tolerance.
Performance (surge-dispatch)
- ~45–65× faster N-1 security screening: per-period parallelism via
rayonand flat per-branch state inHourlySecurityContext
remove the inner-loopHashMaprebuild on 6049-bus and larger. - 16× sparser PTDF security cuts on the
scuc_disable_bus_power_balancepath: active-period gating moved
above PTDF row construction,bus_load_p_mw_with_maphoisted out
of the per-row loop, per-rowHashMapallocation eliminated.
617-bus D1 SCUC: 118 M NZ / 20.9 s → ~7 M / sub-second.
Changed
- GO C3 exporter: consumer reserve shedding
(ExportOptions::allow_consumer_reserve_shedding, default on)
caps per-consumer up/down reserve awards to the available room
afterac_dispatchcurtailment, fixing spurious validator
viol_cs_t_p_on_*flags on physically valid solutions. - GO C3 defaults:
scuc_loss_treatment="scalar_feedback"(was
static),scuc_security_preseed_count_per_period=0(was 1000).
Build
- Dashboard Docker image installs
zstandardfor compressed
network blob round-trips.
Dashboards (dashboards/rto, dashboards/battery) saw substantial
work this cycle but are not part of the published release surface.
v0.1.6
surge-dispatch release: SCUC LP tightening, large-network
performance, and a fix for unbounded thermal-slack relaxations. GO C3
adapter gains diagnostic knobs for isolating large-network bottlenecks.
Fixed
- Bounded thermal-slack relaxation in SCUC. Per-branch thermal
slack columns (branch_lower_slack,branch_upper_slack) were
allocated withcol_upper = +∞, letting the LP relaxation
hallucinate unbounded virtual capacity on degenerate networks.
col_upperis now capped at 10× rating; slack rates are unchanged,
so the economic tradeoff is preserved. On 1576-bus D1 s003 this
takes the SCUC MIP fromtime_limitat 3637s with a −$1.7e14 dual
bound tooptimalat 66s with a 1.92% gap; commitment decisions
unchanged.
Added
- Sparse reserve-product participation in SCUC. Reserve LP columns
are now emitted only for(product, resource)pairs that can
qualify under some commitment state AND have a nonzero offer
capacity in some period. Applies to both generators and
dispatchable loads. On 617-bus D2 the pre-presolve LP shrinks by
~97k columns. - Consumer-level DL reserve aggregation. Dispatchable loads that
share areserve_group(the GO C3 pattern of price-decomposed
consumer blocks) now share a single reserve variable per product,
bounded by total offer and coupled to total served. Removes a
spurious per-block pro-rata constraint that was over-restricting
consumer reserve when block served-levels were uneven. - Sparse reserve row families. Cross-headroom / cross-footroom,
shared-limit, and energy-coupling rows are now emitted only for
participating resources. On 73-bus D3 s303 pre-presolve rows drop
37% and nonzeros 17%. - SW0 branch-binary strip. When
allow_branch_switching=false,
branch_commitment/startup/shutdowncolumns and their
state-evolution rows are omitted from the LP entirely instead of
allocated and pinned. On 617-bus D2 this removes ~123k cols and
~82k rows up-front. - GO C3 SCUC diagnostic knobs on
GoC3Policy/DispatchRuntime:scuc_disable_bus_power_balance— drop per-bus KCL rows and
pb_*slack cols; replace with a single system-balance row plus
a post-solve DC-PF theta repair before N-1 screening. Defaults to
truefor GO C3. On 6049-bus D1 s015 this takes SCUC from
unsolved at 300s to optimal in 8s.scuc_copperplate— zero the power-balance penalty so per-bus
rows become trivially satisfied via free slack (for isolating
whether MIP cost lives in UC or in network coupling).scuc_firm_bus_balance_slacks,scuc_firm_branch_thermal_slacks,
disable_scuc_thermal_limits— per-family slack-firming probes.
Performance (surge-dispatch)
- O(N²) hoists in
attach_keyed_period_views. Branch / flowgate
shadow-price lookups and zonal reserve participant matching no
longer re-scan the network per period. On 4224-bus D1 s014 this
function drops from 108s to sub-second. - Hoisted
network.bus_index_map()rebuilds out of the
build_capacity_logic_reserve_rowszone loops. Per-product,
per-period cost drops ~1000× on 4224-bus D1 s014. - Cached zonal participant sets on
ActiveZonalRequirement,
eliminating an O(N_bus) HashMap rebuild per DL per zonal
requirement per period in SCUC bounds construction.
v0.1.5
Python-side release: agent / MCP integration helpers, a PyPSA netCDF
bridge, and accessor consistency fixes. No Rust crate API changes.
Added
- Agent-friendly MCP helpers on
surge-py..to_dict()now exists
on every solver result (AcPfResult,DcPfResult,DcOpfResult,
ScopfResult,AcOpfHvdcResult,ContingencyAnalysis,
AcAtcResult,PtdfResult,LodfResult,LodfMatrixResult,
OtdfResult, and the nested contingency / screening types) so MCP
hosts and tool-calling agents can serialize results with one call.
Matrix results acceptformat={"summary","sparse","full"}and a
top_k_per_branchknob. - Network convenience accessors.
Network.summary(),
Network.loads_dataframe(),Network.shunts_dataframe()round out
the existing generator / bus / branch DataFrame surface. - Built-in case helpers.
surge.list_builtin_cases()and
surge.load_builtin_case(name)enumerate the packaged IEEE / market
cases by string name.surge.builtin_case_rated_flags()reports
which built-ins ship with branch thermal ratings (relevant for
transfer-capability studies). - Explicit format override on load.
surge.load(path, format=...)
and thesurge.load_networkalias let MCP hosts pass an explicit
format when the extension is ambiguous or missing. - PyPSA netCDF bridge. New
surge.io.pypsa_nc.load(path)reads
PyPSA netCDF directly into a SurgeNetwork, preserving per-bus
v_mag_pu_setthat the MATPOWER round-trip path cannot always
carry through. Requires the optionalpypsapackage. - Format interop guide. New
docs/format-interop.md
documents per-format round-trip caveats and when to prefer the
PyPSA bridge over a MATPOWER hop.
Changed
- Accessor consistency on
AcPfResult.branch_apparent_power
andbranch_loading_pctare now properties, matching the rest of
the result surface. Breaking for callers using()— drop the
parentheses:result.branch_loading_pct(not
result.branch_loading_pct()). - Branch type auto-detection on
Network.add_branch. An
off-nominal tap (|tap − 1| > 1e-6) or non-zero phase shift now
tags the branch as aTransformer, matching the MATPOWER reader
convention. Previously Python-built networks landed asLine
regardless. - Strict-JSON-safe matrix serialization. PTDF / LODF / OTDF
to_dictnow filters non-finite entries (NaN / ±∞ from radial /
islanding outages) fromnnz,max_abs, and top-k lists, surfaces
nan_count/inf_countseparately, and emits PythonNonefor
non-finite cells informat="full"so the payload round-trips
through strict JSON encoders.
Build
- Docker image builds HiGHS 1.14.0 from source rather than relying
on the Debianlibhighs-devpackage, which lagged behind the
workspace's vendored HiGHS.
v0.1.4
Added
- Dispatch observability.
DispatchSolutionnow carries stage-failure
diagnostics and per-period AC-OPF statistics, making multi-stage workflow
failures and AC-SCED iteration costs inspectable without re-running the
solve. - SCUC loss-factor warm start and per-period load-pattern sensitivity
insurge-dispatchSCUC — reduces MIP root relaxation time on
loss-aware formulations. Loss-factor coefficient writes now use a 1e-4
cutoff to keep the LP sparse. - Flowgate directional slack on
surge-network::Flowgate— lets
flowgate limits be relaxed in one direction without disabling the
constraint. - HiGHS MIP trace.
MipTraceis now populated unconditionally on every
HiGHS MIP solve (previously gated); primal bound recovery falls back to
objective_function_valuewhenmip_primal_boundis NaN.
Fixed
- GO C3 adapter: new market-extras fields are now forwarded into
run-report.json.
v0.1.3
Changed
- HiGHS MIP backend tuning. Presolve is now left on by default even when a
primal-start hint is supplied (previously forced off).simplex_scale_strategy=4
is now the default for MIP LP solves. HiGHS MIP verbose logging is now gated by
SURGE_HIGHS_VERBOSE(previously LP/QP only).
Added
SURGE_HIGHS_*environment variables for tuning HiGHS without a rebuild:
THREADS,PARALLEL,RANDOM_SEED,SIMPLEX_STRAT,SCALE_STRAT,
PRIMAL_FEAS_TOL,DUAL_FEAS_TOL,CROSSOVER,MIP_HEURISTIC,
MIP_DETECT_SYM,MIP_FEAS_TOL,MIP_REL_GAP.
v0.1.2
Added
New crates
surge-dispatch— unified economic dispatch and unit commitment kernel.
TypedDispatchModel/DispatchRequest/solve_dispatchAPI covers DC
and AC SCED, DC SCUC, time-coupled multi-period dispatch, reliability
commitment, AC redispatch, and SCED-AC Benders decomposition through one
request surface with three orthogonal study axes (Formulation × Interval
Coupling × Commitment Policy). Includes reserve-product modeling, N-1
security screening (explicit contingencies or iterative screening),
HVDC co-dispatch, emissions and carbon pricing, and a ledger-first
DispatchSolutionwith an exactObjectiveTermaudit.surge-market— canonical market-formulation layer on top of
surge-dispatch. Provides standard reserve-product constructors
(regulation, synchronized, non-synchronized, ramping, reactive
headroom) and zonal-requirement builders, commitment helpers,
piecewise offer-curve construction, per-bus load aggregation,
startup/shutdown trajectory derivation, and time-window translators.
Adds a typed multi-stage workflow runner (MarketStage,
MarketWorkflow,solve_market_workflow) with commitment handoff
and dispatch pinning, the canonical two-stage DC SCUC → AC SCED
workflow, the AC SCED setup combinator (reactive-reserve filter,
commitment augmentation, bandable-subset producer pinning, AC warm
start, Q-bound overrides), and the AC refinement runtime
(RetryPolicynested grid of OPF / band / NLP / HVDC attempts with
feedback providers and commitment probes). Includes the GO Competition
Challenge 3 format adapter as the reference implementation.
Python
- New
surge.dispatchnamespace exposing the canonical dispatch API —
DispatchRequest,DispatchSolution, study-axis enums, timeline
helpers, and reserve/market/network configuration builders. - New
surge.marketnamespace withMarketConfig,MarketWorkflow,
WorkflowRunner,run_market_solve, reserve catalog constants,
penalty-curve builders, AC reconciliation helpers, and
violation-assessment utilities. - New
surge.market.go_c3namespace with a one-callload/
build_workflow/solve_workflow/export/saverecipe for the
GO C3 adapter. - Typed
.pyistubs for dispatch and market namespaces;surge.opf
namespace module added. - New
solve_scedbinding.
Optimization (surge-opf)
- AC-OPF Benders subproblem support that produces the optimality cuts
consumed bysurge-dispatch's SCED-AC Benders loop. - Canonical reactive-reserve modeling in AC-OPF with per-product
headroom/footroom constraints and deliverability caps. - HVDC co-optimization inside AC-OPF, including converter-terminal Q
constraints and per-link dispatch bands. - Generator P-Q capability curves, piecewise cost epigraph support, and
improved tap / phase-shifter / switched-shunt / SVC / TCSC handling. - Pre-solve model-reduction backend (
backends::reduce) that removes
bound-implied-zero columns and duplicate rows before handing the LP
to the chosen backend. - Canonical MIP gap schedule / progress monitor API so commitment
solves can target time-varying gap thresholds. - Expanded Gurobi and HiGHS backend coverage (MIP callbacks, incumbent
tracking, Benders-compatible LP resolves); improved COPT backend for
AC-OPF NLPs. - AC-OPF result envelope now carries the full objective-ledger audit,
and thesurge-solveCLI fails closed when the ledger audit fails.
Network Model (surge-network)
- First-class
DispatchableLoadwith offer schedules and reserve
participation. - Reserve market primitives:
ReserveProduct,ReserveDirection,
ReserveKind,QualificationRule,EnergyCoupling,
ZonalReserveRequirement,SystemReserveRequirement. - Generator extensions for reserve capability (regulation, spinning,
non-spinning) and startup tiers keyed by offline hours. - Flowgate and interface refinements, penalty-curve types, and power-
balance penalty configuration.
Shared Solution Types (surge-solution)
- New
economicsmodule defining the exactObjectiveBucket/
ObjectiveTerm/ObjectiveLedgerMismatch/SolutionAuditReport
contracts used bysurge-dispatchfor ledger-first cost reporting. - New
idsmodule with canonical resource-id helpers
(generator_resource_id,dispatchable_load_resource_id,
combined_cycle_plant_id,default_machine_id).
v0.1.1
Fixed
- Corrected several DC-SCOPF issues affecting angle-limit handling, HVDC and
MTDC power balance, piecewise-linear cost passthrough, corrective Hessian
sizing, loss-factor outputs, and HVDC contingency accounting.
Added
- Added co-optimized variable HVDC dispatch, PAR scheduled-interchange
treatment, soft generator limits, iterative loss-factor support, and the
related CLI and Python SCOPF options.
Changed
- DC-SCOPF now defaults to LP costs in Rust and Python for more robust HiGHS
behavior on large cases. surge-bindingsis now published on crates.io, and installation guidance now
leads withcargo install surge-bindingsandpip install surge-py.
Documentation
- Refreshed the quickstart, support matrix, SCOPF tutorial, CLI reference,
notebook, and crate docs to match the new defaults and release packaging.
v0.1.0
Surge v0.1.0
AC/DC power flow, OPF, contingency analysis, and HVDC solver engine.
Install
Rust:
cargo add surge-ac # or any of the 11 published cratesPython:
pip install surge-pyCLI:
cargo install surge-bindingsHighlights
- Full AC Newton-Raphson and Fast Decoupled power flow with KLU sparse factorization
- DC-OPF, AC-OPF (with Ipopt analytical Hessian), and Security-Constrained OPF
- N-1/N-2 contingency analysis with LODF screening and parallel execution
- LCC/VSC HVDC and multi-terminal DC network solving
- NERC-style ATC/AFC transfer capability analysis
- 10+ file formats: MATPOWER, PSS/E RAW/DYR, CGMES, XIIDM, UCTE, IEEE CDF, OpenDSS
- Python bindings with NumPy interop and typed stubs
- 13-crate workspace, edition 2024, MSRV 1.87
Changelog
Power Flow (surge-ac, surge-dc)
- AC Newton-Raphson solver with sparse KLU factorization and reactive power
limit enforcement. - AC Newton-Raphson warm-start variant with DC-initialized voltage angles.
- Fast Decoupled Power Flow (FDPF) with B-prime / B-double-prime splitting.
- DC power flow (B-theta) with sparse KLU factorization.
- Linear sensitivity matrices: PTDF, LODF, OTDF, BLDF, GSF, and N-2 LODF.
HVDC (surge-hvdc)
- LCC and VSC HVDC link modeling with sequential, block-coupled, and hybrid
AC/DC iteration strategies. - Multi-terminal DC (MTDC) network solver with converter loss modeling.
Security and Contingency (surge-contingency)
- N-1 branch and generator contingency analysis with parallel execution via
rayon. - N-2 branch-pair contingency analysis.
- LODF-based fast screening with configurable thresholds.
- P4 and P6 post-contingency post-dispatch workflow support.
- Local voltage-stress screening for voltage stability assessment.
- Corrective action modeling with topology and redispatch remediation.
Optimization (surge-opf)
- DC-OPF via sparse B-theta formulation with LMP extraction from power balance
duals. - AC-OPF via Ipopt NLP with exact analytical Hessian and LMP decomposition
(energy, congestion, loss components). - Security-Constrained OPF (SCOPF) with iterative constraint generation
(cutting-plane) and penalty slack formulation. - Optimal Transmission Switching (OTS) and Optimal Reactive Power Dispatch
(ORPD). - SOCP and SDP relaxation workflows.
- Pluggable solver backends: HiGHS (bundled), Gurobi, COPT, CPLEX (runtime
detected), Ipopt (link-time).
Transfer (surge-transfer)
- NERC-style ATC (Available Transfer Capability) workflows.
- AFC (Available Flowgate Capability) and multi-transfer studies via DFAX.
- AC transfer capability with thermal, voltage, and transient stability limits.
- TPL-001-5.1 compliance report generation (P1-P7 categories).
Network Model (surge-network)
- Comprehensive power system network model: buses, branches, generators,
loads, shunts, HVDC links, transformers (2- and 3-winding), switched shunts,
FACTS devices, storage (unified as generators withStorageParams). - Area, zone, and owner metadata for regional analysis.
- Contingency definition with branch, generator, and HVDC outage types plus
modification actions (tap, load, generation, shunt adjustments). - Flowgate and interface constraint definitions.
- Versioned native JSON schema (
surge-network-jsonv0.1.0) with Zstandard
compression and compact binary variants.
Topology (surge-topology)
- Node-breaker to bus-branch topology projection.
- Island detection and connectivity analysis.
- Topology rebuild workflows for retained switching studies.
File Formats (surge-io)
- MATPOWER
.mreader and writer. - PSS/E RAW reader and writer (v30-v36) with RAWX support.
- PSS/E DYR dynamics data reader (130+ model types).
- PSS/E sequence data reader (zero/positive/negative sequence impedances).
- CGMES 2.4.15 and CGMES 3.0 (CIM100) reader (29 import waves).
- XIIDM (PowSyBl) reader and writer including phase tap changers.
- UCTE
.uctreader. - IEEE Common Data Format (CDF) reader.
- OpenDSS
.dssreader for 3-phase distribution models. - COMTRADE reader for oscillography data.
- Surge native JSON, compressed JSON (Zstandard), and binary format
reader/writer.
Sparse Infrastructure (surge-sparse)
- Compressed Sparse Column (CSC) matrix with COO-to-CSC assembly.
- KLU sparse LU factorization with symbolic reuse and numeric refactor.
- Complex KLU solver for Y-bus admittance matrix operations.
Solution Types (surge-solution)
- Shared result contracts for power flow and OPF outputs.
- Replay-friendly solved state snapshots.
CLI (surge-bindings)
surge-solvebinary with solver methods:acpf,acpf-warm,fdpf,
dcpf,dc-opf,ac-opf,socp-opf,scopf,ots,orpd,
contingency,n-2,hvdc,injection-capability,nerc-atc.- Format auto-detection from file extension.
- JSON, text, and binary output modes.
- Solver backend selection via
--solver.
Python Bindings (surge-py)
surgePython package with typed stubs (.pyi) andpy.typedmarker.- Root-level entry points:
solve_ac_pf,solve_dc_pf,solve_dc_opf,
solve_ac_opf,solve_scopf,analyze_n1_branch,
analyze_n1_generator,analyze_n2_branch,load,save. - Namespaced APIs:
surge.powerflow,surge.optimization,
surge.contingency,surge.transfer,surge.dc,surge.io,surge.batch. - NumPy interop for voltage, angle, and sensitivity arrays.
- Parameter sweep with parallel scenario execution.
- Custom exception hierarchy (
SurgeErrorbase with solver-specific
subclasses). - Python 3.10 through 3.14 support.
Packaging and Build
- Rust workspace with 13 member crates, edition 2024, MSRV 1.87.
- Vendored HiGHS 1.13.1 for reproducible LP/QP builds.
- SuiteSparse/KLU linked for sparse factorization.
- Release profile:
opt-level=3, fat LTO, single codegen unit. - Generic public wheel builds: Linux x86_64, Linux aarch64, macOS aarch64,
Windows x86_64. - Optional targeted GitHub Release wheel artifacts for
x86-64-v4. - PolyForm Noncommercial 1.0.0 license with commercial dual-license option.
Documentation
- 8 user tutorials with Jupyter notebook companions.
- 15 per-crate reference guides.
- Architecture, validation evidence, and method fidelity documentation.
- CLI reference, Python API surface guide, and quickstart.
- Packaged example cases (IEEE 118-bus, ACTIVSg10k, pglib cases) in native
format with provenance records.
License
PolyForm Noncommercial 1.0.0. Commercial licensing available — contact licensing@amptimal.com.