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.18
to
2.6.19
+419
py_wake/wind_farm_models/all2alliterative.py
import warnings
from numpy import newaxis as na
from tqdm import tqdm
from py_wake import np
from py_wake.superposition_models import CumulativeWakeSum, LinearSum, WeightedSum
from py_wake.utils import gradients
from py_wake.utils.gradients import cabs, item_assign
from py_wake.wind_farm_models.engineering_models import (
EngineeringWindFarmModel,
PropagateUpDownIterative,
)
import abc
from abc import ABC
class All2AllIterative(EngineeringWindFarmModel):
"""Wake and blockage deficits calculated from all wt to all points of interest (wt/map points).
The calculations are iteratively repeated until convergence (change of effective wind speed < convergence_tolerance)"""
def __init__(self, site, windTurbines, wake_deficitModel,
superpositionModel=LinearSum(),
blockage_deficitModel=None, deflectionModel=None, turbulenceModel=None,
rotorAvgModel=None, inputModifierModels=[], externalWindFarms=[],
solver=None, **kwargs):
"""Initialize flow model
Parameters
----------
site : Site
Site object
windTurbines : WindTurbines
WindTurbines object representing the wake generating wind turbines
wake_deficitModel : DeficitModel
Model describing the wake(downstream) deficit
rotorAvgModel : RotorAvgModel, optional
Model defining one or more points at the down stream rotors to
calculate the rotor average wind speeds from.\n
if None, default, the wind speed at the rotor center is used
superpositionModel : SuperpositionModel
Model defining how deficits sum up
blockage_deficitModel : DeficitModel
Model describing the blockage(upstream) deficit
deflectionModel : DeflectionModel
Model describing the deflection of the wake due to yaw misalignment, sheared inflow, etc.
turbulenceModel : TurbulenceModel
Model describing the amount of added turbulence in the wake
convergence_tolerance : float or None
if float: maximum accepted change in WS_eff_ilk [m/s]
if None: return after first iteration. This only makes sense for benchmark studies where CT,
wakes and blockage are independent of effective wind speed WS_eff_ilk
"""
EngineeringWindFarmModel.__init__(self, site, windTurbines, wake_deficitModel, superpositionModel, rotorAvgModel,
blockage_deficitModel=blockage_deficitModel, deflectionModel=deflectionModel,
turbulenceModel=turbulenceModel, inputModifierModels=inputModifierModels,
externalWindFarms=externalWindFarms)
try:
kwargs.pop('convergence_tolerance')
raise ValueError("""The `convergence_tolerance` argument is deprecated. Use the `solver` argument instead, e.g.
`solver=FixedPointSolver(tolerance=1e-6)`""")
except BaseException:
assert len(kwargs) == 0, f'Invalid keyword argument(s) provided: {list(kwargs.keys())}'
self.solver = solver or FixedPointSolver(tolerance=1e-6, verbose=self.verbose)
def _calc_wt_interaction(self, ws, wd, WD_ilk, WS_ilk, TI_ilk,
WS_eff_ilk, TI_eff_ilk,
D_i, time,
I, L, K, **kwargs):
if any([np.iscomplexobj(v) for v in ([kwargs.get(k, 0)
for k in ['x_ilk', 'y_ilk', 'h_ilk', 'D_i', 'yaw_ilk', 'tilt_ilk']] +
[ws, wd])]):
dtype = np.complex128
else:
dtype = float
WS_ILK = np.broadcast_to(WS_ilk, (I, L, K))
# calculate WS_eff without blockage as a first guess
if WS_eff_ilk is None:
# Initialize with PropagateDownwind
blockage_deficitModel = self.blockage_deficitModel
self.blockage_deficitModel = None
dw_order_indices_ld = self.site.distance.dw_order_indices(kwargs['x_ilk'], kwargs['y_ilk'], wd)[:, 0]
self.direction = 'down'
WS_eff_ilk, TI_eff_ilk = PropagateUpDownIterative._propagate_deficit(
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, time=time, **kwargs)[:2]
self.blockage_deficitModel = blockage_deficitModel
elif np.all(WS_eff_ilk == 0):
WS_eff_ilk = WS_ILK + 0.
TI_eff_ilk = TI_ilk
else:
WS_eff_ilk = np.zeros((I, L, K)) + WS_eff_ilk
TI_eff_ilk = TI_ilk
WS_eff_ilk = WS_eff_ilk.astype(dtype)
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, time=time)
kwargs['WD_ilk'] = WD_ilk
wt_kwargs = self.get_wt_kwargs(TI_eff_ilk, kwargs)
ct_ilk = self.windTurbines.ct(ws=WS_eff_ilk, **wt_kwargs)
model_kwargs = {'WS_ilk': WS_ilk,
'WS_eff_ilk': WS_eff_ilk,
'WS_jlk': WS_ilk,
'WD_ilk': WD_ilk,
'TI_ilk': TI_ilk,
'TI_eff_ilk': TI_eff_ilk,
'D_src_il': D_i[:, na],
'D_dst_ijl': D_i[na, :, na],
'dw_ijlk': dw_iilk,
'hcw_ijlk': hcw_iilk,
'cw_ijlk': np.sqrt(hcw_iilk**2 + dh_iilk**2),
'dh_ijlk': dh_iilk,
'z_ijlk': kwargs['h_ilk'][:, na] + dh_iilk,
'IJLK': (I, I, L, K),
'type_il': kwargs['type_i'][:, na],
** kwargs,
}
if 'wake_radius_ijl' in self.args4all:
model_kwargs['wake_radius_ijl'] = self.wake_deficitModel.wake_radius(**model_kwargs)[:, :, :, 0]
if not self.deflectionModel:
self._init_deficit(**model_kwargs)
cw_iilk = np.sqrt(hcw_iilk**2 + dh_iilk**2)
i2i_zero = ~np.eye(I).astype(bool)[:, :, na, na]
self.ct_ilk_lst = []
self.unstable = np.zeros((I, L, K)).astype(bool)
max_iter = max(20, I)
self.iterations = 0
def get_new_WS_eff_ilk(WS_eff_ilk, TI_eff_ilk, gradient_evaluation=False):
ct_ilk = self.windTurbines.ct(np.maximum(WS_eff_ilk, 0), **wt_kwargs)
if not gradient_evaluation:
self.iterations += 1
if self.iterations > max_iter:
raise StopIteration()
if len(self.ct_ilk_lst) > 1:
# consider last max 6 iterations
N = 6
ct_change = np.diff(np.array(self.ct_ilk_lst[-N:] + [ct_ilk]), axis=0)
# max ct step (cummax)
mc = [np.real(cabs(ct_change[-1]))]
for ct_c in ct_change[::-1][1:]:
mc.append(np.maximum(mc[-1], np.real(cabs(ct_c))))
# actual change in ct compared to previuos iterations
ac = np.real(cabs(np.cumsum(ct_change[::-1], 0)))
sc = np.real(np.cumsum(cabs(ct_change[::-1]), 0)) # sum of step changes
with warnings.catch_warnings():
warnings.filterwarnings('ignore', 'invalid value encountered in divide')
unstable = ((ac / sc < 0.1) & # change in ct < 10% of step sum
(sc / mc > 2.8)) # step sum > 2.5 x max step, e.g. up-down-up
self.unstable |= np.any(unstable, 0)
# for unstable turbines, ct can only go down (typically shut-down)
ct_ilk = np.where(self.unstable, np.minimum(self.ct_ilk_lst[-1], ct_ilk), ct_ilk)
self.ct_ilk_lst.append(ct_ilk)
# def p(v): np.round(np.array(v).squeeze(), 3)
#
# for i, ct in enumerate(np.array(self.ct_ilk_lst).squeeze().T):
# import matplotlib.pyplot as plt
# plt.plot(ct, '-', marker=['.', 'x'][int(self.unstable.squeeze()[i])], label=i)
# plt.legend()
# plt.show()
model_kwargs.update(dict(ct_ilk=ct_ilk, WS_eff_ilk=WS_eff_ilk))
if self.inputModifierModels:
# x_ilk, y_ilk and h_ilk is may be updated by an inputModifierModel and
# must be reset in every iterations
model_kwargs.update(dict(x_ilk=kwargs['x_ilk'], y_ilk=kwargs['y_ilk'], h_ilk=kwargs['h_ilk']))
if self.deflectionModel:
model_kwargs.update(dict(
# dw_ijlk, hcw_ijlk and dh_ijlk is updated by deflection model and must be reset in every iterations
dw_ijlk=dw_iilk,
hcw_ijlk=hcw_iilk,
cw_ijlk=cw_iilk,
dh_ijlk=dh_iilk,
z_ijlk=kwargs['h_ilk'][:, na] + dh_iilk))
modified_input_dict = {}
for inputModidifierModel in self.inputModifierModels:
modified_input_dict = inputModidifierModel(**model_kwargs)
model_kwargs.update(modified_input_dict)
if any([k in modified_input_dict for k in ['x_ilk', 'y_ilk']]):
model_kwargs.update({k: v for k, v in zip(
['dw_ijlk', 'hcw_ijlk', 'dh_ijlk'],
self.site.distance(*[model_kwargs[k + '_ilk'] for k in 'xyh'], wd_l=wd, WD_ilk=WD_ilk))})
model_kwargs['cw_ijlk'] = gradients.hypot(model_kwargs['dh_ijlk'], model_kwargs['hcw_ijlk'])
if not self.deflectionModel:
self._init_deficit(**model_kwargs)
if self.deflectionModel:
dw_ijlk, hcw_ijlk, dh_ijlk = self.deflectionModel.calc_deflection(**model_kwargs)
model_kwargs.update({'dw_ijlk': dw_ijlk, 'hcw_ijlk': hcw_ijlk, 'dh_ijlk': dh_ijlk,
'cw_ijlk': gradients.hypot(dh_ijlk, hcw_ijlk)})
self._reset_deficit()
if 'wake_radius_ijlk' in self.args4all:
model_kwargs['wake_radius_ijlk'] = self.wake_deficitModel.wake_radius(**model_kwargs)
if self.turbulenceModel:
model_kwargs['TI_eff_ilk'] = TI_eff_ilk
# Calculate deficit
if isinstance(self.superpositionModel, WeightedSum):
deficit_iilk, deficit_centre_iilk, uc_iilk, sigmasqr_iilk, blockage_iilk = self._calc_deficit_convection(
**model_kwargs)
deficit_centre_iilk *= i2i_zero
elif isinstance(self.superpositionModel, CumulativeWakeSum):
sigmasqr_iilk = (self.wake_deficitModel.sigma_ijlk(**model_kwargs))**2 * \
(model_kwargs['dw_ijlk'] > 1e-10)
deficit_iilk, blockage_iilk = self._calc_deficit(**model_kwargs)
else:
deficit_iilk, blockage_iilk = self._calc_deficit(**model_kwargs)
for i, ewf in enumerate(self.externalWindFarms, I - len(self.externalWindFarms)):
deficit_jlk = ewf(i=i, l=np.ones(L, dtype=bool), deficit_jlk=None, dst_xyh_jlk=dst_xyh_jlk,
**model_kwargs)
deficit_iilk = item_assign(deficit_iilk, idx=i, values=deficit_jlk)
# set own deficit to 0
deficit_iilk *= i2i_zero
if blockage_iilk is not None:
blockage_iilk *= i2i_zero
sp_kwargs = {'deficit_jxxx': deficit_iilk}
if isinstance(self.superpositionModel, (WeightedSum, CumulativeWakeSum)):
cw_ijlk = model_kwargs['cw_ijlk']
if self.wake_deficitModel.rotorAvgModel:
cw_ijlk = self.wake_deficitModel.rotorAvgModel(lambda **kwargs: kwargs['cw_ijlk'], **model_kwargs)
sp_kwargs.update({'sigma_sqr_jxxx': sigmasqr_iilk,
'cw_jxxx': cw_ijlk,
'hcw_jxxx': model_kwargs['hcw_ijlk'],
'dh_jxxx': dh_iilk})
if isinstance(self.superpositionModel, WeightedSum):
sp_kwargs.update({'WS_xxx': WS_ilk,
'convection_velocity_jxxx': uc_iilk,
'deficit_centre_jxxx': deficit_centre_iilk})
else:
sp_kwargs.update({'WS0_xxx': WS_ILK,
'WS_eff_xxx': model_kwargs['WS_eff_ilk'],
'ct_xxx': model_kwargs['ct_ilk'],
'D_xx': model_kwargs['D_src_il']})
WS_eff_ilk = WS_ilk.astype(dtype) - self.superpositionModel.superpose_deficit(**sp_kwargs)
if self.blockage_deficitModel:
WS_eff_ilk -= self.blockage_deficitModel.superpositionModel(blockage_iilk)
if self.turbulenceModel:
add_turb_ijlk = self.turbulenceModel(**model_kwargs)
add_turb_ijlk *= i2i_zero
TI_eff_ilk = self.turbulenceModel.calc_effective_TI(TI_ilk, add_turb_ijlk)
return WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict
WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict = self.solver(get_new_WS_eff_ilk, WS_eff_ilk, TI_eff_ilk,
max_iter)
# print("All2AllIterative converge after %d iterations" % (j + 1))
# print(self.iterations, np.abs(get_new_WS_eff_ilk(WS_eff_ilk, TI_eff_ilk)[0] - WS_eff_ilk).max())
self._reset_deficit()
kwargs.update({k: modified_input_dict[k] for k in modified_input_dict})
return WS_eff_ilk, np.broadcast_to(TI_eff_ilk, (I, L, K)), ct_ilk, kwargs
class All2AllIterativeSolver(ABC):
def __init__(self, no_convergence='warning', debug=False):
assert no_convergence in ['warning', 'error', 'ignore']
self.no_convergence = no_convergence
self.debug = debug
def __call__(self, get_new_WS_eff, WS_eff_ilk, TI_eff_ilk, max_iter):
self.diff = []
self.iteration = 0
def wrap(WS_eff_ilk_last, TI_eff_ilk_last):
try:
WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict = get_new_WS_eff(WS_eff_ilk_last, TI_eff_ilk_last)
self.last_result = WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict
err = WS_eff_ilk - WS_eff_ilk_last
self.diff.append([err.max(), err.min()][int(cabs(err.min()) > cabs(err.max()))])
if self.debug:
i, l, k = list(zip(*np.where(np.abs(err) == np.abs(err).max())))[0]
print(
f"Iteration: {len(self.diff)}, max diff_ilk: {self.diff[-1]:.6f}, ilk: ({i},{l},{k}), WS_eff: {WS_eff_ilk[i, l, k]}")
except StopIteration:
msg = f'All2AllIterative did not converge, max WS_eff difference from last iteration {self.diff[-1]}'
if self.no_convergence == 'warning':
warnings.warn(msg)
elif self.no_convergence == 'error':
raise Exception(msg)
return self.last_result
return WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict
return self._solve(wrap, WS_eff_ilk, TI_eff_ilk, max_iter)
@abc.abstractmethod
def _solve(self, get_new_WS_eff, WS_eff_ilk, TI_eff_ilk, max_iter):
""
def plot(self):
import matplotlib.pyplot as plt
plt.plot(self.diff, '.-')
plt.axhline(0, color='k')
class ScipyOptimizeSolver(All2AllIterativeSolver):
def __init__(self, optimizer, no_convergence='warning', debug=False, **kwargs):
All2AllIterativeSolver.__init__(self, no_convergence, debug)
self.optimizer = optimizer
self.kwargs = kwargs
def _solve(self, get_new_WS_eff, WS_eff_ilk, TI_eff_ilk, max_iter):
self.TI_eff_ilk = TI_eff_ilk
I, L, K = WS_eff_ilk.shape
def f(WS_eff):
# transform solving f(x)=x to root finding problem: 0 = f(x) - x
self.WS_eff_ilk, self.TI_eff_ilk = get_new_WS_eff(WS_eff.reshape((I, L, K)), self.TI_eff_ilk)[:2]
return self.WS_eff_ilk.ravel() - WS_eff
self.optimizer(f, WS_eff_ilk.ravel(), **{**self.kwargs})
return self.last_result
class FixedStep():
def reset(self, solver):
pass
def __call__(self, x, x_last, **_):
return x
class AdaptiveStep(FixedStep):
def __init__(self, a_min=0.7, a_max=1, a_decr=.1, a_incr=.1, start=10):
self.a_min = a_min
self.a_max = a_max
self.a_decr = a_decr
self.a_incr = a_incr
self.start = start
def reset(self, solver):
self.a = 1
self.a_lst = []
self.solver = solver
def __call__(self, x, x_last, **_):
if len(self.solver.diff) >= self.start:
if np.sign(self.solver.diff[-2:]).sum() == 0: # diff sign due to overshoot
self.a = np.maximum(self.a - self.a_decr, self.a_min)
else:
self.a = np.minimum(self.a + self.a_incr, self.a_max)
self.a_lst.append(self.a)
return (x - x_last) * self.a + x_last
class FixedPointSolver(All2AllIterativeSolver):
def __init__(self, tolerance=1e-6, step_func=FixedStep(), verbose=False, debug=False, no_convergence='warning'):
All2AllIterativeSolver.__init__(self, no_convergence)
self.tolerance = tolerance
self.step_func = step_func
self.verbose = verbose
self.debug = debug
def _solve(self, get_new_WS_eff, WS_eff_ilk, TI_eff_ilk, max_iter):
WS_eff_ilk_last = WS_eff_ilk + 0 # fast autograd-friendly copy
self.step_func.reset(self)
# Iterate until convergence
for j in tqdm(range(max_iter + 1), disable=not self.verbose,
desc="Calculate flow interaction (All2AllIterative)", unit="Iteration"):
WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict = get_new_WS_eff(WS_eff_ilk, TI_eff_ilk)
max_diff = cabs(self.diff[-1])
if self.tolerance is None or max_diff < self.tolerance:
break
WS_eff_ilk = self.step_func(WS_eff_ilk, WS_eff_ilk_last,
TI_eff_ilk=TI_eff_ilk, get_new_WS_eff=get_new_WS_eff)
WS_eff_ilk_last = WS_eff_ilk + 0 # fast autograd-friendly copy
return WS_eff_ilk, TI_eff_ilk, ct_ilk, modified_input_dict
def plot(self):
All2AllIterativeSolver.plot(self)
import matplotlib.pyplot as plt
plt.plot(getattr(self.step_func, 'a_lst', []), '.-')
class All2All(All2AllIterative):
def __init__(self, site, windTurbines, wake_deficitModel,
superpositionModel=LinearSum(),
blockage_deficitModel=None, deflectionModel=None, turbulenceModel=None,
rotorAvgModel=None):
All2AllIterative.__init__(self, site, windTurbines, wake_deficitModel, superpositionModel=superpositionModel,
blockage_deficitModel=blockage_deficitModel, deflectionModel=deflectionModel,
turbulenceModel=turbulenceModel, solver=self.solver,
rotorAvgModel=rotorAvgModel)
def _calc_wt_interaction(self, WS_eff_ilk, **kwargs):
return All2AllIterative._calc_wt_interaction(self, WS_eff_ilk=0, **kwargs)
def solver(self, get_new_WS_eff, WS_eff_ilk, TI_eff_ilk, max_iter):
return get_new_WS_eff(WS_eff_ilk, TI_eff_ilk)
+1
-1
Metadata-Version: 2.4
Name: py_wake
Version: 2.6.18
Version: 2.6.19
Summary: Open source static wake modeling framework from DTU

