Technical manual — chapter list

Protection assessment (a passive relay overlay)

Chapter 15 documents the active protection layer - the IActiveAssetDynamics controllers that trip infeed, shed load and open branches during a simulation, changing the trajectory. This chapter documents its passive counterpart: a protection-simulation overlay that reads a solved state and reports which relays would operate and why, without ever altering the solve. It is the evidence-apparatus sibling of the physics-conformance audit (ch. 16) - an independent read-only overlay, not a control loop - and it exists to let a run conclude, with a straight face, "on branch PITS_3-WIBA_3, thermal-overload protection would likely operate - loaded to 123% of RateA; the IEC inverse-time element trips in 3.3 s."

What it is not

Real relay settings are unobtainable (site-specific, commercially confidential), so this is deliberately not a certified protection study. The operating quantities are always computed from the solved state; the pickups they are compared against are generic standard-practice values, honestly graded:

  • Grounded - the statutory GB frequency band (47.5 / 52 Hz) and the modern ALoMCP RoCoF limit (1.0 Hz/s).
  • Generic - everything else (voltage band, overcurrent multiples, distance zone reaches, thermal pickup): a plausible default a real scheme would grade per site. Overridable per run.
  • NotCheckable - elements a positive-sequence phasor model cannot evaluate, reported as such rather than fabricated (see below).

The engine (src/GridSim.Core/Protection/)

ProtectionAssessment.Assess(model, result, settings?, trajectory?) builds a ProtectionContext - every operating quantity computed once from the solved state (per-bus voltage, per-branch apparent power / current / loading / apparent impedance, the busbar KCL differential residual, system frequency) - then runs each relay in ProtectionRegistry.All over it. The relays are pure comparisons, so the whole assessment is a read-only overlay: it never calls the solver and never mutates the model or result (pinned by a test).

Each relay yields a RelayVerdict per location where it operates, plus the single closest non-operating location for context, carrying: the ANSI device number, the operating quantity + unit, the pickup, the signed margin, an inverse-time TimeToTripS where the element has a curve, a plain-language Basis ("Vm 0.74 pu at bus 7 is below the 0.80 pu undervoltage pickup"), and the confidence grade. ProtectionReport.Operating is the subset that would fire, worst-margin first.

The relay library

ANSI Element Operating quantity Notes
27 / 59 Under / overvoltage bus Vm vs band per bus
32 Reverse power generator Pg < -pickup motoring detection
37 Undercurrent branch |I| below an absolute floor a de-energized in-service circuit, NOT a normally lightly-loaded line
49 Thermal overload branch loading vs RateA first-order thermal replica gives the operating time
50 Instantaneous overcurrent |I| / rated definite/instant operation
51 Time overcurrent |I| / rated IEC 60255 standard-inverse t = TMS.0.14/(M^0.02-1)
21 Distance apparent Z = V²/conj(S) at the from end three forward zones scaled from the line's own Z; load encroachment shows here
81U / 81O Under / overfrequency run min/max (or steady) frequency statutory band (Grounded)
81R RoCoF peak |df/dt| needs a trajectory (else NotCheckable)
78 Vector shift / loss-of-mains peak voltage-angle jump needs a trajectory
87 Busbar differential KCL current residual at the bus ~machine-epsilon on a converged solve; bites only under an injected internal fault (the bus shunt is netted off, or a capacitor bank reads as a false fault)
50N/51N/21N/46 Earth / negative-sequence - NotCheckable: a positive-sequence model carries no zero/negative-sequence network, so there is no residual current to compute

Honest scope (the "Gauss law" of protection)

Just as the physics audit reports Gauss's law as not modelled in a phasor model rather than inventing a residual, the earth-fault and negative-sequence elements (50N/51N/21N/46) are reported NotCheckable with exactly what a real assessment would need (an unbalanced sequence-impedance model). The busbar differential (87) is checkable but ~zero on a balanced converged state - reported secure with the largest residual shown, meaningful only once an internal fault is injected. RoCoF/vector-shift (81R/78) need a dynamic run; on a steady snapshot they report NotCheckable rather than a fabricated transient. When a dynamic run is available, a ProtectionTrajectory (peak RoCoF, min/max frequency, peak vector shift) enables them.

