An experimental Physics-Informed Neural Network (PINN) for estimating effective grid inertia from publicly available frequency data — without proprietary generator dispatch information or known power disturbances.
⚠️ This is exploratory research. Results are preliminary. The methodology has not been validated against independent ground-truth inertia measurements. Claims should be treated as physically plausible hypotheses, not established findings.
As renewable penetration increases across European grids, synchronous generators are displaced by inverter-based resources. This reduces rotational inertia — the physical resistance of the grid to frequency changes — and increases vulnerability to disturbances.
Grid operators need to know how much inertia the system has at any moment in order to decide how much synthetic inertia compensation (from batteries and flywheels) to procure. The standard approach — summing generator inertia constants weighted by dispatch — systematically undercounts because it ignores load-side inertia from industrial motors and rotating machinery, assigns zero to wind and solar, and is only available at 15-minute resolution from delayed dispatch reports.
This project asks: can effective system inertia be estimated in real-time from frequency measurements alone?
The stochastic swing equation governs grid frequency dynamics near equilibrium:
where
The key insight: if
has zero autocorrelation at all lags. The model identifies
Important caveat: this identification is theoretically sound but numerically weak on CE grid data. The gradient signal driving
Fits a Tanh MLP
nn.Parameter values trained jointly with the network weights via the whiteness loss. A curvature penalty on
Status: produces physically plausible
Purpose: validation tool and slow reference estimator. Not the operational product.
Trained once on multiple years of data. A single forward pass on any new frequency window produces
Uses a 1D-CNN to extract temporal features from the standardised frequency window, followed by an MLP with sigmoid-bounded output heads for
Status: trained on 2015–2017, validated on 2018–2019. Produces a diurnal inertia cycle (higher overnight, lower midday) consistent with physical expectations. Shows a small but correct decrease in
Trained on 2015–2017 German grid frequency data. Validated on 2018–2019 (unseen years with higher renewable penetration).
| Metric | Value | Notes |
|---|---|---|
| M_PINN mean | 6.17 ± 0.71 MWs/MVA | Full test set mean |
| M_table mean | 3.41 MWs/MVA | Generation-side only — known underestimate |
| Load-side ΔM | ~2.76 MWs/MVA | Excess not attributable to generation mix |
| D mean | 0.21 ± 0.52 MW/Hz | High variance — poorly constrained |
| Night M | 6.30 MWs/MVA | 00:00–06:00 UTC |
| Day M | 5.92 MWs/MVA | 12:00–18:00 UTC |
| Night−Day Δ | 0.38 MWs/MVA | Diurnal industrial load cycle |
| M drop 2018→2019 | 0.08 MWs/MVA | Correct direction, modest magnitude |
| Inference time | <20ms | Single forward pass |
What these numbers mean and do not mean:
The ~2.76 MWs/MVA gap between M_PINN and M_table is physically interpretable as load-side inertia — real rotational inertia from motors and industrial machinery that the generation table cannot see. Literature estimates for CE load-side inertia are in the 2–4 MWs/MVA range, making this consistent. However, without validation against event-based ground truth, this remains a hypothesis.
The diurnal pattern is the strongest result: M is higher overnight without the model being told the time of day. This is consistent with overnight industrial processes contributing more rotational inertia than daytime electronic loads. The pattern appeared on both test years without being present in the training signal explicitly.
The year-on-year drop (0.08 MWs/MVA from 2018 to 2019) is in the correct physical direction — more renewables should mean less inertia — but is small relative to the standard deviation of M estimates. It is consistent with physics but not a strong signal.
D is poorly constrained and should not be interpreted quantitatively. The damping term is difficult to identify from ambient frequency data because
| Test | M (MWs/MVA) | Notes |
|---|---|---|
| Original inference | 6.17 ± 0.71 | Diurnal pattern, load-side contribution visible |
| Phase-randomised | 6.13 ± 0.69 | Residual whitening preserved, M robust to phase randomisation |
| df/dt scaling | 6.17 | Network robust to linear scaling of df/dt |
| Renewable correlation | r=-0.098 | Negative correlation with increased renewable penetration, consistent with expectations |
The generation-weighted formula:
has three systematic problems this model addresses:
- Missing load-side inertia — motors, pumps, compressors, and industrial flywheels all contribute synchronous inertia. The formula assigns zero to all of them.
- Zero for renewables — correct for inverter-based generation, but obscures the total system picture.
- Latency and resolution — generation dispatch data is available at 15-minute resolution with reporting delays. The model runs on real-time 1-second frequency data.
normalised time t ∈ [0,1]
↓ Tanh MLP (hidden_dim × n_layers)
↓ scaled f_s(t) → autograd df/dt → physical df/dt [Hz/s]
↓ R = M·df/dt + D·(f-f0)
M, D: nn.Parameter (physical units, Softplus-positive)
Loss: whiteness of R + curvature penalty on d²f/dt²
Tuned: Optuna over lr, beta, delta, architecture, epochs
raw f(t) — 3600s window
↓ Savitzky-Golay smooth (window=61, poly=3) → df/dt
↓ StandardScaler normalise → f_norm
↓ 1D-CNN: Conv1d(1→32, k=60, s=30) → Conv1d(32→64, k=10, s=5) → AdaptiveAvgPool(16)
↓ MLP: Linear(1024→128) × 4 layers, GELU
↓ Output heads with sigmoid bounds
M ∈ [1, 15] MWs/MVA D ∈ [0.1, 10] MW/Hz
Loss: whiteness of R across batch + weak Gaussian prior on M
grid-inertia-pinn/
├── data/
│ ├── raw/
│ │ └── de_frequency_1s_{year}.csv ← 1-second TransnetBW frequency
│ └── processed/
│ ├── de_load_15min.csv
│ ├── de_solar_15min.csv
│ ├── de_wind_15min.csv
│ └── de_inertia_15min.csv
│
├── models/
│ ├── pinn.py ← InertiaPINN + InertiaNet
│ └── losses.py ← PINNLoss + InertiaNetLoss
│
├── notebooks/
│ ├── 03_pinn_training.ipynb ← per-window PINN, Optuna tuning
│ └── 04_inference.ipynb ← InertiaNet training + validation
│
├── data/
│ ├── build_data.py ← builds processed CSVs from OPSD
│ └── fetch_frequency_1s.py ← downloads TransnetBW frequency data
│
└── checkpoints/
├── pinn/ ← InertiaPINN weights
└── inertianet/ ← InertiaNet trained weights
pip install torch pandas numpy matplotlib seaborn scikit-learn scipy optuna# 1. Download 1-second frequency data
python data/fetch_frequency_1s.py --years 2015 2016 2017 2018 2019
# 2. Build processed CSVs from OPSD
python data/build_data.py
# 3. Per-window PINN with Optuna tuning
jupyter notebook notebooks/03_pinn_training.ipynb
# 4. Train InertiaNet + validate on unseen years
jupyter notebook notebooks/04_inference.ipynb- No ground truth validation — M_PINN has not been compared against event-based RoCoF estimates from known generator trips. This is the critical missing validation step.
- Weak identification signal — the whiteness criterion is theoretically correct but numerically underdetermined on CE ambient frequency data. The gradient driving M toward the true value is ~O(1e-6) per window. Multi-year training strengthens this but does not fully resolve it.
- D is not reliably estimated — damping is harder to identify than inertia from ambient data. D estimates have high variance and should not be interpreted quantitatively without further validation.
- CE grid stability — the CE synchronous area is one of the most stable in the world. Inertia variation is subtle year-on-year. Results would likely be more pronounced on GB or Nordic grids where inertia swings more dramatically.
- Stationarity assumption — the model assumes M and D are constant within each 1-hour window. This breaks during rapid renewable ramps.
- SG filter trade-off — the Savitzky-Golay smoothing reduces df/dt noise ~54x but also removes genuine fast dynamics. This limits the whiteness of R achievable in principle.
- Event-based validation — use ENTSO-E transparency event logs or National Grid ESO disturbance records to compute ground-truth M from known ΔP events, then compare against InertiaNet estimates at the same timestamps
- Nordic or GB grid — apply the same methodology to Fingrid or National Grid ESO data where inertia variation is more pronounced and event data is publicly available
- Multi-year trend analysis — extend training to 2015–2022 to track the full German energy transition
- Synthetic inertia detection — as battery-based synthetic inertia services are deployed, track whether M_PINN captures their contribution
- Live inference pipeline — connect to ENTSO-E Transparency Platform API for real-time M estimation
| Source | Description | Resolution |
|---|---|---|
| OPSD Time Series | Load, wind, solar generation | 15-min |
| TransnetBW / OSF | German grid frequency (CE synchronous area) | 1-second |
MIT — experimental research code, use at your own risk.
