Running power flows
This chapter covers the CLI's default surface: load a case and solve it - once, live, or as a recorded time-domain run - plus how the solver engine is chosen, what lands on disk, and how to read the console output. The analysis, evidence and estimation verbs each have their own chapter.
The three outcomes of a bare run
GridSim.Cli <case> (a built-in name, a .m path, --mpc <file>.m, or
--dir <folder> - see 02-loading-networks.md) ends
in exactly one of three ways:
| You add | What runs |
|---|---|
| (nothing) | the live loop: re-solve a day/night demand curve each tick until a key is pressed |
--once |
one solve, one full engineering report, exit |
--ticks N |
the live loop, headless: N ticks, one summary line each, exit |
--enableExport[=path] |
one fully-traced solve dumped to JSON, exit |
case9 is the exception: it always solves once, prints the report and exits
(it is the ground-truth benchmark; animating it is never the point) - unless
--enableExport is present, in which case it is dumped like any other case.
Global switches can appear anywhere on the line and combine with any of the above:
| Switch | Default | Meaning |
|---|---|---|
--once |
off | solve once and print the detailed report |
--ticks N |
0 (interactive) | run N headless live ticks then exit; a malformed N exits 2 |
--cpu / --gpu[=rocm\|opencl\|cuda] |
--cpu |
compute backend; --gpu auto-detects AMD-first (ROCm -> OpenCL -> CUDA); a missing device (or an OpenCL device without FP64) warns and falls back to CPU |
--bfs |
off | force the radial backward/forward-sweep solver |
--inertia-model lumped\|distributed |
lumped |
inertia model for the dynamics verbs (trip integrates distributed; other dynamics verbs warn and run lumped) |
--enableExport[=path] |
off | dump one traced solve (schema gridsim-solve-export/1) |
--export-jacobian |
off | force the (large) Jacobian into the export, past its size gate |
Solver selection
Power flow runs on one of three engines behind one interface, and selection is automatic:
- Radial network (one slack, exactly buses - 1 in-service branches), or
--bfsgiven -> backward/forward sweep - the distribution-class solver for tree feeders the transmission Newton method is not built for. - More than 3,000 buses -> sparse Newton-Raphson (the dense Jacobian stops fitting and stops being fast past a few thousand buses).
- Otherwise -> dense Newton-Raphson, the validated reference.
Where both Newton engines solve a case they agree on iteration count and final
mismatch, so the automatic choice never changes the answer, only the cost.
transient exposes the same choice explicitly as
--solver auto|dense|sparse|bfs; the desktop app's SOLVER picker is the same
set again. Default solve options are a mismatch tolerance of 1e-8 p.u., a
30-iteration cap, and generator Q-limits enforced (PV->PQ switching).
The compute backend (--cpu/--gpu) swaps the linear solver inside each
Newton step; the physics never changes. Check what your machine offers before
relying on --gpu:
dotnet run --project src/GridSim.Cli gpucheck
gpucheck probes CPU, ROCm, OpenCL and CUDA in turn, runs a tiny dense and sparse
solve on each present backend, and prints a FAIL line naming any failing call.
Every report and run directory stamps the backend it actually used, including
cpu (<requested> requested but unavailable) when a GPU was asked for but
absent.
The OLTC outer loop
Whatever engine is picked, it is wrapped in a steady-state outer loop that
settles the on-load tap changers: solve, step any OLTC whose controlled bus is
outside its deadband, re-solve, up to 25 passes (the synth verb takes
--oltc N, default 30). The convergence line reports both loops:
Converged (3 NR iters, 3 OLTC passes, max mismatch 1.29E-011 p.u.)
Zero OLTC passes just means the case has no tap changers (all the MATPOWER cases) or none needed to move.
Reading the console output
The --once report, top to bottom: a header (name, bus/branch/generator
counts, base MVA, frequency); the convergence line above; system totals
(generation, demand, losses, inertia); a per-bus table (kV, Vm p.u., Va deg,
net P and Q); boundary flows when the case defines them, flagged OVERLOAD
past 100 %; the five most-loaded branches; and a closing voltage-range verdict
(in band is 0.94-1.06 p.u.) with total real and reactive losses.
The live loop starts a simulated clock at 08:00 and advances 20 simulated
minutes per tick, scaling demand along the GB daily curve and re-solving.
Interactively it redraws a full terminal dashboard; frequency reads a constant
50.00 Hz because each tick is a steady-state solve - dynamics live in
transient and the dashboards. With --ticks N it prints one line per tick:
t=08:00 tick 0 load 27.65GW gen 27.68GW loss 27MW V 0.998-1.040 ok (3 NR)
48 ticks is a simulated day. ok/DIV is the convergence verdict; a
non-convergence in a case that normally solves is worth investigating
(see 17-troubleshooting.md).
Solve exports (--enableExport)
dotnet run --project src/GridSim.Cli case118 --enableExport
[export] dense-newton: converged=True iters=6 maxMis=2.85E-014 -> ...\exports\case118-solve.json
This runs one traced solve on the raw engine (no OLTC loop, iteration cap
raised to 100, Q-limits on) and writes everything the solve touched - Y-bus,
per-unit spec, per-iteration mismatch and correction, Q-limit switching,
converged state and flows - as a gridsim-solve-export/1 JSON document, by
default to exports/<case>-solve.json under the current directory. Add
--export-jacobian to include the full Jacobian. The metadata block records
case, backend, git commit, timestamp, elapsed ms and machine. This is the
document crossval diffs against pandapower and the desktop app replays, so
one schema serves export, validation and replay (see
15-exports-and-formats.md).
Recorded runs: transient and the run directory
transient is the headless time-domain form: it drives the live simulator
(hold-steady, warm-started) for a simulated duration at a fine time slice,
integrating swing-equation frequency each slice, and records the lot.
dotnet run --project src/GridSim.Cli transient case118 --minutes 10 --dt-ms 20 --trip 1000 --trip-at 60
dotnet run --project src/GridSim.Cli transient --cases suite --minutes 5
| Flag | Default | Meaning |
|---|---|---|
<case> / --cases a,b,c / --cases suite |
case9 |
one case, a list, or the built-in suite (case9...case300 + pegase/case1354pegase.m) |
--minutes M (alias --duration) |
60 | simulated duration |
--dt-ms D |
1.0 | slice length in milliseconds |
--trip MW --trip-at S |
off | trip that many MW of infeed at S seconds; a --trip-at past the run end aborts (exit 2) rather than silently answering "no event" |
--trip-window S |
2.0 | seconds around the trip in which every slice is exported |
--log-every N |
1 | CSV row cadence |
--export-every N |
0 | also export a full solve every N slices (--export-jac adds the Jacobian) |
--solver auto\|dense\|sparse\|bfs |
auto |
engine override |
--out DIR |
results/transient-<case>-<stamp> |
run directory |
The run directory is the standard output shape most recording verbs share:
results/transient-case118-20260713-141530/
|-- run-metadata.json what ran: description, machine, runtime, git commit, backend
|-- timeseries.csv per-slice: t, frequency, RoCoF, gen/demand, iterations, mismatch, V range, solve ms, converged
`-- exports/
`-- slice-000000001.json full solve exports (first slice, the trip window, every --export-every N)
replay-event, scenario, fleet, evidence, gda-replay, estimate and
crossval write the same pattern - results/<verb>-<id>/ with a
run-metadata.json - so any result can be traced to the commit and backend
that produced it. Run directories under results/ are auto-discovered by the
desktop app and can be stepped through frame by frame
(04-the-desktop-app.md).
The console summary at the end of a transient run names the nadir, the worst
RoCoF and their times, plus any non-converged slices; the CSV carries the full
trace for plotting.
See also
- 02-loading-networks.md - case selection in full
- 04-the-desktop-app.md - the same solves, drawn live; replaying run directories
- 06-contingency-analysis.md - trip, screen, nminus1, stress, chain
- 14-validation-tools.md - crossval and bench
- 19-cli-reference.md - every verb and flag in one table