User manual — chapter list

Contingency analysis

Six CLI verbs answer "what happens if something fails or the load grows": trip (lose a generator), screen (rank every credible single loss), nminus1 (outage every branch), nminus1-sweep (the same, parallel and at scale), stress (load-to-collapse), and chain (consecutive warm-started solves). The GUI adds a right-click trip on the network map.

Run every verb through the CLI project:

dotnet run --project src/GridSim.Cli <verb> [flags]

A flag with an unparseable value fails loudly with exit code 2 - it is never silently replaced by the default.

trip - lose one generator

dotnet run --project src/GridSim.Cli trip [<gen>] [--dir <case-dir>] [--export <csv>]
Flag Default Meaning
<gen> largest non-slack unit with H > 0 substring match on the generator name (case-insensitive)
--dir data/uk JSON case directory to trip on
--export off write the frequency trajectory to a CSV (dtm,f columns)

The verb removes the unit's output and its spinning inertia, integrates the swing response, and prints: the tripped unit and MW lost, system inertia before -> after, initial RoCoF, nadir (with time), settling frequency, an ASCII sparkline of the trajectory, and - for context - the same trip at half the remaining inertia.

A name that matches no generator exits 2 and lists what is available; it never falls back to a different unit. An exported trajectory can be played back in the console: dotnet run --project src/GridSim.Cli replay <csv>.

trip is the one dynamics verb that honours --inertia-model distributed (full multi-domain integration, reporting the centre-of-inertia response).

screen - rank credible single losses

dotnet run --project src/GridSim.Cli screen [--dir <case-dir>] [--top 12] [--csv <path>]
Flag Default Meaning
--dir data/uk case directory
--top 12 rows printed (all losses are still screened and counted)
--csv off write every result to a CSV

For each credible single loss the table shows MW lost, remaining inertia, initial RoCoF, nadir, and a verdict: ok, >0.125 Hz/s (RoCoF breach), <49.5 Hz (statutory breach) or LFDD RISK. The footer gives the breach count, the worst RoCoF, and for the binding case the minimum spinning inertia needed to hold 0.125 Hz/s, with the current headroom against it.

nminus1 - branch outage screening

dotnet run --project src/GridSim.Cli nminus1 [--dir <case-dir>]

(n-1 is accepted as an alias; default case directory data/uk.)

Each branch is removed in turn and the case re-solved. Per outage the table reports Status, max branch loading, worst boundary loading, and the voltage range. Read the status column as:

  • secure - converged with no violations.
  • VIOLATIONxN - converged, but N limit violations. A violation is one of: a branch loaded above 100 % of its rating (branch <name> <pct>%), a boundary above its limit (boundary <name> <pct>%), any bus below 0.94 pu (undervoltage) or above 1.06 pu (overvoltage).
  • ISLANDED - the power flow could not converge, typically because the outaged element was the only feed to some load.

The footer totals outages screened, secure, with violations, and islanded.

nminus1-sweep - the full sweep, in parallel

dotnet run --project src/GridSim.Cli nminus1-sweep <case|--all> [--parallel N] [--sample N] [--out <path>]
Flag Default Meaning
<case> case118 a built-in case name or a .m file; --all sweeps the whole case registry
--parallel logical CPU count worker threads
--sample full sweep screen only N evenly spaced branches (logged, never silent)
--out results/nminus1-sweep.md (under the current directory) markdown report path; a .csv sibling and run-metadata.json land beside it

Output is one summary row per case: buses, branches, outages screened, secure / violations / islanded counts, solves per second and wall time. Sampled cases are marked (sampled). Use nminus1 on a single case when you want the per-outage detail; use the sweep for coverage and throughput.

Continuous N-1 in the cycle engine

Beyond these one-shot verbs, N-1 also runs continuously inside the real-time cycle engine - the CYCLE tab, and the gridsim cycle verb (see 19-cli-reference.md). Each cycle re-screens the hot branch set as High-priority work every cycle, while the remaining branches rotate through Low-priority shards that reach full coverage over several cycles. The ContingencyAnalysis.ScreenBranchesParallel primitive these verbs share gained an optional CancellationToken (wired onto its ParallelOptions) so a deferred shard aborts cleanly between outages when a cycle hits its deadline; the default token is a no-op, so the standalone verbs above are unchanged.

stress - load-to-collapse

dotnet run --project src/GridSim.Cli stress <case|--all> [--from 0.5] [--to 2.0] [--step 0.05] [--parallel N] [--out <path>]
Flag Default Meaning
<case> case118 case name or .m file; --all for the registry
--from / --to / --step 0.5 / 2.0 / 0.05 load-factor sweep (x base load); --step must be positive (exit 2 otherwise)
--parallel logical CPU count load points solved concurrently
--out results/stress.md report path (.csv sibling, run-metadata.json)

Every load point is solved independently; max loadability is the highest factor that still converges before the first non-convergence, reported with the minimum voltage at that point. A case that converges across the whole range is noted "did not collapse in range" - widen --to if you need the actual limit.

chain - consecutive warm-started solves

dotnet run --project src/GridSim.Cli chain <case> [--steps 50] [--mode fixed|ramp|daily] [--ramp-pct 0.5] [--out <path>]
Flag Default Meaning
<case> case118 case name or .m file
--steps 50 number of consecutive solves
--mode fixed fixed = same point re-solved; ramp = +--ramp-pct % load per step; daily = a 24 h demand curve
--ramp-pct 0.5 per-step load growth for ramp mode
--out results/chain-<case>.md report path (.csv sibling)

Each step feeds the previous solved voltages in as the initial condition. The report gives per-step iterations, mismatch and voltage range, plus the cold (flat-start) iteration count for comparison. In fixed mode expect warm-start iterations to drop to <= 1 with no drift - if they do not, something is wrong with the case or the build.

The GUI right-click trip

On the NETWORK map, right-click behaviour depends on the mode:

  • Live sim (and local replay): right-click a bus to trip the largest generator dispatched at that bus. The loss is injected into the live frequency integrator, the event is logged with its headline RoCoF and nadir, an alarm is raised, and the GENERATION & INERTIA tab's trace plot and read-outs update with the with/without-device comparison. A bus with no generation logs "No generation to trip" and does nothing.
  • Bridge mode: right-click opens a context menu of on-demand GDA physics queries - on a bus, "Feasibility: +500 MW here" and "Scenario: trip nearest generator" (the largest unit on that bus, else the largest in the model); on a branch, "Scenario: trip this". The returned solve renders as a what-if overlay on the map (live frames held off), and the results panel shows the verdict, the binding constraint, and each violation as kind / element / value-vs-limit / message. Pick Return to live stream (in the same menu, or the toolbar button) to drop the overlay and resume the stream.

See frequency studies for watching the transient a trip produces at a fine time-step.

Note on default output locations

nminus1-sweep, stress and chain write under results/ in your current working directory. trip, screen and nminus1 print to the console (plus whatever --csv/--export path you give). Pass --out/--csv explicitly when you want the artefacts somewhere specific.

See also