Newer
Older

Mads M. Pedersen
committed
import numpy as np
from numpy import newaxis as na
from py_wake.tests import npt
from py_wake.site.distance import StraightDistance, TerrainFollowingDistance, TerrainFollowingDistance2
from py_wake.site._site import UniformSite
import pytest
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines

Mads M. Pedersen
committed
from py_wake import NOJ
from py_wake.examples.data.ParqueFicticio import ParqueFicticioSite
from py_wake.flow_map import HorizontalGrid

Mads M. Pedersen
committed

Mads M. Pedersen
committed
class FlatSite(UniformSite):

Mads M. Pedersen
committed
def __init__(self):
UniformSite.__init__(self, p_wd=[1], ti=.075)

Mads M. Pedersen
committed
class HalfCylinder(UniformSite):

Mads M. Pedersen
committed
def __init__(self, height, distance_resolution):
self.height = height

Mads M. Pedersen
committed
super().__init__(p_wd=[1], ti=0)
self.distance = TerrainFollowingDistance(distance_resolution=distance_resolution)

Mads M. Pedersen
committed
def elevation(self, x_i, y_i):
return np.sqrt(np.maximum(self.height**2 - x_i**2, 0))
class Rectangle(TerrainFollowingDistance, UniformSite):
def __init__(self, height, width, distance_resolution):
self.height = height
self.width = width

Mads M. Pedersen
committed
super().__init__(p_wd=[1], ti=0)
self.distance = TerrainFollowingDistance(distance_resolution=distance_resolution)

Mads M. Pedersen
committed
def elevation(self, x_i, y_i):
return np.where(np.abs(x_i) < self.width / 2, self.height, 0)

Mads M. Pedersen
committed
@pytest.mark.parametrize('distance', [StraightDistance(),
TerrainFollowingDistance()])
def test_flat_distances(distance):

Mads M. Pedersen
committed
x = [0, 50, 100, 100]
y = [100, 100, 100, 0]
h = [0, 10, 20, 30]
wdirs = [0, 30, 90]

Mads M. Pedersen
committed
dw_ijl, hcw_ijl, dh_ijl, dw_indices_l = distance(FlatSite(), src_x_i=x, src_y_i=y, src_h_i=h, dst_x_j=[0], dst_y_j=[0], dst_h_j=[0],
wd_il=np.array(wdirs)[na])

Mads M. Pedersen
committed
if 0:

Mads M. Pedersen
committed
distance.plot(src_x_i=x, src_y_i=y, src_h_i=h, dst_x_j=[0], dst_y_j=[0], dst_h_j=[0],

Mads M. Pedersen
committed
wd_il=np.array(wdirs)[na])
npt.assert_array_almost_equal(dw_ijl, [[[100, 86.6025404, 0]],
[[100, 111.602540, 50]],
[[100, 136.602540, 100]],
[[0, 50, 100]]])
npt.assert_array_almost_equal(hcw_ijl, [[[0, 50, 100]],
[[-50, 6.69872981, 100]],
[[-100, -36.6025404, 100]],
[[-100, -86.6025404, 0]]])
npt.assert_array_almost_equal(dh_ijl, [[[0, 0, 0]],
[[-10, -10, -10]],
[[-20, -20, -20]],
[[-30, -30, -30]]])
npt.assert_array_equal(dw_indices_l, [[2, 1, 0, 3],
[2, 1, 0, 3],
[2, 3, 1, 0]])

Mads M. Pedersen
committed
@pytest.mark.parametrize('distance', [StraightDistance(),
TerrainFollowingDistance()])
def test_flat_distances_wt2wt(distance):

Mads M. Pedersen
committed
x = [0, 50, 100]
y = [100, 100, 0]
h = [0, 10, 20]
wdirs = [0, 30]

Mads M. Pedersen
committed
dw_ijl, hcw_ijl, dh_ijl, dw_indices_l = distance(FlatSite(), src_x_i=x, src_y_i=y, src_h_i=h, dst_x_j=x, dst_y_j=y, dst_h_j=[1, 2, 3],
wd_il=np.array(wdirs)[na])

Mads M. Pedersen
committed
if 0:

