Exemplo n.º 1
0
def main():
    if __name__ == '__main__':
        from py_wake.examples.data.iea37._iea37 import IEA37Site
        from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines
        from py_wake.superposition_models import LinearSum
        from py_wake.wind_farm_models import All2AllIterative
        from py_wake.deficit_models.no_wake import NoWakeDeficit
        from py_wake.deficit_models.vortexcylinder import VortexCylinder
        from py_wake.deficit_models.vortexdipole import VortexDipole
        import matplotlib.pyplot as plt
        from py_wake import HorizontalGrid
        from timeit import default_timer as timer

        # setup site, turbines and wind farm model
        site = IEA37Site(16)
        x, y = site.initial_position.T
        windTurbines = IEA37_WindTurbines()
        d = windTurbines.diameter()
        ra = Rathmann()
        grid = HorizontalGrid(x=np.linspace(-6, 6, 100) * d, y=np.linspace(0, 4, 100) * d)

        noj_ra = All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(), blockage_deficitModel=ra)
        noj_vc = All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(), blockage_deficitModel=VortexCylinder())
        noj_vd = All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(), blockage_deficitModel=VortexDipole())
        t1 = timer()
        flow_map = noj_ra(x=[0], y=[0], wd=[270], ws=[10]).flow_map(grid=grid)
        t2 = timer()
        flow_map_vc = noj_vc(x=[0], y=[0], wd=[270], ws=[10]).flow_map(grid=grid)
        t3 = timer()
        flow_map_vd = noj_vd(x=[0], y=[0], wd=[270], ws=[10]).flow_map(grid=grid)
        t4 = timer()
        print(t2 - t1, t3 - t2, t4 - t3)

        plt.figure()
        clevels = np.array([.6, .7, .8, .9, .95, .98, .99, .995, .998, .999, 1., 1.005, 1.01, 1.02, 1.05]) * 10.
        flow_map.plot_wake_map(levels=clevels)
        plt.contour(flow_map.x, flow_map.y, flow_map.WS_eff[:, :, 0, -1, 0], levels=clevels, colors='k', linewidths=1)
        plt.contour(flow_map.x, flow_map.y, flow_map_vc.WS_eff[:, :, 0, -1, 0], levels=clevels, colors='r', linewidths=1, linestyles='dashed')
        plt.contour(flow_map.x, flow_map.y, flow_map_vd.WS_eff[:, :, 0, -1, 0], levels=clevels, colors='b', linewidths=1, linestyles='dotted')
        plt.title('Rathmann')
        plt.ylabel("Crosswind distance [y/R]")
        plt.xlabel("Downwind distance [x/R]")
        plt.show()

        # run wind farm simulation
        sim_res = noj_ra(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])

        # calculate AEP
        aep = sim_res.aep().sum()

        # plot wake map
        plt.figure()
        print(noj_ra)
        flow_map = sim_res.flow_map(wd=0, ws=10)
        flow_map.plot_wake_map(levels=clevels, plot_colorbar=False)
        plt.title('Rathmann model, AEP: %.3f GWh' % aep)
        plt.show()
Exemplo n.º 2
0
def test_with_all_turbulence_models(WFM, turbulenceModel):
    site = IEA37Site(16)
    windTurbines = IEA37_WindTurbines()

    wfm = WFM(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
              rotorAvgModel=CGIRotorAvg(4),
              superpositionModel=LinearSum(),
              turbulenceModel=turbulenceModel())

    wfm2 = WFM(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
               superpositionModel=LinearSum(),
               turbulenceModel=turbulenceModel(rotorAvgModel=CGIRotorAvg(4)))
    kwargs = {'x': [0, 0, 500, 500], 'y': [0, 500, 0, 500], 'wd': [0], 'ws': [8]}
    npt.assert_array_equal(wfm(**kwargs).TI_eff, wfm2(**kwargs).TI_eff, turbulenceModel.__name__)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
