def test_interpolation(): wts = HornsrevV80() path = tfp + 'fuga/2MW/Z0=0.00408599Zi=00400Zeta0=0.00E+00/' site = UniformSite([1, 0, 0, 0], ti=0.075) plot = 0 if plot: ax1 = plt.gca() ax2 = plt.twinx() for wdm, n_d_values in ( (FugaDeficit(path, method='linear'), 4), (FugaDeficit(path, method='spline'), 20), (FugaYawDeficit(path, method='linear'), 4), (FugaYawDeficit(path, method='spline'), 20), ): wfm = PropagateDownwind(site, wts, wdm) sim_res = wfm(x=[0], y=[0], wd=[270], ws=[10], yaw=[[[10]]]) fm = sim_res.flow_map(XYGrid(x=[200], y=np.arange(-10, 11))) fm = sim_res.flow_map( XYGrid(x=np.arange(-100, 800, 10), y=np.arange(-10, 11))) # linear has 4 line segments with same gradient, while spline has 20 different gradient values npt.assert_equal( len(np.unique(np.round(np.diff(fm.WS_eff.sel(x=500).squeeze()), 6))), n_d_values) if plot: ax1.plot(fm.y, fm.WS_eff.sel(x=500).squeeze()) ax2.plot(fm.y[:-1], np.diff(fm.WS_eff.sel(x=500).squeeze()), '--') if plot: plt.show() plt.close('all')
def test_fuga_downwind_vs_notebook(): powerCtFunction = PowerCtTabular([0, 100], [0, 0], 'w', [0.850877, 0.850877]) wt = WindTurbine(name='', diameter=80, hub_height=70, powerCtFunction=powerCtFunction) path = tfp + 'fuga/2MW/Z0=0.00001000Zi=00400Zeta0=0.00E+00' site = UniformSite([1, 0, 0, 0], ti=0.075) wfm_ULT = PropagateDownwind(site, wt, FugaYawDeficit(path)) WS = 10 p = Path(tfp) / "fuga/v80_wake_4d_y_no_deflection.csv" y, notebook_deficit_4d = np.array( [v.split(",") for v in p.read_text().strip().split("\n")], dtype=float).T sim_res = wfm_ULT([0], [0], wd=270, ws=WS, yaw=[[[17.4493]]]) fm = sim_res.flow_map(XYGrid(4 * wt.diameter(), y=y)) npt.assert_allclose(fm.WS_eff.squeeze() - WS, notebook_deficit_4d, atol=1e-6) if 0: plt.plot(y, notebook_deficit_4d, label='Notebook deficit 4d') plt.plot(y, fm.WS_eff.squeeze() - WS) plt.show() plt.close('all')
def test_wake_blockage_split(upstream_only, ref): class MyWakeModel(WakeDeficitModel): args4deficit = [] def calc_deficit(self, dw_ijlk, **kwargs): return np.ones_like(dw_ijlk) * 2 class MyBlockageModel(BlockageDeficitModel): args4deficit = [] def calc_deficit(self, dw_ijlk, **kwargs): return np.ones_like(dw_ijlk) site = Hornsrev1Site() windTurbines = IEA37_WindTurbines() wf_model = All2AllIterative( site, windTurbines, wake_deficitModel=MyWakeModel(), blockage_deficitModel=MyBlockageModel(upstream_only=upstream_only)) sim_res = wf_model([0], [0], ws=10, wd=270) fm = sim_res.flow_map(XYGrid(x=[-100, 100], y=[-100, 0, 100])) if 0: sim_res.flow_map().plot_wake_map() print(fm.WS_eff.values.squeeze().T) plt.show() npt.assert_array_equal(fm.WS_eff.values.squeeze().T, ref)
def run(self, windFarmModel): windFarmModel.site = self.site windFarmModel.windTurbines = self.windTurbines fm = windFarmModel([0], [0]).flow_map(XYGrid(y=-self.x, x=0)) wd = (fm.wd.values + 180) % 360 - 180 ws = (fm.WS_eff / fm.ws).squeeze() return wd, ws
def test_yaw_tilt(yaw, tilt, cx, cz): site = IEA37Site(16) x, y = [0], [0] windTurbines = V80() D = windTurbines.diameter() wfm = IEA37SimpleBastankhahGaussian( site, windTurbines, deflectionModel=JimenezWakeDeflection()) x_lst = np.linspace(-200, 1000, 100) y_lst = np.linspace(-100, 100, 201) z_lst = np.arange(10, 200, 1) fm_yz = wfm(x, y, wd=270, ws=10, yaw=yaw, tilt=tilt).flow_map(YZGrid(x=5 * D, y=y_lst, z=z_lst)) fm_xz = wfm(x, y, wd=180, ws=10, yaw=yaw, tilt=tilt).flow_map(YZGrid(x=0, y=x_lst, z=z_lst)) fm_xy = wfm(x, y, wd=270, ws=10, yaw=yaw, tilt=tilt).flow_map(XYGrid(x=x_lst)) if 0: axes = plt.subplots(3, 1)[1].flatten() fm_xy.plot_wake_map(ax=axes[0]) axes[0].axvline(5 * D) fm_xz.plot_wake_map(ax=axes[1]) axes[1].axvline(5 * D) fm_yz.plot_wake_map(ax=axes[2]) plt.show() wake_center = fm_yz.WS_eff.where(fm_yz.WS_eff == fm_yz.WS_eff.min(), drop=True).squeeze() npt.assert_allclose(wake_center.y, cx, atol=.1) npt.assert_allclose(wake_center.h, cz, atol=.24)
def test_YZGrid_terrain_parallel(): site = ParqueFicticioSite(distance=StraightDistance()) x, y = site.initial_position.T windTurbines = IEA37_WindTurbines() wind_farm_model = IEA37SimpleBastankhahGaussian(site, windTurbines) simulation_result = wind_farm_model(x, y, wd=0, ws=10) x = 264000 fm = simulation_result.flow_map( grid=YZGrid(x, z=110, resolution=20, extend=0)) y = fm.X[0] x = np.zeros_like(y) + x z = site.elevation(x, y) simulation_result.flow_map(XYGrid(extend=0.005)).plot_wake_map() plt.plot(x, y, '.') plt.figure() simulation_result.flow_map(grid=YZGrid( fm.x.item(), fm.y, z=np.arange(30, 210, 10))).plot_wake_map() plt.plot(y, z + 110, '.') plt.plot(y, fm.WS_eff_xylk[:, 0, 0, 0] * 100, label="ws*100") plt.legend() if 0: print(np.round(fm.WS_eff_xylk[:, 0, 0, 0], 2).values.tolist()) plt.show() plt.close('all') npt.assert_array_almost_equal(fm.WS_eff_xylk[:, 0, 0, 0], [ 4.55, 3.89, 3.15, 2.31, 4.41, 4.3, 7.41, 7.2, 7.03, 7.23, 7.32, 6.77, 6.83, 5.58, 11.01, 11.51, 11.93, 12.17, 11.03, 9.89 ], 2)
def test_min_ws_eff_line(): site = IEA37Site(16) x, y = [0, 600, 1200], [0, 0, 0] # site.initial_position[:2].T windTurbines = IEA37_WindTurbines() wfm = IEA37SimpleBastankhahGaussian( site, windTurbines, deflectionModel=JimenezWakeDeflection()) yaw_ilk = np.reshape([-30, 30, 0], (3, 1, 1)) plt.figure(figsize=(14, 3)) fm = wfm(x, y, yaw=yaw_ilk, wd=270, ws=10).flow_map( XYGrid(x=np.arange(-100, 2000, 10), y=np.arange(-500, 500, 10))) min_ws_line = fm.min_WS_eff() if 0: fm.plot_wake_map() min_ws_line.plot() print(np.round(min_ws_line[::10], 2)) plt.show() npt.assert_array_almost_equal(min_ws_line[::10], [ np.nan, np.nan, 11.6, 21.64, 30.42, 38.17, 45.09, 51.27, -8.65, -18.66, -27.51, -35.37, -42.38, -48.58, -1.09, -1.34, -1.59, -1.83, -2.07, -2.31, -2.56 ], 2)
def test_fuga_wake_center_vs_notebook(): p = Path(tfp) / "fuga/v80_wake_center_x.csv" x, notebook_wake_center = np.array([v.split(",") for v in p.read_text().strip().split("\n")], dtype=float).T powerCtFunction = PowerCtTabular([0, 100], [0, 0], 'w', [0.850877, 0.850877]) wt = WindTurbine(name='', diameter=80, hub_height=70, powerCtFunction=powerCtFunction) path = tfp + 'fuga/2MW/Z0=0.00001000Zi=00400Zeta0=0.00E+00' site = UniformSite([1, 0, 0, 0], ti=0.075) wfm = PropagateDownwind( site, wt, wake_deficitModel=FugaYawDeficit(path), deflectionModel=FugaDeflection(path, 'input_par') ) WS = 10 sim_res = wfm([0], [0], yaw=[17.4493], wd=270, ws=[WS]) y = wfm.wake_deficitModel.mirror(wfm.wake_deficitModel.y, anti_symmetric=True) fm = sim_res.flow_map(XYGrid(x=x[1:], y=y[240:271])) fuga_wake_center = [np.interp(0, InterpolatedUnivariateSpline(ws.y, ws.values).derivative()(ws.y), ws.y) for ws in fm.WS_eff.squeeze().T] if 0: plt.plot(x, notebook_wake_center, label='Notebook deflection') plt.plot(x[1:], fuga_wake_center) plt.show() plt.close('all') npt.assert_allclose(fuga_wake_center, notebook_wake_center[1:], atol=.14)
def test_YZGrid_terrain_perpendicular(): site = ParqueFicticioSite(distance=StraightDistance()) x, y = site.initial_position.T windTurbines = IEA37_WindTurbines() wind_farm_model = IEA37SimpleBastankhahGaussian(site, windTurbines) simulation_result = wind_farm_model(x, y, wd=270, ws=10) x = x.max() + 10 fm = simulation_result.flow_map( grid=YZGrid(x, z=110, resolution=20, extend=0)) y = fm.X[0] x = np.zeros_like(y) + x z = site.elevation(x, y) simulation_result.flow_map(XYGrid(extend=.005)).plot_wake_map() plt.plot(x, y, '.') plt.figure() simulation_result.flow_map(grid=YZGrid( fm.x.item(), y=fm.y, z=np.arange(30, 210, 10))).plot_wake_map() plt.plot(y, z + 110, '.') plt.plot(y, fm.WS_eff_xylk[:, 0, 0, 0] * 100, label="ws*100") plt.legend() if 0: print(np.round(fm.WS_eff_xylk[:, 0, 0, 0], 2).values.tolist()) plt.show() plt.close('all') npt.assert_array_almost_equal(fm.WS_eff_xylk[:, 0, 0, 0], [ 5.39, 8.48, 8.42, 6.42, 5.55, 11.02, 4.99, 11.47, 5.32, 10.22, 13.39, 8.79, 8.51, 12.4, 5.47, 10.78, 10.12, 6.54, 10.91, 7.18 ], 2)
def test_blockage_map(setup, blockage_model, center_ref, side_ref): site, windTurbines = setup wm = All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit(), superpositionModel=LinearSum(), blockage_deficitModel=blockage_model()) xy = np.linspace(-200, 200, 500) flow_map = wm(x=[0], y=[0], wd=[270], ws=[10]).flow_map(XYGrid(x=xy[::50], y=xy[[190, 250]])) X_j, Y_j = flow_map.XY WS_eff = flow_map.WS_eff_xylk[:, :, 0, 0] if debug: flow_map_full = wm(x=[0], y=[0], wd=[270], ws=[10]).flow_map() X_j_full, Y_j_full = flow_map_full.XY WS_eff_full = flow_map_full.WS_eff_xylk[:, :, 0, 0] plt.contourf(X_j_full, Y_j_full, WS_eff_full) plt.plot(X_j.T, Y_j.T, '.-') print(list(np.round(np.array(WS_eff[0]), 6))) print(list(np.round(np.array(WS_eff[1]), 6))) plt.title(blockage_model.__name__) plt.show() npt.assert_array_almost_equal(WS_eff[0], center_ref) npt.assert_array_almost_equal(WS_eff[1], side_ref)
def plot(wfm, yaw, ax, min_ws): levels = np.arange(6.5, 10.5, .5) sim_res = wfm([0], [0], wd=270, ws=10, yaw=[[[yaw]]]) fm = sim_res.flow_map(XYGrid(x=np.arange(-100, 500, 5))) npt.assert_almost_equal(fm.WS_eff.min(), min_ws) fm.plot_wake_map(ax=ax, levels=levels) fm.min_WS_eff(fm.x, 70).plot(ax=ax, color='r') plt.axhline(0, color='k')
def main(): if __name__ == '__main__': from py_wake.examples.data.iea37 import IEA37Site, IEA37_WindTurbines from py_wake.deficit_models.selfsimilarity import SelfSimilarityDeficit from py_wake.deficit_models.gaussian import ZongGaussianDeficit from py_wake.turbulence_models.stf import STF2017TurbulenceModel from py_wake.flow_map import XYGrid import matplotlib.pyplot as plt site = IEA37Site(16) x, y = site.initial_position.T windTurbines = IEA37_WindTurbines() from py_wake.deficit_models.noj import NOJDeficit from py_wake.superposition_models import SquaredSum # NOJ wake model noj = PropagateDownwind(site, windTurbines, wake_deficitModel=NOJDeficit(), superpositionModel=SquaredSum()) # NOJ wake and selfsimilarity blockage noj_ss = All2AllIterative( site, windTurbines, wake_deficitModel=NOJDeficit(), superpositionModel=SquaredSum(), blockage_deficitModel=SelfSimilarityDeficit()) # Zong convection superposition zongp_ss = PropagateDownwind(site, windTurbines, wake_deficitModel=ZongGaussianDeficit(), superpositionModel=WeightedSum(), turbulenceModel=STF2017TurbulenceModel()) # Zong convection superposition zong_ss = All2AllIterative( site, windTurbines, wake_deficitModel=ZongGaussianDeficit(), superpositionModel=WeightedSum(), blockage_deficitModel=SelfSimilarityDeficit(), turbulenceModel=STF2017TurbulenceModel()) for wm in [noj, noj_ss, zongp_ss, zong_ss]: sim = wm(x=x, y=y, wd=[30], ws=[9]) plt.figure() sim.flow_map(XYGrid(resolution=200)).plot_wake_map() plt.title(' AEP: %.3f GWh' % sim.aep().sum()) plt.show()
def test_All2AllIterativeDeflection(): site = IEA37Site(16) windTurbines = IEA37_WindTurbines() wf_model = All2AllIterative(site, windTurbines, wake_deficitModel=NOJDeficit(), superpositionModel=SquaredSum(), deflectionModel=JimenezWakeDeflection()) sim_res = wf_model([0, 500], [0, 0], wd=270, ws=10, yaw=30) if 0: sim_res.flow_map( XYGrid(x=np.linspace(-200, 1000, 100))).plot_wake_map() plt.show()
def test_turning_mean(complex_grid_site, wfm): ds = xr.Dataset( data_vars={'Turning': (['x', 'y'], np.arange(-2, 4, 1).reshape((2, 3)).T), 'Sector_frequency': ('wd', f), 'Weibull_A': ('wd', A), 'Weibull_k': ('wd', k), 'TI': .1}, coords={'x': [0, 500, 1000], 'y': [0, 500], 'wd': np.linspace(0, 360, len(f), endpoint=False)}) site = XRSite(ds) wt = V80() wfm = wfm(site, wt, NOJDeficit()) sim_res = wfm([500, 500], [100, 400], wd=0, ws=10) print(sim_res.Power) if 0: sim_res.flow_map(XYGrid(y=np.linspace(0, 500, 100))).plot_wake_map() plt.show() assert sim_res.WS_eff.sel(wt=0).item() < sim_res.WS_eff.sel(wt=1).item() fm = sim_res.flow_map(Points([500, 500], [100, 400], [70, 70])) assert fm.WS_eff.sel(i=0).item() < fm.WS_eff.sel(i=1).item()
def test_deflection_model(deflectionModel, dy10d): site = IEA37Site(16) x, y = [0], [0] windTurbines = V80() D = windTurbines.diameter() wfm = IEA37SimpleBastankhahGaussian(site, windTurbines, deflectionModel=deflectionModel()) yaw_ilk = np.reshape([-30], (1, 1, 1)) sim_res = wfm(x, y, yaw=yaw_ilk, wd=270, ws=10) fm = sim_res.flow_map(XYGrid(x=np.arange(-D, 10 * D + 10, 10))) min_WS_line = fm.min_WS_eff() if 0: plt.figure(figsize=(14, 3)) fm.plot_wake_map() min_WS_line.plot() plt.plot(10 * D, dy10d * D, '.', label="Ref, 10D") plt.legend() plt.show() npt.assert_almost_equal(min_WS_line.interp(x=10 * D).item() / D, dy10d)
def test_plot_deflection_grid(deflectionModel): site = IEA37Site(16) x, y = [0], [0] windTurbines = V80() D = windTurbines.diameter() wfm = IEA37SimpleBastankhahGaussian(site, windTurbines, deflectionModel=deflectionModel()) yaw_ilk = np.reshape([-30], (1, 1, 1)) sim_res = wfm(x, y, yaw=yaw_ilk, wd=270, ws=10) fm = sim_res.flow_map(XYGrid(x=np.arange(-D, 10 * D + 10, 10))) plt.figure(figsize=(14, 3)) fm.plot_wake_map() fm.plot_deflection_grid() min_WS_line = fm.min_WS_eff() min_WS_line.plot() plt.legend() plt.title(wfm.deflectionModel) if 0: plt.show() plt.close('all')