Skip to content

ResearchMy master’s thesis

State estimation: from a few meters, work out the voltage everywhere on a power grid.

Ten meters, and a load forecast at every other bus. Change the loads and see how far each estimate lands from the true voltage.

Colour the buses by
01234567891011121314151617181920212223242526272829303132Substation

WLS0.29%

average error, 33 buses

GNN…

loading the network

Bus 17 · PMU · load 80 kW

true 92.5% · WLS 92.5% (0.00)

The question

A distribution feeder carries power from a substation to homes and businesses, and its operator has to keep the voltage at every point within limits. Only a few points have a meter. State estimation works out the rest from the meters’ readings, a forecast of every load and the physics of the lines. The standard method is weighted least squares (WLS): the voltages that best fit every reading, each weighted by how far it can be trusted.

My master’s thesis (UPC Barcelona, 2026) asked whether a graph neural network (GNN), which learns from examples, or one also trained on the physics (a PINN, physics-informed) could estimate better. In October 2026 I re-checked it and asked a second question: are its numbers right?

The data

The feeder
The IEEE 33-bus test feeder: 33 buses on 32 lines at 12.66 kV, with 3.7 MW of load. At its base load the voltage falls to 91.3% of nominal at bus 17, the far end.
The meters
Each test sample has 10 meters at random buses, 2 of them PMUs. A meter reads its bus’s voltage and power: a PMU to ±0.1% (and the angle), a smart meter to ±0.5%, a SCADA meter to ±1%, each with a bias of up to ±1%.
The scenarios
Every load is its base value × (1 + 0.5 × a normal draw), each on its own. A bus without a meter gets a forecast: its base load, 50% uncertain. Every number below is over the 400 test samples, which played no part in any choice.

Voltages are shown as a share of the nominal 12.66 kV, and errors as the mean distance from the true voltage, over every bus of every sample: 0.32% is 0.0032 p.u.

What I found re-checking it

v1’s code ran, and its published numbers came back within the range of the re-runs for the GNN and for WLS, though not for the PINN. But the re-run showed that those numbers didn’t mean what they seemed to.

The thesis’s metric couldn’t tell a model from a constant

It averaged the predictions over 32 test samples before comparing them with the truth, which cancels every error except a constant offset. By that metric, always answering the average voltage profile, with no model at all, scores 0.06%: better than any GNN run. And the same GNN scores anywhere from 0.11% to 1.06% (9 times as much), depending on where its training happened to stop.

Taken on every bus of every sample, the constant’s 0.35% beats 3 of the 5 GNN runs. The other 2 beat it only by reading the answer (below): with those inputs shuffled between samples they fall behind it too (0.45% and 0.46%).

v1 re-run: |V| error by the thesis’s metric, and on every sample

  • the thesis’s metric: 32 samples averaged, then compared
  • every bus of every sample
  1. No model: the average profile
  2. GNN, run 1
  3. GNN, run 2
  4. GNN, run 3
  5. GNN, run 4
  6. GNN, run 5
  7. PINN, run 1
  8. PINN, run 2
  9. PINN, run 3
The numbers
RunThesis’s metricEvery sample
No model: the average profile0.06%0.35%
GNN, run 10.41%0.45%
GNN, run 21.06%1.10%
GNN, run 30.12%0.29%
GNN, run 40.63%0.68%
GNN, run 50.11%0.31%
PINN, run 11.22%1.32%
PINN, run 21.56%1.64%
PINN, run 31.31%1.41%
  • The inputs held the answer

    At an unmetered bus the model was given a voltage reading centred on the true voltage, and variances computed from the true values: 23 of the 33 buses carried their true voltage in a feature.

  • WLS was given the wrong loads

    Every load had the wrong sign, and the substation was recorded as supplying 0 MW instead of 3.9 MW, as the most trusted reading in the set. Undoing just those two takes WLS’s error from 1.08% to 0.43%.

  • The feeder wasn’t IEEE 33

    Its lines were converted to per-unit twice, leaving each with 62% of its impedance: the lowest voltage was 94.7% instead of 91.3%, the losses 120 kW instead of 203.

  • The PINN’s physics term wasn’t Ohm’s law

    It used the wrong current, standardised impedances and mixed units, so it couldn’t be zero at the true state. It pulled every PINN run away from it: all 3 sat 1.27% to 1.62% above the truth.

  • The training stopped with an offset

    Even on its own training samples the GNN was off by a constant 0.68% on average. Standardising the outputs and letting the learning rate decay brings that to 0.01%, with the same model and data.

  • What still stands

    The GNN’s and WLS’s published errors are within the range of the re-runs (the GNN’s 0.88% among 0.11% to 1.06%), and so is the thesis’s conclusion that the PINN was of limited use. Its published PINN error (0.77%) can’t be made again from its code.

Fixed, the networks beat a constant, and WLS beats them

With the data honest, the thesis’s training leaves both networks no better than answering the average profile (0.81% and 0.67% against 0.64%). With the training fixed both beat it, at 0.43%.