def test_blockage_map(setup):
    site, windTurbines, ss = setup
    wm = All2AllIterative(site,
                          windTurbines,
                          wake_deficitModel=NoWakeDeficit(),
                          superpositionModel=LinearSum(),
                          blockage_deficitModel=ss)

    flow_map = wm(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
    X_j, Y_j = flow_map.XY
    WS_eff = flow_map.WS_eff_xylk[:, :, 0, 0]

    if 0:
        plt.contourf(X_j, Y_j, WS_eff)
        plt.plot(X_j[200, ::50], Y_j[200, ::50], '.-')
        plt.plot(X_j[250, ::50], Y_j[250, ::50], '.-')
        print(list(np.round(WS_eff[200, ::50], 6)))
        print(list(np.round(WS_eff[250, ::50], 6)))
        ss.windTurbines.plot([0], [0], wd=[270])
        plt.show()

    npt.assert_array_almost_equal(WS_eff[200, ::50], [
        9.940967, 9.911659, 9.855934, 9.736016, 9.44199, 10.0, 10.0, 10.0,
        10.0, 10.0
    ])
    npt.assert_array_almost_equal(WS_eff[250, ::50], [
        9.937601, 9.90397, 9.834701, 9.659045, 9.049764, 10.0, 10.0, 10.0,
        10.0, 10.0
    ])
Exemplo n.º 5
0
def test_wake_radius_not_implemented():
    site = IEA37Site(16)
    x, y = site.initial_position.T
    windTurbines = IEA37_WindTurbines()
    wfm = PropagateDownwind(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
                            turbulenceModel=GCLTurbulence())
    with pytest.raises(NotImplementedError, match="wake_radius not implemented for NoWakeDeficit"):
        wfm(x, y)
def test_double_wind_farm_model():
    """Check that a new wind farm model does not change results of previous"""
    site = IEA37Site(16)
    x, y = site.initial_position.T
    windTurbines = IEA37_WindTurbines()
    wfm = PropagateDownwind(site, windTurbines, wake_deficitModel=IEA37SimpleBastankhahGaussianDeficit())
    aep_ref = wfm(x, y).aep().sum()
    PropagateDownwind(site, windTurbines, wake_deficitModel=NoWakeDeficit())
    aep = wfm(x, y).aep().sum()
    npt.assert_array_equal(aep, aep_ref)
Exemplo n.º 7
0
def main():
    if __name__ == '__main__':
        import matplotlib.pyplot as plt
        from py_wake.examples.data.hornsrev1 import Hornsrev1Site
        from py_wake.examples.data import hornsrev1
        from py_wake.superposition_models import LinearSum
        from py_wake.wind_farm_models import All2AllIterative

        site = Hornsrev1Site()
        windTurbines = hornsrev1.HornsrevV80()
        ws = 10
        D = 80
        R = D / 2
        WS_ilk = np.array([[[ws]]])
        D_src_il = np.array([[D]])
        ct_ilk = np.array([[[.8]]])
        ss = SelfSimilarityDeficit()

        x, y = -np.arange(200), np.array([0])
        deficit = ss.calc_deficit(WS_ilk=WS_ilk,
                                  D_src_il=D_src_il,
                                  dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                  cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                  ct_ilk=ct_ilk)
        plt.title('Fig 11 from [1]')
        plt.xlabel('x/R')
        plt.ylabel('a')
        plt.plot(x / R, deficit[0, :, 0, 0] / ws)

        plt.figure()
        x, y = np.array([-2 * R]), np.arange(200)
        deficit = ss.calc_deficit(WS_ilk=WS_ilk,
                                  D_src_il=D_src_il,
                                  dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                  cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                  ct_ilk=ct_ilk)
        plt.title('Fig 10 from [1]')
        r12 = np.sqrt(ss.lambda_ * (ss.eta + (x / R)**2))  # Eq. (13) from [1]
        print(x, r12)
        plt.xlabel('y/R12 (epsilon)')
        plt.ylabel('f')
        plt.plot((y / R) / r12, deficit[0, :, 0, 0] / deficit[0, 0, 0, 0])

        plt.figure()
        noj_ss = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=ss)
        flow_map = noj_ss(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
        flow_map.plot_wake_map()
        flow_map.plot_windturbines()

        plt.show()
def test_double_wind_farm_model_All2AllIterative():
    """Check that a new wind farm model does not change results of previous"""
    site = IEA37Site(64)
    x, y = site.initial_position.T
    x, y = wt_x, wt_y
    windTurbines = IEA37_WindTurbines()
    wfm = All2AllIterative(site, windTurbines, wake_deficitModel=IEA37SimpleBastankhahGaussianDeficit())
    aep_ref = wfm(x, y).aep().sum()
    All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit())(x, y)
    aep = wfm(x, y).aep().sum()
    npt.assert_array_equal(aep, aep_ref)