@@ -5,0 +5,0 @@ Author: DTU Wind Energy

@@ -12,2 +12,3 @@ import warnings

from py_wake.utils.grid_interpolator import GridInterpolator
from py_wake.utils import gradients

@@ -56,3 +57,3 @@

theta_ilk = np.deg2rad(yaw_ilk)
theta_ilk = gradients.deg2rad(yaw_ilk)
cos_ilk, sin_ilk = np.cos(theta_ilk), np.sin(theta_ilk)

@@ -59,0 +60,0 @@

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

if self.plane[0] in ['XZ', "YZ"]:
h_i = self.simulationResult.h.values
h_ilk = self.simulationResult.h.ilk()
x_ilk, y_ilk = self.simulationResult.x.ilk(), self.simulationResult.y.ilk()

@@ -236,6 +236,6 @@

if self.plane[0] == 'XZ':
fm.windTurbines.plot_yz(x_ilk[:, l, k], z_ilk[:, l, k], h_i, types=type_i, wd=wd, yaw=yaw, tilt=tilt,
fm.windTurbines.plot_yz(x_ilk[:, l, k], z_ilk[:, l, k], h_ilk[:, l, k], types=type_i, wd=wd, yaw=yaw, tilt=tilt,
normalize_with=normalize_with, ax=ax)
else:
fm.windTurbines.plot_yz(y_i, z_ilk[:, l, k], h_i, types=type_i, wd=self.wd, yaw=yaw, tilt=tilt,
fm.windTurbines.plot_yz(y_i, z_ilk[:, l, k], h_ilk[:, l, k], types=type_i, wd=self.wd, yaw=yaw, tilt=tilt,
normalize_with=normalize_with, ax=ax)

@@ -242,0 +242,0 @@ else: # self.plane[0] == "XY":

@@ -270,8 +270,8 @@ from abc import ABC, abstractmethod

if lo < 0:
sector[lo % 360 + 1:] = i
sector[lo % 360:] = i
lo = 0
if up > 359:
sector[:up % 360 + 1] = i
up = 359
sector[lo + 1:up + 1] = i
sector[:up % 360] = i
up = 360
sector[lo:up] = i
return sector

@@ -278,0 +278,0 @@

import matplotlib.pyplot as plt
from py_wake import np
from py_wake.deficit_models.gcl import GCLDeficit, get_dU
from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site
from py_wake.superposition_models import LinearSum
from py_wake.tests import npt
from py_wake.tests.check_speed import timeit
from py_wake.wind_farm_models.engineering_models import PropagateDownwind
from py_wake.tests.check_speed import timeit
from py_wake.examples.data.hornsrev1 import Hornsrev1Site, V80

@@ -27,7 +28,7 @@

# test that the result is equal to previuos runs (no evidens that these number are correct)
aep_ref = 1055.956615887197
# test that the result is equal to previuos runs (no evidence that these number are correct)
aep_ref = 1056.0418025254896
npt.assert_almost_equal(sim_res.aep_ilk(normalize_probabilities=True).sum(), aep_ref, 5)
sim_res = wfm(x, y, ws=np.arange(3, 10))
npt.assert_array_almost_equal(sim_res.aep_ilk(normalize_probabilities=True).sum(), 261.6143039016946, 5)
npt.assert_array_almost_equal(sim_res.aep_ilk(normalize_probabilities=True).sum(), 261.63664, 5)
import warnings
import matplotlib.pyplot as plt
import pytest
from numpy import newaxis as na
import matplotlib.pyplot as plt
from py_wake import np
from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussianDeficit
from py_wake.deficit_models.noj import NOJ
from py_wake.deficit_models.utils import ct2a_mom1d
from py_wake.examples.data import hornsrev1
from py_wake.examples.data.hornsrev1 import wt9_x, wt9_y, Hornsrev1Site
from py_wake.examples.data.hornsrev1 import Hornsrev1Site, wt9_x, wt9_y
from py_wake.tests import npt
from py_wake.utils.gradients import autograd, plot_gradients, fd, cs
from py_wake.utils.gradients import autograd, cs, fd, plot_gradients
from py_wake.wind_farm_models.engineering_models import PropagateDownwind
from py_wake.wind_farm_models.wind_farm_model import WindFarmModel
from py_wake.wind_turbines import WindTurbines, WindTurbine, OneTypeWindTurbines
from py_wake.wind_turbines import OneTypeWindTurbines, WindTurbine, WindTurbines
from py_wake.wind_turbines.power_ct_functions import PowerCtTabular
from py_wake.wind_turbines.wind_turbines_deprecated import DeprecatedWindTurbines, DeprecatedOneTypeWindTurbines
from numpy import newaxis as na
from py_wake.deficit_models.utils import ct2a_mom1d
from py_wake.deficit_models.noj import NOJ
from py_wake.wind_turbines.wind_turbines_deprecated import (
DeprecatedOneTypeWindTurbines,
DeprecatedWindTurbines,
)
WindFarmModel.verbose = False

@@ -54,3 +56,3 @@

npt.assert_array_equal(wts.types(), [0])
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0, yaw=0), 81.2066072392765)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0, yaw=0), 81.20692684738599)

@@ -57,0 +59,0 @@

@@ -359,2 +359,29 @@ import warnings

def test_flow_map_type():
site = IEA37Site(16)
v80 = V80()
v120 = WindTurbine('V120 low induction', 120, 90, powerCtFunction=PowerCtTabular(
hornsrev1.power_curve[:, 0], hornsrev1.power_curve[:, 1], 'w', hornsrev1.ct_curve[:, 1] * .8))
windTurbines = WindTurbines.from_WindTurbine_lst([v80, v120])
wfm = PropagateDownwind(site, windTurbines,
wake_deficitModel=IEA37SimpleBastankhahGaussianDeficit(),
superpositionModel=SquaredSum())
sim_res1, sim_res2 = [wfm([0, -50], [0, 0], h=[70, 150], type=[0, 1], wd=[90, 270], n_cpu=n) for n in [1, 2]]
fm_dict = {(i, j): sim_res.flow_map(XZGrid(y=0, z=np.linspace(0, 250), x=100), wd=270, n_cpu=j)
for j in [1, 2] for i, sim_res in enumerate([sim_res1, sim_res2], 1)}
if 0:
sim_res1.flow_map(XZGrid(y=0, z=np.linspace(0, 250)), wd=270).plot_wake_map()
for (i, j), fm in fm_dict.items():
plt.plot(fm.WS_eff.squeeze() * 10, fm.h, label=f'WS_eff x 10, n_cpu=({i}, {j})')
plt.legend()
plt.show()
for (i, j), fm in fm_dict.items():
npt.assert_array_equal(fm.WS_eff.squeeze(), fm_dict[(1, 1)].WS_eff.squeeze())
def test_aep_map():

@@ -380,3 +407,3 @@ wfm = IEA37CaseStudy1(16)

v80 = V80()
v120 = WindTurbine('V80_low_induc', 80, 70, powerCtFunction=PowerCtTabular(
v120 = WindTurbine('V120', 120, 150, powerCtFunction=PowerCtTabular(
hornsrev1.power_curve[:, 0], hornsrev1.power_curve[:, 1] * 1.5, 'w', hornsrev1.ct_curve[:, 1]))

@@ -383,0 +410,0 @@

import os
import matplotlib.pyplot as plt
import pytest
from py_wake import np
import matplotlib.pyplot as plt
from py_wake.tests import npt
from py_wake.site._site import UniformWeibullSite, UniformSite
from py_wake.examples.data.iea37._iea37 import IEA37Site
from py_wake.site._site import UniformSite, UniformWeibullSite
from py_wake.site.shear import PowerShear
from py_wake.site.xrsite import XRSite
from py_wake.tests import npt
from py_wake.tests.test_files import tfp
from py_wake.examples.data.iea37._iea37 import IEA37Site

@@ -100,4 +102,4 @@ f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348,

p = site.plot_ws_distribution(wd=[90, 180, 270, 0], include_wd_distribution=True)
npt.assert_array_almost_equal(p.ws[p.argmax('ws')], [8.25, 8.15, 9.55, 7.75, ])
npt.assert_array_almost_equal(p.max('ws'), [0.002182, 0.002771, 0.003548, 0.001257])
npt.assert_array_almost_equal(p.ws[p.argmax('ws')], [8.25, 8.15, 9.55, 7.75])
npt.assert_array_almost_equal(p.max('ws'), [0.002169, 0.002771, 0.003548, 0.001269])

@@ -104,0 +106,0 @@ if 0:

@@ -305,4 +305,4 @@ import contextlib

plt.close('all')
npt.assert_array_almost_equal(p, [0.052, 0.043, 0.058, 0.085, 0.089, 0.061,
0.047, 0.083, 0.153, 0.152, 0.108, 0.068], 3)
npt.assert_array_almost_equal(p, [0.053, 0.043, 0.057, 0.084, 0.09, 0.062, 0.047, 0.081, 0.151,
0.153, 0.11, 0.069], 3)

@@ -316,14 +316,14 @@

plt.show()
npt.assert_array_almost_equal(p, [[0.039, 0.013, 0.001, 0.0, 0.0],
npt.assert_array_almost_equal(p, [[0.039, 0.014, 0.001, 0.0, 0.0],
[0.034, 0.009, 0.0, 0.0, 0.0],
[0.035, 0.022, 0.0, 0.0, 0.0],
[0.034, 0.048, 0.003, 0.0, 0.0],
[0.034, 0.047, 0.003, 0.0, 0.0],
[0.031, 0.052, 0.007, 0.0, 0.0],
[0.03, 0.03, 0.002, 0.0, 0.0],
[0.03, 0.031, 0.002, 0.0, 0.0],
[0.027, 0.019, 0.001, 0.0, 0.0],
[0.034, 0.043, 0.006, 0.0, 0.0],
[0.047, 0.082, 0.023, 0.001, 0.0],
[0.048, 0.074, 0.026, 0.003, 0.0],
[0.044, 0.046, 0.015, 0.002, 0.0],
[0.041, 0.023, 0.003, 0.0, 0.0]], 3)
[0.034, 0.041, 0.006, 0.0, 0.0],
[0.047, 0.081, 0.022, 0.001, 0.0],
[0.048, 0.074, 0.027, 0.003, 0.0],
[0.044, 0.047, 0.016, 0.003, 0.0],
[0.041, 0.024, 0.004, 0.0, 0.0]], 3)
plt.close('all')

@@ -330,0 +330,0 @@

@@ -1,28 +0,32 @@

from py_wake import np
from py_wake.site.shear import PowerShear
from py_wake.site.xrsite import XRSite, GlobalWindAtlasSite, UniformSite
import warnings
from urllib.error import HTTPError, URLError
import matplotlib.pyplot as plt
import pytest
import xarray as xr
from py_wake.tests import npt
import pytest
import matplotlib.pyplot as plt
from numpy import newaxis as na
from py_wake.tests.test_files import tfp
from py_wake.examples.data.hornsrev1 import Hornsrev1Site, V80
from py_wake import np
from py_wake.deficit_models.gaussian import (
BastankhahGaussian,
BastankhahGaussianDeficit,
)
from py_wake.deficit_models.noj import NOJ
from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines, IEA37Site
from py_wake.wind_turbines import WindTurbines
from py_wake.deficit_models.gaussian import BastankhahGaussian, BastankhahGaussianDeficit
from py_wake.wind_farm_models.engineering_models import PropagateDownwind
from py_wake.examples.data.ParqueFicticio._parque_ficticio import ParqueFicticioSite
from py_wake.flow_map import XYGrid
from py_wake.site._site import LocalWind
from py_wake.site.shear import PowerShear
from py_wake.site.xrsite import GlobalWindAtlasSite, UniformSite, XRSite
from py_wake.superposition_models import LinearSum
from py_wake.tests import npt
from py_wake.tests.check_speed import timeit
from py_wake.site._site import LocalWind
from py_wake.tests.test_files import tfp
from py_wake.utils import weibull
from py_wake.deficit_models.noj import NOJ
from py_wake.flow_map import XYGrid
import warnings
from urllib.error import HTTPError, URLError
from py_wake.examples.data.ParqueFicticio._parque_ficticio import ParqueFicticioSite
from py_wake.utils.gradients import fd, autograd, cs
from py_wake.utils.functions import mean_deg
from py_wake.utils.gradients import autograd, cs, fd
from py_wake.wind_farm_models.engineering_models import PropagateDownwind
from py_wake.wind_turbines import WindTurbines
f = [0.035972, 0.039487, 0.051674, 0.070002, 0.083645, 0.064348,

@@ -403,3 +407,3 @@ 0.086432, 0.117705, 0.151576, 0.147379, 0.10012, 0.05166]

res = complex_ws_site.plot_wd_distribution()
ref = [0.0312, 0.0332, 0.043, 0.0568, 0.0648, 0.0567, 0.0718, 0.0967, 0.1199, 0.1154, 0.0809, 0.045]
ref = [0.0314, 0.033, 0.0426, 0.0564, 0.0649, 0.0567, 0.0711, 0.0958, 0.1195, 0.1161, 0.0822, 0.0459]
if 0:

@@ -406,0 +410,0 @@ print(np.round(res.squeeze().values, 4).tolist())

@@ -0,6 +1,7 @@

import matplotlib.pyplot as plt
import pytest
from autograd import numpy as anp
from autograd.core import primitive, defvjp
import pytest
import matplotlib.pyplot as plt
from autograd.core import defvjp, primitive
from xarray.core.dataset import Dataset
from numpy import newaxis as na
from py_wake import np

@@ -11,8 +12,15 @@ from py_wake.examples.data.hornsrev1 import V80

from py_wake.utils import gradients
from py_wake.utils.gradients import autograd, plot_gradients, fd, cs, hypot, cabs, interp, set_gradient_function, \
item_assign
from py_wake.wind_turbines import WindTurbines
from py_wake.wind_turbines import _wind_turbines
from xarray.core.dataset import Dataset
from py_wake.utils.gradients import (
autograd,
cabs,
cs,
fd,
hypot,
interp,
item_assign,
plot_gradients,
set_gradient_function,
)
from py_wake.utils.numpy_utils import AutogradNumpy
from py_wake.wind_turbines import WindTurbines, _wind_turbines

@@ -269,2 +277,7 @@

def test_minimum():
assert gradients.minimum(4, 5) == 4
assert autograd(gradients.minimum)(4, 5) == 1
@pytest.mark.parametrize('x', [0., .4])

@@ -532,1 +545,25 @@ def test_sqrt_sqare(x):

npt.assert_array_equal(cs(f)(x), autograd(f)(x))
def test_isin():
npt.assert_array_equal(gradients.isin([2, 3, 4], [4, 5]), [0, 0, 1])
x = np.array([2., 3, 4, 5, 6])
def f(x):
return np.sum(x[gradients.isin(x, [4, 5])])
def g(y):
return np.sum(x[gradients.isin(x, y)])
npt.assert_array_equal(autograd(f)(x), [0, 0, 1, 1, 0])
npt.assert_array_equal(autograd(g)([4., 5]), [0, 0])
def test_floor():
x = np.array([.49, .5, .51, 1.49, 1.5, 1.51])
npt.assert_array_equal(gradients.floor(x), np.floor(x))
npt.assert_array_equal(gradients.floor(x + 1j), np.floor(x) + 1j)
x = (np.linspace(-3, 3)[na] + np.linspace(-3, 3)[:, na] * 1j).flatten()
npt.assert_array_equal(gradients.floor(x + .5 + .5j), np.round(x))
print()
import matplotlib.pyplot as plt
import pytest
import xarray as xr
import matplotlib.pyplot as plt
from py_wake import np
from py_wake.tests import npt
from py_wake.tests.check_speed import timeit
from py_wake.utils.grid_interpolator import GridInterpolator, EqDistRegGrid2DInterpolator
import xarray as xr
from py_wake.utils.grid_interpolator import (
EqDistRegGrid2DInterpolator,
GridInterpolator,
)

@@ -78,7 +81,7 @@

(['linear', 'linear', 'linear'], [15.5, 40.5, 42.5, 47.5, 48]),
('nearest', [25, 46, 48, 53, 54]), # [25, 47, 49, 54, 54]
(['nearest', 'nearest', 'nearest'], [25, 46, 48, 53, 54]), # [25, 47, 49, 54, 54]
('nearest', [26, 47, 49, 54, 54]),
(['nearest', 'nearest', 'nearest'], [26, 47, 49, 54, 54]),
('linear', [15.5, 40.5, 42.5, 47.5, 48]),
(['linear', 'linear', 'nearest'], [15, 40, 42, 47, 48]), # [15, 41, 43, 48, 48]
(['nearest', 'linear', 'nearest'], [23, 48, 50, 55, 56]), # [23, 49, 51, 56, 56]
(['linear', 'linear', 'nearest'], [16., 41., 43., 48., 48.]),
(['nearest', 'linear', 'nearest'], [24., 49., 51., 56., 56.]),

@@ -85,0 +88,0 @@ ])