The PINN equals the GNN: at the physics weight chosen on validation (α = 0.1), the physics term changes the error by 1%.

WLS is lower still, at 0.32%.

|V| error at 10 meters, 400 test samples

  • WLS
  • the networks, as the thesis trained them
  • the networks, training fixed
  • no model
  1. No model: the average voltage profile0.64%
  2. GNN, the thesis’s training0.81%
  3. PINN, the thesis’s training0.67%
  4. GNN, training fixed0.43%
  5. PINN, training fixed0.43%
  6. GNN for 0 to 33 meters (the game’s)0.44%
  7. WLS0.32%

The thin line through the bars is the no-model baseline.

The numbers
Estimator|V| error
No model: the average voltage profile0.64%
GNN, the thesis’s training0.81%
PINN, the thesis’s training0.67%
GNN, training fixed0.43%
PINN, training fixed0.43%
GNN for 0 to 33 meters (the game’s)0.44%
WLS0.32%

Fewer or more meters

The thesis concluded that its GNN copes with other meter configurations, but its models only ever saw 10 meters. The GNN here (the game’s) was trained on 0 to 33.

WLS has the lowest error at every count from 3 meters to 33. The GNN degrades as gracefully but stays behind, at 1.3 to 2.1 times WLS’s error.

Two exceptions. With one meter, the substation’s alone, WLS is behind even the no-model baseline (0.74% against 0.61%): that one voltage reading sets the level of the whole estimate. With none, WLS has no answer at all.

The game shows two more. A wrong voltage reading is caught by WLS’s bad-data test in 126 of 126 trials, a wrong P or Q reading in 0 of 274. And without load forecasts WLS needs at least 22 meters: of the 1,673,828 placements of 22 that could work, 4,096 do.

|V| error by number of meters, new samples for each count

  • WLS
  • GNN
  • No model

Meters on the feeder

The numbers
MetersWLSGNNNo model
0no estimate0.63%0.63%
10.74%0.60%0.61%
30.48%0.64%0.71%
50.42%0.53%0.62%
100.30%0.42%0.59%
150.25%0.37%0.61%
200.21%0.32%0.58%
330.12%0.24%0.61%

What I built

v1 · the thesis · 2026

WLS with GridCal, the GNN and the PINN in PyTorch Geometric, on the IEEE 33-bus feeder; the thesis and its code, kept exactly as handed in: state-estimation-GNN-PINN (opens in a new tab).

v2 · the re-check · October 2026

  1. 1. Re-ran v1 from its own code

    Imported the thesis’s modules as they are and ran its notebook’s model, loss and training; regenerated its data with seeds and retrained it, 5 GNN runs and 3 PINN runs.

    The report (opens in a new tab)
  2. 2. Fixed it and measured again

    Honest inputs, the right signs, the real feeder, Ohm’s law in the physics term and a training that converges; the PINN’s weight chosen on validation; every estimator scored on every bus of every test sample.

    The report (opens in a new tab)
  3. 3. A WLS for the browser

    Gauss-Newton in plain numpy, written to port line for line. It lands on GridCal’s answer wherever GridCal reaches the minimum, and showed that GridCal stops short on 10 of the 400 test samples.

    The report (opens in a new tab)
  4. 4. Observability and bad data

    Tested all 1,673,828 placements of 22 meters that could fix the state without forecasts, and WLS’s chi-square and largest-residual tests on the test samples with one reading made wrong in each.

    The report (opens in a new tab)
  5. 5. A GNN for any number of meters

    The thesis’s model with the fixed training, on 4,000 samples with 0 to 33 meters each; of 3 seeds, the one with the lowest validation error.

    The report (opens in a new tab)
  6. 6. This page

    The power flow, WLS with its tests and the GNN’s forward pass, ported to TypeScript and checked against the Python case by case. The game runs in your browser, with no server.

The result in plain words

WLS is still the most accurate on this data: 0.32% average error with 10 meters, against 0.43% for the fixed GNN, and the lowest at every count from 3 meters up. The fixed GNN is close behind and degrades as gracefully as WLS when meters are taken away. The PINN equals the GNN.

That is what this data should give. Its load errors are independent and Gaussian, which is exactly what WLS assumes, so there is little left for a learned model to find. The thesis’s headline numbers don’t stand: its metric hid the errors, and its inputs held the answer.

What I’d do next

  1. A physics term weighted like WLS

    The PINN’s physics term trusts a 50%-uncertain load forecast as much as a meter, so more weight on it makes the estimate worse: the validation error goes from 0.43% with none to 0.61% at α = 10. Weighted by each reading’s variance, the term becomes the WLS objective itself: the hybrid the thesis proposed in its chapter 7.

  2. Loads that move together

    Here every load varies on its own, which is exactly what WLS assumes. Real loads rise and fall together through the day. WLS’s forecasts can’t express that, but a learned model can learn it: that is where a GNN could beat WLS, and the test I’d run next.