def test_huge_farm():
    site = UniformSite([1], ti=0)
    windTurbines = IEA37_WindTurbines()
    wfm = PropagateDownwind(site, windTurbines, NoWakeDeficit())
    N = 200
    x = np.arange(N) * windTurbines.diameter(0) * 4

    import tracemalloc
    tracemalloc.start()
    wfm(x, x * 0, ws=10)
    current, peak = tracemalloc.get_traced_memory()  # @UnusedVariable
    peak /= 1024**2
    assert peak < 800
    tracemalloc.stop()
Exemplo n.º 10
0
def test_aep_two_turbines(setup, blockage_model, blockage_loss):
    site, windTurbines = setup

    nwm_ss = All2AllIterative(site, windTurbines, wake_deficitModel=NoWakeDeficit(),
                              blockage_deficitModel=blockage_model(), superpositionModel=LinearSum())

    sim_res = nwm_ss(x=[0, 80 * 3], y=[0, 0])
    aep_no_blockage = sim_res.aep_ilk(with_wake_loss=False).sum(2)
    aep = sim_res.aep_ilk().sum(2)

    # blockage reduce aep(wd=270) by .5%
    npt.assert_almost_equal((aep_no_blockage[0, 270] - aep[0, 270]) / aep_no_blockage[0, 270] * 100, blockage_loss)

    if debug:
        plt.plot(sim_res.WS_eff_ilk[:, :, 7].T)
        plt.title(blockage_model.__name__)
        plt.show()
Exemplo n.º 11
0
def main():
    if __name__ == '__main__':
        from py_wake.examples.data.iea37._iea37 import IEA37Site
        from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines
        from py_wake.superposition_models import LinearSum
        from py_wake.wind_farm_models import All2AllIterative
        from py_wake.deficit_models.no_wake import NoWakeDeficit
        import matplotlib.pyplot as plt

        # setup site, turbines and wind farm model
        site = IEA37Site(16)
        x, y = site.initial_position.T
        windTurbines = IEA37_WindTurbines()
        hi = HybridInduction()

        plt.figure()
        noj_hi = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=hi)
        flow_map = noj_hi(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
        clevels = np.array([
            .6, .7, .8, .9, .95, .98, .99, .995, .998, .999, 1., 1.01, 1.02
        ]) * 10.
        flow_map.plot_wake_map(levels=clevels)
        plt.title('Vortex Dipole (far-field) + Self-Similar (near-rotor)')
        plt.ylabel("Crosswind distance [y/R]")
        plt.xlabel("Downwind distance [x/R]")
        plt.show()

        # run wind farm simulation
        sim_res = noj_hi(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])

        # calculate AEP
        aep = sim_res.aep().sum()

        # plot wake map
        plt.figure()
        print(noj_hi)
        flow_map = sim_res.flow_map(wd=0, ws=10)
        flow_map.plot_wake_map(levels=clevels, plot_colorbar=False)
        plt.title(
            'Vortex Dipole (far-field) + Self-Similar (near-rotor), AEP: %.3f GWh'
            % aep)
        plt.show()
