Work / Post-PhD research · experimental

Transferring wind corrections to places with no observations

Bias corrections only exist where there is observed generation to learn from. This work asks whether a constrained, physics-informed model can carry a correction to a region it has never seen, and fixes the tests before running them.

Period
2026
Stack
Python · PyTorch · differentiable forward operator · pre-registration · leave-one-region-out validation
01

Context

A generalisable correction was a goal during the PhD. After machine learning lost to interpolation under spatial validation, I dropped it and put the corrected wind into energy system models instead. I picked it back up in 2026 as independent work. It is not a thesis chapter, and it is experimental: no stable API, and its tests need an optional PyTorch install that CI does not include.

02

Method

  • A gated, constrained linear correction inside a differentiable forward operator, trained on some regions and tested zero-shot on others.
  • A pre-specification fixed the gates, thirteen predictions and the conditions that would falsify them before each run.
  • An unconstrained ablation at matched features and parameter count tests whether the constraints, rather than the capacity, are doing the work.
03

Results

  • Zero-shot, leave-one-region-out across Denmark, Germany, the UK, the US and Brazil: as registered, it beat uncorrected ERA5 in 5 of 5 and degraded none. The smallest margins, 0.0025 (US) and 0.0027 (UK) in RMSE, are not yet resampled.
  • Against the incumbent random-forest transfer it won in 4 of 5, the exception being Germany, where turbine locations are postcode centroids. Mean skill was +0.238 against the random forest's −0.099. That comparison is not yet reproducible from a single commit.
  • The unconstrained ablation was worse than doing nothing in every region, so the gain comes from the constraints.
  • Leave-one-country-out across Europe (working branch, unpublished): trained on eight countries, it cut national monthly RMSE in 8 of 9, to a median 29% of the uncorrected error, recovering a median 94% of what fitting inside the country achieves. It failed in France, whose uncorrected series was already unbiased, making its error 78% worse.
04

What failed

  • Seven of the thirteen registered predictions failed. They are published as failures rather than removed.
  • Two physics extensions were built, tested and rejected. A wake term cut the dense-fleet residual span by 61% and cost transfer in all five regions. A profile-curvature term improved Germany alone and cost mean skill 0.0089 against a 0.005 tolerance.
  • A configuration chosen after seeing results was re-tested on four regions never used as holdouts, with the consequence registered first. It passed transfer 4 of 4 but lost to the simpler configuration in 3 of 4, so the simpler one became the headline.
  • Adding six non-European regions to the training pool did not help Europe, as predicted.
05

Related study

A separate pre-registered test, committed before the code that ran it existed, asked whether plant-level underperformance grows with sub-grid terrain. All five gates passed: Spearman ρ 0.488 [0.393, 0.576] on 356 US plants, and in the top decile of relief the median plant's observed capacity factor is 2.1 times its simulated one. Nothing from it is implemented yet.

More work

Open-source library · Author
PyVWF: bias-corrected wind power from reanalysis

ERA5 is the default input for simulating wind power, and its wind speeds are biased in ways that change with place and season. PyVWF learns those biases from observed generation and corrects them, at whatever spatial and temporal resolution the data can support.

PyPSA-Eur fork · PhD Part II
How wind representation moves energy system plans

Energy system models plan decades of investment on wind inputs that are rarely questioned. I extended PyPSA-Eur to test how much three of those inputs, reanalysis bias, wake losses and spatial resolution, change the answer.