Skip to content
Snippets Groups Projects
Commit 5fc939e4 authored by Mads M. Pedersen's avatar Mads M. Pedersen
Browse files

update site docs with description of custom sites

parent 56c6083c
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags:
# Site
%% Cell type:markdown id: tags:
For a given position, reference wind speed (WS<sub>ref</sub>) and wind direction (WD<sub>ref</sub>), `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).
%% Cell type:markdown id: tags:
### Predefined example sites
## 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
%% Cell type:code id: tags:
``` python
# Install PyWake if needed
try:
import py_wake
except ModuleNotFoundError:
!pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/PyWake.git
```
%% Cell type:code id: tags:
``` python
from py_wake.examples.data.hornsrev1 import Hornsrev1Site
from py_wake.examples.data.iea37 import IEA37Site
from py_wake.examples.data.ParqueFicticio import ParqueFicticioSite
import numpy as np
import matplotlib.pyplot as plt
sites = {"IEA37": IEA37Site(n_wt=16),
"Hornsrev1": Hornsrev1Site(),
"ParqueFicticio": ParqueFicticioSite()}
```
%% Cell type:markdown id: tags:
## Define your own site
You can define your own site using one of the `Site` classes:
- [UniformWeibullSite](#UniformWeibullSite): Site with uniform sector-dependent weibull distributed wind speed
- [WaspGridSite](#WaspGridSite): Site with gridded non-uniform inflow based on *.grd files exported from WAsP
- [XRSite](#XRSite): The flexible general base class behind all Sites
%% Cell type:markdown id: tags:
### UniformWeibullSite
%% Cell type:code id: tags:
``` python
from py_wake.site import UniformWeibullSite
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 (not needed in all cases)
)
```
%% Cell type:markdown id: tags:
### WaspGridSite
%% Cell type:code id: tags:
``` python
from py_wake.site import WaspGridSite
from py_wake.examples.data.ParqueFicticio import ParqueFicticio_path
site = WaspGridSite.from_wasp_grd(ParqueFicticio_path)
```
%% Cell type:markdown id: tags:
### XRSite
The `XRSite` is the most general and flexible `Site`. It takes a xarray dataset with some required and optional data variables. Each variable may be constant or depend on any combination of:
- ws: Reference wind speed
- wd: Refernce wind direction
- i: Wind turbine position (one position per wind turbine)
- x,y: Gridded 2d position
- x,y,h: Gridded 3d position
- time: Time
**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
**Examples**
Examples can be found in the top of https://gitlab.windenergy.dtu.dk/TOPFARM/PyWake/-/blob/master/py_wake/tests/test_sites/test_xrsite.py
%% Cell type:markdown id: tags:
### Local wind
The method `local_wind` returns a `LocalWind`-xarray dataset with a few additional methods:
%% Cell type:code id: tags:
``` python
localWinds = {name: site.local_wind(x_i=site.initial_position[:,0], # x position
y_i = site.initial_position[:,1], # y position
h_i=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()}
```
%% Cell type:markdown id: tags:
`LocalWind` objects have some coordinates:
- 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
and data variables:
- WD: Local wind direction
- WS: Local wind speed
- TI: Local turbulence intensity
- P: Probability of flow case (wind direction and wind speed)
%% Cell type:markdown id: tags:
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 depends on wind direction.
%% Cell type:code id: tags:
``` python
localWinds['IEA37']
```
%% Output
<xarray.LocalWind>
Dimensions: (i: 16, wd: 360, ws: 1)
Coordinates:
* ws (ws) float64 9.8
* wd (wd) int32 0 1 2 3 4 5 6 7 8 ... 352 353 354 355 356 357 358 359
* i (i) int32 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
x (i) float64 0.0 650.0 200.9 -525.9 ... -401.7 401.7 1.052e+03
y (i) float64 0.0 0.0 618.2 382.1 ... -1.236e+03 -1.236e+03 -764.1
h (i) float64 70.0 70.0 70.0 70.0 70.0 ... 70.0 70.0 70.0 70.0 70.0
Data variables:
WS (ws) float64 9.8
WD (wd) int32 0 1 2 3 4 5 6 7 8 ... 352 353 354 355 356 357 358 359
TI float64 0.075
ws_lower (ws) float64 9.3
ws_upper (ws) float64 10.3
P (wd) float64 0.001111 0.001111 0.001111 ... 0.001111 0.001111
Attributes:
wd_bin_size: 1
%% Cell type:markdown id: tags:
The `Hornsrev1` site has 80 wind turbines on a uniform site and the data variables therefore depends on wind direction and wind speed.
%% Cell type:code id: tags:
``` python
localWinds['Hornsrev1']
```
%% Output
<xarray.LocalWind>
Dimensions: (i: 80, wd: 360, ws: 23)
Coordinates:
* ws (ws) int32 3 4 5 6 7 8 9 10 11 ... 18 19 20 21 22 23 24 25
* wd (wd) int32 0 1 2 3 4 5 6 7 ... 353 354 355 356 357 358 359
* i (i) int32 0 1 2 3 4 5 6 7 8 ... 71 72 73 74 75 76 77 78 79
x (i) float64 4.24e+05 4.24e+05 ... 4.294e+05 4.295e+05
y (i) float64 6.151e+06 6.151e+06 ... 6.148e+06 6.148e+06
h (i) float64 70.0 70.0 70.0 70.0 ... 70.0 70.0 70.0 70.0
Data variables:
WS (ws) int32 3 4 5 6 7 8 9 10 11 ... 18 19 20 21 22 23 24 25
WD (wd) int32 0 1 2 3 4 5 6 7 ... 353 354 355 356 357 358 359
TI float64 0.1
ws_lower (ws) float64 2.5 3.5 4.5 5.5 6.5 ... 21.5 22.5 23.5 24.5
ws_upper (ws) float64 3.5 4.5 5.5 6.5 7.5 ... 22.5 23.5 24.5 25.5
Weibull_A (wd) float64 9.177 9.177 9.177 9.177 ... 9.177 9.177 9.177
Weibull_k (wd) float64 2.393 2.393 2.393 2.393 ... 2.393 2.393 2.393
Sector_frequency (wd) float64 0.001199 0.001199 ... 0.001199 0.001199
P (wd, ws) float64 6.147e-05 8.559e-05 ... 2.193e-08
Attributes:
wd_bin_size: 1
%% Cell type:markdown id: tags:
Finally, the `ParqueFicticio` site has 8 turbines in a complex terrain and the data variables therefore dependents on both wind direction, wind speed and position
%% Cell type:code id: tags:
``` python
localWinds['ParqueFicticio']
```
%% Output
<xarray.LocalWind>
Dimensions: (i: 8, wd: 360, ws: 23)
Coordinates:
* i (i) int32 0 1 2 3 4 5 6 7
* wd (wd) int32 0 1 2 3 4 5 6 7 ... 353 354 355 356 357 358 359
* ws (ws) int32 3 4 5 6 7 8 9 10 11 ... 18 19 20 21 22 23 24 25
x (i) float64 2.637e+05 2.639e+05 ... 2.64e+05 2.639e+05
y (i) float64 6.507e+06 6.506e+06 ... 6.505e+06 6.505e+06
h (i) float64 70.0 70.0 70.0 70.0 70.0 70.0 70.0 70.0
Data variables:
WS (i, wd, ws) float64 3.785 5.046 6.308 ... 23.61 24.59
WD (i, wd) float64 9.367 10.34 11.32 ... 355.2 356.5 357.8
ws_lower (i, wd, ws) float64 3.154 4.415 5.677 ... 22.13 23.12 24.1
ws_upper (i, wd, ws) float64 4.415 5.677 6.939 ... 23.12 24.1 25.09
Weibull_A (i, wd) float64 5.363 5.365 5.368 5.37 ... 4.382 4.341 4.3
Weibull_k (i, wd) float64 1.807 1.815 1.822 ... 1.827 1.835 1.842
Sector_frequency (i, wd) float64 0.001768 0.001752 ... 0.001512 0.001479
P (i, wd, ws) float64 0.0003305 0.0002909 ... 5.015e-14
TI (i, wd, ws) float64 0.2759 0.2326 0.2066 ... 0.1616 0.1605
Attributes:
wd_bin_size: 1
%% Cell type:markdown id: tags:
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
%% Cell type:code id: tags:
``` python
for name, lw in localWinds.items():
print (name)
print (lw.WS.isel(ws=0)) #[:8,0,0])
print ("="*100)
```
%% Output
IEA37
<xarray.DataArray 'WS' ()>
array(9.8)
Coordinates:
ws float64 9.8
Attributes:
Description: Local free-stream wind speed [m/s]
====================================================================================================
Hornsrev1
<xarray.DataArray 'WS' ()>
array(3)
Coordinates:
ws int32 3
Attributes:
Description: Local free-stream wind speed [m/s]
====================================================================================================
ParqueFicticio
<xarray.DataArray 'WS' (i: 8, wd: 360)>
array([[3.78471012, 3.80282588, 3.82094165, ..., 3.73730114, 3.75310413,
3.76890713],
[3.95569235, 3.97160588, 3.98751942, ..., 3.9194794 , 3.93155038,
3.94362137],
[3.54177811, 3.56318035, 3.5845826 , ..., 3.53682328, 3.53847489,
3.5401265 ],
...,
[3.38782152, 3.39601996, 3.4042184 , ..., 3.41634561, 3.40683758,
3.39732955],
[2.90165596, 2.90889396, 2.91613196, ..., 2.93079949, 2.92108498,
2.91137047],
[2.93723526, 2.94254094, 2.94784663, ..., 2.97948279, 2.96540028,
2.95131777]])
Coordinates:
* i (i) int32 0 1 2 3 4 5 6 7
* wd (wd) int32 0 1 2 3 4 5 6 7 8 ... 352 353 354 355 356 357 358 359
ws int32 3
x (i) float64 2.637e+05 2.639e+05 2.64e+05 ... 2.64e+05 2.639e+05
y (i) float64 6.507e+06 6.506e+06 6.506e+06 ... 6.505e+06 6.505e+06
h (i) float64 70.0 70.0 70.0 70.0 70.0 70.0 70.0 70.0
Attributes:
Description: Local free-stream wind speed [m/s]
====================================================================================================
%% Cell type:markdown id: tags:
The ParqueFicticio site models variations within the site, i.e. the local wind speed varies over the area
%% Cell type:code id: tags:
``` python
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')
```
%% Output
(262878.0, 264778.0, 6504714.0, 6506614.0)
%% Cell type:markdown id: tags:
### Distance
For the `IEA37Site` and the `Hornsrev1` the distances between points are the straight line distances, as these site types are flat.
For the ParqueFicticioSite, on the other hand, the down-wind distance is larger as it follows the non-flat terrain.
%% Cell type:code id: tags:
``` python
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_i=[wt_x, wt_x], src_y_i=[wt_y, wt_y-1000], src_h_i=[70,90]) # wt2 1000m to the south)
dw_ijl, cw_ijl, dh_ijl = site.distance(wd_il=[wd], src_idx=[0], dst_idx=[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_ijl[0,0,:]))
print ('Cross wind distance [m]: \t%.1f\t\t%.1f\t\t%.1f'%tuple(cw_ijl[0,0,:]))
print ('Height difference [m]: \t\t%.1f\t\t%.1f\t\t%.1f'%tuple(dh_ijl[0,0,:]))
print()
```
%% Output
------- 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
%% Cell type:markdown id: tags:
### Distribution plots
%% Cell type:markdown id: tags:
Site has a few plot function to visualize its properties
%% Cell type:code id: tags:
``` python
import matplotlib.pyplot as plt
site = sites['Hornsrev1']
```
%% Cell type:code id: tags:
``` python
_ = site.plot_wd_distribution(n_wd=12, ws_bins=[0,5,10,15,20,25])
```
%% Output
%% Cell type:code id: tags:
``` python
_ = site.plot_ws_distribution(wd=[0,90,180,270])
```
%% Output
%% Cell type:code id: tags:
``` python
_ = site.plot_ws_distribution(wd=[0,90,180,270], include_wd_distribution=True)
```
%% Output
......
......@@ -263,11 +263,12 @@ class UniformSite(XRSite):
constant wind speed probability of 1. Only for one fixed wind speed
"""
def __init__(self, p_wd, ti, ws=12, interp_method='nearest', shear=None, initial_position=None):
def __init__(self, p_wd, ti=None, ws=12, interp_method='nearest', shear=None, initial_position=None):
ds = xr.Dataset(
data_vars={'P': ('wd', p_wd), 'TI': ti},
data_vars={'P': ('wd', p_wd)},
coords={'wd': np.linspace(0, 360, len(p_wd), endpoint=False)})
if ti is not None:
ds['TI'] = ti
XRSite.__init__(self, ds, interp_method=interp_method, shear=shear, initial_position=initial_position,
default_ws=np.atleast_1d(ws))
......@@ -277,7 +278,7 @@ class UniformWeibullSite(XRSite):
weibull distributed wind speed
"""
def __init__(self, p_wd, a, k, ti, interp_method='nearest', shear=None):
def __init__(self, p_wd, a, k, ti=None, interp_method='nearest', shear=None):
"""Initialize UniformWeibullSite
Parameters
......@@ -288,7 +289,7 @@ class UniformWeibullSite(XRSite):
Weilbull scaling parameter of wind direction sectors
k : array_like
Weibull shape parameter
ti : float or array_like
ti : float or array_like, optional
Turbulence intensity
interp_method : 'nearest', 'linear'
p_wd, a, k, ti and alpha are interpolated to 1 deg sectors using this
......@@ -303,6 +304,8 @@ class UniformWeibullSite(XRSite):
"""
ds = xr.Dataset(
data_vars={'Sector_frequency': ('wd', p_wd), 'Weibull_A': ('wd', a), 'Weibull_k': ('wd', k), 'TI': ti},
data_vars={'Sector_frequency': ('wd', p_wd), 'Weibull_A': ('wd', a), 'Weibull_k': ('wd', k)},
coords={'wd': np.linspace(0, 360, len(p_wd), endpoint=False)})
if ti is not None:
ds['TI'] = ti
XRSite.__init__(self, ds, interp_method=interp_method, shear=shear)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment