Technical manual — chapter list

Asset-dynamics data grounding

Which per-asset dynamics parameters are grounded in real UK data (mined from the GDA lake) versus literature-approximated [VERIFY] (unmeasurable / absent from the lake). This is the honest provenance ledger behind the authored asset classes (data/<case>/asset-classes.json, and GDA's NetworkModel/build_asset_classes.py). Every value below was read from an actual file, not a catalogue claim. Paths are relative to D:\Work\GDA\v1.

The rule: a grounded value is tagged Recorded (published fact) or DerivedFromRecorded (computed from records); everything else is CuratedPlaceholder + the literal [VERIFY] token, and the aggregate fleet result is UnvalidatedAtScale. The curve shape is assumption-driven; capacity/location and the few grounded dynamics below are not.

Grounded — inverter fleet

Parameter Grounded value Source
dispatchRampMwPerMin (per fuel) wind ≈ 32, solar ≈ 39, storage 60 MW/min Outputs/ramp_correlation.json (observed gas-vs-renewable ramp bands, 24 mo)
rocofTripHzPerS (modern) 1.0 Hz/s ALoMCP setting, Documentation/manual/54-frequency-rocof-detectors.md; GridSim FrequencyLimits.RocofLimitModernHzPerS
rocofTripHzPerS (legacy) 0.125 Hz/s legacy LoM relay, same source; FrequencyLimits.RocofLimitLegacyHzPerS
rocofTripConfirmS (modern) 0.5 s definite-time delay ALoMCP 500 ms definite-time delay, manual/54
rocofTripConfirmS (legacy) 0.0 s (instantaneous) legacy relays had no intentional delay, manual/54
deadbandHz 0.015 Hz NESO frequency-response service deadband (published)
per-technology capacity + bus grounded per unit TEC TECRegister/…/tec_2026-07-10.parquet (Built 81.6 GW), REPD, DUKES, BMU crosswalk
fleet ramp-absorption context 0.40–0.55 of a renewable swing Outputs/flex_stack_response.json (informs headroom plausibility)

Grounded — passive plant (transformer / cable)

Parameter Grounded value Source
transformer tapStepPu ~0.0125 (1.0–1.25% nominal) SCADA-recovered DataSources/Derived/tap_changers/tap_changers.parquet step_pct (0.46% observed)
transformer minTap/maxTap ±0.15 (≈31% span, −12…+4 ≈ 16 steps) LTDS ltds_tap_span_pct (median 31%) + NetworkModel/normalized/<lic>_tx2.parquet tap positions
transformer emergency headroom 1.58–2.0× nominal (short-term) <lic>_tx2.parquet emergency_rating_mva/nominal_rating_mva (median 1.583)
cable/line derateAtFullThermal 0.11 (summer ≈ 0.89 × winter) <lic>_circuits.parquet summer_rating_mva/winter_rating_mva (0.86–0.91; NPGN = 1.0)
cable-vs-OHL split cable ≈ 6.5% of route-km (transmission) NetworkModel/resolved/etys_circuits.parquet circuit_type + ohl_km/cable_km
line R/X/B + ratings + length grounded per circuit normalized LTDS <lic>_circuits.parquet (feeds transmission.json)

Grounded — system context (validation, not per-asset params)

Quantity Grounded value Source
GB system inertia 101–338 GVA·s; typical ~150; synchronous floor 107.5 Derived/inertia_reconstructed/…_validation.json, Derived/weather_inertia_coupling/…_validation.json
inertia ← synchronous GW 7.45 GVA·s per GW synchronous (r²=0.87) weather_inertia_coupling_validation.json
worst-case RoCoF ~0.42 Hz/s @ 1800 MW at the inertia floor inertia_reconstructed_validation.json
response-curve deviation grid 0.2 / 0.5 / 0.8 Hz NESO firm_frequency_response_ffr_post_tender_reports schema
arrest-layer held volumes (SystemResponseService MW) DC ≈ 950–1000 MW, DM ≈ 500–550 MW, DR ≈ 480–500 MW each direction; legacy FFR ≈ 0.5 GW Primary @0.5 Hz (207 MW @0.2 Hz) NESO EAC auction clears (enduring_auction_capability_eac_auction_results), DM/DR/DC requirement forecasts, FFR post-tender — all materialised. Delivery-curve shape (DC full @0.5 Hz, DM/DR full @0.2 Hz, 0.015 Hz deadband) is NESO published spec
reserve held Positive Balancing Reserve ≈ 450 MW, Negative 1450 MW; Quick Reserve 300–500 MW NESO balancing_reserve_…, quick_reserve_… forecasts
frequency validation data 1 s (NESO), 10 Hz (EirGrid all-island) Derived/frequency_all_srcs, EirGrid/frequency_10hz — materialised
GB phasor (per-node RoCoF + phase angle) 4 nodes (london, buckingham, manchester, strathclyde), 100 ms free / 6 kHz tier Gridradar/gb_frequency — schema-registered but not materialised (token-gated). NB: the framework is worded "5-node" in places — the real GB Gridradar network is 4 nodes; corrected.
PMU event signatures forced-oscillation / ring-down, ~30 fps, 16 points GESL/signaturesUS data, not GB (physics/method validation only), and not materialised
per-domain inertia shares (sync-vs-converter split) thermal 98.6% / hydro 1.4% / inverter 0% of spinning inertia; converters ≈ 57% of online MW; LOS-fragmentation flag true ~9% Derived/speed_domains/… (grounds the distributed multi-domain model; the H-constant table itself stays [VERIFY])
sub-cycle RoCoF uplift (local > COI) instantaneous RoCoF ≈ 1.16× typical, up to 1.35× the 1 s-averaged value Derived/subcycle_period_features/… rocof_uplift_ratio (reconstruction-based, not PMU-measured)
inter-domain propagation τ ~5–8 ms/corridor (wave speed 500–1500 km/s) Derived/propagation_delays/…synthetic (is_synthetic_speed=True, literature band); τ stays [VERIFY]
BSP transformer power factor ≈ 0.95 mean / 0.98 median (so MVA ≈ MW at most BSPs) Derived/bsp_power_factor_summary/…

Grounded — synchronous plant (Elexon per-BMU dynamic parameters)

The Elexon dynamic-parameter hives (DataSources/Elexon/Parquet/{rure,rdre,sel,mels,mzt,mnzt,ndz}/…, git-ignored but materialised) carry the real per-unit dispatch primitives, joined to fuel via Reference/bmunits_all.json. These ground a future synchronous-machine asset class (deferred — a machine trip must drop E live, plan risk 1), not the inverter classes:

Parameter Grounded value (per fuel) Note
run-up ramp (rure rate3) CCGT ≈ 15 MW/min, pumped-storage ≈ unconstrained WIND / NUCLEAR / interconnectors submit no run-up rate — not run-up-dispatchable
run-down ramp (rdre) CCGT ≈ 15–25 MW/min
headroom (MELS−SEL)/MELS CCGT ≈ 0.40, nuclear ≈ 0.03 grounds a synchronous headroom; inverter headroom stays [VERIFY]
min run / min off / notice CCGT ≈ 6 h / 6 h / 70 min; PS 30 / 15 / 2 min grounds unit-commitment constraints

Consequence for the inverter classes: dispatchRampMwPerMin for wind/solar is correctly a system-level proxy (DerivedFromRecorded from ramp_correlation), because those technologies do not submit a per-unit run-up rate at all — they track weather / curtail rather than ramp on command.

Grounded — recorded event targets (validation anchors)

The GDA lake's post-event replay reports (reports/…) give the real numbers the asset-fleet back-test must reproduce (AssetValidation.Compare). The anchor is 2019-08-09:

Quantity Recorded value Source
pre-event frequency 49.992 Hz reports/rocof_events-20190809T155233-0386/report.json
nadir 48.787 Hz @ 15:53:49Z same
peak |RoCoF| −0.151 Hz/s (1 s window) same
infeed loss ΔP 1618 MW (detector est.; real-world ≈1878 MW = 800 Hornsea + 640 Little Barford + ≈430 embedded) co-located infeed_loss-…
inertia at event NESO Outturn 215 GVA·s (swing-equation estimate 267.8) same
LFDD armed at the 48.787 Hz nadir (no MW disconnected recorded) same

Gap: the report records only the aggregate loss — no per-asset (Hornsea/Little Barford/embedded) breakdown and no LFDD MW. Those must come from the ESO Technical Report, not GDA. So the embedded-gen trip volume (the cascade's headline) stays externally-sourced / swept.

Blind-predict set (freeze params on the anchor, predict these): cleanest is 2026-05-31, 992 MW → 49.806 Hz nadir (reports/infeed_loss-20260531T180031-31869). Loss-magnitude-only (no frequency trajectory): 601 MW (IC trip 2026-06-26), 1014 / 798 / 514 MW (2026-07-03). The 2024-08-14 "19.7 GW" record is a detector artefact — reject.

Grounded — protections (device operation from the GDA event-detector layer)

The protections layer (ch. 15) grounds its frequency-domain thresholds in the pre-detected, graded gda-events/1 event streams:

Protection Grounded value Source
RoCoF / Loss-of-Mains grades 0.0625 / 0.125 / 0.25 / 0.5 Hz/s (+ 1 s & 3 s streams); modern ALoMCP 1.0 Hz/s + 500 ms delay Events/rocof_events (794 events), Random/detect_rocof_events.py
LFDD first stage 48.8 Hz (Recorded) + 632 MW coincident block, 2019-08-09 Events/lfdd_risk, Random/find_lfdd_events.py
under/over-frequency statutory 49.5 / 50.5 Hz FrequencyLimits; GDA lfdd_risk stages
loss-of-infeed / interconnector trip MW + nadir + RoCoF + recovery per event Events/infeed_loss (8,288), Events/interconnector_trips (755)

Protections that stay [VERIFY] (no operational data exists): recloser / auto-reclose / breaker operation (only distribution customer-outage counts, no device data), under/over-voltage (no measured GB voltage series), thermal / reactive overload, and fault level / short-circuit MVA (confirmed absent). These are generic settings; the topology recloser's mechanism is modelled fully, but its settings are assumed.

Stays [VERIFY] / swept — genuinely not in the lake

  • All inverter internal control loops: droop/df·dt gains, detection/compute/actuate latencies, PLL & current-loop time constants, fast-slew MW/s, LVRT/FRT — vendor-proprietary, absent everywhere.
  • BESS capacityMwh / storage duration — confirmed absent from REPD, TEC, DUKES and the BMU register (no MWh/hours/energy column anywhere). Must be assumed as a C-rate × MW. MW sizing is grounded (REPD operational batteries: 171 sites, 4,755 MW, median ~23 MW); the duration is not.
  • The legacy-vs-upgraded DG relay fraction — the single highest-leverage knob for the RoCoF-trip cascade. The lake encodes the relay thresholds (manual/54) but no register of how much embedded DG was upgraded under ALoMCP. This is exactly why the deliverable for any real-fleet claim is a parameter-sweep envelope over this fraction (AssetEnvelope), not a point prediction — if the band brackets cascade/no-cascade, that is the honest finding.
  • OLTC mechanical delay (seconds/tap) and transformer/cable thermal time constants (minutes) — no tap-position/time channel and no temperature series exist (confirmed in DataSources/UkPowerNetworks/Processors/detect_tap_changers.py). Grounded ratings give steady-state headroom only, not the time constant.
  • Fault level / short-circuit MVA (grid stiffness) — no fault-level product exists in the lake (no normalized/resolved fault tables). The local-stiffness / effective-local-inertia proxy stays [VERIFY].
  • Transformer MW/MVAr loading — no transformer_flows product; only a BSP power-factor summary (≈0.95, so MVA ≈ MW). Real per-transformer thermal duty stays [VERIFY].
  • Inter-domain propagation τ / wave speedDerived/propagation_delays is flagged synthetic (is_synthetic_speed=True, literature 500–1500 km/s band), not a GB measurement.

Known modelling limitations (honest caveats)

  • Vector-shift trip is a |Δf| proxy, not a true phase-jump detector. Phase is smoothly integrated (phaseDeg += 360·(f−f0)·dt), so the "vector-shift" trip effectively fires on sustained frequency offset, not on a discrete loss-of-mains angle step (no discrete angle event is modelled). vectorShiftTripDeg therefore does not carry a real relay's setting meaning — treat it as a proxy.
  • OLTC tap direction is convention-dependent. TransformerDynamics assumes lowering TapRatio lowers the controlled-bus voltage; whether that holds depends on the power-flow solver's tap convention (primary/secondary vs secondary/primary). Verify against the solver before wiring the passive fleet into the live tap loop (PassivePlantFleet.ApplyTo is a pure helper, not yet in the per-tick solve).

localRocofUpliftFactor — grounded and wired

The sub-cycle data grounds that local RoCoF ≈ 1.16× (up to 1.35×) the 1 s COI RoCoF. This is now a parameter (AssetParams.LocalRocofUpliftFactor, default 1.0 so the reduction gate and all existing tests are unchanged) that multiplies the RoCoF the LoM relay acts on — and only the relay, since the slower FFR response effectively sees the averaged value. The GDA emitter sets it to 1.16 (DerivedFromRecorded) on every inverter class, so a real-fleet run trips on the realistic local RoCoF rather than the COI average. Suite-pinned (InverterTripCascadeTests.Local_rocof_uplift_...).

Validation — the 2019-08-09 cascade: what is real vs calibrated (read this carefully)

The framework reproduces the 9 Aug 2019 cascade mechanism from first principles: fed only the primary Hornsea + Little Barford losses at the recorded 215 GVA·s, a legacy pre-ALoMCP DG fleet (0.125 Hz/s, sub-cycle uplift) crosses its RoCoF threshold and trips on its own protection, unprompted — the timing and triggering are emergent physics.

But the depth is NOT predicted, and the close agreement you may see is not independent validation. Measured honestly (single-bus lumped model — network topology is not used here):

Path Nadir Why
Recorded (Ofgem/GDA) 48.787 Hz
Scripted replay (Ofgem 9-step + recorded LFDD) 48.82 Hz it is the report's loss sequence fed back in — replay, not prediction
Dynamic fleet, 500 MW embedded 48.85 Hz
Dynamic fleet, 1290 MW embedded 48.23 Hz the nadir swings 2.7 Hz across plausible fleet sizes
Dynamic fleet, 2500 MW embedded 47.29 Hz
Dynamic fleet, 4000 MW embedded 46.12 Hz

The embedded volume that trips is [VERIFY]/swept (not per-unit recorded), and the nadir is a strong function of it. So the honest claim is the envelope one: the recorded 48.787 Hz lies within the band the fleet spans (≈47.3–48.85), which brackets — but does not independently predict — reality. The agreement of the scripted path is replay of recorded inputs; the dynamic path is calibration- sensitive. This is a mechanism + envelope result, tagged UnvalidatedAtScale. Suite-pinned (Asset2019EventTests), which asserts the mechanism and the bracketing band, not a nadir match — the genuine test of predictive power is a blind cross-event prediction (e.g. the held-out 2026-05-31 event), which no parameter set has yet been shown to pass.

Method / safety

Mined under the GDA hardware-fragility rules: no recursive lake scans; files located via git ls-files and one-level listing; data read one file at a time (normalized network parquets and derived-analysis JSONs are materialized; the large raw timeseries hives are not on this checkout, so system-context values come from the derived validation JSONs, which carry real computed values). See also docs/technical/05-frequency-dynamics.md (the pAssetFleet term) and docs/manual/18-extending-gridsim.md.