Example #1
0
def test_NOJ_Nibe_result():
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).

    site = UniformSite([1], 0.1)
    wake_model = NOJ(site, NibeA0)
    x_i = [0, 0, 0]
    y_i = [0, -40, -100]
    h_i = [50, 50, 50]
    WS_eff_ilk = wake_model.calc_wake(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])
Example #2
0
def test_NOJ_Nibe_result():
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).

    wake_model = NOJ(NibeA0)
    WS_ilk = np.array([[[8.1]], [[8.1]], [[8.1]]])
    TI_ilk = np.zeros_like(WS_ilk)
    site = UniformSite([1], 0.1)
    dw_iil, cw_iil, dh_iil, dw_order_indices_l = site.wt2wt_distances(
        x_i=[0, 0, 0], y_i=[0, -40, -100], h_i=[50, 50, 50], wd_il=[[0]])
    WS_eff_ilk = wake_model.calc_wake(WS_ilk, TI_ilk, dw_iil, cw_iil, dh_iil, dw_order_indices_l, [0, 1, 1])[0]
    npt.assert_array_almost_equal(WS_eff_ilk[:, 0, 0], [8.1, 4.35, 5.7])
Example #3
0
def test_NOJ_two_turbines_in_row(wdir, x, y):
    # Two turbines in a row, North-South
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).

    windTurbines = NibeA0
    site = UniformSite([1], 0.1)
    wake_model = NOJ(site, windTurbines)
    h_i = [50, 50, 50]
    WS_eff_ilk = wake_model.calc_wake(x, y, h_i, [0, 0, 0], wdir, 8.1)[0]
    ws_wt3 = 8.1 - np.hypot(8.1 * 2 / 3 * (20 / 26)**2, 8.1 * 2 / 3 *
                            (20 / 30)**2)
    npt.assert_array_almost_equal(WS_eff_ilk[:, 0, 0], [8.1, 4.35, ws_wt3])
Example #4
0
def test_NOJ_6_turbines_in_row():
    n_wt = 6
    x = [0] * n_wt
    y = -np.arange(n_wt) * 40 * 2

    site = UniformSite([1], 0.1)
    wake_model = NOJ(site, NibeA0)
    WS_eff_ilk = wake_model.calc_wake(x, y, [50] * n_wt, [0.0] * n_wt, 0.0,
                                      11.0)[0]
    np.testing.assert_array_almost_equal(
        WS_eff_ilk[1:, 0, 0], 11 - np.sqrt(
            np.cumsum(
                ((11 * 2 / 3 * 20**2)**2) / (20 + 8 * np.arange(1, 6))**4)))
Example #5
0
def test_NOJ_two_turbines_in_row(wdir, x, y):
    # Two turbines in a row, North-South
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).

    windTurbines = NibeA0
    wake_model = NOJ(windTurbines)
    WS_ilk = np.array([[[8.1]], [[8.1]], [[8.1]]])
    TI_ilk = np.zeros_like(WS_ilk)
    site = UniformSite([1], 0.1)
    dw_iil, cw_iil, dh_iil, dw_order_indices_l = site.wt2wt_distances(x_i=x, y_i=y, h_i=[50, 50, 50], wd_il=[[wdir]])
    WS_eff_ilk = wake_model.calc_wake(WS_ilk, TI_ilk, dw_iil, cw_iil, dh_iil, dw_order_indices_l, [0, 0, 0])[0]
    ws_wt3 = 8.1 - np.sqrt((8.1 * 2 / 3 * (20 / 26)**2)**2 + (8.1 * 2 / 3 * (20 / 30)**2)**2)
    npt.assert_array_almost_equal(WS_eff_ilk[:, 0, 0], [8.1, 4.35, ws_wt3])
Example #6
0
def test_wake_map():
    site = IEA37Site(16)

    x, y = site.initial_position.T

    windTurbines = IEA37_WindTurbines(iea37_path + 'iea37-335mw.yaml')
    wake_model = NOJ(site, windTurbines)
    aep = AEPCalculator(wake_model)
    x_j = np.linspace(-1500, 1500, 200)
    y_j = np.linspace(-1500, 1500, 100)
    X, Y, Z = aep.wake_map(x_j, y_j, 110, x, y, wd=[0], ws=[9])

    if 0:
        import matplotlib.pyplot as plt
        c = plt.contourf(X, Y, Z)  # , np.arange(2, 10, .01))
        plt.colorbar(c)
        windTurbines.plot(x, y)

        plt.show()

    ref = [
        3.27, 3.27, 9.0, 7.46, 7.46, 7.46, 7.46, 7.31, 7.31, 7.31, 7.31, 8.3,
        8.3, 8.3, 8.3, 8.3, 8.3
    ]
    npt.assert_array_almost_equal(Z[49, 100:133:2], ref, 2)
