Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

py-wake

Package Overview
Dependencies
Maintainers
2
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

py-wake - npm Package Compare versions

Comparing version
2.6.14
to
2.6.15
+47
py_wake/site/wrf.py
from py_wake.utils.streamline import VectorField3D
import numpy as np
from scipy.interpolate._rgi import RegularGridInterpolator as RGI
from py_wake.site.xrsite import XRSite
from py_wake.site.streamline_distance import StreamlineDistance
def wrf2pywake(ds, TI=None):
if 'west_east' in ds:
ds = ds.rename(west_east='x', south_north='y', height='h')
if 'TI' not in ds:
if TI is None:
TI = np.sqrt(2 / 3 * ds['TKE']) / ds['WS']
ds['TI'] = TI
return ds[['WD', 'WS', 'TI']].transpose('x', 'y', 'h', 'time')
class WRFVectorField(VectorField3D):
def __init__(self, ds):
ds = wrf2pywake(ds)
self.ds = ds
grid = [ds.x.values, ds.y.values, ds.h.values, np.arange(len(ds.time))]
theta = np.deg2rad(270 - ds.WD.values)
Vx, Vy = np.cos(theta) * ds.WS.values, np.sin(theta) * ds.WS.values
values = np.moveaxis([Vx, Vy], 0, -1)
self.mean_values = np.mean(values, (1, 2, 3))
self.interp = RGI(grid, values, bounds_error=False)
def __call__(self, wd, time, x, y, h):
time = np.broadcast_to(time, x.shape)
Vx, Vy = np.transpose(self.interp(np.array([x, y, h, time]).T))
return np.array([Vx, Vy, Vx * 0]).T
class WRFSite(XRSite):
def __init__(self, ds, TI=None, streamlines=True):
if streamlines:
distance = StreamlineDistance(WRFVectorField(ds))
else:
distance = None
ds = wrf2pywake(ds, TI)
ds['P'] = 1
ds['datetime'] = ds.time
ds['time'] = np.arange(len(ds.time))
ds['ws'] = [0]
XRSite.__init__(self, ds, distance=distance)
from py_wake.examples.data.hornsrev1 import Hornsrev1WRFSite, V80
from py_wake.tests import npt
import numpy as np
import matplotlib.pyplot as plt
import pytest
from py_wake.wind_farm_models.engineering_models import PropagateDownwind, All2AllIterative
from py_wake.deficit_models.noj import NOJLocalDeficit
from py_wake.flow_map import XYGrid
@pytest.mark.parametrize('streamlines,ref', [(False, [548.22095, 26.745916]),
(True, [586.881971, -182.716646])])
def test_Hornsrev1WRFSite(streamlines, ref):
site = Hornsrev1WRFSite(time_slice=slice(f"2020-04-27 12:00", f"2020-04-27"), streamlines=streamlines)
wts = V80()
x, y = site.initial_position[:4].T
h = wts.hub_height()
t = 10
p = site.ds.interp(x=x[0], y=y[0], h=70).isel(time=t)
npt.assert_array_almost_equal([p.WS.item(), p.WD.item(), p.TI.item()], [5.566621, 348.0761, 0.04780247], 4)
t = 9
dw, cw = [v[0, 1, 0, 0] for v in site.distance(x[:2], y[:2], x[:2] * 0 + h, wd_l=[0], time=[t])[:2]]
if 0:
X, Y = np.meshgrid(site.ds.x.values, site.ds.y.values)
theta = np.deg2rad(270 - site.ds.WD)
WS = site.ds.WS
Vx, Vy = np.cos(theta) * WS, np.sin(theta) * WS
site.ds.WS.isel(time=t).interp(h=h).plot.contourf(cmap='Blues_r', x='x')
wts.plot(x[:2], y[:2], wt_number=0)
plt.quiver(X, Y, Vx.isel(time=t).interp(h=h).values.T, Vy.isel(time=t).interp(h=h).values.T)
if streamlines:
streamlines = site.distance.vectorField.stream_lines(np.array([0]), time=[t],
start_points=np.array([x[:1], y[:1], [h]]).T,
dw_stop=np.array([4000]))
plt.plot(streamlines[0][:, 0], streamlines[0][:, 1])
plt.plot([x[0], x[0] + cw], [y[0], y[0] - dw])
plt.xlim([x[0] - 4000, x[0] + 4000])
plt.ylim([y[0] - 4000, y[0] + 4000])
plt.show()
npt.assert_array_almost_equal([dw, cw], ref)
for cls in [PropagateDownwind, All2AllIterative]:
wfm = cls(site, wts, NOJLocalDeficit(use_effective_ti=False))
sim_res = wfm(x, y, wd=[0, 10, 20], ws=[10, 10, 10], time=True)
fm = sim_res.flow_map(XYGrid(resolution=20))
npt.assert_array_equal(fm.wd, [0, 10, 20])
fm = sim_res.flow_map(XYGrid(resolution=20), time=1)
npt.assert_array_equal(fm.wd, [10])
from py_wake.utils.maps import dk_coast
import matplotlib.pyplot as plt
from py_wake.tests import npt
import pytest
@pytest.mark.parametrize('crs,bounds', [(None, [7., 54., 14., 58.]),
('EPSG:25832', [381782.654552, 5983532.157506, 827373.774988, 6432168.470282])])
def test_dk_coast(crs, bounds):
dk = dk_coast(crs)
npt.assert_array_almost_equal(dk.total_bounds, bounds)
dk.plot()
if 0:
plt.show()
plt.close('all')
import os
import geopandas as gpd
from py_wake.tests import ptf
import zipfile
def dk_coast(crs=None):
f = ptf('maps/dk_coast.zip', known_hash='c6b90f62fddec4134762d41777dbfcc50122d8d1a0d2fa0e49a0601382aaecff')
with zipfile.ZipFile(f, 'r') as zip_ref:
zip_ref.extractall(os.path.dirname(f))
f = os.path.join(os.path.dirname(f), 'dk_coast/dk_coast.shp')
dk = gpd.read_file(f)
if crs:
dk = dk.to_crs(crs)
return dk
def main():
if __name__ == '__main__':
import matplotlib.pyplot as plt
dk = dk_coast()
plt.show()
main()
+3
-1
Metadata-Version: 2.4
Name: py_wake
Version: 2.6.14
Version: 2.6.15
Summary: Open source static wake modeling framework from DTU

