예제 #1
0
def test_with_all_deficit_models(WFM, deficitModel):
    site = IEA37Site(16)
    windTurbines = IEA37_WindTurbines()

    wfm = WFM(site,
              windTurbines,
              wake_deficitModel=deficitModel,
              rotorAvgModel=RotorCenter(),
              superpositionModel=LinearSum(),
              deflectionModel=None,
              turbulenceModel=STF2017TurbulenceModel())

    wfm2 = WFM(site,
               windTurbines,
               wake_deficitModel=deficitModel,
               rotorAvgModel=EqGridRotorAvg(1),
               superpositionModel=LinearSum(),
               deflectionModel=None,
               turbulenceModel=STF2017TurbulenceModel())
    kwargs = {
        'x': [0, 0, 500, 500],
        'y': [0, 500, 0, 500],
        'wd': [0],
        'ws': [8]
    }
    npt.assert_equal(wfm.aep(**kwargs), wfm2.aep(**kwargs))
예제 #2
0
파일: rathmann.py 프로젝트: hmharley/PyWake
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()
예제 #3
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__)
예제 #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
    ])
예제 #5
0
def test_GCL_ex80():
    site = Hornsrev1Site()

    x, y = site.initial_position.T
    windTurbines = V80()
    wfm = PropagateDownwind(site,
                            windTurbines,
                            wake_deficitModel=GCLDeficit(),
                            superpositionModel=LinearSum())
    if 0:
        windTurbines.plot(x, y)
        plt.show()

    sim_res = timeit(wfm.__call__,
                     line_profile=0,
                     profile_funcs=[get_dU],
                     verbose=0)(x, y, ws=np.arange(10, 15))[0]

    # test that the result is equal to previuos runs (no evidens that  these number are correct)
    aep_ref = 1055.956615887197
    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)
예제 #6
0
def test_wake_and_blockage(setup):
    site, windTurbines, ss = setup
    noj_ss = All2AllIterative(site,
                              windTurbines,
                              wake_deficitModel=NOJDeficit(),
                              blockage_deficitModel=ss,
                              superpositionModel=LinearSum())

    flow_map = noj_ss(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]

    npt.assert_array_almost_equal(WS_eff[200, ::50], [
        9.940967, 9.911659, 9.855934, 9.736016, 9.44199, 4.560631, 5.505472,
        6.223921, 6.782925, 7.226399
    ])
    npt.assert_array_almost_equal(WS_eff[250, ::50], [
        9.937601, 9.90397, 9.834701, 9.659045, 9.049764, 4.560631, 5.505472,
        6.223921, 6.782925, 7.226399
    ])

    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()
예제 #7
0
 def __init__(self,
              LUT_path,
              site,
              windTurbines,
              rotorAvgModel=RotorCenter(),
              deflectionModel=None,
              turbulenceModel=None):
     """
     Parameters
     ----------
     LUT_path : str
         path to look up tables
     site : Site
         Site object
     windTurbines : WindTurbines
         WindTurbines object representing the wake generating wind turbines
     rotorAvgModel : RotorAvgModel
         Model defining one or more points at the down stream rotors to
         calculate the rotor average wind speeds from.\n
         Defaults to RotorCenter that uses the rotor center wind speed (i.e. one point) only
     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
     """
     PropagateDownwind.__init__(self,
                                site,
                                windTurbines,
                                wake_deficitModel=FugaDeficit(LUT_path),
                                rotorAvgModel=rotorAvgModel,
                                superpositionModel=LinearSum(),
                                deflectionModel=deflectionModel,
                                turbulenceModel=turbulenceModel)
예제 #8
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)
예제 #9
0
파일: stf.py 프로젝트: knutss/PyWake
 def __init__(self,
              c=[1.5, 0.8],
              addedTurbulenceSuperpositionModel=LinearSum(),
              weight_function=FrandsenWeight(),
              **kwargs):
     TurbulenceModel.__init__(self, addedTurbulenceSuperpositionModel,
                              **kwargs)
     self.c = c
     self.apply_weight = weight_function.apply_weight
예제 #10
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_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]
    npt.assert_array_almost_equal(power[:2], power[2:])
