This comparison passes the same rotor-plane velocity fields to the installed FLORIS, FOXES, and PyWake packages and compares the outputs of their native rotor sampling and averaging implementations. It does not compare wake-model physics, turbine curves, superposition, or induction.
All sampling coordinates are normalized by rotor radius R.
Methods used by each software
FLORIS
TurbineCubatureGrid (3 x 3)
Samples
9
Aggregation
linear cubature of velocity
9 cubature points spanning the rotor disk with FLORIS' native cubature quadrature.
Executed with FLORIS TurbineCubatureGrid(grid_resolution=3) and FLORIS average_velocity using the grid's native power_average_method and cubature weights.
FOXES
GridRotor (grid16)
Samples
16
Aggregation
weighted arithmetic mean of velocity
Sixteen cell-center points on a 4 x 4 square spanning the rotor. Weights are evaluated by FOXES from each cell's overlap with the disk; the four corner cell centers lie outside the disk but retain partial-cell weight.
Executed with FOXES ModelBook grid16 and GridRotor.eval_rpoint_results, requesting FOXES' native REWS output.
PyWake
CGIRotorAvg(n=9)
Samples
9
Aggregation
weighted arithmetic mean of velocity
9 quadrature points in the rotor plane with built-in CGI weights.
Executed with PyWake CGIRotorAvg.__call__. PyWake averages the supplied deficit at its native rotor nodes; the comparison converts that result back to normalized velocity.
A ladder of test cases
Rather than jumping straight to a waked rotor, the comparison walks through four velocity fields of increasing difficulty. Each step adds exactly one new way for a coarse stencil to go wrong, so a deviation can be attributed to a specific cause instead of to the case as a whole.
Reference: 128-point Gauss-Legendre radial integration with 720 azimuthal points. Each software result is compared with a dense-disk reference using the same aggregation semantics.
1. Uniform inflow
U/U∞ = 1
A constant field. Any quadrature whose weights sum to one is exact here, so this verifies the harness and the normalization of each stencil rather than discriminating between methods.
Exact area average: 1
Software
Points
Rotor average
Dense reference
Absolute error
Relative error
FLORIS
9
1.000000
1.000000
0.000000
0.00%
FOXES
16
1.000000
1.000000
0.000000
0.00%
PyWake
9
1.000000
1.000000
0.000000
0.00%
2. Linear vertical shear
U/U∞ = 1 + 0.2 (z/R)
A linear profile. Because all three stencils are symmetric about the hub height, the positive and negative contributions cancel and the area average is still recovered exactly. Point placement starts to matter only once the aggregation is nonlinear.
Exact area average: 1
Software
Points
Rotor average
Dense reference
Absolute error
Relative error
FLORIS
9
1.000000
1.000000
0.000000
0.00%
FOXES
16
1.000000
1.000000
0.000000
0.00%
PyWake
9
1.000000
1.000000
0.000000
0.00%
3. Quadratic radial deficit
U/U∞ = 1 - 0.2 (r/R)²
The first case with real curvature. The exact area average is 0.9. Stencils clustered near the hub under-resolve the slower flow near the blade tips and overpredict the rotor average, which exposes how far each sampling pattern reaches toward the rotor edge.
A laterally offset deficit that approximates a partially waked rotor. It is neither symmetric nor smooth on the scale of the coarse stencils, so it is the most demanding case and the one most representative of wake-model use.
Software
Points
Rotor average
Dense reference
Absolute error
Relative error
FLORIS
9
0.945390
0.946132
0.000742
0.08%
FOXES
16
0.947192
0.946132
0.001060
0.11%
PyWake
9
0.951528
0.946132
0.005396
0.57%
Errors across the ladder
All three methods use arithmetic averaging in this configuration, so each error is measured against a dense-disk arithmetic reference.
How to interpret this comparison
Every case uses one identical velocity field; differences come only from sampling and averaging.
Uniform inflow is exact for all three methods, which confirms that each set of weights is normalized.
Linear shear is exact for all three methods. FOXES and PyWake have stencils that are symmetric about hub height, and FLORIS now takes a linear (cubature-weighted) average, so it no longer reads 1.006623 as it does with the default cubic mean.
The quadratic case is exact for FLORIS and PyWake (errors 0.00% and 0.00%): a nine-point cubature integrates a quadratic over the disk exactly. FOXES keeps itsgrid16 stencil, whose four corner points sit at r/R = 1.06, beyond the rim, and lands slightly low (0.36%).
On the offset Gaussian the errors fall to 0.08% for FLORIS (from 1.76% in the default view), 0.57% for PyWake (from 3.86%) and 0.11% for FOXES. A nine-point stencil still cannot resolve the narrow deficit core exactly, but it is much closer than the default four- and nine-point square stencils.
These results isolate quadrature error and are not a ranking of full wake-model accuracy.