Example #7
0
def test_NOJ_6_turbines_in_row():
    n_wt = 6
    x = [0] * n_wt
    y = - np.arange(n_wt) * 40 * 2

    wake_model = NOJ(NibeA0)
    site = UniformSite([1], .1)
    WD_ilk, WS_ilk, _, _ = site.local_wind(x_i=x, y_i=y, wd=[0], ws=[11])
    TI_ilk = np.zeros_like(WS_ilk)
    site = UniformSite([1], 0.1)
    dw_iil, cw_iil, dh_iil, dw_order_indices_l = site.wt2wt_distances(
        x_i=x, y_i=y, h_i=[50] * n_wt, wd_il=WD_ilk.mean(2))
    WS_eff_ilk = wake_model.calc_wake(WS_ilk, TI_ilk, dw_iil, cw_iil, dh_iil, dw_order_indices_l, [0] * n_wt)[0]

    np.testing.assert_array_almost_equal(
        WS_eff_ilk[1:, 0, 0], 11 - np.sqrt(np.cumsum(((11 * 2 / 3 * 20**2)**2) / (20 + 8 * np.arange(1, 6))**4)))
Example #8
0
def test_distance_over_rectangle():
    x, y = [-100, 50], [200, -100]
    windTurbines = IEA37_WindTurbines()
    site = Rectangle(height=200, width=100, distance_resolution=100)
    wake_model = NOJ(site, windTurbines)
    aep = AEPCalculator(wake_model)
    x_j = np.linspace(-100, 500, 100)
    y_j = np.linspace(-200, 300, 100)
    X, Y, Z = aep.wake_map(x_j, y_j, 110, x, y, wd=[270], ws=[9])

    my = np.argmin(np.abs(Y[:, 0] - 200))
    my2 = np.argmin(np.abs(Y[:, 0] + 100))

    if 0:
        import matplotlib.pyplot as plt
        c = plt.contourf(X, Y, Z, cmap='Blues_r',
                         levels=100)  # , np.arange(2, 10, .01))
        plt.colorbar(c)
        windTurbines.plot(x, y)
        H = site.elevation(X, Y)
        plt.plot(X[my], Z[my] * 10, label='wsp*10')
        plt.plot(X[my2], Z[my2] * 10, label='wsp*10')
        plt.contour(X, Y, H)
        plt.plot(X[my, :50:4], Z[my, :50:4] * 10, '.')
        plt.plot(x_j, site.elevation(x_j, x_j * 0), label='terrain level')
        plt.legend()
        plt.show()

    ref = [
        9., 3.42, 3.8, 6.02, 6.17, 6.31, 6.43, 7.29, 7.35, 7.41, 7.47, 7.53,
        7.58
    ]
    npt.assert_array_almost_equal(Z[my, :50:4], ref, 2)
Example #9
0
def test_twotype_windturbines():
    from py_wake.wind_turbines import WindTurbines
    v80 = V80()

    def power(ws, types):
        power = v80.power(ws)
        # add 10% type 1 turbines
        power[types == 1] *= 1.1
        return power

    wts = WindTurbines(names=['V80', 'V88'],
                       diameters=[80, 88],
                       hub_heights=[70, 77],
                       ct_funcs=[v80.ct_funcs[0], v80.ct_funcs[0]],
                       power_funcs=[v80.power, lambda ws: v80.power(ws) * 1.1],
                       power_unit='w')

    import matplotlib.pyplot as plt
    types0 = [0] * 9
    types1 = [0, 0, 0, 1, 1, 1, 0, 0, 0]
    types2 = [1] * 9
    wts.plot(wt9_x, wt9_y, types1)

    aep_calculator = AEPCalculator(NOJ(Hornsrev1Site(), wts))
    npt.assert_almost_equal(
        aep_calculator.calculate_AEP(wt9_x, wt9_y, type_i=types0).sum(),
        81.2066072392765)
    npt.assert_almost_equal(
        aep_calculator.calculate_AEP(wt9_x, wt9_y, type_i=types1).sum(),
        83.72420504573488)
    npt.assert_almost_equal(
        aep_calculator.calculate_AEP(wt9_x, wt9_y, type_i=types2).sum(),
        88.87227386796884)
    if 0:
        plt.show()
