Advanced Wind Turbine Simulation Workflow#

  • A more advanced turbine workflow will include many steps (Which have been showcased in previous examples)

Workflow:

  1. Weather data extraction from a MERRA dataset (windspeed, pressure, temperature)

  2. Spatial adjustment of the windspeeds

  3. Vertical projection of the wind speeds

  4. Wind speed density correction

  5. Power curve convolution

  6. Capacity Factor Estimation

import reskit as rk

import numpy as np
import matplotlib.pyplot as plt

Simulate a Single Location#

# Set some constants for later

TURBINE_CAPACITY = 4200  # kW
TURBINE_HUB_HEIGHT = 120  # meters
TURBINE_ROTOR_DIAMETER = 136  # meters
TURBINE_LOCATION = (6.0, 50.5)  # (lon, lat)
# 1. Create a weather source, load, and extract weather variables
src = rk.weather.MerraSource(rk.TEST_DATA["merra-like"], bounds=[5, 49, 7, 52], verbose=False)

src.sload_elevated_wind_speed()
src.sload_surface_pressure()
src.sload_surface_air_temperature()

raw_windspeeds = src.get("elevated_wind_speed", locations=TURBINE_LOCATION, interpolation="bilinear")
raw_pressure = src.get("surface_pressure", locations=TURBINE_LOCATION, interpolation="bilinear")
raw_temperature = src.get("surface_air_temperature", locations=TURBINE_LOCATION, interpolation="bilinear")

print(raw_windspeeds.head())
2015-01-01 00:30:00+00:00    5.383743
2015-01-01 01:30:00+00:00    5.323299
2015-01-01 02:30:00+00:00    5.232418
2015-01-01 03:30:00+00:00    5.160997
2015-01-01 04:30:00+00:00    5.439261
Name: (6.0, 50.5), dtype: float64
# 2. Vertically project wind speeds to hub height

roughness = rk.wind.roughness_from_clc(clc_path=rk.TEST_DATA["clc-aachen_clipped.tif"], loc=TURBINE_LOCATION)


projected_windspeed = rk.wind.apply_logarithmic_profile_projection(
    measured_wind_speed=raw_windspeeds,
    measured_height=50,  # The MERRA dataset offers windspeeds at 50m
    target_height=TURBINE_HUB_HEIGHT,
    roughness=roughness,
)

print(projected_windspeed.head())
2015-01-01 00:30:00+00:00    6.506035
2015-01-01 01:30:00+00:00    6.432992
2015-01-01 02:30:00+00:00    6.323166
2015-01-01 03:30:00+00:00    6.236856
2015-01-01 04:30:00+00:00    6.573127
Name: (6.0, 50.5), dtype: float64
# 3. Apply density correction

pressure_corrected_windspeeds = rk.wind.apply_air_density_adjustment(
    wind_speed=projected_windspeed,
    pressure=raw_pressure,
    temperature=raw_temperature,
    height=TURBINE_HUB_HEIGHT,
)

pressure_corrected_windspeeds.head()
2015-01-01 00:30:00+00:00    6.560702
2015-01-01 01:30:00+00:00    6.485689
2015-01-01 02:30:00+00:00    6.374120
2015-01-01 03:30:00+00:00    6.287352
2015-01-01 04:30:00+00:00    6.626462
Name: (6.0, 50.5), dtype: float64
# 4. Power curve estimation and convolution

power_curve = rk.wind.PowerCurve.from_capacity_and_rotor_diam(
    capacity=TURBINE_CAPACITY, rotor_diam=TURBINE_ROTOR_DIAMETER
)

convoluted_power_curve = power_curve.convolute_by_gaussian(scaling=0.06, base=0.1)
# 5. Capacity factor estimation
capacity_factors = convoluted_power_curve.simulate(wind_speed=pressure_corrected_windspeeds)

capacity_factors
array([0.27273363, 0.26315142, 0.24928885, 0.23878838, 0.2813027 ,
       0.38840875, 0.46433861, 0.50707569, 0.55526571, 0.49867274,
       0.5716173 , 0.71244977, 0.70559868, 0.61191423, 0.70556453,
       0.91621572, 0.98436881, 0.98905482, 0.99521448, 0.99879609,
       0.99956091, 0.99987679, 0.99996843, 0.99999171, 0.99999641,
       0.99999844, 0.99999941, 0.99999979, 0.99999986, 0.99999954,
       0.99999577, 0.99996633, 0.99986441, 0.99835949, 0.99779936,
       0.98064443, 0.94692822, 0.97454365, 0.97228814, 0.97970383,
       0.97176293, 0.93889837, 0.87918241, 0.82917666, 0.78503089,
       0.73943709, 0.6327937 , 0.60788396, 0.56244002, 0.49216547,
       0.48407326, 0.55137321, 0.66608584, 0.71491774, 0.71633097,
       0.77210396, 0.8345534 , 0.76770054, 0.56405061, 0.42807357,
       0.41323894, 0.41240108, 0.32953804, 0.23966265, 0.13567885,
       0.12706234, 0.32103426, 0.49467238, 0.26512148, 0.20028125,
       0.37167453])
plt.plot(capacity_factors)
plt.xlabel("Time")
plt.ylabel("Capacity Factor")
plt.grid()
plt.show()
../../_images/ca7849a7e02503d7e7bfa01e841036070d9e731c0f63bd13d909e367946b2814.png