Exemplo n.º 12
0
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())

    flow_map = wm(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
    X_j, Y_j = flow_map.XY
    WS_eff = flow_map.WS_eff_xylk[:, :, 0, 0]

    if debug:
        plt.contourf(X_j, Y_j, WS_eff)
        plt.plot(X_j[190, ::50], Y_j[190, ::50], '.-')
        plt.plot(X_j[250, ::50], Y_j[250, ::50], '.-')
        print(list(np.round(np.array(WS_eff[190, ::50]), 6)))
        print(list(np.round(np.array(WS_eff[250, ::50]), 6)))
        plt.title(blockage_model.__name__)
        plt.show()

    npt.assert_array_almost_equal(WS_eff[190, ::50], center_ref)
    npt.assert_array_almost_equal(WS_eff[250, ::50], side_ref)
Exemplo n.º 13
0
        def pywake_run(blockage_models):

            grid = HorizontalGrid(x=np.linspace(-10 * d, 10 * d, 100),
                                  y=np.linspace(-15, 2 * d, 100))

            res = {}
            out = {}
            for nam, blockage_model in blockage_models:
                print(nam, blockage_model)
                # for dum, rotor_avg_model in rotor_avg_models:
                wm = All2AllIterative(site,
                                      wt,
                                      wake_deficitModel=NoWakeDeficit(),
                                      superpositionModel=LinearSum(),
                                      blockage_deficitModel=blockage_model,
                                      rotorAvgModel=RotorCenter())
                res[nam] = wm(wt_x, wt_y, wd=[180., 195., 210., 225.], ws=[1.])
                tic = time.perf_counter()
                flow_map = res[nam].flow_map(grid=grid, ws=[1.], wd=225.)
                toc = time.perf_counter()
                elapsed_time = toc - tic
                out[nam] = flow_map['WS_eff'] / flow_map['WS']
                out[nam]['time'] = elapsed_time
            return out, res
Exemplo n.º 14
0
def main():
    if __name__ == '__main__':
        import matplotlib.pyplot as plt
        from py_wake.examples.data.hornsrev1 import Hornsrev1Site
        from py_wake.examples.data import hornsrev1
        from py_wake.superposition_models import LinearSum
        from py_wake.wind_farm_models import All2AllIterative

        site = Hornsrev1Site()
        windTurbines = hornsrev1.HornsrevV80()
        ws = 10
        D = 80
        R = D / 2
        WS_ilk = np.array([[[ws]]])
        D_src_il = np.array([[D]])
        ct_ilk = np.array([[[.8]]])
        ss = SelfSimilarityDeficit()
        ss20 = SelfSimilarityDeficit2020()

        x, y = -np.arange(200), np.array([0])
        # original model
        deficit = ss.calc_deficit(WS_ilk=WS_ilk,
                                  D_src_il=D_src_il,
                                  dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                  cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                  ct_ilk=ct_ilk)
        # updated method
        deficit20 = ss20.calc_deficit(WS_ilk=WS_ilk,
                                      D_src_il=D_src_il,
                                      dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                      cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                      ct_ilk=ct_ilk)
        plt.figure()
        plt.title('Fig 11 from [1]')
        plt.xlabel('x/R')
        plt.ylabel('a')
        plt.plot(x / R, deficit[0, :, 0, 0] / ws, label='original')
        plt.plot(x / R, deficit20[0, :, 0, 0] / ws, '--', label='updated')
        plt.legend()

        plt.figure()
        x, y = np.array([-2 * R]), np.arange(200)
        deficit = ss.calc_deficit(WS_ilk=WS_ilk,
                                  D_src_il=D_src_il,
                                  dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                  cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                  ct_ilk=ct_ilk)
        deficit20 = ss20.calc_deficit(WS_ilk=WS_ilk,
                                      D_src_il=D_src_il,
                                      dw_ijlk=x.reshape((1, len(x), 1, 1)),
                                      cw_ijlk=y.reshape((1, len(y), 1, 1)),
                                      ct_ilk=ct_ilk)
        plt.title('Fig 10 from [1]')
        r12 = ss.r12(x / R)
        r12_20 = ss20.r12(x / R)
        plt.xlabel('y/R12 (epsilon)')
        plt.ylabel('f')
        plt.plot((y / R) / r12,
                 deficit[0, :, 0, 0] / deficit[0, 0, 0, 0],
                 label='original')
        plt.plot((y / R) / r12_20,
                 deficit20[0, :, 0, 0] / deficit20[0, 0, 0, 0],
                 '--',
                 label='updated')
        plt.legend()

        plt.figure()
        noj_ss = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=ss)
        noj_ss20 = All2AllIterative(site,
                                    windTurbines,
                                    wake_deficitModel=NoWakeDeficit(),
                                    superpositionModel=LinearSum(),
                                    blockage_deficitModel=ss20)
        flow_map = noj_ss(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
        flow_map20 = noj_ss20(x=[0], y=[0], wd=[270], ws=[10]).flow_map()
        clevels = [.9, .95, .98, .99, .995, .998, .999, 1., 1.01, 1.02, 1.03]
        flow_map.plot_wake_map()
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map.WS_eff[:, :, 0, -1, 0] / 10,
                    levels=clevels,
                    colors='k',
                    linewidths=0.5)
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map20.WS_eff[:, :, 0, -1, 0] / 10,
                    levels=clevels,
                    colors='r',
                    linewidths=0.5)
        plt.title('Original (black) vs updated (red)')
        plt.show()

        from py_wake.examples.data.iea37._iea37 import IEA37Site
        from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines

        # setup site, turbines and wind farm model
        site = IEA37Site(16)
        x, y = site.initial_position.T
        windTurbines = IEA37_WindTurbines()

        noj_ss = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=ss)
        noj_ss20 = All2AllIterative(site,
                                    windTurbines,
                                    wake_deficitModel=NoWakeDeficit(),
                                    superpositionModel=LinearSum(),
                                    blockage_deficitModel=ss20)
        # run wind farm simulation
        sim_res = noj_ss(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])
        sim_res20 = noj_ss20(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])

        # calculate AEP
        aep = sim_res.aep().sum()
        aep20 = sim_res20.aep().sum()

        # plot wake map
        fig, (ax1, ax2) = plt.subplots(1,
                                       2,
                                       figsize=(9, 4.5),
                                       tight_layout=True)
        levels = np.array(
            [.9, .95, .98, .99, .995, .998, .999, 1., 1.01, 1.02, 1.03]) * 10.
        print(noj_ss)
        flow_map = sim_res.flow_map(wd=30, ws=10.)
        flow_map.plot_wake_map(levels=levels, ax=ax1, plot_colorbar=False)
        ax1.set_title('Original Self-Similar, AEP: %.3f GWh' % aep)

        # plot wake map
        print(noj_ss20)
        flow_map = sim_res20.flow_map(wd=30, ws=10.)
        flow_map.plot_wake_map(levels=levels, ax=ax2, plot_colorbar=False)
        ax2.set_title('Self-Similar 2020, AEP: %.3f GWh' % aep20)
        plt.show()
