Edit on Gitlab Launch with Binder

Site Object

For a given position, reference wind speed (WSref) and wind direction (WDref), Site provides the local wind condition in terms of wind speed (WS), wind direction (WD), turbulence intensity (TI) and the probability of each combination of wind direction and wind speed. Furthermore, Site is responsible for calculating the down-wind, cross-wind and vertical distance between wind turbines (which in non-flat terrain is different from the straight-line distances).

Intall PyWake if needed

[1]:
# Install PyWake if needed
try:
    import py_wake
except ModuleNotFoundError:
    !pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/PyWake.git

Predefined example sites

PyWake contains a few predefined sites of different complexities:

  • IEA37Site: UniformSite (fix wind speed (9.8m/s), predefined wind sector probability).

  • Hornsrev1: UniformWeibullSite (Weibull distributed wind speed, predefined wind sector propability, uniform wind a over flat wind area).

  • ParqueFicticioSite: WaspGridSite (position-dependent Weibull distributed wind speed and sector probability. Terrain following distances over non-flat terrain). Loaded from a set of *.grd files exported from WAsP.

First we import all sites and Python elements for later use

[2]:
import numpy as np
import matplotlib.pyplot as plt
[3]:
from py_wake.examples.data.hornsrev1 import Hornsrev1Site
from py_wake.examples.data.iea37 import IEA37Site
from py_wake.examples.data.ParqueFicticio import ParqueFicticioSite

sites = {"IEA37": IEA37Site(n_wt=16),
         "Hornsrev1": Hornsrev1Site(),
         "ParqueFicticio": ParqueFicticioSite()}

PyWake also allows for user-defined sites

You can define your own site using one of the Site classes:

  • UniformWeibullSite: Site with uniform sector-dependent Weibull distributed wind speed.

  • WaspGridSite: Site with gridded non-uniform inflow based on *.grd files exported from WAsP.

  • XRSite: The flexible general base class behind all Sites.

For more information on these classes, please see the API reference on the Site object.

UniformWeibullSite

[4]:
from py_wake.site import UniformWeibullSite

#specifying the necessary parameters for the UniformWeibullSite object
site = UniformWeibullSite(p_wd = [.20,.25,.35,.25],                         # sector frequencies
                          a = [9.176929,  9.782334,  9.531809,  9.909545],  # Weibull scale parameter
                          k = [2.392578, 2.447266, 2.412109, 2.591797],     # Weibull shape parameter
                          ti = 0.1                                          # turbulence intensity, optional
                         )

WaspGridSite

[5]:
from py_wake.site import WaspGridSite
from py_wake.examples.data.ParqueFicticio import ParqueFicticio_path

site = WaspGridSite.from_wasp_grd(ParqueFicticio_path)

XRSite

The XRSite is the most general and flexible Site. For the input dataset there are some required and optional data variables, such as:

  • Required data variables:

    • P: probability of flow case(s)

    or

    • Weibull_A: Weibull scale parameter(s)

    • Weibull_k: Weibull shape parameter(s)

    • Sector_frequency: Probability of each wind direction sector

  • Optional data variables:

    • WS: Wind speed, if not present, the reference wind speed ws is used

    • Speedup: Factor multiplied to the wind speed

    • Turning: Wind direction turning

    • TI: Turbulence intensity

    • xxx: Custom variables needed by the wind turbines to compute power, ct or loads

  • Each data variable may be constant or depend on a combination of the following inputs (Note, the input variables must be ordered according to the list, i.e. P(wd,ws) is ok, while P(ws,wd) is not):

    • i: Wind turbine position (one position per wind turbine)

    • x,y: Gridded 2d position

    • x,y,h: Gridded 3d position

    • time: Time

    • wd: Refernce wind direction

    • ws : Reference wind speed

[6]:
from py_wake.site import XRSite
from py_wake.site.shear import PowerShear
import xarray as xr
import numpy as np
from py_wake.utils import weibull
from numpy import newaxis as na