@@ -30,2 +30,4 @@ Author: DTU Wind Energy

Requires-Dist: pooch
Requires-Dist: windkit
Requires-Dist: geopandas
Provides-Extra: test

@@ -32,0 +34,0 @@ Requires-Dist: pytest; extra == "test"

@@ -0,3 +1,9 @@

import warnings
import xarray as xr
from py_wake import np
from py_wake.site._site import UniformWeibullSite
from py_wake.site.wrf import WRFSite
from py_wake.tests import ptf
from py_wake.wind_turbines import WindTurbine

@@ -108,2 +114,21 @@ from py_wake.wind_turbines.power_ct_functions import PowerCtTabular

class Hornsrev1WRFSite(WRFSite):
"""WRF Site covering Hornsrev1 for April 2020"""
def __init__(self, time_slice=slice("2020-04-01 00:00", "2020-04-30"), streamlines=True):
wrf_ds = xr.load_dataset(ptf('wrf/Hornsrev1_2020_04.nc',
known_hash='65f7f774f6b67bb89870b7978a601b945aaf9bb17894351e6e607fdbcdbc8973'))
WRFSite.__init__(self, wrf_ds.sel(time=time_slice), streamlines=streamlines)
try:
import windkit as wk
xy_crs = wk.spatial.create_dataset(wt_x, wt_y, 70, "EPSG:25832")
crs = wk.spatial.get_crs(wrf_ds)
xy_crs = wk.spatial.reproject(xy_crs, crs)
wt_x_crs, wt_y_crs = xy_crs.west_east.values, xy_crs.south_north.values
self.initial_position = np.array([wt_x_crs, wt_y_crs]).T
except BaseException:
warnings.warn('windkit not available. Could not reproject initial position to current crs')
def main():

@@ -110,0 +135,0 @@ wt = V80()

@@ -192,3 +192,4 @@ from py_wake import np

# c = data.isel(h=0).plot(levels=levels, cmap=cmap, ax=ax, add_colorbar=plot_colorbar)
c = ax.contourf(self.X / n, self.Y / n, data.squeeze().values, levels=levels, cmap=cmap)
c = ax.contourf(self.X / n, self.Y / n, data.squeeze().values, levels=levels, cmap=cmap,
)
if plot_colorbar:

@@ -195,0 +196,0 @@ plt.colorbar(c, label=clabel, ax=ax, cax=cax)

@@ -7,8 +7,5 @@ import warnings

from py_wake import np
from py_wake.deficit_models.noj import NOJ
from py_wake.examples.data.hornsrev1 import V80
from py_wake.examples.data.ParqueFicticio._parque_ficticio import ParqueFicticioSite
from py_wake.flow_map import XYGrid
from py_wake.site.distance import StraightDistance
from py_wake.utils.model_utils import DeprecatedModel
from py_wake.utils.streamline import VectorField3D

@@ -34,3 +31,3 @@

def __call__(self, src_x_ilk, src_y_ilk, src_h_ilk, wd_l=None, WD_ilk=None, time=None, dst_xyh_jlk=None):
def __call__(self, src_x_ilk, src_y_ilk, src_h_ilk, time, wd_l=None, WD_ilk=None, dst_xyh_jlk=None):
(src_x_ilk, src_y_ilk, src_h_ilk), (dst_x_jlk, dst_y_jlk, dst_h_jlk) = self.get_pos(

@@ -40,6 +37,5 @@ src_x_ilk, src_y_ilk, src_h_ilk, wd_l, WD_ilk, dst_xyh_jlk)

start_points_m = np.moveaxis([v[:, :, 0].flatten() for v in [src_x_ilk, src_y_ilk, src_h_ilk]], 0, -1)
dw_ijlk, hcw_ijlk, dh_ijlk = StraightDistance.__call__(self, src_x_ilk, src_y_ilk, src_h_ilk, wd_l=wd_l,
dst_xyh_jlk=dst_xyh_jlk)
I, J, L, K = dw_ijlk.shape
src_z_ilk = self.site.elevation(src_x_ilk, src_y_ilk)

@@ -52,7 +48,10 @@ dst_z_jlk = self.site.elevation(dst_x_jlk, dst_y_jlk)

dz_ijlk = np.broadcast_to(dz_ijlk, dw_ijlk.shape) + 0.
I, J, L, K = dw_ijlk.shape
dw_mj, hcw_mj, dh_mj, dz_mj = [np.moveaxis(v, 1, 2).reshape(I * L, J)
for v in [dw_ijlk, hcw_ijlk, dh_ijlk, dz_ijlk]]
start_points_m = np.moveaxis([np.broadcast_to(v[:, :, 0], (I, L)).flatten()
for v in [src_x_ilk, src_y_ilk, src_h_ilk]], 0, -1)
wd_m = np.tile(wd_l, I)
if time is not False:
time = np.tile(time, I)