Exemplo n.º 15
0
 def get_wf_model(cls):
     return cls(site, NibeA0, wake_deficitModel=NoWakeDeficit(),
                superpositionModel=LinearSum(),
                turbulenceModel=STF2017TurbulenceModel())
Exemplo n.º 16
0
def main():
    if __name__ == '__main__':
        from py_wake.examples.data.iea37._iea37 import IEA37Site
        from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines
        from py_wake.site._site import UniformSite
        from py_wake.wind_turbines import OneTypeWindTurbines
        from py_wake.superposition_models import LinearSum
        from py_wake.wind_farm_models import All2AllIterative
        from py_wake.deficit_models.no_wake import NoWakeDeficit
        from py_wake.rotor_avg_models import RotorCenter
        from py_wake.deficit_models.vortexcylinder import VortexCylinder
        from py_wake.deficit_models.vortexdipole import VortexDipole
        import matplotlib.pyplot as plt
        from py_wake import HorizontalGrid
        from timeit import default_timer as timer
        import time

        # setup site, turbines and wind farm model
        site = IEA37Site(16)
        x, y = site.initial_position.T
        windTurbines = IEA37_WindTurbines()
        d = windTurbines.diameter()
        ra = Rathmann()
        ras = RathmannScaled()
        grid = HorizontalGrid(x=np.linspace(-6, 6, 100) * d,
                              y=np.linspace(0, 4, 100) * d)

        noj_ra = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=ra)
        noj_ras = All2AllIterative(site,
                                   windTurbines,
                                   wake_deficitModel=NoWakeDeficit(),
                                   superpositionModel=LinearSum(),
                                   blockage_deficitModel=ras)
        noj_vc = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=VortexCylinder())
        noj_vd = All2AllIterative(site,
                                  windTurbines,
                                  wake_deficitModel=NoWakeDeficit(),
                                  superpositionModel=LinearSum(),
                                  blockage_deficitModel=VortexDipole())
        t1 = timer()
        flow_map = noj_ra(x=[0], y=[0], wd=[270], ws=[10]).flow_map(grid=grid)
        t2 = timer()
        flow_map_ras = noj_ras(x=[0], y=[0], wd=[270],
                               ws=[10]).flow_map(grid=grid)
        t3 = timer()
        flow_map_vc = noj_vc(x=[0], y=[0], wd=[270],
                             ws=[10]).flow_map(grid=grid)
        t4 = timer()
        flow_map_vd = noj_vd(x=[0], y=[0], wd=[270],
                             ws=[10]).flow_map(grid=grid)
        t5 = timer()
        print(t2 - t1, t3 - t2, t4 - t3, t5 - t4)

        plt.figure()
        clevels = np.array([
            .6, .7, .8, .9, .95, .98, .99, .995, .998, .999, 1., 1.005, 1.01,
            1.02, 1.05
        ]) * 10.
        flow_map.plot_wake_map(levels=clevels)
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map.WS_eff[:, :, 0, -1, 0],
                    levels=clevels,
                    colors='k',
                    linewidths=1)
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map_ras.WS_eff[:, :, 0, -1, 0],
                    levels=clevels,
                    colors='g',
                    linewidths=1,
                    linestyles='dashed')
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map_vc.WS_eff[:, :, 0, -1, 0],
                    levels=clevels,
                    colors='r',
                    linewidths=1,
                    linestyles='dashed')
        plt.contour(flow_map.x,
                    flow_map.y,
                    flow_map_vd.WS_eff[:, :, 0, -1, 0],
                    levels=clevels,
                    colors='b',
                    linewidths=1,
                    linestyles='dotted')
        plt.plot([0, 0], [0, 0], 'k-', label='Rathmann')
        plt.plot([0, 0], [0, 0], 'g--', label='scaled Rathmann')
        plt.plot([0, 0], [0, 0], 'r--', label='vortex cylinder')
        plt.plot([0, 0], [0, 0], 'b:', label='vortex dipole')
        plt.title('Rathmann')
        plt.ylabel("Crosswind distance [y/R]")
        plt.xlabel("Downwind distance [x/R]")
        plt.legend()
        plt.show()

        # run wind farm simulation
        sim_res = noj_ra(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])
        # calculate AEP
        aep = sim_res.aep().sum()
        # plot wake map
        plt.figure()
        print(noj_ra)
        flow_map = sim_res.flow_map(wd=0, ws=10)
        flow_map.plot_wake_map(levels=clevels, plot_colorbar=False)
        plt.title('Rathmann model, AEP: %.3f GWh' % aep)
        plt.show()

        # run wind farm simulation
        sim_res = noj_ras(x, y, wd=[0, 30, 45, 60, 90], ws=[5, 10, 15])
        # calculate AEP
        aep = sim_res.aep().sum()
        # plot wake map
        plt.figure()
        print(noj_ras)
        flow_map = sim_res.flow_map(wd=0, ws=10)
        flow_map.plot_wake_map(levels=clevels, plot_colorbar=False)
        plt.title('Rathmann model, AEP: %.3f GWh' % aep)
        plt.show()

        class epfl_model_wt(OneTypeWindTurbines):
            def __init__(self):
                OneTypeWindTurbines.__init__(self,
                                             'NREL 5MW',
                                             diameter=2,
                                             hub_height=1,
                                             ct_func=self._ct,
                                             power_func=self._power,
                                             power_unit='W')

            def _ct(self, u):
                ct = 0.798
                return ct * u / u

            def _power(self, u):
                cp = 0.5
                A = np.pi
                rho = 1.225
                return 0.5 * rho * u**3 * A * cp

        wt = epfl_model_wt()
        d = wt.diameter()
        h = wt.hub_height()
        wt_x = np.array([-6. * d, -3. * d, 0. * d, 3. * d, 6. * d])
        wt_y = np.array([0., 0., 0., 0., 0.])

        class epfl_wt(UniformSite):
            def __init__(self):
                p_wd = [1]
                ws = [1]
                ti = [0.06]
                UniformSite.__init__(self, p_wd=p_wd, ti=ti, ws=ws)
                self.initial_position = np.array([wt_x, wt_y]).T

        site = epfl_wt()
        blockage_models = [('Rathmann', Rathmann()),
                           ('RathmannScaled', RathmannScaled())]

        def pywake_run(blockage_models):

            grid = HorizontalGrid(x=np.linspace(-10 * d, 10 * d, 100),
                                  y=np.linspace(-15, 2 * d, 100))

            res = {}
            out = {}
            for nam, blockage_model in blockage_models:
                print(nam, blockage_model)
                # for dum, rotor_avg_model in rotor_avg_models:
                wm = All2AllIterative(site,
                                      wt,
                                      wake_deficitModel=NoWakeDeficit(),
                                      superpositionModel=LinearSum(),
                                      blockage_deficitModel=blockage_model,
                                      rotorAvgModel=RotorCenter())
                res[nam] = wm(wt_x, wt_y, wd=[180., 195., 210., 225.], ws=[1.])
                tic = time.perf_counter()
                flow_map = res[nam].flow_map(grid=grid, ws=[1.], wd=225.)
                toc = time.perf_counter()
                elapsed_time = toc - tic
                out[nam] = flow_map['WS_eff'] / flow_map['WS']
                out[nam]['time'] = elapsed_time
            return out, res

        out, res = pywake_run(blockage_models)
        # CFD data from Meyer Forsting et al. 2017
        p_cfd = np.array([[
            -1.12511646713429, 0.268977884040651, 0.712062872514373,
            1.08033923355738, 1.97378837188847
        ],
                          [
                              -0.610410399845213, 0.355339771667814,
                              0.670255435929930, 0.915154608331424,
                              1.52808830519513
                          ],
                          [
                              -0.0988002822865217, 0.451698279664756,
                              0.636987630794206, 0.751760283763044,
                              1.03629687168984
                          ],
                          [
                              0.477918399858401, 0.628396438496795,
                              0.663799054750132, 0.628396438496795,
                              0.479688468006036
                          ]])

        plt.figure()
        lines = ['.-', 'o--', '^', '-.', '.-', '.-']
        theta = [0, 15, 30, 45]
        viridis = plt.cm.viridis(np.linspace(0, 0.9, 5))
        jj = 0
        tno = np.arange(1, 6, 1)
        for i in range(4):
            ii = len(theta) - i - 1
            plt.plot(tno,
                     ((p_cfd[ii, :] / 100. + 1.) /
                      (p_cfd[ii, 0] / 100. + 1.) - 1.) * 100,
                     's:',
                     color=viridis[i],
                     label='CFD: ' + str(theta[i]) + 'deg',
                     lw=2)

        for nam, blockage_model in blockage_models:
            for i in range(4):
                if i == 3:
                    plt.plot(
                        tno,
                        (res[nam].Power[:, i, 0] - res[nam].Power[0, i, 0]) /
                        res[nam].Power[0, i, 0] * 100,
                        lines[jj],
                        label=nam,
                        color=viridis[i],
                        lw=1,
                        alpha=0.8)
                else:
                    plt.plot(
                        tno,
                        (res[nam].Power[:, i, 0] - res[nam].Power[0, i, 0]) /
                        res[nam].Power[0, i, 0] * 100,
                        lines[jj],
                        color=viridis[i],
                        lw=1,
                        alpha=0.8)
            jj += 1

        plt.grid(alpha=0.2)
        plt.xlabel('Turbine no.')
        plt.ylabel('Power change, $(P-P_1)/P_1$ [%]')
        plt.xticks([0, 1, 2, 3, 4, 5])
        plt.xlim([.9, 5.1])
        plt.legend(fontsize=11)
        plt.show()
    wt = IEA37_WindTurbines()
    wfm = IEA37SimpleBastankhahGaussian(site, wt)
    x, y = iea37_site.initial_position[np.array([0, 2, 5, 8, 14])].T

    dAEPdxy_autograd = wfm.dAEPdxy(gradient_method=autograd)(x, y)
    dAEPdxy_cs = wfm.dAEPdxy(gradient_method=cs)(x, y)
    dAEPdxy_fd = wfm.dAEPdxy(gradient_method=fd)(x, y)

    npt.assert_array_almost_equal(dAEPdxy_autograd, dAEPdxy_cs, 15)
    npt.assert_array_almost_equal(dAEPdxy_autograd, dAEPdxy_fd, 6)


@pytest.mark.parametrize('wake_deficitModel,blockage_deficitModel',
                         [(FugaDeficit(), None),
                          (NoWakeDeficit(), SelfSimilarityDeficit()),
                          (FugaDeficit(), SelfSimilarityDeficit())])
def test_deficit_symmetry(wake_deficitModel, blockage_deficitModel):
    site = Hornsrev1Site()
    windTurbines = IEA37_WindTurbines()

    wfm = All2AllIterative(site,
                           windTurbines,
                           wake_deficitModel=wake_deficitModel,
                           superpositionModel=LinearSum(),
                           blockage_deficitModel=blockage_deficitModel,
                           deflectionModel=None,
                           turbulenceModel=None)

    power = wfm([0, 0, 500, 500], [0, 500, 0, 500], wd=[0],
                ws=[8]).power_ilk[:, 0, 0]