py-wake
Advanced tools
| 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
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.