@@ -85,2 +84,4 @@ stream_lines = self.vectorField.stream_lines(wd_m, time=time, start_points=start_points_m, dw_stop=dw_mj.max(1),

if __name__ == '__main__':
from py_wake.deficit_models.noj import NOJ
from py_wake.examples.data.hornsrev1 import V80

@@ -87,0 +88,0 @@ wt = V80()

@@ -203,3 +203,3 @@ from py_wake import np

else:
ds_tmp = xr.merge([ds_tmp, xr.Dataset({var_name: da})])
ds_tmp = xr.merge([ds_tmp, xr.Dataset({var_name: da})], join='outer', compat='no_conflicts')

@@ -206,0 +206,0 @@ if first:

@@ -9,2 +9,3 @@ from pathlib import Path

import xarray as xr
import shutil
npt = numpy.testing

@@ -27,1 +28,5 @@ WindFarmModel.verbose = False

return ret
def clear_ptf():
shutil.rmtree(Path.home() / 'PyWakeTestFiles')

@@ -1,26 +0,34 @@

from py_wake import np
from py_wake.examples.data.hornsrev1 import HornsrevV80, V80
import contextlib
import io
import warnings
from pathlib import Path
import matplotlib.pyplot as plt
import pytest
from numpy import newaxis as na
from scipy.optimize._minpack_py import curve_fit
from py_wake import Fuga, np
from py_wake.deficit_models.fuga import (
FugaBlockage,
FugaDeficit,
FugaMultiLUTDeficit,
FugaYawDeficit,
)
from py_wake.examples.data import hornsrev1
from py_wake.examples.data.hornsrev1 import V80, HornsrevV80
from py_wake.flow_map import HorizontalGrid, XYGrid, XZGrid
from py_wake.site._site import UniformSite
from py_wake.tests import npt
from py_wake.tests.test_files import tfp
from py_wake import Fuga
from py_wake.examples.data import hornsrev1
import matplotlib.pyplot as plt
from py_wake.deficit_models.fuga import FugaBlockage, FugaDeficit, FugaYawDeficit, \
FugaMultiLUTDeficit
from py_wake.flow_map import HorizontalGrid, XYGrid, XZGrid
from py_wake.utils import fuga_utils
from py_wake.utils.fuga_utils import FugaUtils
from py_wake.utils.grid_interpolator import GridInterpolator
from py_wake.wind_farm_models.engineering_models import PropagateDownwind, All2AllIterative
import pytest
from pathlib import Path
from py_wake.wind_turbines.power_ct_functions import PowerCtTabular, CubePowerSimpleCt
from py_wake.utils.profiling import timeit
from py_wake.wind_farm_models.engineering_models import (
All2AllIterative,
PropagateDownwind,
)
from py_wake.wind_turbines._wind_turbines import WindTurbine, WindTurbines
from py_wake.utils.profiling import timeit
import warnings
from py_wake.utils import fuga_utils
from py_wake.utils.fuga_utils import FugaUtils
from numpy import newaxis as na
from scipy.optimize._minpack_py import curve_fit
import contextlib
import io
from py_wake.wind_turbines.power_ct_functions import CubePowerSimpleCt, PowerCtTabular

@@ -471,13 +479,13 @@

fm = sim_res.flow_map(XYGrid(x=400, y=np.linspace(-310, 310), h=70))
for t in sim_res.time:
da = sim_res.sel(time=t)
ti = ['z0=0.00001000_z69.2-93.4', 'z0=0.01703452_z68.5-92.5'][da.TI.item() >= .12]
# print(fuga_utils.z0(da.TI.item(), 70, da.zeta0.item()))
deficit = FugaDeficit(
tfp +
f"fuga/2MW/multilut/LUTs_Zeta0={da.zeta0.item():4.2e}_16_32_D80_zhub70_zi{da.zi.item():d}_{ti}_UL_nx128_ny128_dx20.0_dy5.0.nc",
smooth2zero_x=None, smooth2zero_y=None)
wfm_ref = All2AllIterative(UniformSite(), V80(), wake_deficitModel=deficit, blockage_deficitModel=deficit)
fm_ref = wfm_ref([0], [0], wd=270, ws=10,).flow_map(XYGrid(x=400, y=np.linspace(-310, 310), h=70))
fm = sim_res.flow_map(XYGrid(x=400, y=np.linspace(-310, 310), h=70))
for t in sim_res.time:
da = sim_res.sel(time=t)
ti = ['z0=0.00001000_z69.2-93.4', 'z0=0.01703452_z68.5-92.5'][da.TI.item() >= .12]
# print(fuga_utils.z0(da.TI.item(), 70, da.zeta0.item()))
deficit = FugaDeficit(
tfp +
f"fuga/2MW/multilut/LUTs_Zeta0={da.zeta0.item():4.2e}_16_32_D80_zhub70_zi{da.zi.item():d}_{ti}_UL_nx128_ny128_dx20.0_dy5.0.nc",
smooth2zero_x=None, smooth2zero_y=None)
wfm_ref = All2AllIterative(UniformSite(), V80(), wake_deficitModel=deficit, blockage_deficitModel=deficit)
fm_ref = wfm_ref([0], [0], wd=270, ws=10,).flow_map(XYGrid(x=400, y=np.linspace(-310, 310), h=70))

@@ -484,0 +492,0 @@

@@ -0,18 +1,19 @@

import matplotlib.pyplot as plt
import xarray as xr
from py_wake import np
from py_wake.wind_turbines import WindTurbine
from py_wake.deficit_models.rans_lut import RANSLUT, RANSLUTDemoDeficit
from py_wake.examples.data import hornsrev1
from py_wake.examples.data.hornsrev1 import HornsrevV80
from py_wake.flow_map import HorizontalGrid
from py_wake.site._site import UniformSite
from py_wake.tests import npt, ptf
import matplotlib.pyplot as plt
from py_wake.deficit_models.rans_lut import RANSLUT, RANSLUTDemoDeficit
from py_wake.flow_map import HorizontalGrid
from py_wake.turbulence_models.rans_lut_turb import RANSLUTDemoTurbulence
from py_wake.utils.grid_interpolator import GridInterpolator
from py_wake.wind_farm_models.engineering_models import All2AllIterative
from py_wake.utils.profiling import timeit
import xarray as xr
from py_wake.utils.rans_lut_utils import ADControl, get_Ellipsys_equivalent_output
from py_wake.turbulence_models.rans_lut_turb import RANSLUTDemoTurbulence
from py_wake.wind_farm_models.engineering_models import All2AllIterative
from py_wake.wind_turbines import WindTurbine
from py_wake.wind_turbines._wind_turbines import WindTurbines
from py_wake.wind_turbines.power_ct_functions import PowerCtTabular
from py_wake.examples.data import hornsrev1
from py_wake.wind_turbines._wind_turbines import WindTurbines

@@ -280,3 +281,3 @@

hornsrev1.power_curve[:, 0], hornsrev1.power_curve[:, 1], 'w', hornsrev1.ct_curve[:, 1]))
wts = WindTurbine.from_WindTurbines([v80, v120])
wts = WindTurbines.from_WindTurbine_lst([v80, v120])

