Wind Energy from the Mean Speed Is Wrong

On this page

Problem statement

The wind energy estimate for a site was made by reading the power curve at the site's mean wind speed, or from monthly mean speeds out of a climate dataset, or by cubing the mean speed to get the power in the wind. At one site it came out 15% high, at another 40% low, and there is no correction factor that fixes both — because averaging the speed before the non-linear step throws away the information the energy depends on.

The fix is to keep the distribution: hourly speeds if you have them, a fitted Weibull if you have the parameters, and a Rayleigh assumption with an honest error bar if all you have is a mean.

Quick answer

Apply the power curve to each hour and average the power — never the other way round:

import requests, numpy as np, pandas as pd
from windpowerlib import WindTurbine

turbine = WindTurbine(turbine_type="V126/3450", hub_height=117)
cv, cp = turbine.power_curve.wind_speed, turbine.power_curve.value / 3.45e6
power = lambda v: np.interp(v, cv, cp, right=0)

def hub(lat, lon):
    j = requests.get("https://archive-api.open-meteo.com/v1/archive", params={
        "latitude": lat, "longitude": lon,
        "start_date": "2023-01-01", "end_date": "2023-12-31",
        "hourly": "wind_speed_10m,wind_speed_100m", "wind_speed_unit": "ms",
        "timezone": "UTC"}, timeout=120).json()
    d = pd.DataFrame(j["hourly"])
    d.index = pd.to_datetime(d.pop("time"))
    a = np.log(d.wind_speed_100m.mean() / d.wind_speed_10m.mean()) / np.log(10)
    return d.wind_speed_100m * (117 / 100) ** a

sites = {"Ringkøbing": (56.09, 8.24), "Hamburg": (53.55, 9.99), "Albacete": (38.99, -1.86)}
print(f"{'site':<12}{'mean v':>7}{'hourly':>8}{'daily':>8}{'monthly':>9}{'annual':>8}")
for name, (lat, lon) in sites.items():
    v = hub(lat, lon)
    row = [power(v).mean(),
           power(v.resample("D").mean()).mean(),
           power(v.resample("ME").mean()).mean(),
           float(power(v.mean()))]
    print(f"{name:<12}{v.mean():>7.2f}" + "".join(f"{x:>8.1%}" for x in row[:2])
          + f"{row[2]:>9.1%}{row[3]:>8.1%}")
site         mean v  hourly   daily  monthly  annual
Ringkøbing     8.61   55.1%   56.1%    63.5%   63.4%
Hamburg        6.85   39.8%   38.5%    34.0%   31.9%
Albacete       5.30   24.7%   20.6%    14.9%   14.2%

The hourly column is the reference. Every step of averaging before the power curve moves the answer, and not always in the same direction.

Finest time step, else integrate a distribution

1. Use the finest time step the data has

Hourly reanalysis or 10-minute mast data keep the spread of speeds. Daily means already compress it; monthly means compress it further.

2. If you only have Weibull parameters, integrate

Integrate the power curve against the Weibull density. Two numbers carry most of the information that 8,760 hourly values do.

3. If you only have a mean, assume a distribution and say so

A Rayleigh distribution (Weibull with k = 2) is the conventional assumption when only the mean is known. It is often within 10% and occasionally far off; report it as an estimate with that caveat.

4. Never cube the mean speed

The power in the wind is proportional to the mean of v³, which for real wind is 1.7–2 times the cube of the mean. A power-density map built from mean speeds understates every site, and understates the variable ones most.

5. Recompute any figure that came from monthly climatology

Climate datasets often publish monthly mean wind. They are useful for comparing regions and useless for energy without a distribution.

A power curve with two spreads of wind speed: on the convex part the power at the mean is below the mean power, near rated it is above. the curve bends, so the mean misleads06121824hub-height wind speed, m/sAlbacete: curve at mean 14%, true 24.7%Ringkøbing: curve at mean 63%, true 55%bars along the axis: the central range of each site’s hourly speeds spatialworkflow.io
On the convex part of the curve the mean speed under-reads; near rated it over-reads.

The Rayleigh fallback and the cube of the mean

Example 1 — the Rayleigh fallback

from scipy import stats

def rayleigh_cf(mean_v):
    c = mean_v / 0.8862                     # Weibull scale for k = 2
    x = np.linspace(0, 30, 3001)
    return np.trapezoid(stats.weibull_min.pdf(x, 2, scale=c) * power(x), x)

print(f"{'site':<12}{'hourly':>8}{'Rayleigh':>10}{'error':>8}{'fitted k':>10}")
for name, (lat, lon) in sites.items():
    v = hub(lat, lon)
    k, _, _ = stats.weibull_min.fit(v[v > 0], floc=0)
    ref, ray = power(v).mean(), rayleigh_cf(v.mean())
    print(f"{name:<12}{ref:>8.1%}{ray:>10.1%}{ray / ref - 1:>8.0%}{k:>10.2f}")
site          hourly  Rayleigh   error  fitted k
Ringkøbing     55.1%     53.8%     -2%      2.19
Hamburg        39.8%     39.5%     -1%      2.29
Albacete       24.7%     23.7%     -4%      1.83

Where the true shape is close to k = 2 the Rayleigh estimate is good. Where it is not — the spread-out Albacete distribution, k ≈ 1.8 — it misses more. Still far better than reading the curve at the mean.

Example 2 — power density: mean of cube against cube of mean