예제 #12
0
def test_neighbour_farm_speed():
    # import and setup site and windTurbines
    site = IEA37Site(16)

    # setup current, neighbour and all positions
    wt_x, wt_y = site.initial_position.T
    neighbour_x, neighbour_y = wt_x - 4000, wt_y
    all_x, all_y = np.r_[wt_x, neighbour_x], np.r_[wt_y, neighbour_y]

    windTurbines = WindTurbines.from_WindTurbines([IEA37_WindTurbines(), IEA37_WindTurbines()])
    windTurbines._names = ["Current wind farm", "Neighbour wind farm"]
    types = [0] * len(wt_x) + [1] * len(neighbour_x)

    wf_model = PropagateDownwind(site, windTurbines,
                                 wake_deficitModel=BastankhahGaussianDeficit(use_effective_ws=True),
                                 superpositionModel=LinearSum())
    # Consider wd=270 +/- 30 deg only
    wd_lst = np.arange(240, 301)

    sim_res, t = timeit(wf_model, verbose=False)(all_x, all_y, type=types, ws=9.8, wd=wd_lst)
    if 1:
        ext = 100
        flow_box = wf_model(neighbour_x, neighbour_y, wd=wd_lst).flow_box(
            x=np.linspace(min(wt_x) - ext, max(wt_x) + ext, 53),
            y=np.linspace(min(wt_y) - ext, max(wt_y) + ext, 51),
            h=[100, 110, 120])

        wake_site = XRSite.from_flow_box(flow_box)
        wake_site.save('tmp.nc')
    else:
        wake_site = XRSite.load('tmp.nc')

    wf_model_wake_site = PropagateDownwind(wake_site, windTurbines,
                                           wake_deficitModel=BastankhahGaussianDeficit(use_effective_ws=True),
                                           superpositionModel=LinearSum())

    sim_res_wake_site, _ = timeit(wf_model_wake_site, verbose=False)(wt_x, wt_y, ws=9.8, wd=wd_lst)
    npt.assert_allclose(sim_res.aep().sel(wt=np.arange(len(wt_x))).sum(), sim_res_wake_site.aep().sum(), rtol=0.0005)
    npt.assert_array_almost_equal(sim_res.aep().sel(wt=np.arange(len(wt_x))), sim_res_wake_site.aep(), 2)
예제 #13
0
파일: test_noj.py 프로젝트: knutss/PyWake
def test_NOJ_Nibe_result():
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).

    site = UniformSite([1], 0.1)
    x_i = [0, 0, 0]
    y_i = [0, -40, -100]
    h_i = [50, 50, 50]
    wfm = All2AllIterative(site,
                           NibeA0,
                           wake_deficitModel=NOJDeficit(),
                           superpositionModel=LinearSum())
    WS_eff_ilk = wfm.calc_wt_interaction(x_i, y_i, h_i, [0, 1, 1], 0.0, 8.1)[0]
    npt.assert_array_almost_equal(WS_eff_ilk[:, 0, 0], [8.1, 4.35, 5.7])
예제 #14
0
    def __init__(self,
                 site,
                 windTurbines,
                 wake_deficitModel,
                 rotorAvgModel=RotorCenter(),
                 superpositionModel=LinearSum(),
                 blockage_deficitModel=None,
                 deflectionModel=None,
                 turbulenceModel=None,
                 groundModel=None,
                 convergence_tolerance=1e-6):
        """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
            Model defining one or more points at the down stream rotors to
            calculate the rotor average wind speeds from.\n
            Defaults to RotorCenter that uses the rotor center wind speed (i.e. one point) only
        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
            maximum accepted change in WS_eff_ilk [m/s]
        """
        EngineeringWindFarmModel.__init__(
            self,
            site,
            windTurbines,
            wake_deficitModel,
            rotorAvgModel,
            superpositionModel,
            blockage_deficitModel=blockage_deficitModel,
            deflectionModel=deflectionModel,
            turbulenceModel=turbulenceModel,
            groundModel=groundModel)
        self.convergence_tolerance = convergence_tolerance
예제 #15
0
파일: gcl.py 프로젝트: knutss/PyWake
 def __init__(self,
              site,
              windTurbines,
              rotorAvgModel=RotorCenter(),
              superpositionModel=LinearSum(),
              deflectionModel=None,
              turbulenceModel=None,
              groundModel=None):
     PropagateDownwind.__init__(self,
                                site,
                                windTurbines,
                                wake_deficitModel=GCLDeficit(),
                                rotorAvgModel=rotorAvgModel,
                                superpositionModel=superpositionModel,
                                deflectionModel=deflectionModel,
                                turbulenceModel=turbulenceModel,
                                groundModel=groundModel)
예제 #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.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()
예제 #17
0
파일: fuga.py 프로젝트: xtoworks/PyWake
 def __init__(self, LUT_path, site, windTurbines, turbulenceModel=None, convergence_tolerance=1e-6):
     """
     Parameters
     ----------
     LUT_path : str
         path to look up tables
     site : Site
         Site object
     windTurbines : WindTurbines
         WindTurbines object representing the wake generating wind turbines
     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
     """
     fuga_deficit = FugaDeficit(LUT_path)
     All2AllIterative.__init__(self, site, windTurbines, wake_deficitModel=fuga_deficit,
                               superpositionModel=LinearSum(), blockage_deficitModel=fuga_deficit,
                               turbulenceModel=turbulenceModel, convergence_tolerance=convergence_tolerance)
