Beispiel #1
0
def test_local_wind(site):
    x_i = y_i = np.arange(5)
    wdir_lst = np.arange(0, 360, 90)
    wsp_lst = np.arange(3, 6)
    lw = site.local_wind(x_i=x_i, y_i=y_i, wd=wdir_lst, ws=wsp_lst)
    npt.assert_array_equal(lw.WS_ilk.shape, (5, 4, 3))

    lw = site.local_wind(x_i=x_i, y_i=y_i)
    npt.assert_array_equal(lw.WS_ilk.shape, (5, 360, 23))

    # check probability local_wind()[-1]
    npt.assert_equal(site.local_wind(x_i=x_i, y_i=y_i, wd=[0], ws=[10], wd_bin_size=1).P_ilk,
                     site.local_wind(x_i=x_i, y_i=y_i, wd=[0], ws=[10], wd_bin_size=2).P_ilk / 2)
    npt.assert_almost_equal(site.local_wind(x_i=x_i, y_i=y_i, wd=[0], ws=[9, 10, 11]).P_ilk.sum((1, 2)),
                            site.local_wind(x_i=x_i, y_i=y_i, wd=[0], ws=[10], ws_bins=3).P_ilk[:, 0, 0], 5)

    z = np.arange(1, 100)
    zero = [0] * len(z)

    ws = site.local_wind(x_i=zero, y_i=zero, h_i=z, wd=[0], ws=[10]).WS_ilk[:, 0, 0]
    site2 = UniformWeibullSite(f, A, k, ti, shear=PowerShear(70, alpha=np.zeros_like(f) + .3))
    ws70 = site2.local_wind(x_i=zero, y_i=zero, h_i=z, wd=[0], ws=[10]).WS_ilk[:, 0, 0]
    if 0:
        import matplotlib.pyplot as plt
        plt.plot(ws, z)
        plt.plot(ws70, z)
        plt.show()
    npt.assert_array_equal(10 * (z / 50)**.3, ws)
    npt.assert_array_equal(10 * (z / 70)**.3, ws70)
Beispiel #2
0
 def __init__(self):
     f = [3.597152, 3.948682, 5.167395, 7.000154, 8.364547, 6.43485,
          8.643194, 11.77051, 15.15757, 14.73792, 10.01205, 5.165975]
     a = [9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921,
          9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803]
     k = [2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703,
          2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172]
     UniformWeibullSite.__init__(self, f, a, k, .1)
     self.initial_position = np.array([wt_x, wt_y]).T
Beispiel #3
0
 def __init__(self):
     f = [
         5.55, 5.13, 5.32, 7.63, 9.39, 7.14, 8.93, 12.22, 14.44, 13.66,
         5.87, 4.72
     ]
     a = [9.42] * 12
     k = [2.41] * 12
     UniformWeibullSite.__init__(self, f, a, k, .1)
     self.initial_position = np.array([wt_x, wt_y]).T
Beispiel #4
0
 def __init__(self):
     f = [3.8, 4.5, 0.4, 2.8, 8.3, 7.5, 9.9, 14.8, 14.3, 17.0, 12.6, 4.1]
     a = [4.5, 4.7, 3.0, 7.2, 8.8, 8.2, 8.4, 9.5, 9.2, 9.9, 10.3, 6.7]
     k = [
         1.69, 1.78, 1.82, 1.70, 1.97, 2.49, 2.72, 2.70, 2.88, 3.34, 2.84,
         2.23
     ]
     UniformWeibullSite.__init__(self, f, a, k, .1)
     self.initial_position = np.array([wt_x, wt_y]).T
Beispiel #5
0
def test_plot_wd_distribution(site):
    import matplotlib.pyplot as plt
    site.plot_wd_distribution(n_wd=12, ax=plt)
    plt.figure()
    site.plot_wd_distribution(n_wd=12, ax=plt.gca())
    plt.figure()
    site.plot_wd_distribution(n_wd=360)
    UniformWeibullSite(f, A, k, ti, 'spline').plot_wd_distribution(n_wd=360)
    UniformWeibullSite(f, A, k, ti, 'linear').plot_wd_distribution(n_wd=360)

    if 0:
        plt.show()
Beispiel #6
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)
Beispiel #7
0
def test_plot_wd_distribution(site):
    import matplotlib.pyplot as plt
    p1 = site.plot_wd_distribution(n_wd=12, ax=plt)
    npt.assert_array_almost_equal(p1, f, 4)
    plt.figure()
    site.plot_wd_distribution(n_wd=12, ax=plt.gca())
    plt.figure()
    p2 = site.plot_wd_distribution(n_wd=360)
    npt.assert_array_almost_equal(np.array(p2)[::30] * 30, f, 4)
    UniformWeibullSite(f, A, k, ti, 'spline').plot_wd_distribution(n_wd=360)
    UniformWeibullSite(f, A, k, ti, 'linear').plot_wd_distribution(n_wd=360)

    if 0:
        plt.show()
Beispiel #8
0
def site():
    return UniformWeibullSite(f,
                              A,
                              k,
                              ti,
                              shear=PowerShear(50,
                                               alpha=np.zeros_like(f) + .3))
Beispiel #9
0
def test_site():
    with pytest.raises(
            NotImplementedError,
            match="interp_method=missing_method not implemeted yet."):
        site = UniformWeibullSite([1], [10], [2],
                                  .75,
                                  interp_method='missing_method')
Beispiel #10
0
def test_missing_interp_method():
    with pytest.raises(
            AssertionError,
            match=
            'interp_method "missing_method" not implemented. Must be "linear" or "nearest"'
    ):
        site = UniformWeibullSite([1], [10], [2],
                                  .75,
                                  interp_method='missing_method')
