Esempio n. 1
0
 def __init__(self,
              site,
              windTurbines,
              rotorAvgModel=RotorCenter(),
              k=.1,
              superpositionModel=SquaredSum(),
              deflectionModel=None,
              turbulenceModel=None):
     """
     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=NOJDeficit(k),
                                rotorAvgModel=rotorAvgModel,
                                superpositionModel=superpositionModel,
                                deflectionModel=deflectionModel,
                                turbulenceModel=turbulenceModel)
Esempio n. 2
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))
Esempio n. 3
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)
Esempio n. 4
0
 def __init__(self,
              site,
              windTurbines,
              rotorAvgModel=RotorCenter(),
              superpositionModel=SquaredSum(),
              deflectionModel=None,
              turbulenceModel=None):
     """
     Parameters
     ----------
     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
     superpositionModel : SuperpositionModel, default SquaredSum
         Model defining how deficits sum up
     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=IEA37SimpleBastankhahGaussianDeficit(),
         rotorAvgModel=rotorAvgModel,
         superpositionModel=superpositionModel,
         deflectionModel=deflectionModel,
         turbulenceModel=turbulenceModel)
Esempio n. 5
0
    def __init__(self, site, windTurbines, rotorAvgModel=RotorCenter(), superpositionModel=LinearSum(),
                 deflectionModel=None, turbulenceModel=None):

        PropagateDownwind.__init__(self, site, windTurbines,
                                   wake_deficitModel=GCLDeficit(use_effective_ws=True, use_effective_ti=True),
                                   rotorAvgModel=rotorAvgModel, superpositionModel=superpositionModel,
                                   deflectionModel=deflectionModel, turbulenceModel=turbulenceModel)
Esempio n. 6
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
Esempio n. 7
0
def test_RotorGridAvg_deficit():
    site = IEA37Site(16)
    x, y = site.initial_position.T
    windTurbines = IEA37_WindTurbines()
    wfm = IEA37SimpleBastankhahGaussian(site,
                                        windTurbines)
    flow_map = wfm([0, 500], [0, 0], wd=270, ws=10).flow_map(HorizontalGrid(x=[500], y=np.arange(-100, 100)))
    plt.plot(flow_map.Y[:, 0], flow_map.WS_eff_xylk[:, 0, 0, 0])
    R = windTurbines.diameter() / 2

    for name, rotorAvgModel, ref1 in [
            ('RotorCenter', RotorCenter(), 7.172723970425709),
            ('RotorGrid2', EqGridRotorAvg(2), 7.495889360682771),
            ('RotorGrid3', EqGridRotorAvg(3), 7.633415167369133),
            ('RotorGrid4', EqGridRotorAvg(4), 7.710215921858325),
            ('RotorGrid100', EqGridRotorAvg(100), 7.820762402628349),
            ('RotorGQGrid_4,3', GQGridRotorAvg(4, 3), 7.826105012683896),
            ('RotorCGI4', CGIRotorAvg(4), 7.848406907726826),
            ('RotorCGI4', CGIRotorAvg(7), 7.819900693605533),
            ('RotorCGI4', CGIRotorAvg(9), 7.82149363932618),
            ('RotorCGI4', CGIRotorAvg(21), 7.821558905416136)]:

        # test with PropagateDownwind
        wfm = IEA37SimpleBastankhahGaussian(site,
                                            windTurbines,
                                            rotorAvgModel=rotorAvgModel)
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.WS_eff_ilk[1, 0, 0], ref1)

        # test with All2AllIterative
        wfm = All2AllIterative(site, windTurbines,
                               IEA37SimpleBastankhahGaussianDeficit(),
                               rotorAvgModel=rotorAvgModel,
                               superpositionModel=SquaredSum())
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.WS_eff_ilk[1, 0, 0], ref1)

        plt.plot([-R, R], [sim_res.WS_eff_ilk[1, 0, 0]] * 2, label=name)
    if 0:
        plt.legend()
        plt.show()
    plt.close('all')
