WindIO#
WIFA uses the WindIO schema to standardize inputs across all flow models. This ensures that the same input files work with PyWake, foxes, WAYVE, and code_saturne.
Input Structure#
A WIFA simulation requires a hierarchical set of YAML files:
wind_energy_system/
├── system.yaml # Main entry point
└── analysis.yaml # Model-specific configuration
plant_energy_site/
└── site.yaml # Site boundaries and resource reference
plant_energy_resource/
└── resource.nc # Wind resource data (NetCDF)
plant_wind_farm/
├── farm.yaml # Turbine layout
└── turbine.yaml # Turbine specifications
Wind Energy System (system.yaml)#
The main entry point that references all other components:
name: My Wind Farm Study
site: !include ../plant_energy_site/site.yaml
wind_farm: !include ../plant_wind_farm/farm.yaml
attributes:
flow_model:
name: foxes # Required: pywake, foxes, wayve, codesaturne
analysis: !include analysis.yaml
model_outputs_specification:
output_folder: "results"
run_configuration:
times_run:
all_occurences: false
subset: [0, 2, 5] # Specific time indices to run
turbine_outputs:
turbine_nc_filename: 'turbine_data.nc'
output_variables: ['power', 'rotor_effective_velocity']
flow_field:
report: true
flow_nc_filename: flow_field.nc
output_variables: ['wind_speed', 'wind_direction']
z_planes:
z_sampling: "hub_heights" # or "plane_list"
z_list: [100, 119, 150] # if plane_list
xy_sampling: "grid"
x_bounds: [-1000, 5000]
y_bounds: [-1000, 1000]
dx: 150
dy: 150
Site Configuration (site.yaml)#
Defines site boundaries and references the wind resource:
name: My Site
boundaries:
polygons:
- x: [0, 5000, 5000, 0] # Polygon vertices (meters)
y: [0, 0, 2000, 2000]
energy_resource: !include ../plant_energy_resource/resource.yaml
Wind Farm Layout (farm.yaml)#
Single Turbine Type:
name: My Wind Farm
layouts:
- coordinates:
x: [0, 1000, 2000, 3000] # Turbine x positions (meters)
y: [0, 0, 0, 0] # Turbine y positions (meters)
turbines: !include turbine.yaml
Multiple Turbine Types:
name: My Wind Farm
layouts:
- coordinates:
x: [0, 1000, 2000, 3000]
y: [0, 0, 0, 0]
turbine_types: [1, 2, 2, 3] # Index into turbine_types dict
turbine_types:
1: !include turbine_type1.yaml
2: !include turbine_type2.yaml
3: !include turbine_type3.yaml
Turbine Definition (turbine.yaml)#
name: IEA 15MW Reference
hub_height: 150.0 # meters
rotor_diameter: 240.0 # meters
performance:
# Option A: Power curve
power_curve:
power_values: [0, 500000, ..., 15000000] # Watts
power_wind_speeds: [3, 4, ..., 25] # m/s
# Option B: Cp curve (alternative to power_curve)
Cp_curve:
Cp_values: [0.0, 0.2, 0.45, ...] # dimensionless
Cp_wind_speeds: [3, 4, 5, ...] # m/s
# Required with either option:
Ct_curve:
Ct_values: [0.0, 0.8, 0.75, ...] # dimensionless
Ct_wind_speeds: [3, 4, 5, ...] # m/s
Wind Resource Formats#
Wind resource data is can be provided as NetCDF files linked with the !include directive. WIFA supports several formats:
Time Series#
NetCDF structure for time-varying wind conditions:
Dimensions:
time: N # Number of time steps
Coordinates:
time: float64 (time,) # Time index or timestamp
Data Variables:
wind_speed: float64 (time,) # Hub-height wind speed [m/s]
wind_direction: float64 (time,) # Wind direction [degrees, 0=N, 90=E]
turbulence_intensity: float64 (time,) # TI as fraction [0-1]
Creating time series in Python:
import xarray as xr
import numpy as np
n_times = 1000
ds = xr.Dataset(
coords={"time": np.arange(n_times, dtype=np.float64)},
data_vars={
"wind_speed": ("time", np.random.weibull(2, n_times) * 8 + 4),
"wind_direction": ("time", np.random.uniform(0, 360, n_times)),
"turbulence_intensity": ("time", np.full(n_times, 0.06)),
},
)
ds.to_netcdf("timeseries_resource.nc")
Turbine-Specific Time Series#
For per-turbine wind conditions (e.g., SCADA data):
Dimensions:
time: N # Number of time steps
wind_turbine: M # Number of turbines
Coordinates:
time: float64 (time,)
wind_turbine: int64 (wind_turbine,) # Turbine indices [0, 1, 2, ...]
Data Variables:
wind_speed: float64 (time, wind_turbine)
wind_direction: float64 (time, wind_turbine)
turbulence_intensity: float64 (time, wind_turbine)
operating: float64 (time, wind_turbine) # 1.0=on, 0.0=off
Weibull Wind Rose#
For probabilistic AEP calculations:
Dimensions:
wind_direction: D # Number of direction sectors
Coordinates:
wind_direction: float64 (wind_direction,) # Sector centers [degrees]
Data Variables:
sector_probability: float64 (wind_direction,) # Sum = 1.0
weibull_a: float64 (wind_direction,) # Scale parameter [m/s]
weibull_k: float64 (wind_direction,) # Shape parameter [-]
turbulence_intensity: float64 (wind_direction,)
Heterogeneous Wind Rose (per turbine)#
For spatially varying wind resources:
Dimensions:
wind_turbine: M # Number of turbines
wind_direction: D # Number of direction sectors
Coordinates:
wind_turbine: int64 (wind_turbine,)
wind_direction: float64 (wind_direction,)
Data Variables:
sector_probability: float64 (wind_turbine, wind_direction)
weibull_a: float64 (wind_turbine, wind_direction)
weibull_k: float64 (wind_turbine, wind_direction)
turbulence_intensity: float64 (wind_turbine, wind_direction)
x: float64 (wind_turbine,) # Turbine x position [m]
y: float64 (wind_turbine,) # Turbine y position [m]
height: float64 (wind_turbine,) # Reference height [m]
Variable Conventions#
Variable |
Units |
Valid Range |
Notes |
|---|---|---|---|
|
m/s |
>= 0 |
At hub height |
|
degrees |
[0, 360) |
Meteorological: 0=N, 90=E |
|
fraction |
[0, 1] |
0.06 = 6% TI |
|
fraction |
[0, 1] |
Sum = 1.0 |
|
m/s |
> 0 |
Scale parameter |
|
dimensionless| > 0 |
Shape (2.0 = Rayleigh) |
|
|
flag |
0 or 1 |
1 = on, 0 = off |
Outputs#
WIFA outputs results as NetCDF files in the specified output folder:
Turbine Data (turbine_data.nc)#
Per-turbine results for each simulation state:
Dimensions:
turbine: M # Number of turbines
time/wd/ws: N # Simulation states
Data Variables:
power: float64 (states, turbine) # Power [W]
rotor_effective_velocity: float64 (states, turbine) # [m/s]
Flow Field (flow_field.nc)#
Spatial flow data on the requested grid:
Dimensions:
x: Nx
y: Ny
z: Nz
time/wd/ws: N
Data Variables:
wind_speed: float64 (states, x, y, z) # [m/s]
wind_direction: float64 (states, x, y, z) # [degrees]
turbulence_intensity: float64 (states, x, y, z) # [fraction]
See the windIO documentation for the full schema specification.