Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import numpy as np
from numpy import newaxis as na
from abc import abstractmethod, ABC
class Shear(ABC):
@abstractmethod
def __call__(self, WS_ilk, WD_ilk, h_i):
"""Get wind speed at height
Parameters
----------
WS_ilk : array_like
wind speed
WD_ilk : array_like
wind direction
h_i : array_like
height
Returns
-------
WS_ilk : array_like
Wind speed at height h_i
"""
class NoShear(Shear):
def __call__(self, WS_ilk, WD_ilk, h_i):
return WS_ilk
class PowerShear():
def __init__(self, h_ref, alpha, interp_method='piecewise'):
self.h_ref = h_ref
from py_wake.site._site import Sector2Subsector
self.alpha = Sector2Subsector(np.atleast_1d(alpha), interp_method=interp_method)
def __call__(self, WS_ilk, WD_ilk, h_i):
WD_index_ilk = np.round(WD_ilk).astype(np.int)
wind_shear_ratio = (np.asarray(h_i) / self.h_ref)[:, na, na] ** self.alpha[WD_index_ilk]
return WS_ilk * wind_shear_ratio
# ======================================================================================================================
# Potentially the code below can be used to implement power/log shear interpolation between grid layers
# ======================================================================================================================
# class InterpolationShear(ABC):
# @abstractmethod
# def setup(self, ds):
# """"""
#
# @abstractmethod
# def __call__(self):
# """"""
#
#
# class LinearInterpolationShear():
# def setup(self, ds):
# pass
#
# def __call__(self, WS_ilk, WD_ilk, h_i):
# return WS_ilk
#
#
# class PowerInterpolationShear():
# """Apply wind shear coefficient based on speed-up factor at different
# # height and a reference far field wind shear coefficient (alpha_far)"""
#
# def __init__(self, alpha_far=.143):
# self.alpha_far = alpha_far
#
# def setup(self, ds):
# ds['wind_shear'] = copy.deepcopy(ds['spd'])
#
# heights = ds['wind_shear'].coords['z'].data
#
# # if there is only one layer, assign default value
# if len(heights) == 1:
#
# ds['wind_shear'].data = (np.zeros_like(ds['wind_shear'].data) + self.alpha_far)
#
# print('Note there is only one layer of wind resource data, ' +
# 'wind shear are assumed as uniform, i.e., {0}'.format(self.alpha_far))
# else:
# ds['wind_shear'].data[:, :, 0, :] = (self.alpha_far +
# np.log(ds['spd'].data[:, :, 0, :] / ds['spd'].data[:, :, 1, :]) /
# np.log(heights[0] / heights[1]))
#
# for h in range(1, len(heights)):
# ds['wind_shear'].data[:, :, h, :] = (
# self.alpha_far +
# np.log(ds['spd'].data[:, :, h, :] / ds['spd'].data[:, :, h - 1, :]) /
# np.log(heights[h] / heights[h - 1]))
#
# def __call__(self, WS_ilk, WD_ilk, h_i):
# ????? WS_ilk = (WS_ilk * (H_hub / self.height_ref) ** wind_shear_il[i_wt, l_wd])