Example #10
0
def run_NOJ():
    windTurbines = IEA37_WindTurbines()
    site = IEA37Site(64)
    wake_model = NOJ(windTurbines)
    aep_calculator = AEPCalculator(site, windTurbines, wake_model)

    x, y = site.initial_position.T
    print(aep_calculator.calculate_AEP(x, y).sum())
Example #11
0
def main():
    if __name__ == '__main__':
        import matplotlib.pyplot as plt
        wt = HornsrevV80()
        wt.plot(wt_x, wt_y)
        aep_calculator = AEPCalculator(Hornsrev1Site(), wt, NOJ(wt))
        print('AEP', aep_calculator.calculate_AEP(wt_x, wt_y)[0].sum())
        plt.show()
Example #12
0
def test_wake_model():
    _, _, freq = read_iea37_windrose(iea37_path + "iea37-windrose.yaml")
    site = UniformSite(freq, ti=0.75)
    windTurbines = IEA37_WindTurbines(iea37_path + 'iea37-335mw.yaml')
    wake_model = NOJ(windTurbines)
    aep = AEPCalculator(site, windTurbines, wake_model)
    with pytest.raises(ValueError, match="Turbines 0 and 1 are at the same position"):
        aep.calculate_AEP([0, 0], [0, 0], wd=np.arange(0, 360, 22.5), ws=[9.8])
Example #13
0
def test_smart_start_aep_map():
    site = IEA37Site(16)
    n_wt = 4
    np.random.seed(1)
    x, y = site.initial_position[:n_wt].T
    wd_lst = np.arange(0, 360, 45)
    ws_lst = [10]
    turbines = hornsrev1.HornsrevV80()
    site = UniformSite([1], .75)
    site.default_ws = ws_lst
    site.default_wd = wd_lst

    aep = PyWakeAEP(site=site, windTurbines=turbines, wake_model=NOJ(turbines))
    aep_1wt = aep.calculate_AEP([0], [0]).sum()

    tf = TopFarmProblem(design_vars={
        'x': x,
        'y': y
    },
                        cost_comp=aep.get_TopFarm_cost_component(n_wt),
                        driver=EasyScipyOptimizeDriver(),
                        constraints=[
                            SpacingConstraint(160),
                            CircleBoundaryConstraint((0, 0), 500)
                        ])
    x = np.arange(-500, 500, 10)
    y = np.arange(-500, 500, 10)
    XX, YY = np.meshgrid(x, y)

    tf.smart_start(XX,
                   YY,
                   aep.get_aep4smart_start(wd=wd_lst, ws=ws_lst),
                   radius=40)
    tf.evaluate()

    if 0:
        wt_x, wt_y = tf['x'], tf['y']
        for i, _ in enumerate(wt_x, 1):
            print(aep.calculate_AEP(wt_x[:i], wt_y[:i]).sum((1, 2)))
        X_j, Y_j, aep_map = aep.aep_map(x,
                                        y,
                                        0,
                                        wt_x,
                                        wt_y,
                                        ws=ws_lst,
                                        wd=wd_lst)
        print(tf.evaluate())
        import matplotlib.pyplot as plt
        c = plt.contourf(X_j, Y_j, aep_map, 100)
        plt.colorbar(c)
        plt.plot(wt_x, wt_y, '2r')
        for c in tf.model.constraint_components:
            c.plot()
        plt.axis('equal')
        plt.show()
    npt.assert_almost_equal(aep_1wt * n_wt, tf['AEP'], 5)
Example #14
0
def test_aep_no_wake_loss_hornsrev():
    wt = hornsrev1.V80()
    x, y = hornsrev1.wt_x, hornsrev1.wt_y
    site = UniformWeibullSite([1], [10], [2], .75)
    site.default_ws = np.arange(3, 25)

    aep = AEPCalculator(site, wt, NOJ(wt))

    npt.assert_almost_equal(aep.calculate_AEP_no_wake_loss(x, y).sum() / 80, 8.260757098)
    cap_factor = aep.calculate_AEP(x, y).sum() / aep.calculate_AEP_no_wake_loss(x, y).sum()
    # print(cap_factor)
    npt.assert_almost_equal(cap_factor, 0.947175839142014)
Example #15
0
def test_NOJ_Nibe_result_wake_map():
    # Replicate result from: Jensen, Niels Otto. "A note on wind generator interaction." (1983).
    def ct_func(_):
        return 8 / 9

    def power_func(*_):
        return 0
    windTurbines = NibeA0
    wake_model = NOJ(windTurbines)
    site = UniformSite([1], 0.1)
    aep = AEPCalculator(site, windTurbines, wake_model)
    _, _, WS_eff_yx = aep.wake_map(x_j=[0], y_j=[0, -40, -100], h=50, wt_x=[0], wt_y=[0], wd=[0], ws=[8.1])
    npt.assert_array_almost_equal(WS_eff_yx[:, 0], [8.1, 4.35, 5.7])