f = [0.036, 0.039, 0.052, 0.07, 0.084, 0.064, 0.086, 0.118, 0.152, 0.147, 0.1, 0.052]
A = [9.177, 9.782, 9.532, 9.91, 10.043, 9.594, 9.584, 10.515, 11.399, 11.687, 11.637, 10.088]
k = [2.393, 2.447, 2.412, 2.592, 2.756, 2.596, 2.584, 2.549, 2.471, 2.607, 2.627, 2.326]
wd = np.linspace(0, 360, len(f), endpoint=False)
ti = .1

# Site with constant wind speed, sector frequency, constant turbulence intensity and power shear
uniform_site = XRSite(
    ds=xr.Dataset(data_vars={'WS': 10, 'P': ('wd', f), 'TI': ti},
                  coords={'wd': wd}),
    shear=PowerShear(h_ref=100, alpha=.2))

# Site with wind direction dependent weibull distributed wind speed
uniform_weibull_site = XRSite(
    ds=xr.Dataset(data_vars={'Sector_frequency': ('wd', f), 'Weibull_A': ('wd', A), 'Weibull_k': ('wd', k), 'TI': ti},
                  coords={'wd': wd}))

# Site with a speedup and a turning value per WT
x_i, y_i = np.arange(5) * 100, np.zeros(5)  # WT positions

complex_fixed_pos_site = XRSite(
    ds=xr.Dataset(
        data_vars={'Speedup': ('i', np.arange(.8, 1.3, .1)),
                   'Turning': ('i', np.arange(-2, 3)),
                   'P': ('wd', f)},
        coords={'i': np.arange(5), 'wd': wd}),
    initial_position=np.array([x_i, y_i]).T)

# Site with gridded speedup information
complex_grid_site = XRSite(
    ds=xr.Dataset(
        data_vars={'Speedup': (['x', 'y'], np.arange(.8, 1.4, .1).reshape((3, 2))),
                   'P': ('wd', f)},
        coords={'x': [0, 500, 1000], 'y': [0, 500], 'wd': wd}))

# Site with ws dependent speedup and wd- and ws distributed probability
P_ws = weibull.cdf(np.array([3, 5, 7, 9, 11, 13]), 10, 2) - weibull.cdf(np.array([0, 3, 5, 7, 9, 11]), 10, 2)
P_wd_ws = P_ws[na, :] * np.array(f)[:, na]

complex_ws_site = XRSite(
    ds=xr.Dataset(
        data_vars={'Speedup': (['ws'], np.arange(.8, 1.4, .1)),
                   'P': (('wd', 'ws'), P_wd_ws), 'TI': ti},
        coords={'ws': [1.5, 4, 6, 8, 10, 12], 'wd': wd}))

Gridded non-uniform wind resources as time series with XRSite

This example creates a site with 2D non-uniform time series resources for wind speed (ws), wind direction (wd), and turbulence intensity (ti). The data is provided as arrays with dimensions corresponding to spatial coordinates (x, y) and time.

[7]:
site_x, site_y = np.meshgrid(np.arange(0.1, 1000, 100), np.arange(0.1, 2000, 100))
site_x, site_y = site_x.flatten(), site_y.flatten()
site_time = np.arange(100)
site_ws = np.random.uniform(3.0, 21.0, (len(site_x), len(site_y), len(site_time)))
site_wd = np.random.uniform(0.0, 360.0, (len(site_x), len(site_y), len(site_time)))
ds = xr.Dataset(
    data_vars=dict(
        WS=(["x", "y", "time"], site_ws),
        WD=(["x", "y", "time"], site_wd),
        TI=(["x", "y", "time"], np.ones_like(site_ws) * 0.1),  # hardcoded TI=0.1
        P=1,  # deterministic wind resource
    ),
    coords=dict(
        x=("x", site_x),
        y=("y", site_y),
        time=("time", site_time),
    ),
)
non_uniform_ts_site = XRSite(ds)
wss_at_mean_loc = non_uniform_ts_site.local_wind(
    site_x.mean(), site_y.mean(), time=site_time
)["WS_ilk"]
print(f"Mean wind speed at the mean location: {wss_at_mean_loc.mean():.2f} m/s")