@@ -37,2 +37,3 @@ import warnings

from py_wake.tests import npt
from py_wake.tests.test_verification.test_turbopark import kwargs
from py_wake.turbulence_models.stf import STF2005TurbulenceModel, STF2017TurbulenceModel

@@ -73,2 +74,3 @@ from py_wake.turbulence_models.turbulence_model import TurbulenceModel

cs(output_func, True, 0)(xp, wt_y, **kwargs)
dOutputdx_lst = [grad(output_func, True, 0)(xp, wt_y, **kwargs)[2] for grad in [fdstep, cs, autograd]]

@@ -75,0 +77,0 @@ npt.assert_almost_equal(dOutputdx_lst[0], dOutputdx_lst[1], fd_decimal)

@@ -0,14 +1,21 @@

import matplotlib.pyplot as plt
import pytest
import xarray as xr
from scipy.optimize._nonlin import anderson
import matplotlib.pyplot as plt
from py_wake import np
from py_wake.deficit_models.fuga import FugaDeficit
from py_wake.deficit_models.gaussian import TurboGaussianDeficit
from py_wake.deficit_models.no_wake import NoWakeDeficit
from py_wake.deficit_models.noj import NOJDeficit
from py_wake.deficit_models.rathmann import Rathmann
from py_wake.deficit_models.selfsimilarity import SelfSimilarityDeficit
from py_wake.deficit_models.selfsimilarity import (
SelfSimilarityDeficit,
SelfSimilarityDeficit2020,
)
from py_wake.deflection_models.jimenez import JimenezWakeDeflection
from py_wake.examples.data import wtg_path
from py_wake.examples.data.hornsrev1 import Hornsrev1Site, V80, wt16_x, wt16_y
from py_wake.examples.data.iea37._iea37 import IEA37Site, IEA37_WindTurbines
from py_wake.examples.data.dtu10mw._dtu10mw import DTU10MW
from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site, wt16_x, wt16_y
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines, IEA37Site
from py_wake.flow_map import XYGrid

@@ -18,7 +25,13 @@ from py_wake.rotor_avg_models.rotor_avg_model import CGIRotorAvg

from py_wake.superposition_models import LinearSum
from py_wake.wind_farm_models.engineering_models import All2AllIterative
from py_wake.turbulence_models.crespo import CrespoHernandez
from py_wake.wind_farm_models import All2AllIterative
from py_wake.wind_farm_models.all2alliterative import (
AdaptiveStep,
FixedPointSolver,
FixedStep,
ScipyOptimizeSolver,
)
from py_wake.wind_turbines._wind_turbines import WindTurbines
import xarray as xr
from py_wake.examples.data.iea34_130rwt._iea34_130rwt import IEA34_130_1WT_Surrogate
from py_wake.turbulence_models.stf import STF2017TurbulenceModel
import contextlib
import warnings

@@ -86,12 +99,21 @@

def test_convergence_hornsrev():
@pytest.mark.parametrize('solver,it', [(None, 10),
(FixedPointSolver(step_func=FixedStep()), 10),
(FixedPointSolver(step_func=AdaptiveStep()), 10),
(ScipyOptimizeSolver(optimizer=anderson, M=5, alpha=1), 9)
])
def test_convergence_hornsrev(solver, it):
site = Hornsrev1Site()
wfm = All2AllIterative(site, windTurbines=V80(),
wake_deficitModel=NOJDeficit(),
blockage_deficitModel=RathmannCounter())
blockage_deficitModel=RathmannCounter(),
solver=solver)
x, y = site.initial_position.T
sim_res = wfm(x, y, wd=90)
assert wfm.blockage_deficitModel.counter == 13
assert wfm.blockage_deficitModel.counter == it
wfm.solver.plot()
if 0:
plt.figure()
sim_res.flow_map().plot_wake_map()

@@ -101,3 +123,8 @@ plt.show()

def test_not_converge():
@pytest.mark.parametrize('solver', [FixedPointSolver(step_func=FixedStep()),
FixedPointSolver(step_func=FixedStep(), no_convergence='error'),
FixedPointSolver(step_func=AdaptiveStep()),
ScipyOptimizeSolver(optimizer=anderson, M=5, alpha=1)
])
def test_not_converge(solver):
class RandomRathmann(Rathmann):

@@ -111,7 +138,46 @@

wake_deficitModel=NOJDeficit(),
blockage_deficitModel=RandomRathmann())
with pytest.warns(match='All2AllIterative did not converge, max WS_eff difference from last iteration '):
wfm(wt16_x, wt16_y)
blockage_deficitModel=RandomRathmann(),
solver=solver)
if solver.no_convergence == 'warning':
with pytest.warns(match='All2AllIterative did not converge, max WS_eff difference from last iteration '):
wfm(wt16_x, wt16_y)
elif solver.no_convergence == 'error':
with pytest.raises(Exception, match='All2AllIterative did not converge, max WS_eff difference from last iteration '):
wfm(wt16_x, wt16_y)
else:
with warnings.catch_warnings():
warnings.filterwarnings('error')
wfm(wt16_x, wt16_y)
def test_convergence():
site = Hornsrev1Site()
solver = FixedPointSolver(step_func=FixedStep(), verbose=0, debug=True)
wake_deficitModel = TurboGaussianDeficit()
turbulenceModel = CrespoHernandez()
wfm = All2AllIterative(site,
DTU10MW(),
wake_deficitModel=wake_deficitModel,
blockage_deficitModel=SelfSimilarityDeficit2020(),
turbulenceModel=turbulenceModel,
superpositionModel=LinearSum(),
solver=solver,
)
x = np.array([209.0, -267.0, 1248.0, 1190.0])
y = np.array([921.0, 1676.0, 124.0, 1583.0])
with contextlib.redirect_stdout(None):
sim_res = wfm(x, y, ws=4, wd=300)
if 0:
for i, ct in enumerate(np.array(wfm.ct_ilk_lst).squeeze().T):
plt.plot(np.arange(len(ct)) + i / 20, ct, '.-', label=i)
plt.legend()
plt.figure()
solver.plot()
plt.figure()
sim_res.flow_map().plot_wake_map()
plt.show()
assert wfm.iterations == 9
#
# def test_convergence():

@@ -133,4 +199,4 @@ # """Unstable from beginning

# plt.show()
#
#
# def test_convergence2():

@@ -137,0 +203,0 @@ # # stable case. WT 0 should turn on due to speedup of wt1

@@ -0,22 +1,32 @@

import os
import warnings
import matplotlib.pyplot as plt
import pytest
from py_wake import np
from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussianDeficit, BastankhahGaussian
from py_wake import examples, np
from py_wake.deficit_models.gaussian import (
BastankhahGaussian,
IEA37SimpleBastankhahGaussianDeficit,
)
from py_wake.deficit_models.noj import NOJ
from py_wake.examples.data.hornsrev1 import Hornsrev1Site, V80, wt9_y, wt9_x, wt16_x, wt16_y
from py_wake.examples.data.iea37._iea37 import IEA37Site, IEA37_WindTurbines
from py_wake.wind_turbines import WindTurbines
from py_wake.tests import npt
from py_wake.utils.gradients import autograd, cs, fd
from py_wake.utils.profiling import timeit, profileit
import matplotlib.pyplot as plt
from py_wake.deficit_models.utils import ct2a_mom1d
from py_wake.deflection_models.jimenez import JimenezWakeDeflection
from py_wake.examples.data.hornsrev1 import (
V80,
Hornsrev1Site,
wt9_x,
wt9_y,
wt16_x,
wt16_y,
)
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines, IEA37Site
from py_wake.flow_map import XYGrid
import os
from py_wake import examples
from py_wake.literature.iea37_case_study1 import IEA37CaseStudy1
from py_wake.site._site import UniformSite
from py_wake.tests import npt
from py_wake.utils.gradients import autograd, cs, fd
from py_wake.utils.profiling import profileit, timeit
from py_wake.wind_farm_models.engineering_models import PropagateDownwind
from py_wake.site._site import UniformSite
from py_wake.deficit_models.utils import ct2a_mom1d
import warnings
from py_wake.wind_turbines import WindTurbines

@@ -123,5 +133,5 @@

dAEP_autograd = wfm.aep_gradients(gradient_method=autograd, wrt_arg=wrt_arg)(**kwargs)
dAEP_cs = wfm.aep_gradients(gradient_method=cs, wrt_arg=wrt_arg)(**kwargs)
dAEP_fd = wfm.aep_gradients(gradient_method=fd, wrt_arg=wrt_arg)(**kwargs)
dAEP_autograd = wfm.aep_gradients(gradient_method=autograd, wrt_arg=wrt_arg)(**kwargs)[0]
dAEP_cs = wfm.aep_gradients(gradient_method=cs, wrt_arg=wrt_arg)(**kwargs)[0]
dAEP_fd = wfm.aep_gradients(gradient_method=fd, wrt_arg=wrt_arg)(**kwargs)[0]