Mads M. Pedersen
committed
distance.plot(src_x_i=x, src_y_i=y, src_h_i=h, dst_x_j=x, dst_y_j=y, dst_h_j=[1, 2, 3],

Mads M. Pedersen
committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
wd_ijl=np.array(wdirs)[na, na])
# check down wind distance wind from North and 30 deg
npt.assert_array_almost_equal(dw_ijl[:, :, 0], [[0, 0, 100],
[0, 0, 100],
[-100, -100, 0]])
npt.assert_array_almost_equal(dw_ijl[:, :, 1], [[0, -25, 36.60254038],
[25, 0, 61.60254038],
[-36.60254038, -61.60254038, 0]])
# check cross wind distance wind from North and 30 deg
npt.assert_array_almost_equal(hcw_ijl[:, :, 0], [[0, 50, 100],
[-50, 0, 50],
[-100, -50, 0]])
npt.assert_array_almost_equal(hcw_ijl[:, :, 1], [[0, 43.30127019, 136.60254038],
[-43.30127019, 0., 93.30127019],
[-136.60254038, -93.30127019, 0.]])
# check cross wind distance wind from North
npt.assert_array_almost_equal(dh_ijl[:, :, 0], [[1, 2, 3],
[-9, -8, -7],
[-19, -18, -17]])
# check dw indices
npt.assert_array_equal(dw_indices_l, [[1, 0, 2],
[1, 0, 2]])
def test_iea37_distances():
from py_wake.examples.data.iea37 import IEA37Site
n_wt = 16 # must be 9, 16, 36, 64
site = IEA37Site(n_wt)
x, y = site.initial_position.T

Mads M. Pedersen
committed
lw = site.local_wind(x_i=x, y_i=y,
wd=site.default_wd,
ws=site.default_ws)

Mads M. Pedersen
committed
dw_iil, hcw_iil, _, _ = site.wt2wt_distances(
x_i=x, y_i=y,
h_i=np.zeros_like(x),

Mads M. Pedersen
committed
wd_il=lw.WD_ilk.mean(2))

Mads M. Pedersen
committed
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# Wind direction.
wdir = np.rad2deg(np.arctan2(hcw_iil, dw_iil))
npt.assert_allclose(
wdir[:, 0, 0],
[180, -90, -18, 54, 126, -162, -90, -54, -18, 18, 54, 90, 126, 162, -162, -126],
atol=1e-4)
if 0:
import matplotlib.pyplot as plt
_, ax = plt.subplots()
ax.scatter(x, y)
for i, txt in enumerate(np.arange(len(x))):
ax.annotate(txt, (x[i], y[i]), fontsize='large')
def test_terrain_following_half_cylinder():
hc = HalfCylinder(height=100, distance_resolution=100000)
src_x, src_y = np.array([-100, -50, 0]), [0, 0, 0]
dst_x, dst_y = np.array([100, 200, 300, 400]), [0, 0, 0, 0]
x = np.arange(-150, 150)
dw_ijl, hcw_ijl, _, _ = hc.distances(src_x_i=src_x, src_y_i=src_y, src_h_i=src_x * 0,
dst_x_j=dst_x, dst_y_j=dst_y, dst_h_j=dst_x * 0,
wd_il=np.array([0, 90])[na])
if 0:
import matplotlib.pyplot as plt
plt.plot(x, hc.elevation(x_i=x, y_i=x * 0))
plt.plot(src_x, hc.elevation(x_i=src_x, y_i=src_y), '.')
plt.plot(dst_x, dst_y, 'o')
plt.axis('equal')
plt.show()
dist2flat = np.pi * np.array([1, 2 / 3, .5]) * 100
dist2flat = dist2flat[:, na] + (np.arange(4) * 100)
npt.assert_array_almost_equal(dw_ijl[:, :, 1], -dist2flat, 2)
npt.assert_array_almost_equal(hcw_ijl[:, :, 0], [[200., 300., 400., 500.],
[150., 250., 350., 450.],
[100., 200., 300., 400.]], 2)
# down wind distance for 0 deg and cross wind distance for 30 deg ~ 0
npt.assert_array_almost_equal(dw_ijl[:, :, 0], 0)
npt.assert_array_almost_equal(hcw_ijl[:, :, 1], 0)
def test_distance_over_rectangle():
x, y = [-100, 50], [200, -100]
windTurbines = IEA37_WindTurbines()
site = Rectangle(height=200, width=100, distance_resolution=100)

Mads M. Pedersen
committed
wf_model = NOJ(site, windTurbines)
sim_res = wf_model(x, y, wd=[270], ws=[9])

Mads M. Pedersen
committed
x_j = np.linspace(-100, 500, 100)
y_j = np.linspace(-200, 300, 100)

Mads M. Pedersen
committed
flow_map = sim_res.flow_map(HorizontalGrid(x_j, y_j))
Z = flow_map.WS_eff_xylk[:, :, 0, 0]
X, Y = flow_map.X, flow_map.Y