Surfacing

  • gridsim protection-check <case> [--uv pu] [--ov pu] [--uf/--of Hz] [--oc xIn] [--thermal frac] [--rocof Hz/s] - solve the case and print the operating elements (device, location, quantity, pickup, time, basis), the not-evaluated elements, and the headline "PROTECTION SIMULATION suggests N protection event(s)...". The flags override the generic pickups so a run can ask "what would a tighter relay do".
  • End of a plain solve - PrintDetailed appends one line: either "no relay would operate on this state" or "N event(s) suggested - e.g. on X, relay Y would likely operate (...)". The solve above is untouched; this is the passive overlay, exactly as asked.

On the real GB spine one operating point yields two events - a thermal overload and its time-overcurrent on the branch loaded to 123% of its 1,500 MVA rating - and nothing else: the noise-free, defensible statement the overlay is for.

Fault injection (FaultAnalysis)

The differential (87) and distance (21) elements only bite on a real fault, so FaultAnalysis.ThreePhase injects one. It is the classic Thevenin / bus-impedance superposition: from the prefault solved voltages it builds the fault-study admittance (network Ybus + each load as a constant-impedance shunt + each generator as its subtransient reactance to ground), solves one column of the bus-impedance matrix for the fault bus, and superposes the fault:

If = V0_k / (Zth_kk + Zf),    V_faulted = V0 - Zbus[:,k] . If

The faulted branch currents then drive the overlay. It is positive-sequence, so it represents the balanced three-phase fault exactly; an earth (single-line-to-ground) fault needs a sequence-network model and is reported not-representable. Generator subtransient reactances are synthesised (a generic X"d, since the model carries no machine reactance) and provenance-noted. Dense (the bus-impedance column is a dense complex solve), so it fails loud above a bus limit. ProtectionAssessment.AssessThreePhaseFault applies the fault and assesses the faulted state in one call, feeding the fault current to the differential.

gridsim fault <case> --bus <id> [--zf pu] prints the fault current (pu and kA), the Thevenin impedance, the collapsed bus voltage, and the relays that operate. On IEEE-14 a bolted fault at bus 4 draws ~12.4 pu, collapses the bus to 0, and operates 87 on bus 4 (at the fault current), 21 Zone 2 on the two faulted-branch relays with Zone 3 backup on remote relays, and 27 across the depressed network - textbook.

Cascade propagation (ProtectionCascade)

A read-only "what-if" that follows a protection event as it propagates: from a prefault state it assesses the overlay, trips the branch element that would operate FIRST (shortest inverse-time), opens that branch in a COPY of the model, re-solves, and re-assesses - chaining until nothing else trips, the re-solve fails (a split / blackout, the honest terminal state), or a step cap is hit. It never touches the caller's solve. Branch-tripping elements only (49/50/51/21); voltage/frequency elements shed or trip infeed and are left to the active layer (ch. 15). gridsim protection-check <case> --cascade prints the ordered sequence. On the GB spine the single 123%-overload seeds a seven-trip cascade that ends in a non-convergent split - the cascade-to-blackout story, quantified.

Invariants (pinned by ProtectionAssessmentTests, FaultAndCascadeTests)

  • Read-only - Assess never mutates the result (voltage array identical before/after).
  • No false differential - a healthy converged case raises no 87 (the bus shunt is netted off the KCL residual).
  • Threshold logic - tightening the band around the real voltage spread fires 27 and 59; a branch rated below its flow fires 49/50/51 with sensible inverse-time; more current trips 51 sooner.
  • Trajectory gating - 81R and 78 are NotCheckable and never operate without a trajectory; a supplied trajectory that dipped to 47.0 Hz at 2.0 Hz/s fires 81U and 81R.
  • Honest not-checkable - the earth/negative-sequence element always reports NotCheckable.

Key files

Protection/{ProtectionTypes,ProtectionContext,ProtectionRelays,ProtectionAssessment,FaultAnalysis, ProtectionCascade}.cs; GridSim.Cli/Program.cs (protection-check + --cascade, fault verbs + the PrintDetailed end-of-run line). Tests: ProtectionAssessmentTests, FaultAndCascadeTests.