Example #16
0
def main():
    if __name__ == '__main__':
        site = WaspGridSiteBase.from_wasp_grd(ParqueFicticio_path, speedup_using_pickle=False)
        site.initial_position = np.array([
            [263655.0, 6506601.0],
            [263891.1, 6506394.0],
            [264022.2, 6506124.0],
            [264058.9, 6505891.0],
            [264095.6, 6505585.0],
            [264022.2, 6505365.0],
            [264022.2, 6505145.0],
            [263936.5, 6504802.0],
        ])
        windTurbines = IEA37_WindTurbines()
        wake_model = NOJ(site, windTurbines)
        x, y = site.initial_position.T
        aep_calculator = AEPCalculator(wake_model)
        print(aep_calculator.calculate_AEP(x, y).sum())
Example #17
0
def test_wake_map():
    _, _, freq = read_iea37_windrose(iea37_path + "iea37-windrose.yaml")
    n_wt = 16
    x, y, _ = read_iea37_windfarm(iea37_path + 'iea37-ex%d.yaml' % n_wt)

    site = UniformSite(freq, ti=0.75)
    windTurbines = IEA37_WindTurbines(iea37_path + 'iea37-335mw.yaml')
    wake_model = NOJ(windTurbines)
    aep = AEPCalculator(site, windTurbines, wake_model)
    x_j = np.linspace(-1500, 1500, 200)
    y_j = np.linspace(-1500, 1500, 100)
    X, Y, Z = aep.wake_map(x_j, y_j, 110, x, y, wd=[0], ws=[9])

    if 0:
        import matplotlib.pyplot as plt
        c = plt.contourf(X, Y, Z)  # , np.arange(2, 10, .01))
        plt.colorbar(c)
        site.plot_windturbines(x, y)

        plt.show()

    ref = [3.27, 3.27, 9.0, 7.46, 7.46, 7.46, 7.46, 7.31, 7.31, 7.31, 7.31, 8.3, 8.3, 8.3, 8.3, 8.3, 8.3]
    npt.assert_array_almost_equal(Z[49, 100:133:2], ref, 2)
Example #18
0
def test_wake_map():
    site = IEA37Site(16)
    x, y = site.initial_position.T
    windTurbines = IEA37_WindTurbines()
    wake_model = NOJ(site, windTurbines)
    aep = AEPCalculator(wake_model)
    x_j = np.linspace(-1500, 1500, 200)
    y_j = np.linspace(-1500, 1500, 100)
    X, Y, Z = aep.wake_map(x_j, y_j, 110, x, y, wd=[0], ws=[9])
    m = 49, slice(100, 133, 2)
    # print(np.round(Z[m], 2).tolist()) # ref
    if 0:
        import matplotlib.pyplot as plt
        c = plt.contourf(X, Y, Z)  # , np.arange(2, 10, .01))
        plt.colorbar(c)
        windTurbines.plot(x, y)
        plt.plot(X[m], Y[m], '.-r')
        plt.show()

    ref = [
        3.27, 3.27, 9.0, 7.46, 7.46, 7.46, 7.46, 7.31, 7.31, 7.31, 7.31, 8.3,
        8.3, 8.3, 8.3, 8.3, 8.3
    ]
    npt.assert_array_almost_equal(Z[m], ref, 2)
Example #19
0
def test_aep_no_wake():
    site = UniformWeibullSite([1], [10], [2], .75)
    V80 = hornsrev1.V80()
    aep = AEPCalculator(NOJ(site, V80))
    npt.assert_almost_equal(
        aep.calculate_AEP([0], [0], ws=np.arange(3, 25)).sum(), 8.260757098, 9)