@@ -283,0 +284,0 @@ wfm = RANSLUT([ds, lut_V120], UniformSite(ti=0.075 * 0.8), wts)

@@ -324,3 +324,4 @@ import warnings

sim_res = wfm(x, y, wd=wd, ws=10)
dw = site.distance(x, y, x * 0 + wt.hub_height(), wd_l=wd, WD_ilk=np.repeat(wd[na, na], len(x), 0))[0][:, :, 0, 0]
dw = site.distance(x, y, x * 0 + wt.hub_height(),
wd_l=wd, WD_ilk=np.repeat(wd[na, na], len(x), 0), time=False)[0][:, :, 0, 0]
# streamline downwind distance (positive numbers, upper triangle) cannot be shorter than

@@ -334,5 +335,6 @@ # straight line distances in opposite direction (negative numbers, lower triangle)

y=np.linspace(site.ds.y[0].item(), site.ds.y[-1].item(), 500)))
x, y = x[6:], y[6:]
stream_lines = vf3d.stream_lines(wd=np.full(x.shape, wd), start_points=np.array([x, y, np.full(x.shape, 70)]).T,
dw_stop=y - 6504700)
if 0:
dw_stop=np.full(x.shape, 2000))
if 1:
fm.plot_wake_map()

@@ -361,3 +363,3 @@ for sl in stream_lines:

dw = site.distance(wt_x, wt_y, wt_x * 0 + wt.hub_height(), wd_l=wd,
WD_ilk=np.repeat(wd[na, na], len(wt_x), 0))[0][:, :, 0, 0]
WD_ilk=np.repeat(wd[na, na], len(wt_x), 0), time=False)[0][:, :, 0, 0]
# streamline downwind distance (positive numbers, upper triangle) cannot be shorter than

@@ -364,0 +366,0 @@ # straight line distances in opposite direction (negative numbers, lower triangle)

@@ -0,6 +1,9 @@

from pathlib import Path
import pytest
from py_wake import np
from py_wake.tests import clear_ptf, ptf
from py_wake.utils.check_input import check_input
from py_wake import np
from pathlib import Path
from py_wake.tests import ptf
import time

@@ -24,3 +27,11 @@

def test_ptf():
assert Path(ptf('test.txt',
'ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae')).read_text() == 'test123'
f = Path(ptf('test.txt', 'ecd71870d1963316a97e3ac3408c9835ad8cf0f3c1bc703527c30265534f75ae'))
assert f.read_text() == 'test123'
for _ in range(3):
try:
clear_ptf()
break
except Exception:
time.sleep(0.5)
assert f.exists() is False
assert f.parent.exists() is False

@@ -21,7 +21,3 @@ import os

from py_wake.wind_farm_models.external_wind_farm_models import (
ExternalWFMWindFarm,
ExternalWindFarm,
ExternalXRAbsWindFarm,
ExternalXRRelWindFarm,
)
ExternalWFMWindFarm, ExternalXRAbsWindFarm, ExternalXRRelWindFarm)
from py_wake.wind_turbines import WindTurbines

@@ -28,0 +24,0 @@

@@ -1,13 +0,15 @@

import time
import ctypes
import functools
import sys
from py_wake import np
import gc
import linecache
import os
import psutil
import ctypes
import linecache
import sys
import time
import warnings
import psutil
from py_wake import np
def timeit(func, min_time=0, min_runs=1, verbose=False, line_profile=False, profile_funcs=[]):

@@ -18,5 +20,5 @@ @functools.wraps(func)

lp_wrapper = line_timeit(func, profile_funcs)
t = time.time()
t = time.perf_counter()
res, lp = lp_wrapper(*args, **kwargs)
t = time.time() - t
t = time.perf_counter() - t
if verbose:

@@ -27,8 +29,8 @@ lp.print_stats()

t_lst = []
time_start = time.time()
time_start = time.perf_counter()
for i in range(100000):
t0 = time.time_ns()
t0 = time.perf_counter_ns()
res = func(*args, **kwargs)
t_lst.append((time.time_ns() - t0) * 1e-9)
if (time.time() - time_start) > min_time and len(t_lst) >= min_runs:
t_lst.append((time.perf_counter_ns() - t0) * 1e-9)
if (time.perf_counter() - time_start) > min_time and len(t_lst) >= min_runs:
break

@@ -35,0 +37,0 @@

@@ -6,2 +6,3 @@ import xarray as xr

from py_wake.utils.grid_interpolator import GridInterpolator
from scipy.interpolate import RegularGridInterpolator as RGI