@@ -132,5 +142,7 @@ if 0:

ax2.set_title(wrt_arg)
ax2.plot(dAEP_autograd.flatten(), '.', label='autograd')
ax2.plot(dAEP_cs.flatten(), '.', label='cs')
ax2.plot(dAEP_fd.flatten(), '.', label='fd')
x = np.arange(len(dAEP_autograd.flatten()))
ax2.plot(x, dAEP_autograd.flatten(), '.', label='autograd')
ax2.plot(x + .1, dAEP_cs.flatten(), '.', label='cs')
ax2.plot(x + .2, dAEP_fd.flatten(), '.', label='fd')
ax2.ticklabel_format(useOffset=False)
plt.legend()

@@ -141,3 +153,2 @@ plt.show()

npt.assert_array_almost_equal(dAEP_autograd, dAEP_fd, 5)
npt.assert_array_equal(dAEP_autograd, wfm.aep_gradients(gradient_method=autograd, wrt_arg=wrt_arg, **kwargs))

@@ -317,4 +328,4 @@

from py_wake.literature.gaussian_models import Blondel_Cathelain_2020
from py_wake.turbulence_models import CrespoHernandez
from py_wake.literature.gaussian_models import Blondel_Cathelain_2020

@@ -321,0 +332,0 @@ site = IEA37Site(16)

import os
import warnings
import matplotlib.pyplot as plt
import pytest
import matplotlib.pyplot as plt
from py_wake import np
from py_wake.deficit_models.gaussian import IEA37SimpleBastankhahGaussianDeficit
from py_wake.deficit_models.noj import NOJDeficit
from py_wake.examples.data import wtg_path, hornsrev1
from py_wake.examples.data.hornsrev1 import V80, wt9_x, wt9_y, Hornsrev1Site
from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines, IEA37WindTurbines, IEA37Site
from py_wake.deficit_models.utils import ct2a_mom1d
from py_wake.examples.data import hornsrev1, wtg_path
from py_wake.examples.data.hornsrev1 import V80, Hornsrev1Site, wt9_x, wt9_y
from py_wake.examples.data.iea37._iea37 import (
IEA37_WindTurbines,
IEA37Site,
IEA37WindTurbines,
)
from py_wake.superposition_models import SquaredSum

@@ -14,7 +22,8 @@ from py_wake.tests import npt

from py_wake.utils.gradients import autograd, plot_gradients
from py_wake.wind_farm_models.engineering_models import PropagateDownwind, All2AllIterative
from py_wake.wind_turbines import WindTurbines, WindTurbine, OneTypeWindTurbines
from py_wake.wind_farm_models.engineering_models import (
All2AllIterative,
PropagateDownwind,
)
from py_wake.wind_turbines import OneTypeWindTurbines, WindTurbine, WindTurbines
from py_wake.wind_turbines.power_ct_functions import PowerCtTabular
import warnings
from py_wake.deficit_models.utils import ct2a_mom1d

@@ -55,3 +64,3 @@

npt.assert_array_equal(wts.types(), [0])
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0, yaw=0), 81.2066072392765)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0, yaw=0), 81.2069268)

@@ -71,3 +80,3 @@

npt.assert_array_equal(wts.types(), [0])
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.2066072392765)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.20692684)

@@ -80,3 +89,3 @@

npt.assert_array_equal(wts.types(), [0])
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.2066072392765)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.20692684738599)

@@ -111,5 +120,5 @@

npt.assert_array_equal(wts.types(), [0, 1])
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.2066072392765)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types1), 83.72420504573488)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types2), 88.87227386796884)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types0), 81.20692684738599)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types1), 83.72460696861253)
npt.assert_almost_equal(wfm.aep(wt9_x, wt9_y, type=types2), 88.87264035035497)

@@ -116,0 +125,0 @@

@@ -435,1 +435,16 @@ import inspect

return np.sign(x)
def floor(x):
if np.iscomplexobj(x):
return np.floor(x.real) + np.floor(x.imag) * 1j
else:
return np.floor(x)
def isin(element, test_elements, assume_unique=False, invert=False, *, kind=None):
if isinstance(element, ArrayBox):
element = element._value
if isinstance(test_elements, ArrayBox):
test_elements = test_elements._value
return np.isin(element, test_elements, assume_unique, invert, kind=kind)

@@ -0,6 +1,7 @@

from autograd.numpy.numpy_boxes import ArrayBox
from numpy import atleast_1d
from numpy import newaxis as na
from py_wake import np
from numpy import newaxis as na
from numpy import atleast_1d
from py_wake.utils import gradients
from autograd.numpy.numpy_boxes import ArrayBox

@@ -62,6 +63,11 @@