예제 #18
0
def test_aep_two_turbines(setup):
    site, windTurbines, ss = setup

    nwm_ss = All2AllIterative(site,
                              windTurbines,
                              wake_deficitModel=NoWakeDeficit(),
                              blockage_deficitModel=ss,
                              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, 0.4896853)

    if 0:
        plt.plot(sim_res.WS_eff_ilk[:, :, 7].T)
        plt.show()
예제 #19
0
    def __init__(self,
                 site,
                 windTurbines,
                 wake_deficitModel,
                 rotorAvgModel=RotorCenter(),
                 superpositionModel=LinearSum(),
                 deflectionModel=None,
                 turbulenceModel=None,
                 groundModel=None):
        """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.
            Default is RotorCenter, i.e. one point at rotor center
        superpositionModel : SuperpositionModel
            Model defining how deficits sum up
        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
        """
        EngineeringWindFarmModel.__init__(self,
                                          site,
                                          windTurbines,
                                          wake_deficitModel,
                                          rotorAvgModel,
                                          superpositionModel,
                                          blockage_deficitModel=None,
                                          deflectionModel=deflectionModel,
                                          turbulenceModel=turbulenceModel,
                                          groundModel=groundModel)
예제 #20
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)
예제 #21
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
예제 #22
0
파일: noj.py 프로젝트: blondelf/PyWake-1
 def __init__(self,
              site,
              windTurbines,
              rotorAvgModel=RotorCenter(),
              a=[0.38, 4e-3],
              use_effective_ws=True,
              superpositionModel=LinearSum(),
              deflectionModel=None,
              turbulenceModel=STF2017TurbulenceModel()):
     """
     Parameters
     ----------
     site : Site
         Site object
     windTurbines : WindTurbines
         WindTurbines object representing the wake generating wind turbines
     k : float, default 0.1
         wake expansion factor
     superpositionModel : SuperpositionModel, default SquaredSum
         Model defining how deficits sum up
     blockage_deficitModel : DeficitModel, default None
         Model describing the blockage(upstream) deficit
     deflectionModel : DeflectionModel, default None
         Model describing the deflection of the wake due to yaw misalignment, sheared inflow, etc.
     turbulenceModel : TurbulenceModel, default None
         Model describing the amount of added turbulence in the wake
     """
     PropagateDownwind.__init__(self,
                                site,
                                windTurbines,
                                wake_deficitModel=NOJLocalDeficit(
                                    a=a, use_effective_ws=use_effective_ws),
                                rotorAvgModel=rotorAvgModel,
                                superpositionModel=superpositionModel,
                                deflectionModel=deflectionModel,
                                turbulenceModel=turbulenceModel)
예제 #23
0
파일: fuga.py 프로젝트: xtoworks/PyWake
 def __init__(self, LUT_path, site, windTurbines, deflectionModel=None, turbulenceModel=None):
     """
     Parameters
     ----------
     LUT_path : str
         path to look up tables
     site : Site
         Site object
     windTurbines : WindTurbines
         WindTurbines object representing the wake generating wind turbines
     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
     """
     PropagateDownwind.__init__(self, site, windTurbines,
                                wake_deficitModel=FugaDeficit(LUT_path), superpositionModel=LinearSum(),
                                deflectionModel=deflectionModel, turbulenceModel=turbulenceModel)
예제 #24
0
from py_wake.site._site import UniformSite
from py_wake.superposition_models import LinearSum, SquaredSum, MaxSum
from py_wake.tests import npt
from py_wake.wind_turbines import WindTurbines

# Two turbines, 0: Nibe-A, 1:Ct=0
NibeA0 = WindTurbines(names=['Nibe-A'] * 2,
                      diameters=[40] * 2,
                      hub_heights=[50] * 2,
                      ct_funcs=[lambda _: 8 / 9, lambda _: 0],
                      power_funcs=[lambda _: 0] * 2,
                      power_unit='w')

d02 = 8.1 - 5.7
d12 = 8.1 - 4.90473373


@pytest.mark.parametrize('superpositionModel,res',
                         [(LinearSum(), 8.1 - (d02 + d12)),
                          (SquaredSum(), 8.1 - np.hypot(d02, d12)),
                          (MaxSum(), 8.1 - d12)])
def test_superposition_models(superpositionModel, res):
    site = UniformSite([1], 0.1)
    wake_model = NOJ(site, NibeA0, superpositionModel=superpositionModel)
    x_i = [0, 0, 0]
    y_i = [0, -40, -100]
    h_i = [50, 50, 50]
    WS_eff_ilk = wake_model.calc_wt_interaction(x_i, y_i, h_i, [0, 0, 1], 0.0,
                                                8.1)[0]
    npt.assert_array_almost_equal(WS_eff_ilk[-1, 0, 0], res)
