Skip to main content

Module batch

Module batch 

Source
Expand description

Batched power flow: one topology, many scenarios, solved across all cores.

This is the workload where parallelism actually pays. A single solve is ~60% sparse LU, which neither threads nor a GPU help with; but N-1 screening, time series/QSTS and Monte Carlo run thousands of independent solves over one unchanging topology, and those scale essentially linearly.

Two properties make that cheap here:

  • Every scenario shares one YBusSparse, so the Jacobian’s sparsity pattern is identical across the whole batch. Each worker keeps one PersistentSolver and amortizes a single symbolic factorization across its entire share of the batch — measured at ~45% of solve time on a 9,241-bus case when redone per solve.
  • Scenarios are fully independent, so the only coordination is handing out indices.

BatchSolver::solve_contingencies extends this to branch outages, which change the network rather than its bus values. The first property above appears to rule that out — and it was long assumed to — but only the sparsity pattern has to hold still, not the Y-bus itself: network::build_ybus_with_outages takes a branch out while keeping its structural entries, so the symbolic factorization still carries across the sweep. What cannot carry is the Jacobian’s cached per-nonzero recipe, which stores the admittance it was analyzed against; that is re-derived per scenario via PersistentSolver::invalidate_admittances, at O(nonzeros) rather than a fresh symbolic analysis. Measured at 2.0–2.7x against independent solves, single-threaded, before any parallelism.

This is also the CPU baseline any future GPU work has to beat: beating a single-threaded CPU solver is not a result.

Re-exports§

pub use crate::scenario::BatchError;
pub use crate::scenario::BusOverride;
pub use crate::scenario::Scenario;
pub use crate::scenario::uniform_load_scaling;

Structs§

BatchSolver
Solves many scenarios over one shared topology, in parallel.