@@ -13,4 +14,5 @@

self.da = da
self.interpolator = GridInterpolator(
[da.wd.values, da.x.values, da.y.values, da.h.values], da.values, method='linear')
# self.interpolator = GridInterpolator(
# [da.wd.values, da.x.values, da.y.values, da.h.values], da.values, method='linear', bounds='limit')
self.interpolator = RGI([da.wd.values, da.x.values, da.y.values, da.h.values], da.values, bounds_error=False)
vy = property(lambda self: self.da.sel(v_xyz=0))

@@ -24,3 +26,3 @@ vx = property(lambda self: self.da.sel(v_xyz=1))

def __call__(self, wd, time, x, y, h):
return self.interpolator(np.array([np.atleast_1d(v) for v in [wd, x, y, h]]).T, bounds='limit')
return self.interpolator(np.array([np.atleast_1d(v) for v in [wd, x, y, h]]).T)

@@ -37,19 +39,16 @@ @staticmethod

def stream_lines(self, wd, start_points, dw_stop, time=None, step_size=20):
def stream_lines(self, wd, start_points, dw_stop, time=False, step_size=20):
# print(np.shape(wd), np.shape(start_points), time)
if time is None:
wd = np.full(len(start_points), wd)
time = wd * 0
# else:
# if len(start_points) == 1:
# # 1 start point, multiple wd/time
# start_points = np.broadcast_to(start_points, (len(wd), 3))
# elif len(time) == 1:
# time = wd * 0 + time
stream_lines = [start_points]
m = np.arange(len(wd))
co, si = np.cos(np.deg2rad(270 - wd)), np.sin(np.deg2rad(270 - wd))
for _ in range(1000):
t = time
for i in range(int(np.max(dw_stop) * 2 / step_size)):
p = stream_lines[-1].copy()
v = self(wd[m], time[m], p[m, 0], p[m, 1], p[m, 2])
if time is not False:
t = time[m]
v = self(wd[m], t, p[m, 0], p[m, 1], p[m, 2])
mnan = np.any(np.isnan(v), 1)
if np.any(mnan):
v[mnan] = np.array([co[m][mnan], si[m][mnan], co[m][mnan] * 0]).T
v = v / (np.sqrt(np.sum(v**2, -1)) / step_size)[:, na] # normalize vector distance to step_size

@@ -56,0 +55,0 @@ p[m] += v

@@ -31,5 +31,5 @@ # file generated by setuptools-scm

__version__ = version = '2.6.14'
__version_tuple__ = version_tuple = (2, 6, 14)
__version__ = version = '2.6.15'
__version_tuple__ = version_tuple = (2, 6, 15)
__commit_id__ = commit_id = None

@@ -323,3 +323,3 @@ from abc import abstractmethod

dw_ijlk, hcw_ijlk, dh_ijlk = self.site.distance(wt_x_ilk, wt_y_ilk, wt_h_ilk, wd_l=wd, WD_ilk=WD_ilk,
time=model_kwargs.get('time', None), dst_xyh_jlk=(x_jl, y_jl, h_jl))
time=model_kwargs.get('time', False), dst_xyh_jlk=(x_jl, y_jl, h_jl))

@@ -442,4 +442,4 @@ if self.wec != 1:

x_jl[js, ls], y_jl[js, ls], np.broadcast_to(h_jl, x_jl.shape)[js, ls], wd[l], WD_il[:, l],
lw_j.WS_ilk[:, (l, [0])[lw_j.WS_ilk.shape[1] == 1]],
lw_j.TI_ilk[:, (l, [0])[lw_j.TI_ilk.shape[1] == 1]])
lw_j.WS_ilk[(j, [0])[lw_j.WS_ilk.shape[0] == 1]][:, (l, [0])[lw_j.WS_ilk.shape[1] == 1]],
lw_j.TI_ilk[(j, [0])[lw_j.TI_ilk.shape[0] == 1]][:, (l, [0])[lw_j.TI_ilk.shape[1] == 1]])

@@ -743,3 +743,3 @@ l_iter = [get_jl_args(j, l)

*[get_pos(kwargs[k + '_ilk'], i_wt_l, i_wd_l)[na] for k in 'xyh'], wd_l=wd, WD_ilk=WD_mk[m][na],
dst_xyh_jlk=dst_xyh_jlk)
time=kwargs.get('time', False), dst_xyh_jlk=dst_xyh_jlk)

@@ -943,3 +943,3 @@ for inputModidifierModel in self.inputModifierModels:

self, wd, dw_order_indices_ld, WD_ilk=WD_ilk, WS_ilk=WS_ilk, TI_ilk=TI_ilk,
WS_eff_ilk=WS_eff_ilk, TI_eff_ilk=TI_eff_ilk, D_i=D_i, I=I, L=L, K=K, **kwargs)[0]
WS_eff_ilk=WS_eff_ilk, TI_eff_ilk=TI_eff_ilk, D_i=D_i, I=I, L=L, K=K, time=time, **kwargs)[0]
self.blockage_deficitModel = blockage_deficitModel

@@ -959,3 +959,4 @@ elif np.all(WS_eff_ilk == 0):

dst_xyh_jlk = [kwargs[k + '_ilk'] for k in 'xyh']
dw_iilk, hcw_iilk, dh_iilk = self.site.distance(*[kwargs[k + '_ilk'] for k in 'xyh'], wd_l=wd, WD_ilk=WD_ilk)
dw_iilk, hcw_iilk, dh_iilk = self.site.distance(*[kwargs[k + '_ilk'] for k in 'xyh'],
wd_l=wd, WD_ilk=WD_ilk, time=time)
kwargs['WD_ilk'] = WD_ilk

@@ -962,0 +963,0 @@