# check the map of the mean wind speed at the site
mean_resource = ds.WS.mean(dim="time").values
plt.contourf(site_x, site_y, mean_resource)
plt.colorbar()
plt.title("Mean wind speed [m/s]")
plt.xlabel("x [m]")
_ = plt.ylabel("y [m]")
Mean wind speed at the mean location: 12.08 m/s
../_images/notebooks_Site_16_1.png

Wake effects from neighbouring wind farms

In some cases, calculation of wake interaction between the wind farm to optimize and neighbouring wind farms considerably slow down an optimization work flow. To avoid this, a site, which includes wake effects from neighbouring wind farms, can be pre-generated and used for the optimization.

The speed up of this solution depends on the number of turbines in both the current and neighbouring wind farms, as well as the type of sites. If the original site is a uniform site, then a pre-generated site with wake effects from neighbouring wind farms may slow down the workflow as it adds interpolation of inflow characteristics in space.

Note also, that a pre-generated site with wake effects from neighbouring wind farms is only eqivalent to the full simulation if the applied deficit model uses the effective wind speed (some models have an option to switch between effective and free-stream local wind speed).

[8]:
# import and setup site and windTurbines
from py_wake.examples.data.iea37 import IEA37Site, IEA37_WindTurbines
from py_wake.deficit_models.gaussian import BastankhahGaussianDeficit
from py_wake.wind_turbines import WindTurbine, WindTurbines
from py_wake.wind_farm_models import PropagateDownwind
from py_wake.superposition_models import LinearSum

site = IEA37Site(16)

# setup current, neighbour and all positions
wt_x, wt_y = site.initial_position.T
neighbour_x, neighbour_y = wt_x-4000, wt_y
all_x, all_y = np.r_[wt_x,neighbour_x], np.r_[wt_y,neighbour_y]

windTurbines = WindTurbines.from_WindTurbine_lst([IEA37_WindTurbines(),IEA37_WindTurbines()])
windTurbines._names = ["Current wind farm","Neighbour wind farm"]
types = [0]*len(wt_x) + [1]*len(neighbour_x)

wf_model = PropagateDownwind(site, windTurbines,
                             wake_deficitModel=BastankhahGaussianDeficit(use_effective_ws=True),
                             superpositionModel=LinearSum())

# Consider wd=270 +/- 30 deg only
wd_lst = np.arange(240,301)

[9]:
#plotting the wake maps for the desired flow case
wsp = 9.8
wdir = 267

plt.figure(figsize=(16, 6))
wf_model(all_x, all_y, type=types, wd=wdir, ws=wsp, h=110).flow_map().plot_wake_map()
plt.xlabel('x [m]')
plt.ylabel('y [m]')
plt.title('Wake map for'+ f' {wdir} deg and {wsp} m/s')
[9]:
Text(0.5, 1.0, 'Wake map for 267 deg and 9.8 m/s')
../_images/notebooks_Site_19_1.png

Now, we run the simulation of all wind turbines and calculate AEP of current wind farm

[10]:
print("Total AEP: %f GWh"%wf_model(all_x, all_y, type=types, ws=[wsp], wd=wd_lst).aep().isel(wt=np.arange(len(wt_x))).sum())
Total AEP: 85.187662 GWh

We can also calculate the AEP of the current wind farm by enclosing it in a flow box and setting up a new wind farm model

[11]:
#making a flow box covering the area of interest (i.e the current wind farm + 100m)

ext = 1000
flow_box = wf_model(neighbour_x, neighbour_y, wd=wd_lst).flow_box(
    x=np.linspace(min(wt_x) - ext, max(wt_x) + ext, 101),
    y=np.linspace(min(wt_y) - ext, max(wt_y) + ext, 101),
    h=110)

#creating new site based on the flow box

from py_wake.site.xrsite import XRSite
wake_site = XRSite.from_flow_box(flow_box)

Now, we plot the “free-stream” inflow wind speed of the current wind farm.