Esempio n. 8
0
def test_RotorGridAvg_ti():
    site = IEA37Site(16)
    x, y = site.initial_position.T
    windTurbines = IEA37_WindTurbines()
    wfm = IEA37SimpleBastankhahGaussian(site,
                                        windTurbines,
                                        turbulenceModel=STF2017TurbulenceModel())
    flow_map = wfm([0, 500], [0, 0], wd=270, ws=10).flow_map(HorizontalGrid(x=[500], y=np.arange(-100, 100)))
    plt.plot(flow_map.Y[:, 0], flow_map.TI_eff_xylk[:, 0, 0, 0])
    R = windTurbines.diameter() / 2

    for name, rotorAvgModel, ref1 in [
            ('RotorCenter', RotorCenter(), 0.22292190804089568),
            ('RotorGrid2', EqGridRotorAvg(2), 0.2111162769995657),
            ('RotorGrid3', EqGridRotorAvg(3), 0.2058616982653193),
            ('RotorGrid4', EqGridRotorAvg(4), 0.2028701990648858),
            ('RotorGrid100', EqGridRotorAvg(100), 0.1985255601976247),
            ('RotorGQGrid_4,3', GQGridRotorAvg(4, 3), 0.1982984399750206)]:

        # test with PropagateDownwind
        wfm = IEA37SimpleBastankhahGaussian(site,
                                            windTurbines,
                                            rotorAvgModel=rotorAvgModel,
                                            turbulenceModel=STF2017TurbulenceModel())
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.TI_eff_ilk[1, 0, 0], ref1)

        # test with All2AllIterative
        wfm = All2AllIterative(site, windTurbines,
                               IEA37SimpleBastankhahGaussianDeficit(),
                               rotorAvgModel=rotorAvgModel,
                               superpositionModel=SquaredSum(),
                               turbulenceModel=STF2017TurbulenceModel())
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.TI_eff_ilk[1, 0, 0], ref1)

        plt.plot([-R, R], [sim_res.TI_eff_ilk[1, 0, 0]] * 2, label=name)
    if 0:
        plt.legend()
        plt.show()
    plt.close('all')
Esempio n. 9
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)
Esempio n. 10
0
def test_RotorAvg_deficit():
    site = IEA37Site(16)
    windTurbines = IEA37_WindTurbines()
    wfm = IEA37SimpleBastankhahGaussian(site,
                                        windTurbines,
                                        turbulenceModel=STF2017TurbulenceModel())
    flow_map = wfm([0, 500], [0, 0], wd=270, ws=10).flow_map(HorizontalGrid(x=[500], y=np.arange(-100, 100)))
    plt.plot(flow_map.Y[:, 0], flow_map.TI_eff_xylk[:, 0, 0, 0])
    R = windTurbines.diameter() / 2

    for name, rotorAvgModel, ref1 in [
            ('None', None, 0.22292190804089568),
            ('RotorCenter', RotorCenter(), 0.22292190804089568),
            ('RotorGrid100', EqGridRotorAvg(100), 0.1989725533174574),
            ('RotorGQGrid_4,3', GQGridRotorAvg(4, 3), 0.19874837617113356),
            ('RotorCGI4', CGIRotorAvg(4), 0.19822024411411204),
            ('RotorCGI4', CGIRotorAvg(21), 0.1989414764606653)]:

        # test with PropagateDownwind
        wfm = IEA37SimpleBastankhahGaussian(site,
                                            windTurbines,
                                            turbulenceModel=STF2017TurbulenceModel(rotorAvgModel=rotorAvgModel))
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.TI_eff_ilk[1, 0, 0], ref1, err_msg=name)

        # test with All2AllIterative
        wfm = All2AllIterative(site, windTurbines,
                               IEA37SimpleBastankhahGaussianDeficit(),
                               turbulenceModel=STF2017TurbulenceModel(rotorAvgModel=rotorAvgModel),
                               superpositionModel=SquaredSum())
        sim_res = wfm([0, 500], [0, 0], wd=270, ws=10)
        npt.assert_almost_equal(sim_res.TI_eff_ilk[1, 0, 0], ref1)

        plt.plot([-R, R], [sim_res.WS_eff_ilk[1, 0, 0]] * 2, label=name)
    if 0:
        plt.legend()
        plt.show()
    plt.close()