Example #20
0
def test_wasp_resources_grid_point(site):
    #     x = np.array([l.split() for l in """0.6010665    -10.02692    32.71442    -6.746912
    # 0.5007213    -4.591617    37.10247    -11.0699
    # 0.3104101    -1.821247    59.18301    -12.56743
    # 0.4674515    16.14293    44.84665    -9.693183
    # 0.8710347    5.291974    26.01634    -6.154611
    # 0.9998786    -2.777032    15.72486    1.029988
    # 0.9079611    -7.882853    16.33216    6.42329
    # 0.759553    -5.082487    17.23354    10.18187
    # 0.7221162    4.606324    17.96417    11.45838
    # 0.8088576    8.196074    16.16308    9.277925
    # 0.8800673    3.932325    14.82337    5.380589
    # 0.8726974    -3.199536    19.99724    -1.433086""".split("\n")], dtype=np.float)
    #     for x_ in x.T:
    #         print(list(x_))
    x = [262978]
    y = [6504814]
    npt.assert_almost_equal(site.elevation(x, y), 227.8, 1)

    # Data from WAsP:
    # - add turbine (262878,6504814,30)
    # - Turbine (right click) - reports - Turbine Site Report full precision
    wasp_A = [2.197305, 1.664085, 1.353185, 2.651781, 5.28438, 5.038289,
              4.174325, 4.604496, 5.043066, 6.108261, 6.082033, 3.659798]
    wasp_k = [1.771484, 2.103516, 2.642578, 2.400391, 2.357422, 2.306641,
              2.232422, 2.357422, 2.400391, 2.177734, 1.845703, 1.513672]
    wasp_f = [5.188083, 2.509297, 2.869334, 4.966141, 13.16969, 9.514355,
              4.80275, 6.038354, 9.828702, 14.44174, 16.60567, 10.0659]
    wasp_spd = [0.6010665, 0.5007213, 0.3104101, 0.4674515, 0.8710347, 0.9998786,
                0.9079611, 0.759553, 0.7221162, 0.8088576, 0.8800673, 0.8726974]
    wasp_trn = [-10.02692, -4.591617, -1.821247, 16.14293, 5.291974, -
                2.777032, -7.882853, -5.082487, 4.606324, 8.196074, 3.932325, -3.199536]
    wasp_inc = [-6.746912, -11.0699, -12.56743, -9.693183, -6.154611,
                1.029988, 6.42329, 10.18187, 11.45838, 9.277925, 5.380589, -1.433086]
    wasp_ti = [32.71442, 37.10247, 59.18301, 44.84665, 26.01634, 15.72486,
               16.33216, 17.23354, 17.96417, 16.16308, 14.82337, 19.99724]
    rho = 1.179558

    wasp_u_mean = [1.955629, 1.473854, 1.202513, 2.350761, 4.683075,
                   4.463644, 3.697135, 4.080554, 4.470596, 5.409509, 5.402648, 3.300305]
    wasp_p_air = [9.615095, 3.434769, 1.556282, 12.45899, 99.90289,
                  88.03519, 51.41135, 66.09097, 85.69466, 164.5592, 193.3779, 56.86945]
    wasp_aep = np.array([3725293.0, 33722.71, 0.3093564, 3577990.0, 302099600.0, 188784100.0,
                         48915640.0, 84636210.0, 189009800.0, 549195100.0, 691258600.0, 120013000.0]) / 1000
    wasp_aep_no_density_correction = np.array([3937022.0, 36046.93, 0.33592, 3796496.0, 314595600.0,
                                               196765700.0, 51195440.0, 88451200.0, 197132700.0, 568584400.0, 712938400.0, 124804600.0]) / 1000
    wasp_aep_total = 2.181249024
    wasp_aep_no_density_correction_total = 2.26224
    wt_u = np.array([3.99, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25])
    wt_p = np.array([0, 55., 185., 369., 619., 941., 1326., 1741., 2133., 2436., 2617., 2702., 2734.,
                     2744., 2747., 2748., 2748., 2750., 2750., 2750., 2750., 2750., 2750.])
    wt_ct = np.array([0, 0.871, 0.853, 0.841, 0.841, 0.833, 0.797, 0.743, 0.635, 0.543, 0.424,
                      0.324, 0.258, 0.21, 0.175, 0.147, 0.126, 0.109, 0.095, 0.083, 0.074, 0.065, 0.059])
    wt = OneTypeWindTurbines.from_tabular(name="NEG-Micon 2750/92 (2750 kW)", diameter=92, hub_height=70,
                                          ws=wt_u, ct=wt_ct, power=wt_p, power_unit='kw')

    A_lst, k_lst, f_lst, spd_lst, orog_trn_lst, flow_inc_lst, tke_lst = [site.interp_funcs[n](
        (x, y, 30, range(0, 360, 30))) for n in ['A', 'k', 'f', 'spd', 'orog_trn', 'flow_inc', 'tke']]
    f_lst = f_lst * 360 / 12
    pdf_lst = [lambda x, A=A, k=k: k / A * (x / A)**(k - 1) * np.exp(-(x / A)**k) * (x[1] - x[0])
               for A, k in zip(A_lst, k_lst)]
    cdf_lst = [lambda x, A=A, k=k: 1 - np.exp(-(x / A) ** k) for A, k in zip(A_lst, k_lst)]
    dx = .1
    ws = np.arange(dx / 2, 35, dx)

    # compare to wasp data
    npt.assert_array_equal(A_lst, wasp_A)
    npt.assert_array_equal(k_lst, wasp_k)
    npt.assert_array_almost_equal(f_lst, np.array(wasp_f) / 100)
    npt.assert_array_almost_equal(spd_lst, wasp_spd)
    npt.assert_array_almost_equal(orog_trn_lst, wasp_trn)
    npt.assert_array_almost_equal(flow_inc_lst, wasp_inc)
    npt.assert_array_almost_equal(tke_lst, np.array(wasp_ti) / 100)

    # compare pdf, u_mean and aep to wasp
    WD, WS, TI, P = site.local_wind(x, np.array(y) + 1e-6, 30, wd=np.arange(0, 360, 30), ws=ws)
    P = P / f_lst[na, :, na]  # only wind speed probablity (not wdir)

    # pdf
    for i in range(12):
        npt.assert_array_almost_equal(np.interp(ws, WS[0, i], np.cumsum(P[0, i])),
                                      np.cumsum(pdf_lst[i](ws)), 1)

    # u_mean
    npt.assert_almost_equal([A * math.gamma(1 + 1 / k) for A, k in zip(A_lst, k_lst)], wasp_u_mean, 5)
    npt.assert_almost_equal([(pdf(ws) * ws).sum() for pdf in pdf_lst], wasp_u_mean, 5)
    npt.assert_almost_equal((P * WS).sum((0, 2)), wasp_u_mean, 5)

    # air power
    p_air = [(pdf(ws) * 1 / 2 * rho * ws**3).sum() for pdf in pdf_lst]
    npt.assert_array_almost_equal(p_air, wasp_p_air, 3)
    npt.assert_array_almost_equal((P * 1 / 2 * rho * WS**3).sum((0, 2)), wasp_p_air, 2)

    # AEP
    AEP_ilk = AEPCalculator(wake_model=NOJ(site, wt)).calculate_AEP_no_wake_loss(
        x_i=x, y_i=y, h_i=30, wd=np.arange(0, 360, 30), ws=ws)

    if 0:
        import matplotlib.pyplot as plt
        plt.plot(wasp_aep_no_density_correction / 1000, '.-', label='WAsP')
        plt.plot(AEP_ilk.sum((0, 2)) * 1e3, label='PyWake')
        plt.xlabel('Sector')
        plt.ylabel('AEP [MWh]')
        plt.legend()
        plt.show()
    npt.assert_array_less(np.abs(wasp_aep_no_density_correction - AEP_ilk.sum((0, 2)) * 1e6), 300)
    npt.assert_almost_equal(AEP_ilk.sum(), wasp_aep_no_density_correction_total, 3)