[12]:
plt.figure(figsize=(16, 6))
wake_site.ds.WS.sel(wd=267).plot(y='y', cmap = 'Blues_r')
windTurbines.plot(all_x, all_y, types, wd=270)
../_images/notebooks_Site_25_0.png

Then, we setup a new wind farm model with the new pre-generated site and calculate the AEP.

[13]:
wf_model_wake_site = PropagateDownwind(wake_site, windTurbines,
                                       wake_deficitModel=BastankhahGaussianDeficit(use_effective_ws=True),
                                       superpositionModel=LinearSum())
[14]:
print("Total AEP: %f GWh"%wf_model_wake_site(wt_x, wt_y, ws=[wsp], wd=wd_lst).aep().sum())
Total AEP: 85.187032 GWh

Note that the AEP is not exactly equal due to interpolation errors. The discrepancy can be lowered by increasing the resolution of the flow box.

Lastly, we plot the flow map of the current wind farm with the selected flow box.

[15]:
plt.figure(figsize=(16, 6))
wf_model_wake_site(wt_x, wt_y, wd=wdir, ws=wsp, h=110).flow_map().plot_wake_map()
windTurbines.plot(neighbour_x, neighbour_y, type=1, wd=wdir)
plt.xlabel('x [m]')
plt.ylabel('y [m]')
[15]:
Text(0, 0.5, 'y [m]')
../_images/notebooks_Site_30_1.png

Local wind

The method local_wind is used to calculate the local wind in a wind farm given certain turbine positions or coordinates. The class returns a LocalWind-dictionary.

[16]:
localWinds = {name: site.local_wind(x=site.initial_position[:,0],          # x position
                                    y = site.initial_position[:,1],        # y position
                                    h=site.initial_position[:,0]*0+70,     # height
                              ws=None,                                       # defaults to 3,4,..,25
                              wd=None,                                       # defaults to 0,1,...,360
                              ) for name, site in sites.items()}

LocalWind.coords contains the current coordinates, e.g.:

  • i: Point number. Points can be wind turbine position or just points in a flow map

  • wd: Ambient reference wind direction

  • ws: Ambient reference wind speed

  • x,y,h: position and height of points

while the dictionary itself contains some data variables:

  • WD: Local wind direction

  • WS: Local wind speed

  • TI: Local turbulence intensity

  • P: Probability of flow case (wind direction and wind speed)

The IEA37 site has 16 wind turbines on a uniform site with a fixed wind speed of 9.8 m/s and the data variables therefore only depend on wind direction.