Esempio 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.turbulence_models.stf import STF2017TurbulenceModel
        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 = NOJ(site, windTurbines)
        wf_model_local = NOJLocal(site,
                                  windTurbines,
                                  turbulenceModel=STF2017TurbulenceModel())
        wf_model_turbo = PropagateDownwind(
            site,
            windTurbines,
            rotorAvgModel=RotorCenter(),
            wake_deficitModel=TurboNOJDeficit(use_effective_ws=True,
                                              use_effective_ti=False),
            superpositionModel=LinearSum(),
            turbulenceModel=STF2017TurbulenceModel())
        # wf_model_turbo = NOJLocal(
        #     site, windTurbines, turbulenceModel=STF2017TurbulenceModel())
        # run wind farm simulation
        sim_res = wf_model(x, y)
        sim_res_local = wf_model_local(x, y)
        sim_res_turbo = wf_model_turbo(x, y)
        # calculate AEP
        aep = sim_res.aep().sum()
        aep_local = sim_res_local.aep().sum()
        aep_turbo = sim_res_turbo.aep().sum()

        # plot wake map
        fig, (ax1, ax2, ax3) = plt.subplots(1,
                                            3,
                                            figsize=(11, 4.5),
                                            tight_layout=True)
        levels = np.arange(0, 10.5, 0.5)
        print(wf_model)
        flow_map = sim_res.flow_map(wd=30, ws=9.8)
        flow_map.plot_wake_map(levels=levels, ax=ax1, plot_colorbar=False)
        flow_map.plot_windturbines(ax=ax1)
        ax1.set_title('Original Jensen, AEP: %.2f GWh' % aep)

        # plot wake map
        print(wf_model_local)
        flow_map = sim_res_local.flow_map(wd=30, ws=9.8)
        flow_map.plot_wake_map(levels=levels, ax=ax2, plot_colorbar=False)
        flow_map.plot_windturbines(ax=ax2)
        ax2.set_title('Local Jensen, AEP: %.2f GWh' % aep_local)

        # plot wake map
        print(wf_model_turbo)
        flow_map = sim_res_turbo.flow_map(wd=30, ws=9.8)
        flow_map.plot_wake_map(levels=levels, ax=ax3, plot_colorbar=False)
        flow_map.plot_windturbines(ax=ax3)
        ax3.set_title('Turbo Jensen, AEP: %.2f GWh' % aep_turbo)

        plt.figure()
        flow_map.plot_ti_map()
        plt.title('TI map for NOJLocal with STF2017 turbulence model')
        plt.show()

        # plot wake width as in Nygaard 2020
        D = 1
        D_src_il = np.array([[D]])
        x = np.linspace(0, 60, 100)
        dw_ijlk = x[na, :, na, na]

        noj = NOJDeficit(k=0.04)
        noj_wr = noj.wake_radius(D_src_il, dw_ijlk)

        ct_ilk = np.array([[[8 / 9]]])  # thrust coefficient
        TI_ilk = np.array([[[0.06]]])
        TI_eff_ilk = np.array([[[0.06]]])
        tj = TurboNOJDeficit()
        tj_wr = tj.wake_radius(D_src_il,
                               dw_ijlk,
                               ct_ilk=ct_ilk,
                               TI_ilk=TI_ilk,
                               TI_eff_ilk=TI_eff_ilk)

        plt.figure()
        plt.title(
            'Wake width comparison, NOJ orig and TurboNOJ (Nygaard2020) TI=6%')
        plt.plot(x, noj_wr[0, :, 0, 0], label='NOJ, k=0.04')
        plt.plot(x, tj_wr[0, :, 0, 0], label='TurboNOJ')
        plt.xlabel('x/D')
        plt.ylabel('y/D')
        plt.grid()
        plt.legend()
        plt.show()