@@ -75,3 +75,3 @@ from abc import ABC, abstractmethod

def __call__(self, i, l, deficit_jlk, WS_jlk, WS_eff_ilk,
WD_ilk, dst_xyh_jlk, IJLK, dw_ijlk, hcw_ijlk, dh_ijlk, **_):
WD_ilk, dst_xyh_jlk, IJLK, dw_ijlk, hcw_ijlk, dh_ijlk, time=False, **_):
I, J, L, K = IJLK

@@ -86,3 +86,3 @@ WD_l = np.round(WD_ilk[np.minimum(i, len(WD_ilk) - 1), :, 0])

wd_lst = WD_l[m_lst]
sim_res = self.wfm(**{**self.wfm_kwargs, 'ws': ws_lst, 'wd': np.sort(np.unique(wd_lst))})
sim_res = self.wfm(**{**self.wfm_kwargs, 'ws': ws_lst, 'wd': np.sort(np.unique(wd_lst)), 'time': time})
from py_wake.site.streamline_distance import StreamlineDistance

@@ -207,13 +207,12 @@ if isinstance(self.wfm.site.distance, StreamlineDistance):

wf_h = windFarmModel.windTurbines.hub_height(type)
deficit = []
for wd in tqdm(sim_res.wd.values, disable=1):
theta = np.deg2rad(270 - wd)
co, si = np.cos(theta), np.sin(theta)
x_j = co * dw - hcw * si + wf_x
y_j = si * dw + hcw * co + wf_y
h_j = dh + wf_h
lw_j, WS_eff_jlk, TI_eff_jlk = windFarmModel._flow_map(x_j[:, na], y_j[:, na], h_j[:, na], sim_res.localWind,
wd, sim_res.ws, sim_res)
deficit.append(lw_j.WS_ilk - WS_eff_jlk)
deficit = np.moveaxis(deficit, 0, 1).reshape(X.shape + (len(sim_res.wd), len(sim_res.ws)))
theta = np.deg2rad(270 - sim_res.wd.values)
co, si = np.cos(theta), np.sin(theta)
x_jl = co[na] * dw[:, na] - hcw[:, na] * si[na] + wf_x
y_jl = si[na] * dw[:, na] + hcw[:, na] * co[na] + wf_y
h_jl = dh[:, na] + wf_h
lw_j, WS_eff_jlk, TI_eff_jlk = windFarmModel._flow_map(x_jl, y_jl, h_jl, sim_res.localWind,
sim_res.wd.values, sim_res.ws, sim_res)
deficit = (lw_j.WS_ilk - WS_eff_jlk).reshape(X.shape + (len(sim_res.wd), len(sim_res.ws)))
ds = xr.Dataset({'deficit': (['x', 'y', 'h', 'wd', 'ws'], deficit)},

@@ -220,0 +219,0 @@ coords=dict(x=grid_xyh[0], y=grid_xyh[1], h=grid_xyh[2], wd=sim_res.wd, ws=sim_res.ws))

+24
-20

@@ -7,5 +7,5 @@ docs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

py_wake/__init__.py,sha256=-0bNwPpZWQXG-_zE_7hFRoJeG0SRBuDeGM9n5aFWgS0,1188
py_wake/flow_map.py,sha256=zUFPSUQZmxW5LwFTOiBdaL9fPRJxt87UGGemc_PGl3o,22411
py_wake/flow_map.py,sha256=pZCV-mbPDtVLuvdGejKJhUnR52VorJ7fobP10Oj7ZL4,22441
py_wake/superposition_models.py,sha256=mlZSy-T6YiAhdSgAu-reP1YECRsPpgHh8GDCfPAsZ6w,10124
py_wake/version.py,sha256=7zrBk63M80mRuOeY6dfWyf-ZQjC6DN9bM1NV1oUDz0Q,706
py_wake/version.py,sha256=Y_kUiwIfdfJcl4d1EVlpBvcQ85D9f1ATuvVihYhIFyg,706
py_wake/deficit_models/__init__.py,sha256=w1S4F3FmAgtwqGO90fASYoqxOb6SsgjbasiD3V8_1uk,709

@@ -39,3 +39,3 @@ py_wake/deficit_models/deficit_model.py,sha256=iLb9wUO8wDeYAEBAoAlS2W4Q4B16ZSO0L4DhVq3NxYQ,10280

py_wake/examples/data/__init__.py,sha256=2aH-lJ5vWthT6dhoSyMlepji2ouqkM1sv3vx8fXC0N4,105
py_wake/examples/data/hornsrev1.py,sha256=9g-pY49bVywA8786PHMen_gXfD5f9BfxqMPDGv1JHek,5402
py_wake/examples/data/hornsrev1.py,sha256=Sn4Rvk-aIn23-QCq7I7tb--tIKJnrDRGOwx1VyAsH1s,6468
py_wake/examples/data/lillgrund.py,sha256=lMsrmj7zQLXY-nfk7NGmW7ZsmhmMdXLAm0Il6NugwwE,4418

@@ -290,6 +290,7 @@ py_wake/examples/data/time_series.npz,sha256=FObvNeaHVznq0BHqiE7dTlp2S1I-CCaysljcpLh5fAI,765098