Example #21
0
                def setup_prob(differentiable):

                    #####################################
                    ## Setup Floris run with gradients ##
                    #####################################
                    topfarm.x_key = 'turbineX'
                    topfarm.y_key = 'turbineY'
                    turbineX = np.array(
                        [1164.7, 947.2, 1682.4, 1464.9, 1982.6, 2200.1])
                    turbineY = np.array(
                        [1024.7, 1335.3, 1387.2, 1697.8, 2060.3, 1749.7])
                    f = np.array([
                        3.597152, 3.948682, 5.167395, 7.000154, 8.364547,
                        6.43485, 8.643194, 11.77051, 15.15757, 14.73792,
                        10.01205, 5.165975
                    ])
                    wind_speed = 8
                    site = Amalia1Site(f, mean_wsp=wind_speed)
                    site.initial_position = np.array([turbineX, turbineY]).T
                    wt = NREL5MWREF()
                    wake_model = NOJ(site, wt)
                    aep_calculator = AEPCalculator(wake_model)
                    n_wt = len(turbineX)
                    differentiable = differentiable
                    wake_model_options = {
                        'nSamples': 0,
                        'nRotorPoints': 1,
                        'use_ct_curve': True,
                        'ct_curve': ct_curve,
                        'interp_type': 1,
                        'differentiable': differentiable,
                        'use_rotor_components': False
                    }

                    aep_comp = AEPGroup(
                        n_wt,
                        differentiable=differentiable,
                        use_rotor_components=False,
                        wake_model=floris_wrapper,
                        params_IdepVar_func=add_floris_params_IndepVarComps,
                        wake_model_options=wake_model_options,
                        datasize=len(power_curve),
                        nDirections=len(f),
                        cp_points=len(power_curve))  # , cp_curve_spline=None)

                    def cost_func(AEP, **kwargs):
                        return AEP

                    cost_comp = CostModelComponent(input_keys=[('AEP', [0])],
                                                   n_wt=n_wt,
                                                   cost_function=cost_func,
                                                   output_key="aep",
                                                   output_unit="kWh",
                                                   objective=True,
                                                   income_model=True,
                                                   input_units=['kW*h'])
                    group = TopFarmGroup([aep_comp, cost_comp])
                    boundary = np.array([(900, 1000), (2300, 1000),
                                         (2300, 2100),
                                         (900, 2100)])  # turbine boundaries
                    prob = TopFarmProblem(
                        design_vars={
                            'turbineX': (turbineX, 'm'),
                            'turbineY': (turbineY, 'm')
                        },
                        cost_comp=group,
                        driver=EasyRandomSearchDriver(
                            randomize_func=RandomizeTurbinePosition_Square(),
                            max_iter=500),
                        #                        driver=EasyScipyOptimizeDriver(optimizer='SLSQP',tol=10**-12),
                        #                        driver=EasyScipyOptimizeDriver(optimizer='COBYLA'),
                        constraints=[
                            SpacingConstraint(200, units='m'),
                            XYBoundaryConstraint(boundary, units='m')
                        ],
                        plot_comp=plot_comp,
                        expected_cost=-100e2,
                    )
                    turbineZ = np.array([90.0, 100.0, 90.0, 80.0, 70.0, 90.0])
                    air_density = 1.1716  # kg/m^3
                    rotorDiameter = np.zeros(n_wt)
                    hubHeight = np.zeros(n_wt)
                    axialInduction = np.zeros(n_wt)
                    generatorEfficiency = np.zeros(n_wt)
                    yaw = np.zeros(n_wt)
                    for turbI in range(0, n_wt):
                        rotorDiameter[turbI] = wt.diameter()  # m
                        hubHeight[turbI] = wt.hub_height()  # m
                        axialInduction[turbI] = 1.0 / 3.0
                        generatorEfficiency[turbI] = 1.0  # 0.944
                        yaw[turbI] = 0.  # deg.
                    prob['turbineX'] = turbineX
                    prob['turbineY'] = turbineY
                    prob['hubHeight'] = turbineZ
                    prob['yaw0'] = yaw
                    prob['rotorDiameter'] = rotorDiameter
                    prob['hubHeight'] = hubHeight
                    prob['axialInduction'] = axialInduction
                    prob['generatorEfficiency'] = generatorEfficiency
                    prob['windSpeeds'] = np.ones(len(f)) * wind_speed
                    prob['air_density'] = air_density

                    prob['windDirections'] = np.arange(0, 360, 360 / len(f))
                    prob['windFrequencies'] = f / 100
                    # turns off cosine spread (just needs to be very large)
                    prob['model_params:cos_spread'] = 1E12
                    prob['model_params:shearExp'] = 0.25
                    prob['model_params:z_ref'] = 80.
                    prob['model_params:z0'] = 0.
                    prob['rated_power'] = np.ones(n_wt) * 5000.
                    prob['cut_in_speed'] = np.ones(n_wt) * 3
                    prob['cp_curve_wind_speed'] = cp_curve[:, 0]
                    prob['cp_curve_cp'] = cp_curve[:, 1]
                    prob['rated_wind_speed'] = np.ones(n_wt) * 11.4
                    prob['cut_out_speed'] = np.ones(n_wt) * 25.0
                    # if 0:
                    # prob.check_partials(compact_print=True,includes='*direction_group0*')
                    # else:
                    return prob