for name, (lat, lon) in sites.items():
    v = hub(lat, lon)
    true_pd = 0.5 * 1.225 * (v ** 3).mean()
    naive_pd = 0.5 * 1.225 * v.mean() ** 3
    print(f"{name:<12} ½ρ·mean(v³) = {true_pd:>5.0f} W/m²   "
          f"½ρ·mean(v)³ = {naive_pd:>5.0f} W/m²   ratio {true_pd / naive_pd:.2f}")
Ringkøbing   ½ρ·mean(v³) =   688 W/m²   ½ρ·mean(v)³ =   391 W/m²   ratio 1.76
Hamburg      ½ρ·mean(v³) =   331 W/m²   ½ρ·mean(v)³ =   197 W/m²   ratio 1.68
Albacete     ½ρ·mean(v³) =   185 W/m²   ½ρ·mean(v)³ =    91 W/m²   ratio 2.03

This ratio — the energy pattern factor — is always above 1 and larger for more variable winds. A map of mean-speed cubes ranks sites differently from a map of true power density.

Example 3 — where on the curve the mean sits

for name, (lat, lon) in sites.items():
    v = hub(lat, lon)
    below_cut_in = (v < 3).mean()
    at_rated = (v >= 12).mean()
    print(f"{name:<12} mean {v.mean():.1f} m/s → curve reads {power(v.mean()):.0%} of rated; "
          f"{below_cut_in:.0%} of hours below cut-in, {at_rated:.0%} at or above rated")
Ringkøbing   mean 8.6 m/s → curve reads 63% of rated; 7% of hours below cut-in, 19% at or above rated
Hamburg      mean 6.9 m/s → curve reads 32% of rated; 11% of hours below cut-in, 7% at or above rated
Albacete     mean 5.3 m/s → curve reads 14% of rated; 25% of hours below cut-in, 2% at or above rated

At the windy site the mean sits on the steep middle of the curve, where the curve reads high and the hours above rated (whose surplus is thrown away) are not penalised. At the calm site the mean sits near the bottom, where the curve reads low and the windy hours that make all the energy are invisible.

Capacity factor from hourly, daily-mean, monthly-mean and annual-mean speeds at three sites. average the speed first and the answer moveshourlydailymonthlyannualRingkøbing✓55.1%56.1%!63.5%!63.4%Hamburg✓39.8%38.5%!34.0%!31.9%Albacete✓24.7%!20.6%✕14.9%✕14.2%Up by 15% at the windy site, down by 43% at the calm one — no single correction fixes both spatialworkflow.io
Each level of averaging before the curve moves the answer — up at the windy site, down at the calm one.

Why the error has no fixed sign

Why the error has no fixed sign

The power curve is convex from cut-in to near rated and flat above rated. For a convex function, the function of the mean is below the mean of the function (Jensen's inequality); for the flat, capped part the reverse holds, because averaging moves hours from above rated — where the extra speed is wasted — down onto the steep part. Which effect dominates depends on where the site's distribution sits, which is why one correction factor cannot fix it.

Why daily means are already too coarse

A day with a calm morning and a gale in the afternoon averages to a moderate breeze. The turbine saw no output and then rated output; the daily mean predicts steady partial output. Wind varies strongly within a day, so even daily averaging loses a large part of the distribution.

Why the Rayleigh assumption is reasonable

Wind speed is the magnitude of a two-component velocity; if the components are independent and normally distributed with equal spread, the magnitude is Rayleigh-distributed. Real winds are close enough for a first estimate and far enough that a fitted Weibull, when available, is always better.

Capacity factor from hourly speeds against a Rayleigh estimate from the mean speed at three sites. when only the mean is knownsitehourlyRayleigherrorfitted kRingkøbing55.1%53.8%−2%2.19Hamburg39.8%39.5%−1%2.29Albacete24.7%23.7%−4%1.83reading the curve at the mean instead: +15%, −20% and −43%Assume k = 2 when you must; the error grows as the true k moves away from it spatialworkflow.io
A Rayleigh distribution rebuilt from the mean is within a few percent; the mean alone is not.

Air density, climatologies and turbulence

  • Air density still needs correcting; the error from ignoring it is smaller but has a fixed sign.
  • Monthly climatologies can be combined with a typical k for the region to rebuild a distribution, with the same caveats as Rayleigh.
  • Turbulence within the hour also smooths the effective power curve; 10-minute data is the industry standard for that reason.
  • Mean speed is fine for ranking very similar sites with the same distribution shape — not for energy.
  • Wind atlases that publish power density have computed it correctly; do not recompute it from their mean speeds.

FAQ

Can I estimate wind energy from the mean wind speed?

Only with an assumed distribution — Rayleigh if nothing else is known — and with a caveat. Reading the power curve at the mean is wrong in either direction.

Why is the cube of the mean speed wrong?

Because the mean of the cube is larger than the cube of the mean for any variable wind, typically by a factor of 1.7–2.

Are daily mean wind speeds good enough?

No. Most of the variability that decides energy happens within the day.

What is the energy pattern factor?

The ratio of the mean of v³ to the cube of the mean speed. It measures how much a mean-speed shortcut understates the power in the wind.

How good is the Rayleigh assumption?

Often within 10% of the hourly calculation, worse where the distribution's shape parameter is far from 2.

Why can the error be positive at one site and negative at another?

The power curve is convex below rated and capped above it, and where the site's speeds fall on it decides which effect dominates.