[17]:
print (localWinds['IEA37'].coords.keys())
localWinds['IEA37'].P
dict_keys(['wd', 'ws', 'i', 'x', 'y', 'h'])
[17]:
<xarray.DataArray (wd: 360)> Size: 3kB
array([0.00111111, 0.00111111, 0.00111111, 0.00111111, 0.00111111,
       0.00111111, 0.00111111, 0.00111111, 0.00111111, 0.00111111,
       0.00111111, 0.00111111, 0.00106667, 0.00106667, 0.00106667,
       0.00106667, 0.00106667, 0.00106667, 0.00106667, 0.00106667,
       0.00106667, 0.00106667, 0.00106667, 0.00106667, 0.00106667,
       0.00106667, 0.00106667, 0.00106667, 0.00106667, 0.00106667,
       0.00106667, 0.00106667, 0.00106667, 0.00106667, 0.00128889,
       0.00128889, 0.00128889, 0.00128889, 0.00128889, 0.00128889,
       0.00128889, 0.00128889, 0.00128889, 0.00128889, 0.00128889,
       0.00128889, 0.00128889, 0.00128889, 0.00128889, 0.00128889,
       0.00128889, 0.00128889, 0.00128889, 0.00128889, 0.00128889,
       0.00128889, 0.00128889, 0.0016    , 0.0016    , 0.0016    ,
       0.0016    , 0.0016    , 0.0016    , 0.0016    , 0.0016    ,
       0.0016    , 0.0016    , 0.0016    , 0.0016    , 0.0016    ,
       0.0016    , 0.0016    , 0.0016    , 0.0016    , 0.0016    ,
       0.0016    , 0.0016    , 0.0016    , 0.0016    , 0.0028    ,
       0.0028    , 0.0028    , 0.0028    , 0.0028    , 0.0028    ,
       0.0028    , 0.0028    , 0.0028    , 0.0028    , 0.0028    ,
       0.0028    , 0.0028    , 0.0028    , 0.0028    , 0.0028    ,
       0.0028    , 0.0028    , 0.0028    , 0.0028    , 0.0028    ,
...
       0.00946667, 0.00946667, 0.00946667, 0.00946667, 0.00946667,
       0.00946667, 0.00946667, 0.00946667, 0.00946667, 0.00946667,
       0.00946667, 0.00946667, 0.00946667, 0.00946667, 0.00946667,
       0.00946667, 0.00946667, 0.00946667, 0.00946667, 0.00946667,
       0.00946667, 0.00946667, 0.00204444, 0.00204444, 0.00204444,
       0.00204444, 0.00204444, 0.00204444, 0.00204444, 0.00204444,
       0.00204444, 0.00204444, 0.00204444, 0.00204444, 0.00204444,
       0.00204444, 0.00204444, 0.00204444, 0.00204444, 0.00204444,
       0.00204444, 0.00204444, 0.00204444, 0.00204444, 0.00142222,
       0.00142222, 0.00142222, 0.00142222, 0.00142222, 0.00142222,
       0.00142222, 0.00142222, 0.00142222, 0.00142222, 0.00142222,
       0.00142222, 0.00142222, 0.00142222, 0.00142222, 0.00142222,
       0.00142222, 0.00142222, 0.00142222, 0.00142222, 0.00142222,
       0.00142222, 0.00142222, 0.00097778, 0.00097778, 0.00097778,
       0.00097778, 0.00097778, 0.00097778, 0.00097778, 0.00097778,
       0.00097778, 0.00097778, 0.00097778, 0.00097778, 0.00097778,
       0.00097778, 0.00097778, 0.00097778, 0.00097778, 0.00097778,
       0.00097778, 0.00097778, 0.00097778, 0.00097778, 0.00111111,
       0.00111111, 0.00111111, 0.00111111, 0.00111111, 0.00111111,
       0.00111111, 0.00111111, 0.00111111, 0.00111111, 0.00111111])
Coordinates:
  * wd       (wd) int64 3kB 0 1 2 3 4 5 6 7 ... 352 353 354 355 356 357 358 359