return np.array([])
method = atleast_1d(method or self.method)
if method is None:
method = self.method
method = np.atleast_1d(method)
assert all([m in ['linear', 'nearest'] for m in method]), 'method must be "linear" or "nearest"'
assert len(method) in [1, len(self.x)]
linear = [method[min(len(method) - 1, i)] == 'linear' for i in range(len(self.x))]
chunks = np.maximum(2**np.sum(linear) * np.prod(np.shape(xp)) * 8 / 1024**2 // 100, 1)
if chunks > 1:
return np.concatenate([self.__call__(xp_, method, bounds, deg) for xp_ in np.array_split(xp, chunks)])
bounds = bounds or self.bounds

@@ -94,4 +100,5 @@ assert bounds in ['check', 'limit', 'ignore'], 'bounds must be "check", "limit" or "ignore"'

if 'nearest' in method:
# round x.5 down to match old results
xpi = np.where(np.asarray(linear), xpi, np.round(xpi - .1 * (gradients.mod(xpi, 2) == 1.5)))
# round x.5 up (np.round rounds x.5 towards nearest even number)
xpi = np.where(np.asarray(linear), xpi, gradients.floor(xpi + .5))
xpif, xpi0 = gradients.modf(xpi)

@@ -98,0 +105,0 @@

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

import warnings
import matplotlib.pyplot as plt

@@ -21,2 +23,4 @@

ax.legend()
plt.tight_layout()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
plt.tight_layout()

@@ -29,3 +29,3 @@ import ctypes

time_start = time.perf_counter()
for i in range(100000):
for i in range(10000000):
t0 = time.perf_counter_ns()

@@ -32,0 +32,0 @@ res = func(*args, **kwargs)

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

from py_wake import np
from py_wake.utils import gradients

@@ -81,3 +82,3 @@ try: # pragma: no cover

indices = None
if ip_dims and ip_dims[-1] == name and np.all(np.array([x in np.atleast_1d(v) for x in c])):
if ip_dims and ip_dims[-1] == name and np.all(gradients.isin(c, np.atleast_1d(v))):
# all coordinates in var, no need to interpolate

@@ -84,0 +85,0 @@ ip_dims.remove(name)

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

__version__ = version = '2.6.18'
__version_tuple__ = version_tuple = (2, 6, 18)
__version__ = version = '2.6.19'
__version_tuple__ = version_tuple = (2, 6, 19)
__commit_id__ = commit_id = None

@@ -1,2 +0,3 @@

from .engineering_models import PropagateDownwind, All2AllIterative, PropagateUpDownIterative
from .engineering_models import PropagateDownwind, PropagateUpDownIterative
from .all2alliterative import All2AllIterative, All2All
from .wind_farm_model import WindFarmModel

@@ -57,7 +57,8 @@ from abc import ABC, abstractmethod

def _run(self, x, y, h=None, type=0, wd=None, ws=None, time=False, verbose=False, # @ReservedAssignment
def _run(self, x, y, h=None, type=0, wd=None, ws=None, time=False, verbose=None, # @ReservedAssignment
n_cpu=1, wd_chunks=None, ws_chunks=1, **kwargs):
assert len(x) == len(y)
self.verbose = verbose
if verbose is not None:
self.verbose = verbose
h, _ = self.windTurbines.get_defaults(len(x), type, h)

@@ -86,3 +87,3 @@ if len(self.externalWindFarms):

def __call__(self, x, y, h=None, type=0, wd=None, ws=None, time=False, verbose=False, # @ReservedAssignment
def __call__(self, x, y, h=None, type=0, wd=None, ws=None, time=False, verbose=None, # @ReservedAssignment
n_cpu=1, wd_chunks=None, ws_chunks=1, return_simulationResult=True, **kwargs):

@@ -295,4 +296,4 @@ """Run the wind farm simulation

wd_i = np.linspace(0, len(wd) + 1, wd_chunks + 1).astype(int)
ws_i = np.linspace(0, len(ws) + 1, ws_chunks + 1).astype(int)
wd_i = np.linspace(0, len(wd), wd_chunks + 1).astype(int)
ws_i = np.linspace(0, len(ws), ws_chunks + 1).astype(int)

@@ -299,0 +300,0 @@ if time is False:

+30
-29

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

py_wake/__init__.py,sha256=plc0Tgq4NHJw8YvzBvdgI50r5tWRznHaMzZgvrJSXqc,1181
py_wake/flow_map.py,sha256=pZCV-mbPDtVLuvdGejKJhUnR52VorJ7fobP10Oj7ZL4,22441
py_wake/flow_map.py,sha256=qy41iLSPl9Ib5D_vp6MSjwsMAH7_zfJVZWGOIGBXxSE,22464
py_wake/superposition_models.py,sha256=wJ-JJElwdWiNOwv1v0NXjbTV1ZbbBSmC-GJziO1YPJs,10669
py_wake/version.py,sha256=KNVa8zi0dOmLXNcGcJ8wLrs5TVLuqMMpRIpCkCHGrMI,706
py_wake/version.py,sha256=kC4ybwru7e2hQXr01lB38YZjU_2S2x423Mxg6jLVJRk,706
py_wake/deficit_models/__init__.py,sha256=w1S4F3FmAgtwqGO90fASYoqxOb6SsgjbasiD3V8_1uk,709

@@ -28,3 +28,3 @@ py_wake/deficit_models/deficit_model.py,sha256=ly8A6pZQ6kt39fzsAz9OVw_5ohr7b26I5iHRYni2QrM,10466

py_wake/deflection_models/deflection_model.py,sha256=NRDbCrLxAB65Wd_1GrOWP6dJKYf-XJ9Qjl9HZ_VqEZw,3285
py_wake/deflection_models/fuga_deflection.py,sha256=_DX4VNYjJGX7C7H44z4foCfcgiYhFWyIJAzd6NC_mnI,6817
py_wake/deflection_models/fuga_deflection.py,sha256=jsIN40ysQJk7X4BS3Rwew055SGLOHlpcOrinJ6CO8ic,6860
py_wake/deflection_models/gcl_hill_vortex.py,sha256=RVzjomvLIU9Pjkyo4I7UFNgWmoL87PY5SQQbyr90SXE,4484

@@ -286,3 +286,3 @@ py_wake/deflection_models/jimenez.py,sha256=i48tR__COvfllN_5oagnPwvjBA6Axp09s7Ydv2yNGhU,2765

py_wake/site/__init__.py,sha256=YeIRWHuiIo0cRD3NIcaqgoWL6u-NfQkDo3uQsgAxjj4,161
py_wake/site/_site.py,sha256=DfGxjqTwiOm_XSTBYRV3LAwBVghknNbOFWsBUOH5Rg4,16210
py_wake/site/_site.py,sha256=PVTl-FcZgHAhpRG_Ioy2QdObbrzVugztBtNQ8FF6TDw,16194
py_wake/site/distance.py,sha256=61kvn9ye6ld_vn7rTdJ0GgLjA41uB4e_esnoXDWumzw,8947

@@ -298,3 +298,3 @@ py_wake/site/jit_streamline_distance.py,sha256=GJo2mn_bTjuGX3-gSGkv1dkRfo7hGDVKDmefRWYk5o8,159

py_wake/tests/notebook.py,sha256=21RVNXcqRCy6b3GoRcKxR5E0IGV2d9U6BaqqOKZ8f8Y,6804
py_wake/tests/test_flow_map.py,sha256=eJOyk5Jtku0dewznV0owGucDGSRpfyDaZZrxVZVqWxI,22799
py_wake/tests/test_flow_map.py,sha256=uLdufYDabJsUKdaGLAOKrKfBoqhXtBIHv5GM-aK_BSg,24012
py_wake/tests/test_main.py,sha256=pc01ZUXMnFDHZwNh7ulqP5FWZDt9I7-gp0D_TN2-9Bs,1914

@@ -309,3 +309,3 @@ py_wake/tests/test_notebooks.py,sha256=eB95mMOWg-FRHqpbuEIdcNEO2E7mc_nwAVD2yxpxl5E,2216

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_gcl.py,sha256=kqiZVAZ1Ksq5MRJvfFu_64Q-1iXjAVtTLPNfN8W0x-o,1184
py_wake/tests/test_deficit_models/test_noj.py,sha256=qJVv3q3Lp_QILFn-6xdslWevvR4Dmnx0AWj39XCIdXw,5495

@@ -320,3 +320,3 @@ py_wake/tests/test_deficit_models/test_rans_lut.py,sha256=9u94ZVzzGIRZEdJ0CftcN8LX1htqoXrw_U8y35Hi2eM,21881

py_wake/tests/test_deprecated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
py_wake/tests/test_deprecated/test_deprecated_windturbines.py,sha256=LxFkHPX5QJtu1ZRBgXY-W2D3yxzQ11BWRSyFePxwxBA,8135
py_wake/tests/test_deprecated/test_deprecated_windturbines.py,sha256=A7384UtpBvYqA0jgbeNucQo4LZCQqCDdIItwjMxVdL0,8148
py_wake/tests/test_files/__init__.py,sha256=RnRBXbJeH4yQQaRxCgu0Ggnrxb2B0-HeVl_cos0pRW8,67

@@ -345,6 +345,6 @@ py_wake/tests/test_files/fuga/__init__.py,sha256=Mimd77HrbCb-SB8sHz-B0NOMORNFoKpkFMSBnC3a2i8,107

py_wake/tests/test_sites/test_shear_models.py,sha256=g4zg1QCvl2WQY6f10BiRlBAnyJyaaQRVpeiLnkNT4SU,4053
py_wake/tests/test_sites/test_site.py,sha256=NpE0hX1l17fZmzmrBR5x8w12Hc8Bu5w3NzGG9W60URk,11205
py_wake/tests/test_sites/test_wasp_grid_site.py,sha256=lU3N1uVmEyL7rqrb9Upmm3YJtvHj8gsGy8c-a4zLAMk,15644
py_wake/tests/test_sites/test_site.py,sha256=Xf1irQqtCkWNnaTxLT1cH904jr4mYSGpXNkiLesfiAo,11205
py_wake/tests/test_sites/test_wasp_grid_site.py,sha256=KFNSfHeZYOLtNf9eqd3DknzJU5FWacfF-w8nbgLIVpo,15643
py_wake/tests/test_sites/test_wrf.py,sha256=MKTJG7YNHOYES69m8vIzrQzXL6xyubXK90zTDF6aXbQ,3504
py_wake/tests/test_sites/test_xrsite.py,sha256=lvfjrm0rVDvLfJ9O0vKzj1yVecxBWlrMK-Rt1RmVg2M,31451
py_wake/tests/test_sites/test_xrsite.py,sha256=CWAH7-D8emZfU7yeyZIAvYbQcynhh2_gEa2_kCEySLc,31466
py_wake/tests/test_turbulence_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@@ -358,7 +358,7 @@ py_wake/tests/test_turbulence_models/test_rans_lut_turb.py,sha256=koOW0RJ3lXQDUplY-0Sj4r-6mq1FvLJUH4z3EqETHYc,2696

py_wake/tests/test_utils/test_gpu_cupy.py,sha256=tqj2MvNyt0S0FGtkx_Hj3tfLMpNWIj3QGPPbBTxg3OY,1907
py_wake/tests/test_utils/test_gradient_utils.py,sha256=vyacCD9xviDv1YUBmgRoQbG4E1ZiMpSg27anfunw3Kw,16514
py_wake/tests/test_utils/test_grid_interpolator.py,sha256=XWXlIhCpxoRxlSBM6RUeEmEVfYOe3c2wlhjo9hibyWA,7876
py_wake/tests/test_utils/test_gradient_utils.py,sha256=oz9ypkZc0liVKCBP8SCsukt3bFcUOP32VUrSKdZ9uiA,17393
py_wake/tests/test_utils/test_grid_interpolator.py,sha256=Rclk-cegY8DL7hjcHghZ9wB6quhcOLDb777OPIKZu80,7803
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=JRXj5xv4AAMTqz8hubk63wqqJ5BoF9gTq0YC0MiPGH8,12639
py_wake/tests/test_utils/test_model_gradients.py,sha256=fyz45Ek__N8bLiJxdENkmefh3uiOVYMGU9XPXDt3oFA,12758
py_wake/tests/test_utils/test_model_utils.py,sha256=219lb_0_74xshlw2lKdEgTyPGSRXe8F-uplifqpRdnM,3847

@@ -378,3 +378,3 @@ py_wake/tests/test_utils/test_most.py,sha256=WG2Ng8T1mcmIAsP23OnQeGCoVQ9D8NEX-2fmhH4tMd8,1311

py_wake/tests/test_wind_farm_models/test_all2all.py,sha256=KCTignc2zVwIPcoJD2gU0fHqdwnppKmjDY-BsfKIa-M,1556
py_wake/tests/test_wind_farm_models/test_all2allIterative.py,sha256=P1e_7rMbCxeiSL8J-scZHux4UdPpWRec79yGayn5bok,5567
py_wake/tests/test_wind_farm_models/test_all2allIterative.py,sha256=15YjvvoWZrQrxc6z8y8bbR5g6vA4Q5wAq6K35CW5rq8,8246
py_wake/tests/test_wind_farm_models/test_enginering_wind_farm_model.py,sha256=IvbRInNWqnC8FVk8A-IwmDiYOZ3oGNR4Z8drlRHHpnk,28773

@@ -387,3 +387,3 @@ py_wake/tests/test_wind_farm_models/test_external_windfarms.py,sha256=A6MHjEZiDIgTRoXOkWvjC6CbyqlJAUa_QlfPcAUSFu4,12457

py_wake/tests/test_wind_farm_models/test_simulation_result.py,sha256=VoffAnO6EwA4J_4-AbgoCgrU5Lbj-3f_HbC-YeBVav8,1496
py_wake/tests/test_wind_farm_models/test_wind_farm_model.py,sha256=hsv11zdQD4X5p1aB09vOiJKJx1ZxlqqzZ1QnqBDoUB8,14464
py_wake/tests/test_wind_farm_models/test_wind_farm_model.py,sha256=OWl9DhiQ3-XodAonuEAlo6oasdRZg-xygVPkUAyszUA,14500
py_wake/tests/test_windturbines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@@ -393,3 +393,3 @@ py_wake/tests/test_windturbines/test_generic_wind_turbines.py,sha256=nIACFm-5iqM_bsIZxFpifGFp9S3zoF4CTwInPTmhz7I,5502

py_wake/tests/test_windturbines/test_power_ct_wind_turbines.py,sha256=PCPFI1IDAGOamL6wCzCdHBbctfmvwCvmc1iWC2oe6XY,19254
py_wake/tests/test_windturbines/test_windturbines.py,sha256=lpAcRLGDCe66RPGUxALwhMF2F7qLpmbGMt_b-eXwqCo,12539
py_wake/tests/test_windturbines/test_windturbines.py,sha256=e4r6tpojYiVI8yp3pXUddnjuAuf2uqEaCWl8oNaMxHE,12562
py_wake/turbulence_models/__init__.py,sha256=rZWvrg7PgnZrcpyEaHRx81H9h8w1RRx8zQCg_Rbm8fs,254

@@ -409,4 +409,4 @@ py_wake/turbulence_models/crespo.py,sha256=GkB8UXpzjKyFUL0Or13qihC-IISOUuqFvm_1Le7ZH8A,2154

py_wake/utils/gpu_utils.py,sha256=qun-tz8HuwLForxFk7H8DlkdPNmjeRiqMew7f6LOc1c,1618
py_wake/utils/gradients.py,sha256=AvwWkzBfDc0NDKo6_qMUQp4ExaPnx99jWnzpN3BsLSE,15227
py_wake/utils/grid_interpolator.py,sha256=6dL9tL9E6wo_k5NPxX7fBXkgc7_UlPUPnGK-9TQhwQE,8239
py_wake/utils/gradients.py,sha256=3Hsk9_N7VN-4RkjfwUuzZN3_nncto6CUMa9QfPEf9C8,15685
py_wake/utils/grid_interpolator.py,sha256=hweNtt4jY0KVQJGhM1NsXZOXcTM0OAGgfKiT5YCCwrc,8523
py_wake/utils/ieawind37_utils.py,sha256=t32eUKrPP6oH2G7Lc53l03TZOe7cj4XhBt_FlNZB5kQ,305

@@ -420,4 +420,4 @@ py_wake/utils/layouts.py,sha256=YHV1FwZJECBjTqqYIi8ipVIOefXYoWS7AarK7ND048M,998

py_wake/utils/parallelization.py,sha256=aFzRglfLqT6Iq9LoKTae6sXeQjYCPm-gHqzS5cuxF38,3876
py_wake/utils/plotting.py,sha256=zXharIIWIwl-E0Xh2JP3qAnYEEAKGJidQcldhRd0dRo,568
py_wake/utils/profiling.py,sha256=g6aDNtZg_7lcxUg4WdAawGMysaoZW87iPyTWwiPvWdA,4668
py_wake/utils/plotting.py,sha256=YugRaH7b7_3ASskJ86ZKwxe7zqTnLf-MtcoPd6VxXtU,696
py_wake/utils/profiling.py,sha256=pWo_PDkYFdaWlDrxkPzvX2LAtdpK_FHu7PszDdb3L7U,4670
py_wake/utils/rans_lut_utils.py,sha256=BjEurt2nM7ZO2VLQN1bDdaCtig1N3ksqafYcxlOTQxQ,17596

@@ -427,3 +427,3 @@ py_wake/utils/streamline.py,sha256=QSfp_kLVxihTlWq3P0AHvpf_OS-QUIj17xoNhhI8QXk,2835

py_wake/utils/weibull.py,sha256=cD1SIyXHEn17IQueZnsy9-upo2oZivVCpYOWka-_DsE,1262
py_wake/utils/xarray_utils.py,sha256=l4EmohWhs7n35F7Ik0wyIXbInvzxSMMrfFeW5FqluS0,7817
py_wake/utils/xarray_utils.py,sha256=x2S4hXtBqUCK0DrM_DG5e2h6aNuMD-z_cnt2YM8oxJg,7844
py_wake/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@@ -434,7 +434,8 @@ py_wake/validation/ecn_wieringermeer.py,sha256=1PexliJn_LHkeLRM8r6-iMEk72jtIUUBH3kWI0nV4P4,2930

py_wake/validation/validation_lib.py,sha256=C_Rf-51ZjMlGdlDFha8JF4t0ByJY9zFrPtmDQU0t1Uo,27559
py_wake/wind_farm_models/__init__.py,sha256=cl0nC9vqhXgpRuaCFkQpDET2Yyzbwnd5Kv2wgZHUI6E,137
py_wake/wind_farm_models/engineering_models.py,sha256=co-te7NzyLkz3PchizBj2_-YGU6wFlWl6ZbnTgKSLdg,64395
py_wake/wind_farm_models/__init__.py,sha256=zrIf6PTnHFSFkpJA5aONhZo9nEwacRT_4jC34kzignc,175
py_wake/wind_farm_models/all2alliterative.py,sha256=nDGSHtH-35gnciAMfV1eno6W8upPEKzbiJ4nqNp5FIg,20097
py_wake/wind_farm_models/engineering_models.py,sha256=AOg8bsNlRyQtkXDvcKlJ0-0O8qq4f--GyYTDuz6LwN0,49990
py_wake/wind_farm_models/external_wind_farm_models.py,sha256=bFAmIJ7bRHEZEIo_wyAabefw4OYNKZ1-p5OoSAca7Ok,12591
py_wake/wind_farm_models/minimalistic_wind_farm_model.py,sha256=9BepPjAo_WDMcG4feUQo7YDY2WSFJOpNMmzgT0yNBn4,11160
py_wake/wind_farm_models/wind_farm_model.py,sha256=8rQ0tbfZDMs8_9Ag_c1UQz28O7xF7tEBS43wey_BWfs,42573
py_wake/wind_farm_models/wind_farm_model.py,sha256=ZuKGdwpXAKRzDP_mHBAeqCgUWy6_bD_jVbFG1WG6PbQ,42599
py_wake/wind_turbines/__init__.py,sha256=w1D9rLfxk7m_UdrqbVVokWwAikxIzeRh6Wb9zVT2Mhs,145

@@ -446,6 +447,6 @@ py_wake/wind_turbines/_wind_turbines.py,sha256=ukh8Kw4tUHH5vkXiVC8JaI-5xuIjCRVUROWInnJQJcw,18915

py_wake/wind_turbines/wind_turbines_deprecated.py,sha256=HpNmBR8CJL4-8JBaygDI0t086qfw5bR2DOQI8Ox4AZ4,6250
py_wake-2.6.18.dist-info/licenses/LICENSE,sha256=XE2CGPqQgzSXqIajXpAVYJ5SRNmaWOIeMePK6MocsuY,1084
py_wake-2.6.18.dist-info/METADATA,sha256=PU1ObxsVwOxG6HK1VKxC0elqe99jXDW6Y3N3ehSUiOw,3760
py_wake-2.6.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
py_wake-2.6.18.dist-info/top_level.txt,sha256=GsaXU4YwyMkZZ6dkb4h0FMc5RaLIT2Qns_YoScKoXdk,20
py_wake-2.6.18.dist-info/RECORD,,
py_wake-2.6.19.dist-info/licenses/LICENSE,sha256=XE2CGPqQgzSXqIajXpAVYJ5SRNmaWOIeMePK6MocsuY,1084
py_wake-2.6.19.dist-info/METADATA,sha256=QUtOWacPG-xGYPsK9XUCTmtW1xHsC_2UlqNOaHNzUww,3760
py_wake-2.6.19.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
py_wake-2.6.19.dist-info/top_level.txt,sha256=GsaXU4YwyMkZZ6dkb4h0FMc5RaLIT2Qns_YoScKoXdk,20
py_wake-2.6.19.dist-info/RECORD,,
+1
-1
Wheel-Version: 1.0
Generator: setuptools (80.9.0)
Generator: setuptools (82.0.0)
Root-Is-Purelib: true
Tag: py3-none-any

Sorry, the diff of this file is too big to display