Beispiel #11
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)
Beispiel #12
0
def site():
    return UniformWeibullSite(f, A, k, ti, h_ref=50, alpha=.3)
def main(obj=False, max_con_on=True):
    if __name__ == '__main__':
        start = time.time()
        try:
            import matplotlib.pyplot as plt
            plt.gcf()
            plot = True
        except RuntimeError:
            plot = False

        # ------ 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.astype(int)).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()
Beispiel #14
0
def main():
    if __name__ == '__main__':
        try:
            import matplotlib.pyplot as plt
            plt.gcf()
            plot_comp = XYPlotComp
            plot = True
        except RuntimeError:
            plot_comp = NoPlot
            plot = False
        # ------------------------ INPUTS ------------------------

        # ------------------------ DEFINE WIND RESOURCE ------------------------
        # wind resource info (wdir frequency, weibull a and k)
        f = [
            3.597152, 3.948682, 5.167395, 7.000154, 8.364547, 6.43485,
            8.643194, 11.77051, 15.15757, 14.73792, 10.01205, 5.165975
        ]
        a = [
            9.176929, 9.782334, 9.531809, 9.909545, 10.04269, 9.593921,
            9.584007, 10.51499, 11.39895, 11.68746, 11.63732, 10.08803
        ]
        k = [
            2.392578, 2.447266, 2.412109, 2.591797, 2.755859, 2.595703,
            2.583984, 2.548828, 2.470703, 2.607422, 2.626953, 2.326172
        ]
        site = UniformWeibullSite(p_wd=f, a=a, k=k, ti=0.075)
        wt = V80()

        # ------------------------ setup problem ____---------------------------
        rot_diam = 80.0  # rotor diameter [m]
        init_pos = np.array([(0, 2 * rot_diam), (0, 0),
                             (0, -2 * rot_diam)])  # initial turbine positions
        b = 2 * rot_diam + 10  # boundary size
        boundary = [(-b, -b), (-b, b), (b, b),
                    (b, -b)]  # corners of wind farm boundary
        min_spacing = 2.0 * rot_diam  # minimum spacing between turbines [m]

        # ------------------------ OPTIMIZATION ------------------------

        def get_tf(windFarmModel):
            return TopFarmProblem(design_vars=dict(zip('xy', init_pos.T)),
                                  cost_comp=PyWakeAEPCostModelComponent(
                                      windFarmModel,
                                      n_wt=3,
                                      ws=10,
                                      wd=np.arange(0, 360, 12)),
                                  constraints=[
                                      SpacingConstraint(min_spacing),
                                      XYBoundaryConstraint(boundary)
                                  ],
                                  driver=EasyScipyOptimizeDriver(),
                                  plot_comp=plot_comp())

        # GCL: define the wake model and optimization problem
        tf_gcl = get_tf(GCL(site, wt))

        # NOJ: define the wake model and optimization problem
        tf_noj = get_tf(NOJ(site, wt))

        # run the optimization
        cost_gcl, state_gcl, recorder_gcl = tf_gcl.optimize()
        cost_noj, state_noj, recorder_noj = tf_noj.optimize()

        # ------------------------ POST-PROCESS ------------------------

        # get the optimized locations
        opt_gcl = tf_gcl.turbine_positions
        opt_noj = tf_noj.turbine_positions

        # create the array of costs for easier printing
        costs = np.diag([cost_gcl, cost_noj])
        costs[0, 1] = tf_noj.evaluate(state_gcl)[0]  # noj cost of gcl locs
        costs[1, 0] = tf_gcl.evaluate(state_noj)[0]  # gcl cost of noj locs

        # ------------------------ PRINT STATS ------------------------

        aep_diffs = 200 * (costs[:, 0] - costs[:, 1]) / (costs[:, 0] +
                                                         costs[:, 1])
        loc_diffs = 200 * (costs[0, :] - costs[1, :]) / (costs[0, :] +
                                                         costs[1, :])

        print('\nComparison of cost models vs. optimized locations:')
        print('\nCost    |    GCL_aep      NOJ_aep')
        print('---------------------------------')
        print(f'GCL_loc |{costs[0,0]:11.2f} {costs[0,1]:11.2f}' +
              f'   ({aep_diffs[0]:.2f}%)')
        print(f'NOJ_loc |{costs[1,0]:11.2f} {costs[1,1]:11.2f}' +
              f'   ({aep_diffs[1]:.2f}%)')
        print(f'             ({loc_diffs[0]:.2f}%)     ({loc_diffs[1]:.2f}%)')

        # ------------------------ PLOT (if possible) ------------------------
        if plot:

            # initialize the figure and axes
            fig = plt.figure(1, figsize=(7, 5))
            plt.clf()
            ax = plt.axes()

            # plot the boundary and desired locations
            ax.add_patch(Polygon(boundary, fill=False,
                                 label='Boundary'))  # boundary
            ax.plot(init_pos[:, 0], init_pos[:, 1], 'xk', label='Initial')
            ax.plot(opt_gcl[:, 0], opt_gcl[:, 1], 'o', label='GCL')
            ax.plot(opt_noj[:, 0], opt_noj[:, 1], '^', label='NOJ')

            # make a few adjustments to the plot
            ax.autoscale_view()  # autoscale the boundary
            plt.legend(bbox_to_anchor=(0., 1.02, 1., .102),
                       loc=3,
                       ncol=4,
                       mode='expand',
                       borderaxespad=0.)  # add a legend
            plt.tight_layout()  # zoom the plot in
            plt.axis('off')  # remove the axis

            # save the png
            folder, file = os.path.split(__file__)
            fig.savefig(folder + "/figures/" + file.replace('.py', '.png'))