Attributes:
    description:  Probability of wind flow case (i.e. wind direction and wind...

The Hornsrev1 site has 80 wind turbines on a uniform site and the data variables therefore depend on wind direction and wind speed.

[18]:
localWinds['Hornsrev1'].P
[18]:
<xarray.DataArray (wd: 360, ws: 23)> Size: 66kB
array([[6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08],
       [6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08],
       [6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08],
       ...,
       [6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08],
       [6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08],
       [6.14682576e-05, 8.55902794e-05, 1.05949549e-04, ...,
        1.41427496e-07, 5.73800241e-08, 2.19294217e-08]])
Coordinates:
  * wd       (wd) int64 3kB 0 1 2 3 4 5 6 7 ... 352 353 354 355 356 357 358 359
  * ws       (ws) int64 184B 3 4 5 6 7 8 9 10 11 ... 17 18 19 20 21 22 23 24 25
Attributes:
    description:  Probability of wind flow case (i.e. wind direction and wind...

Finally, the ParqueFicticio site has 8 turbines in a complex terrain and the data variables therefore depend on wind direction, wind speed, and position.

[19]:
localWinds['ParqueFicticio'].P
[19]:
<xarray.DataArray (i: 8, wd: 360, ws: 23)> Size: 530kB
array([[[3.30521189e-04, 2.90945174e-04, 2.24051965e-04, ...,
         2.17151164e-12, 4.18358259e-13, 7.59823194e-14],
        [3.29678728e-04, 2.89724248e-04, 2.22255957e-04, ...,
         1.42378793e-12, 2.62971871e-13, 4.56948366e-14],
        [3.28803760e-04, 2.88465466e-04, 2.20425575e-04, ...,
         9.24548089e-13, 1.63531488e-13, 2.71554012e-14],
        ...,
        [3.30774594e-04, 2.93358503e-04, 2.28869097e-04, ...,
         6.51548667e-12, 1.39516685e-12, 2.82983824e-13],
        [3.30714479e-04, 2.92588913e-04, 2.27298658e-04, ...,
         4.55200242e-12, 9.41737928e-13, 1.84263977e-13],
        [3.30630133e-04, 2.91784558e-04, 2.25692881e-04, ...,
         3.15619870e-12, 6.30371964e-13, 1.18883000e-13]],

       [[3.26402880e-04, 2.87997698e-04, 2.21675061e-04, ...,
         1.33860940e-12, 2.44544435e-13, 4.19923483e-14],
        [3.25122046e-04, 2.86441420e-04, 2.19674768e-04, ...,
         8.78625057e-13, 1.53854068e-13, 2.52708344e-14],
        [3.23807130e-04, 2.84847122e-04, 2.17641857e-04, ...,
         5.71244313e-13, 9.57776275e-14, 1.50306673e-14],
...
        [2.67779644e-04, 2.42876825e-04, 1.93108505e-04, ...,
         4.16918542e-12, 8.45231139e-13, 1.61577818e-13],
        [2.64604401e-04, 2.39695129e-04, 1.89957454e-04, ...,
         2.80824529e-12, 5.47526848e-13, 1.00466686e-13],
        [2.61389307e-04, 2.36466495e-04, 1.86766787e-04, ...,
         1.87054990e-12, 3.50331881e-13, 6.16267761e-14]],

       [[2.68959764e-04, 2.42025369e-04, 1.89572325e-04, ...,
         1.01396181e-12, 1.78631113e-13, 2.94758748e-14],
        [2.67147742e-04, 2.40179522e-04, 1.87608989e-04, ...,
         7.02329489e-13, 1.19181235e-13, 1.89068219e-14],
        [2.65308930e-04, 2.38304775e-04, 1.85622456e-04, ...,
         4.82828262e-13, 7.88535765e-14, 1.20155220e-14],
        ...,
        [2.81699963e-04, 2.54713471e-04, 2.01754861e-04, ...,
         3.67828002e-12, 7.34988224e-13, 1.38414208e-13],
        [2.77506454e-04, 2.50543880e-04, 1.97741116e-04, ...,
         2.42517629e-12, 4.65286805e-13, 8.39650246e-14],
        [2.73260191e-04, 2.46314760e-04, 1.93680118e-04, ...,
         1.57862026e-12, 2.90422137e-13, 5.01516262e-14]]])
Coordinates:
  * wd       (wd) int64 3kB 0 1 2 3 4 5 6 7 ... 352 353 354 355 356 357 358 359
  * ws       (ws) int64 184B 3 4 5 6 7 8 9 10 11 ... 17 18 19 20 21 22 23 24 25
  * i        (i) int64 64B 0 1 2 3 4 5 6 7
Attributes:
    description:  Probability of wind flow case (i.e. wind direction and wind...

Wind speeds at the wind turbines for reference wind speed of 3m/s (k=0):

  • IEA37: Constant wind speed of 9.8m/s

  • Hornsrev1: Constant wind speed over the site, 3 m/s

  • ParqueFicticio: Winds speed depends on both wind direction and position

[20]:
for name, lw in localWinds.items():
    print (name)
    print (lw.WS.values, 'm/s')
    print ("="*100)
IEA37
9.8 m/s
====================================================================================================
Hornsrev1
[ 3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25] m/s
====================================================================================================
ParqueFicticio
[[[ 3.78471012  5.04628015  6.30785019 ... 29.01611089 30.27768093
   31.53925096]
  [ 3.80282588  5.07043451  6.33804314 ... 29.15499845 30.42260708
   31.69021571]
  [ 3.82094165  5.09458887  6.36823609 ... 29.29388601 30.56753323
   31.84118045]
  ...
  [ 3.73730114  4.98306819  6.22883524 ... 28.6526421  29.89840915
   31.1441762 ]
  [ 3.75310413  5.00413885  6.25517356 ... 28.77379836 30.02483307
   31.27586779]
  [ 3.76890713  5.0252095   6.28151188 ... 28.89495463 30.151257
   31.40755938]]

 [[ 3.95569235  5.27425647  6.59282059 ... 30.3269747  31.64553882
   32.96410294]
  [ 3.97160588  5.29547451  6.61934314 ... 30.44897845 31.77284708
   33.0967157 ]
  [ 3.98751942  5.31669256  6.64586569 ... 30.5709822  31.90015533
   33.22932847]
  ...
  [ 3.9194794   5.22597253  6.53246567 ... 30.04934207 31.35583521
   32.66232834]
  [ 3.93155038  5.24206718  6.55258397 ... 30.14188628 31.45240308
   32.76291987]
  [ 3.94362137  5.25816182  6.57270228 ... 30.23443049 31.54897095
   32.8635114 ]]

 [[ 3.54177811  4.72237081  5.90296351 ... 27.15363216 28.33422487
   29.51481757]
  [ 3.56318035  4.75090714  5.93863392 ... 27.31771603 28.50544282
   29.6931696 ]
  [ 3.5845826   4.77944346  5.97430433 ... 27.4817999  28.67666076
   29.87152163]
  ...
  [ 3.53682328  4.71576437  5.89470547 ... 27.11564514 28.29458624
   29.47352733]
  [ 3.53847489  4.71796652  5.89745815 ... 27.12830748 28.30779911
   29.48729074]
  [ 3.5401265   4.72016867  5.90021083 ... 27.14096982 28.32101199
   29.50105416]]

 ...

 [[ 3.38782152  4.51709536  5.6463692  ... 25.97329831 27.10257215
   28.23184598]
  [ 3.39601996  4.52802661  5.66003327 ... 26.03615302 27.16815968
   28.30016633]
  [ 3.4042184   4.53895787  5.67369734 ... 26.09900774 27.23374721
   28.36848668]
  ...
  [ 3.41634561  4.55512748  5.69390936 ... 26.19198304 27.33076491
   28.46954678]
  [ 3.40683758  4.54245011  5.67806264 ... 26.11908813 27.25470065
   28.39031318]
  [ 3.39732955  4.52977273  5.66221592 ... 26.04619322 27.1786364
   28.31107958]]

 [[ 2.90165596  3.86887461  4.83609327 ... 22.24602903 23.21324768
   24.18046634]
  [ 2.90889396  3.87852528  4.8481566  ... 22.30152035 23.27115167
   24.24078299]
  [ 2.91613196  3.88817594  4.86021993 ... 22.35701167 23.32905566
   24.30109964]
  ...
  [ 2.93079949  3.90773265  4.88466582 ... 22.46946275 23.44639592
   24.42332908]
  [ 2.92108498  3.89477997  4.86847497 ... 22.39498485 23.36867984
   24.34237483]
  [ 2.91137047  3.88182729  4.85228412 ... 22.32050694 23.29096376
   24.26142059]]

 [[ 2.93723526  3.91631367  4.89539209 ... 22.51880362 23.49788204
   24.47696046]
  [ 2.94254094  3.92338792  4.9042349  ... 22.55948056 23.54032754
   24.52117452]
  [ 2.94784663  3.93046217  4.91307772 ... 22.6001575  23.58277304
   24.56538859]
  ...
  [ 2.97948279  3.97264372  4.96580465 ... 22.84270139 23.83586232
   24.82902325]
  [ 2.96540028  3.95386704  4.9423338  ... 22.73473547 23.72320223
   24.71166898]
  [ 2.95131777  3.93509036  4.91886294 ... 22.62676954 23.61054213
   24.59431472]]] m/s
====================================================================================================

The ParqueFicticio site models variations within the site, so the local wind speed varies over the area.

[21]:
s = sites["ParqueFicticio"]
x = np.linspace(262878,264778,300)
y = np.linspace(6504714,6506614,300)
X,Y = np.meshgrid(x,y)
lw = s.local_wind(X.flatten(),Y.flatten(),30, ws=[10],wd=[0])
Z = lw.WS_ilk.reshape(X.shape)
c = plt.contourf(X,Y,Z, levels=100)
plt.colorbar(c,label='Wind speed [m/s]')
plt.title("Local wind speed at 10m/s and 0deg")
plt.xlabel('x [m]')
plt.ylabel('y [m]')
plt.axis('equal')
[21]:
(262878.0, 264778.0, 6504714.0, 6506614.0)
../_images/notebooks_Site_43_1.png

Distance

We can also calculate the distance between points of a specific site for either flat or complex terrain.

For the IEA37Site and the Hornsrev1 sites the distances between points are straight line distances, as these sites are characterized by flat terrain.

For the ParqueFicticioSite, on the other hand, the down-wind distance is larger as it follows the non-flat terrain.

[22]:
wd = [0, 30,90] # wind direction at source

for name, site in sites.items():
    print ("------- %s -------"%name)
    wt_x, wt_y = site.initial_position[0]
    site.distance.setup(src_x_ilk=[wt_x, wt_x], src_y_ilk=[wt_y, wt_y-1000], src_h_ilk=[70,90], src_z_ilk=[0,0]) # wt2 1000m to the south
    dw_ijlk, cw_ijlk, dh_ijlk = site.distance(wd_l=wd, src_idx=[0], dst_idx=[[1,1,1]])


    print ('Wind direction: \t\t%d deg\t\t%d deg\t\t%d deg'%tuple(wd))
    print ('Down wind distance [m]: \t%.1f\t\t%.1f\t\t%.1f'%tuple(dw_ijlk[0,0,:,0]))
    print ('Cross wind distance [m]: \t%.1f\t\t%.1f\t\t%.1f'%tuple(cw_ijlk[0,0,:,0]))
    print ('Height difference [m]: \t\t%.1f\t\t%.1f\t\t%.1f'%tuple(dh_ijlk[0,0,:,0]))
    print()
------- IEA37 -------
Wind direction:                 0 deg           30 deg          90 deg
Down wind distance [m]:         1000.0          866.0           0.0
Cross wind distance [m]:        0.0             500.0           1000.0
Height difference [m]:          20.0            20.0            20.0

------- Hornsrev1 -------
Wind direction:                 0 deg           30 deg          90 deg
Down wind distance [m]:         1000.0          866.0           0.0
Cross wind distance [m]:        0.0             500.0           1000.0
Height difference [m]:          20.0            20.0            20.0

------- ParqueFicticio -------
Wind direction:                 0 deg           30 deg          90 deg
Down wind distance [m]:         1023.6          886.5           -0.0
Cross wind distance [m]:        0.0             500.0           1000.0
Height difference [m]:          20.0            20.0            20.0

Wind resource distribution plots

The Site object has a few plot function to visualize its properties, mainly the wind resource given by the wind rose and the probability functions.

[23]:
import matplotlib.pyplot as plt
site = sites['Hornsrev1']

Plotting wind rose.

[24]:
_ = site.plot_wd_distribution(n_wd=12, ws_bins=[0,5,10,15,20,25])
../_images/notebooks_Site_50_0.png

Plotting probability density function for the four sectors studied.

[25]:
_ = site.plot_ws_distribution(wd=[0,90,180,270])
../_images/notebooks_Site_52_0.png

Plotting probablity density function for the four sector studied \(\pm\) 45 degrees.

If include_wd_distribution=true, the wind speed probability distributions are multiplied by the wind direction probability.

The sector size is set to 360 / len(wd). This only makes sense if the wd array is evenly distributed

[26]:
_ = site.plot_ws_distribution(wd=[0,90,180,270], include_wd_distribution=True)
../_images/notebooks_Site_54_0.png