Example #22
0
def main(obj=False, max_con_on=True):
    # ------ DEFINE WIND TURBINE TYPES, LOCATIONS & STORE METADATA -------
    windTurbines = WindTurbines(
        names=['Ghost_T1', 'T2'],
        diameters=[40, 84],
        hub_heights=[70, hornsrev1.HornsrevV80().hub_height()],
        ct_funcs=[dummy_thrust(ct_rated=0),
                  hornsrev1.HornsrevV80()._ct],
        power_funcs=[cube_power(power_rated=0),
                     cube_power(power_rated=3000)],
        # hornsrev1.HornsrevV80()._power],
        power_unit='kW')
    Drotor_vector = windTurbines._diameters
    power_rated_vec = np.array(
        [pcurv(25) / 1000 for pcurv in windTurbines.power_funcs])
    hub_height_vector = windTurbines._hub_heights

    x, y = np.meshgrid(range(-840, 840, 420), range(-840, 840, 420))
    n_wt = len(x.flatten())
    # initial turbine positions and other independent variables
    ext_vars = {'x': x.flatten(), 'y': y.flatten(), 'obj': obj * 1}

    capconst = []
    if max_con_on:
        capconst = [
            CapacityConstraint(max_capacity=30.01,
                               rated_power_array=power_rated_vec)
        ]

    # ---------------- DEFINE SITE & SELECT WAKE MODEL -------------------