py_wake/site/shear.py,sha256=OGU2eQCuZ7H3hAjAbATK9ZXqIWBFjDazp9dmKumDnSw,4213
py_wake/site/streamline_distance.py,sha256=Qbjv2GCrPzxFlAp6ev5UhQGPfq2CVyFDzcK4iAHWkP0,4434
py_wake/site/wasp_grid_site.py,sha256=81zqtUIwCAUHaZdgnNvzazBjEIPYk22Gr6r7IQzmsZk,10190
py_wake/site/streamline_distance.py,sha256=01NdwM__ITY0w4kWavUx1arKxCvtc42cEteugQhN7mo,4518
py_wake/site/wasp_grid_site.py,sha256=d-vonrkXMuVVgbq9OG0ri3XHYekdDfvfjdndkigCOrQ,10227
py_wake/site/wrf.py,sha256=l2ziX34vcdxf2xgH3GiGxCdslgJldR8ZUd7BoZqxxEY,1653
py_wake/site/xrsite.py,sha256=-Kr2LMx0dpKI-ke4z3hbRyv-GWulLntjkSU-nY1LWIA,19887
py_wake/tests/__init__.py,sha256=HTCM3UcCGSo3Fibes8XFPV5mI3KzDsafM888VrqS29I,917
py_wake/tests/__init__.py,sha256=-YOzxrKhc4yGKHFLkjCX7YHO-8Km_E65UCtlKNs3Z1Y,1001
py_wake/tests/check_speed.py,sha256=8zPwap754HSH3Pns_CqBYUK6pwlmNvGVX2xC5u5ZBk8,2530

@@ -306,6 +307,6 @@ py_wake/tests/notebook.py,sha256=21RVNXcqRCy6b3GoRcKxR5E0IGV2d9U6BaqqOKZ8f8Y,6804

py_wake/tests/test_deficit_models/test_deficit_models.py,sha256=vIe5H_cX0rZ-V1bD3I4FWgnaeR1qy6NGc-uCefA9qhI,34083
py_wake/tests/test_deficit_models/test_fuga.py,sha256=zuWx-oAThjYGdubhX9c-dR8-wsnBJMTi7uA6R17_kos,24769
py_wake/tests/test_deficit_models/test_fuga.py,sha256=kFa_D4mt5P7NpESPOAE8f3KBaWq8zFFTyQfqqmhZNiA,24824
py_wake/tests/test_deficit_models/test_gcl.py,sha256=i2mIAoNUnGswJ8xXVjjHVw9Imgzhs6thfI8zkgLCt04,1189
py_wake/tests/test_deficit_models/test_noj.py,sha256=qJVv3q3Lp_QILFn-6xdslWevvR4Dmnx0AWj39XCIdXw,5495
py_wake/tests/test_deficit_models/test_rans_lut.py,sha256=jA8h7Fp4euRvjQNrfnT-gqLGofZNwjQElKBuJnbcIpE,17130
py_wake/tests/test_deficit_models/test_rans_lut.py,sha256=gpskfpoK6HBpW-8dFB5dHgD5NKtrZle_2q8ftx8fmlM,17135
py_wake/tests/test_deficit_models/test_selfsimilarity.py,sha256=mI5DUstBbaC36JQ-eCOMrE88jubvZjb3tp_DUQQzU2Y,4446

@@ -339,3 +340,3 @@ py_wake/tests/test_deflection_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

py_wake/tests/test_sites/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
py_wake/tests/test_sites/test_distances.py,sha256=VKox97PB3HmHNH0MO9IbVLiniolY2ffwqz9pNrGiu6M,16338
py_wake/tests/test_sites/test_distances.py,sha256=fsDoPw7gFBu4w7Rze0wvO15XwWsb0ylm0uyoRyrseGY,16420
py_wake/tests/test_sites/test_iea37_readers.py,sha256=nEoXISd3M7USxJe4PFBI2wUlLTjiL6NEnXMvFWHzwxo,1427

@@ -345,2 +346,3 @@ py_wake/tests/test_sites/test_shear_models.py,sha256=g4zg1QCvl2WQY6f10BiRlBAnyJyaaQRVpeiLnkNT4SU,4053

py_wake/tests/test_sites/test_wasp_grid_site.py,sha256=miNHoOVFt31YqM0Auo97GkAfQ86eyUvc_xkoVO86xEA,15662
py_wake/tests/test_sites/test_wrf.py,sha256=5tKl0MCaaAqkinj5Cw06d45NZ9kLJPbMzMbGVU9jb74,2460
py_wake/tests/test_sites/test_xrsite.py,sha256=3lASkg3Cdv-MQwrXZRuGqQDGONy6pzRdLOurQTneKGI,31239

@@ -351,3 +353,3 @@ py_wake/tests/test_turbulence_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

py_wake/tests/test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
py_wake/tests/test_utils/test_check_input.py,sha256=PP38AIp7bEH4vIhSpsz_4Nqn6msLvNWjMMXkR17vzuU,911
py_wake/tests/test_utils/test_check_input.py,sha256=cgevOjDcCie0UhijMQIJjef6vcyTjXlwFJ6e5_ic0nc,1127
py_wake/tests/test_utils/test_elliptic.py,sha256=hxyfSIJcdmNgvFxMOqmAV383sO__-0B0sgAKeBBnTNA,1749

@@ -359,2 +361,3 @@ py_wake/tests/test_utils/test_fuga_utils.py,sha256=6YYCrngD4bA9XJdIQqMxMTQ-GmwOybrKSll1IANLB6A,2260

py_wake/tests/test_utils/test_layouts.py,sha256=9soiopXExIdV1jxSnoG6te_54qbxfRGEd3AdpoGmpNM,1199
py_wake/tests/test_utils/test_maps.py,sha256=GPmATBxFtH-y6u6uZNFNbrrXNobKLz4tsiACly7hO8c,486
py_wake/tests/test_utils/test_model_gradients.py,sha256=JHZ-uZfNDW-O8sNTssBmE-EJR_XDSAan1OmCtaSROhE,12638

@@ -376,3 +379,3 @@ py_wake/tests/test_utils/test_model_utils.py,sha256=219lb_0_74xshlw2lKdEgTyPGSRXe8F-uplifqpRdnM,3847

