← All projects
Project 03 · Wind resource engineering

From a 10 m mast to a wind farm's annual energy

As a Renewable Energy Intern at Greenard Consulting in Casablanca, I learned the industry workflow for assessing a wind site in WAsP. Then I wrote my own Python tool that reproduces the core of it (wake models, Weibull integration and a loss cascade) and checked it against WAsP.

OrganisationGreenard Consulting
LocationCasablanca, Morocco
DatesJun – Aug 2026
RoleRenewable Energy Intern
ReportFrench, 5 chapters
ToolsWAsP 10 · Python · Streamlit
4.90m/s
Mean wind measured at the station, 10 m height
7.85m/s
Predicted at turbine site 003, 50 m hub height
3.149GWh/yr
Net annual energy at site 003, 1.13% wake loss
5.1→17.6%
Capacity factor of a 6 MW farm, raw vs corrected wind climate

The problem

Wind is measured at one mast, often low and in the wrong place, but turbines stand higher and on different terrain. Power in the wind scales with the cube of speed:

powerP = ½ · ρ · A · V³
Betz limitCp,max = 16/27 ≈ 0.593

So a 1 m/s error in mean speed can make or break a project. The job is to carry a measurement correctly across height, terrain roughness and relief, then turn it into energy.

What I did in WAsP

  • Observed wind climate: 12 direction sectors with a Weibull fit for each. West to north-west dominates (270° and 300° together cover over 32% of the time), with a 4.90 m/s mean and 135 W/m² at 10 m.
  • Wind Atlas: removed the local effects of the measurement site and generalised the climate across 5 roughness classes (0 to 1.5 m) and 5 heights (10 to 200 m).
  • Resource grid: 12×15 nodes at 1 km resolution and 50 m height over the "Crest" terrain. Mean speed ranges from 6.52 to 8.19 m/s, and the best corridor follows the ridge.
  • Turbine site 003: up to +14.3% speed-up from terrain in the 270° sector. RIX = 0% on every sector, so the linear model is valid there.
Resource grid "Crest", 50 mMinMeanMax
Mean wind speed [m/s]6.527.318.19
Power density [W/m²]286406571
AEP per 1 MW turbine [GWh/yr]2.1652.7803.438

Method sensitivity. For the same isolated turbine, WAsP gives a gross AEP of 3.239 GWh with the combined Weibull method and 3.185 GWh with the emergent method, a 1.71% gap. Even a simple case depends on the calculation method you choose.

WAsP resource grid map: mean wind speed at 50 m over the Crest terrain, overlaid on contour lines, ranging from 6.52 to 8.19 m/s
Fig. 3.1 Resource grid "Crest", mean speed at 50 m over terrain contours (WAsP). Faster wind (red) follows the ridge.
Wind rose and Weibull histogram of the observed wind climate: mean 4.90 m/s, power density 135 W/m²
Fig. 3.2 Observed wind climate at 10 m: wind rose and Weibull distribution. U = 4.90 m/s, P = 135 W/m².
The Python tool

Rebuilding the engine myself

To really understand what WAsP does inside, I wrote every line of an 8-module energy-yield model with a Streamlit front end. It integrates turbine output over every sector and every 1 m/s speed bin of the Weibull distribution, converts probabilities to hours per year, then applies six post-wake losses.

See the code on GitHub ↗

ModuleResponsibility
turbine.pyPosition, rotor diameter, hub height
wind_farm.pyDownwind and crosswind distances for every turbine pair, in a frame aligned with the wind
wake_model.pyJensen (linear wake expansion Rw = R + kx) and Ainslie eddy-viscosity, solved with an RK45 integrator
power_curve.pyCut-in, ramp-up, rated plateau and cut-out
topography.pyFlat, synthetic hill or imported terrain for turbine elevations
wind_resource.pyWind rose with a Weibull distribution per sector, like the WAsP tables
energy_yield.pyPer-turbine AEP, loss cascade and farm capacity factor
app.pyStreamlit interface for terrain, wind rose, layout and loss inputs

Loss cascade

Loss, applied in orderValue
Shadow flicker1.60 %
Flow / turbine interaction1.08 %
Availability3.00 %
Electrical2.00 %
Turbine performance3.60 %
Environment (icing, soiling)1.00 %
Cf = Enet [kWh/yr] / (Σ Prated [kW] × 8760 h)
Python tool output: 3 by 2 grid of six turbines, T01 to T06, with wind arriving from 270 degrees at 9 m/s
Fig. 3.3 Output from my tool: a 3×2 layout of six 1 MW turbines with wind from 270°.
Validation

Does it agree with WAsP?

Fed the station's 12-sector Weibull table, the tool recomputes a mean of 4.90 m/s, which matches WAsP exactly. Then I compared two scenarios for six 1 MW turbines (54 m rotor, 50 m hub, 5 diameters apart, Jensen wakes).

ScenarioMean speedGross energyNet energyCf
Raw station climate (10 m)4.90 m/s3,679 MWh/yr2,663 MWh/yr5.1 %
Corrected at turbine site (50 m)7.88 m/s16,186 MWh/yr9,264 MWh/yr17.6 %

Same rotors and same rated power, but the capacity factor more than triples. Height extrapolation and terrain correction aren't a detail. They decide whether a project is worth building.

What I learned from the limit. In the second scenario I put all the wind in one direction (270°) to keep things simple. That exaggerates the wake losses, up to 62% on the third turbine in a row. A real site has a spread of wind directions that spreads the wakes out, so a 12-sector wind rose like the one WAsP uses is the realistic input. WAsP's own result for turbine site 003 was a 1.13% wake loss, but that is a different, isolated turbine, so the two numbers are not a like-for-like comparison. You can see the effect of direction yourself below.

Live model

Try it: Jensen wakes

The same Jensen model, running in your browser. Start at 270° (aligned rows) and then skew the wind to 300°.

Speed deficit: nonestrongNumbers under rotors = speed at hub (m/s)
Farm output–
Wake loss–

Assumptions: rotor 54 m, thrust coefficient 0.8, generic 1 MW power curve (cut-in 3 m/s, rated 12 m/s), wakes combined by root-sum-square, one wind direction at a time.

PythonWAsPWind resource assessmentWeibull statisticsWake modellingAEPStreamlit