#        site = UniformWeibullSite(p_wd=[50, 50], a=[9, 9], k=[2.3, 2.3], ti=.1, alpha=0, h_ref=100)
    site = UniformWeibullSite(p_wd=[100], a=[9], k=[2.3], ti=.1)
    site.default_ws = [9]  # reduce the number of calculations
    site.default_wd = [0]  # reduce the number of calculations

    wake_model = NOJ(site, windTurbines)

    AEPCalc = AEPCalculator(wake_model)

    # ------------- OUTPUTS AEP PER TURBINE & FARM IRR -------------------
    def aep_func(
            x, y, type, obj,
            **kwargs):  # TODO fix type as input change to topfarm turbinetype
        out = AEPCalc.calculate_AEP(x_i=x, y_i=y, type_i=type).sum((1, 2))
        if obj:  # if objective is AEP; output the total Farm_AEP
            out = np.sum(out)
        return out * 10**6

    def irr_func(aep, type, **kwargs):
        idx = type.astype(int)
        return economic_evaluation(Drotor_vector[idx], power_rated_vec[idx],
                                   hub_height_vector[idx],
                                   aep).calculate_irr()

    # ----- WRAP AEP AND IRR INTO TOPFARM COMPONENTS AND THEN GROUP  -----
    aep_comp = CostModelComponent(input_keys=[
        topfarm.x_key, topfarm.y_key, topfarm.type_key, ('obj', obj)
    ],
                                  n_wt=n_wt,
                                  cost_function=aep_func,
                                  output_key="aep",
                                  output_unit="GWh",
                                  objective=obj,
                                  output_val=np.zeros(n_wt),
                                  income_model=True)
    comps = [aep_comp]  # AEP component is always in the group
    if not obj:  # if objective is IRR initiate/add irr_comp
        irr_comp = CostModelComponent(input_keys=[topfarm.type_key, 'aep'],
                                      n_wt=n_wt,
                                      cost_function=irr_func,
                                      output_key="irr",
                                      output_unit="%",
                                      objective=True)
        comps.append(irr_comp)

    group = TopFarmGroup(comps)

    # - INITIATE THE PROBLEM WITH ONLY TURBINE TYPE AS DESIGN VARIABLES -
    tf = TopFarmProblem(
        design_vars={
            topfarm.type_key: ([0] * n_wt, 0, len(windTurbines._names) - 1)
        },
        cost_comp=group,
        driver=EasyRandomSearchDriver(randomize_func=RandomizeAllUniform(
            [topfarm.type_key]),
                                      max_iter=1),
        # driver=EasySimpleGADriver(max_gen=2, random_state=1),
        constraints=capconst,
        # plot_comp=TurbineTypePlotComponent(windTurbines._names),
        plot_comp=NoPlot(),
        ext_vars=ext_vars)

    cost, state, rec = tf.optimize()
    # view_model(problem, outfile='ex5_n2.html', show_browser=False)
    end = time.time()
    print(end - start)
    # %%
    # ------------------- OPTIONAL VISUALIZATION OF WAKES ----------------
    post_visual, save = False, False
    if post_visual:
        #        import matplotlib.pyplot as plt
        for cou, (i, j, k, co, ae) in enumerate(
                zip(rec['x'], rec['y'], rec['type'], rec['cost'], rec['aep'])):
            AEPCalc.calculate_AEP(x_i=i, y_i=j, type_i=k)
            AEPCalc.plot_wake_map(wt_x=i,
                                  wt_y=j,
                                  wt_type=k,
                                  wd=site.default_wd[0],
                                  ws=site.default_ws[0],
                                  levels=np.arange(2.5, 12, .1))
            windTurbines.plot(i, j, types=k)
            title = f'IRR: {-np.round(co,2)} %, AEP :  {round(np.sum(ae))} GWh, '
            if "totalcapacity" in rec.keys():
                title += f'Total Capacity: {rec["totalcapacity"][cou]} MW'
            plt.title(title)
            if save:
                plt.savefig(
                    r'..\..\..\ima2\obj_AEP_{}_MaxConstraint_{}_{}.png'.format(
                        obj, max_con_on, cou))
            plt.show()