py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py,sha256=IvbRInNWqnC8FVk8A-IwmDiYOZ3oGNR4Z8drlRHHpnk,28773
py_wake/tests/test_wind_farm_models/test_external_windfarms.py,sha256=MszAdqFAhnQyxbIXABMc-qgGmZ6y_vsL-XMDleiiKVU,12489
py_wake/tests/test_wind_farm_models/test_external_windfarms.py,sha256=A6MHjEZiDIgTRoXOkWvjC6CbyqlJAUa_QlfPcAUSFu4,12457
py_wake/tests/test_wind_farm_models/test_memory_usage.py,sha256=nDGlWHDNVAUrZZD9BOOC-AluRWKuHCLiljp3m8ZofJs,2016

@@ -407,2 +410,3 @@ py_wake/tests/test_wind_farm_models/test_minimalistic_model.py,sha256=Nmu7eNldVD_m_G7bmsOf8eUGkYf_bF5kUhNwFWF9fj8,1566

py_wake/utils/layouts.py,sha256=YHV1FwZJECBjTqqYIi8ipVIOefXYoWS7AarK7ND048M,998
py_wake/utils/maps.py,sha256=cvz1j14Is_EdsXX4wkautCXm_OcDaSwDk4a6JJdhGs4,593
py_wake/utils/model_utils.py,sha256=CkdZ38hwCkmyfTO5x6iwAgrVi3o0hOohDVZ213ti_Uw,15350

@@ -414,5 +418,5 @@ py_wake/utils/most.py,sha256=9DEZ5C06qdttfGdfUCyaFCGt-YT8xPnQ3URIuHpbcdE,1208

py_wake/utils/plotting.py,sha256=zXharIIWIwl-E0Xh2JP3qAnYEEAKGJidQcldhRd0dRo,568
py_wake/utils/profiling.py,sha256=GuE0UcQaZ3KsVnklLHSDFpCc0jQ4fixh0VREwA3aHQ0,4618
py_wake/utils/profiling.py,sha256=g6aDNtZg_7lcxUg4WdAawGMysaoZW87iPyTWwiPvWdA,4668
py_wake/utils/rans_lut_utils.py,sha256=-zs25tCdg2heaoCjyEDdk0vSDTImdhjtTpbDH_YEClI,12423
py_wake/utils/streamline.py,sha256=hFIvkHsdUPLzySvQYdpX6DEUMaz5NayQBEg2fuppPh4,2574
py_wake/utils/streamline.py,sha256=VjpEESETjxvYQwv11--FtL0Z9oX4EG87qyLYpss3Krc,2657
py_wake/utils/tensorflow_surrogate_utils.py,sha256=QdIPqxoYiuXFvieHQyP-TE6gS8syXbxoUZ1liCBFil0,7198

@@ -427,4 +431,4 @@ py_wake/utils/weibull.py,sha256=cD1SIyXHEn17IQueZnsy9-upo2oZivVCpYOWka-_DsE,1262

py_wake/wind_farm_models/__init__.py,sha256=cl0nC9vqhXgpRuaCFkQpDET2Yyzbwnd5Kv2wgZHUI6E,137
py_wake/wind_farm_models/engineering_models.py,sha256=heyGqJroRPO_BjRaMf1QeEyu-kpiUkxntQTw4r5VfeA,63601
py_wake/wind_farm_models/external_wind_farm_models.py,sha256=8Qjkzf9w9RFSVr7AHEE3wPtgiwlsZue4SGlBhb1w32k,12649
py_wake/wind_farm_models/engineering_models.py,sha256=6Ab-eDX3_ZIeHAmJ_qD8OtlWVWo5V75tvp6rPKu6O7I,63786
py_wake/wind_farm_models/external_wind_farm_models.py,sha256=QRSwdq45J4hwmYANBCv87HFGAho04_gkTWY9rUUUazM,12587
py_wake/wind_farm_models/minimalistic_wind_farm_model.py,sha256=9BepPjAo_WDMcG4feUQo7YDY2WSFJOpNMmzgT0yNBn4,11160

@@ -438,6 +442,6 @@ py_wake/wind_farm_models/wind_farm_model.py,sha256=QvYmeqAVz2QyrjH21VEt1T52lJS2NQcTq3cW-W1qUFQ,42814

py_wake/wind_turbines/wind_turbines_deprecated.py,sha256=HpNmBR8CJL4-8JBaygDI0t086qfw5bR2DOQI8Ox4AZ4,6250
py_wake-2.6.14.dist-info/licenses/LICENSE,sha256=XE2CGPqQgzSXqIajXpAVYJ5SRNmaWOIeMePK6MocsuY,1084
py_wake-2.6.14.dist-info/METADATA,sha256=GTsCfUqg3V5gNXNjdrnN3JYWPDYHOun_fqN0ZCqDdj0,3596
py_wake-2.6.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
py_wake-2.6.14.dist-info/top_level.txt,sha256=GsaXU4YwyMkZZ6dkb4h0FMc5RaLIT2Qns_YoScKoXdk,20
py_wake-2.6.14.dist-info/RECORD,,
py_wake-2.6.15.dist-info/licenses/LICENSE,sha256=XE2CGPqQgzSXqIajXpAVYJ5SRNmaWOIeMePK6MocsuY,1084
py_wake-2.6.15.dist-info/METADATA,sha256=SSQCWVa8eKVPv3uF5TFb3P6jgVBLU_g6yIjM3bgWEoA,3644
py_wake-2.6.15.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
py_wake-2.6.15.dist-info/top_level.txt,sha256=GsaXU4YwyMkZZ6dkb4h0FMc5RaLIT2Qns_YoScKoXdk,20
py_wake-2.6.15.dist-info/RECORD,,