예제 #25
0
    if 0:
        fm_res = sim_res.flow_map(YZGrid(x=0, y=np.arange(-100, 10, 1)))
        fm_res.plot_wake_map()
        plt.plot(fm_ref.X[0], fm_ref.Y[0], '.')
        plt.plot(fm_ref.X[0], ref * 10, label='ref, WS*10')
        plt.plot(fm_ref.X[0], res * 10, label='Res, WS*10')

        plt.legend()
        plt.show()
    plt.close()
    npt.assert_array_equal(res, ref)


@pytest.mark.parametrize('wfm_cls', [PropagateDownwind, All2AllIterative])
@pytest.mark.parametrize('groundModel,superpositionModel',
                         [(Mirror(), LinearSum()),
                          (MirrorSquaredSum(), SquaredSum())])
def test_Mirror_flow_map(wfm_cls, groundModel, superpositionModel):
    site = UniformSite([1], ti=0.1)
    wt = V80()
    wfm = NOJ(site, wt, k=.5, superpositionModel=superpositionModel)

    fm_ref = wfm([0, 0 + 1e-20], [0, 0 + 1e-20], wd=0, h=[50, -50]).flow_map(
        YZGrid(x=0, y=np.arange(-100, 100, 1) + .1, z=np.arange(1, 100)))
    fm_ref.plot_wake_map()
    plt.title("Underground WT added manually")

    plt.figure()
    wfm = wfm_cls(site,
                  wt,
                  NOJDeficit(k=.5),
예제 #26
0
from py_wake import NOJ
from py_wake.site._site import UniformSite
from py_wake.superposition_models import LinearSum, SquaredSum, MaxSum
from py_wake.tests import npt
from py_wake.wind_farm_models.engineering_models import PropagateDownwind, All2AllIterative
from py_wake.deficit_models.noj import NOJDeficit
from py_wake.flow_map import HorizontalGrid
from py_wake.tests.test_deficit_models.test_noj import NibeA0
import xarray as xr

d02 = 8.1 - 5.7
d12 = 8.1 - 4.90473373


@pytest.mark.parametrize('superpositionModel,res',
                         [(LinearSum(), 8.1 - (d02 + d12)),
                          (SquaredSum(), 8.1 - np.hypot(d02, d12)),
                          (MaxSum(), 8.1 - d12)])
def test_superposition_models(superpositionModel, res):
    site = UniformSite([1], 0.1)
    wake_model = NOJ(site, NibeA0, superpositionModel=superpositionModel)
    x_i = [0, 0, 0]
    y_i = [0, -40, -100]
    h_i = [50, 50, 50]
    WS_eff_ilk = wake_model.calc_wt_interaction(x_i, y_i, h_i, [0, 0, 1], 0.0,
                                                8.1)[0]
    npt.assert_array_almost_equal(WS_eff_ilk[-1, 0, 0], res)


@pytest.mark.parametrize('superpositionModel,sum_func',
                         [(LinearSum(), np.sum),
예제 #27
0
                                   turbulenceModel=turbulenceModel)


if __name__ == '__main__':
    from py_wake.examples.data.iea37._iea37 import IEA37Site
    from py_wake.examples.data.iea37._iea37 import IEA37_WindTurbines
    import matplotlib.pyplot as plt

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

    wf_model_ss = NOJ(site, windTurbines, k=0.05, superpositionModel=SquaredSum())
    print(wf_model_ss)
    wf_model_ls = NOJ(site, windTurbines, k=0.05, superpositionModel=LinearSum())
    print(wf_model_ls)
    wf_model_ms = NOJ(site, windTurbines, k=0.05, superpositionModel=MaxSum())
    print(wf_model_ms)

    # run wind farm simulation
    sim_res_ss = wf_model_ss(x, y)
    # return SimulationResult(self, localWind=localWind,
    #                         x_i=x, y_i=y, h_i=h, type_i=type, yaw_ilk=yaw_ilk,
    #                         wd=wd, ws=ws,
    #                         WS_eff_ilk=WS_eff_ilk, TI_eff_ilk=TI_eff_ilk,
    #                         power_ilk=power_ilk, ct_ilk=ct_ilk)
    sim_res_ls = wf_model_ls(x, y)
    sim_res_ms = wf_model_ms(x, y)

    # calculate AEP
예제 #28
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()
예제 #29
0
 def get_wf_model(cls):
     return cls(site, NibeA0, wake_deficitModel=NoWakeDeficit(),
                superpositionModel=LinearSum(),
                turbulenceModel=STF2017TurbulenceModel())
예제 #30
0
def test_check_model():
    check_model(LinearSum(), SuperpositionModel)