Mads M. Pedersen
committed
my = np.argmin(np.abs(Y[:, 0] - 200))
my2 = np.argmin(np.abs(Y[:, 0] + 100))
if 0:
import matplotlib.pyplot as plt

Mads M. Pedersen
committed
flow_map.plot_wake_map()

Mads M. Pedersen
committed
H = site.elevation(X, Y)
plt.plot(X[my], Z[my] * 10, label='wsp*10')
plt.plot(X[my2], Z[my2] * 10, label='wsp*10')
plt.contour(X, Y, H)
plt.plot(X[my, :50:4], Z[my, :50:4] * 10, '.')
plt.plot(x_j, site.elevation(x_j, x_j * 0), label='terrain level')
plt.legend()
plt.show()
ref = [9., 3.42, 3.8, 6.02, 6.17, 6.31, 6.43, 7.29, 7.35, 7.41, 7.47, 7.53, 7.58]
npt.assert_array_almost_equal(Z[my, :50:4], ref, 2)
def test_distance_plot():
x = [0, 50, 100, 100]
y = [100, 100, 100, 0]
h = [0, 10, 20, 30]
wdirs = [0, 30, 90]

Mads M. Pedersen
committed
distance = StraightDistance()
distance.plot(None, src_x_i=x, src_y_i=y, src_h_i=h, dst_x_j=[0], dst_y_j=[0], dst_h_j=[0],

Mads M. Pedersen
committed
wd_il=np.array(wdirs)[na])
if 0:
import matplotlib.pyplot as plt
plt.show()
# ======================================================================================================================
# TerrainFollowingDistance2
# ======================================================================================================================

Mads M. Pedersen
committed
class ParqueFicticioSiteTerrainFollowingDistance2(ParqueFicticioSite):
def __init__(self):
ParqueFicticioSite.__init__(self, distance=TerrainFollowingDistance2())
# def __init__():
# site = ParqueFicticioSite(distance=TerrainFollowingDistance2())
# x, y = site.initial_position.T
# return site, x, y

Mads M. Pedersen
committed
def test_distances_ri():

Mads M. Pedersen
committed
site = ParqueFicticioSiteTerrainFollowingDistance2()
x, y = site.initial_position.T

Mads M. Pedersen
committed
site.calc_all = False
site.r_i = np.ones(len(x)) * 90
dw_ijl, cw_ijl, dh_ijl, _ = site.distances(src_x_i=x, src_y_i=y, src_h_i=np.array([70]),
dst_x_j=x, dst_y_j=y, dst_h_j=np.array([70]),
wd_il=np.array([[180]]))
npt.assert_almost_equal(dw_ijl[0, :, 0], np.array([0., -207., -477., -710., -1016., -1236., -1456., -1799.]))
npt.assert_almost_equal(cw_ijl[:, 1, 0], np.array([-236.1, 0., 131.1, 167.8, 204.5, 131.1, 131.1, 45.4]))
npt.assert_almost_equal(dh_ijl, np.zeros_like(dh_ijl))

Mads M. Pedersen
committed
site = ParqueFicticioSiteTerrainFollowingDistance2()

Mads M. Pedersen
committed
site.plot_map('elev')
x = np.arange(-1500, 1000, 500) + 264777
h = x * 0
y = h + 6505450
dw = site.distances(src_x_i=x, src_y_i=y, src_h_i=h,
dst_x_j=x, dst_y_j=y, dst_h_j=h * 0, wd_il=[270])[0]
if 0:
plt.plot(x, y, '.-', label='Terrain line')
plt.plot(x, y + site.elevation(x, y))

Mads M. Pedersen
committed
plt.legend()
plt.show()
# distance between points should be >500 m due to terrain, except last point which is outside map
npt.assert_array_equal(np.round(np.diff(dw[0, :, 0])), [527, 520, 505, 500.])
def test_distance2_outside_map_NorthSouth():

Mads M. Pedersen
committed
site = ParqueFicticioSiteTerrainFollowingDistance2()
import matplotlib.pyplot as plt
site.plot_map('elev')
y = np.arange(-1500, 1000, 500) + 6506613.0
h = y * 0
x = h + 264200
dw = site.distances(src_x_i=x, src_y_i=y, src_h_i=h,
dst_x_j=x, dst_y_j=y, dst_h_j=h * 0, wd_il=[180])[0]
if 0:
plt.plot(x, y, '.-', label='Terrain line')
plt.plot(x + site.elevation(x, y), y)
plt.legend()
plt.show()
# distance between points should be >500 m due to terrain, except last point which is outside map
npt.assert_array_equal(np.round(np.diff(dw[0, :, 0])), [510, 505, 507, 500])