def test_design_var_list(turbineTypeOptimizationProblem, design_vars): tf = TopFarmProblem(design_vars=design_vars, cost_comp=DummyCost(np.array([[2, 0, 1]]).T, ['type']), driver=DOEDriver(FullFactorialGenerator(3))) cost, _, = tf.evaluate() npt.assert_equal(tf.cost, cost) assert tf.cost == 5
def test_3level_type_multistart_XYZ_optimization(): design_vars = {k: v for k, v in zip('xy', optimal.T)} design_vars['z'] = (optimal[:, 2], 0, 4) xyz_problem = TopFarmProblem(design_vars, cost_comp=DummyCost(optimal, ['x', 'y', 'z', 'type']), constraints=[ SpacingConstraint(2), XYBoundaryConstraint([(0, 0), (4, 4)], 'square') ], driver=EasyScipyOptimizeDriver(disp=False)) initial_xyz_problem = TopFarmProblem( design_vars={k: v for k, v in zip('xyz', optimal.T)}, cost_comp=xyz_problem, driver=DOEDriver( ListGenerator([[('x', [0, 4]), ('y', [2, 2]), ('z', [4, 1])]]))) tf = TopFarmProblem({'type': ([0, 0], 0, 1)}, cost_comp=initial_xyz_problem, driver=DOEDriver(FullFactorialGenerator(2))) cost, _, recorder = tf.optimize() best_index = np.argmin(recorder.get('cost')) initial_xyz_recorder = recorder['recorder'][best_index] xyz_recorder = initial_xyz_recorder.get('recorder')[0] npt.assert_almost_equal(xyz_recorder['cost'][-1], cost)
def test_setup_as_constraint_z(): tf = TopFarmProblem( {'z': (initial[:, 2], 0, 2)}, DummyCost(desired[:, :2], 'z'), driver=EasyScipyOptimizeDriver(disp=False), ) tf.optimize() npt.assert_array_less(tf['z'], 2 + 1e-10)
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 n_wt = 16 site = IEA37Site(n_wt) windTurbines = IEA37_WindTurbines() wake_model = IEA37SimpleBastankhahGaussian(site, windTurbines) Drotor_vector = [windTurbines.diameter()] * n_wt power_rated_vector = [float(windTurbines.power(20) / 1000)] * n_wt hub_height_vector = [windTurbines.hub_height()] * n_wt AEPCalc = AEPCalculator(wake_model) def aep_func(x, y, **kwargs): return AEPCalc.calculate_AEP(x_i=x, y_i=y).sum(-1).sum(-1) * 10**6 def irr_func(aep, **kwargs): my_irr = economic_evaluation(Drotor_vector, power_rated_vector, hub_height_vector, aep).calculate_irr() print(my_irr) return my_irr aep_comp = CostModelComponent(input_keys=['x', 'y'], n_wt=n_wt, cost_function=aep_func, output_key="aep", output_unit="GWh", objective=False, output_val=np.zeros(n_wt)) irr_comp = CostModelComponent(input_keys=['aep'], n_wt=n_wt, cost_function=irr_func, output_key="irr", output_unit="%", objective=True, income_model=True) group = TopFarmGroup([aep_comp, irr_comp]) problem = TopFarmProblem( design_vars=dict(zip('xy', site.initial_position.T)), cost_comp=group, driver=EasyRandomSearchDriver( randomize_func=RandomizeTurbinePosition_Circle(), max_iter=50), constraints=[ SpacingConstraint(200), CircleBoundaryConstraint([0, 0], 1300.1) ], plot_comp=plot_comp) cost, state, recorder = problem.optimize()
def test_setup_as_constraint_xyz(): desvar = dict(zip('xy', initial.T)) desvar['z'] = (initial[:, 2], 0, 2) tf = TopFarmProblem(desvar, DummyCost(desired, 'xyz'), driver=EasyScipyOptimizeDriver(disp=False), constraints=[XYBoundaryConstraint(boundary)]) tf.optimize() tb_pos = tf.turbine_positions tol = 1e-4 assert tb_pos[1][0] < 6 + tol # check within border npt.assert_array_less(tf['z'], 2 + tol) # check within height limit
def test_setup_as_penalty_none(): driver = SimpleGADriver() tf = TopFarmProblem(dict(zip('xy', initial.T)), DummyCost(desired), driver=driver) # check that it does not fail if xy and z is not specified assert tf.evaluate()[0] == 121 assert tf.evaluate({ 'x': [2.5, 7, 4.5], 'y': [-3., -7., -3.], 'z': [0., 0., 0.] })[0] == .5
def test_setup_as_penalty_xy(): driver = SimpleGADriver() tf = TopFarmProblem(dict(zip('xy', initial.T)), DummyCost(desired), constraints=[XYBoundaryConstraint(boundary)], driver=driver) # check normal result if boundary constraint is satisfied assert tf.evaluate()[0] == 121 # check penalized result if boundary constraint is not satisfied assert tf.evaluate({ 'x': [2.5, 7, 4.5], 'y': [-3., -7., -3.], 'z': [0., 0., 0.] })[0] == 1e10 + 1
def main(): if __name__ == '__main__': plot_comp = XYPlotComp() site = get_site() n_wt = len(site.initial_position) windTurbines = DTU10MW() min_spacing = 2 * windTurbines.diameter(0) windFarmModel = IEA37SimpleBastankhahGaussian(site, windTurbines) Drotor_vector = [windTurbines.diameter()] * n_wt power_rated_vector = [float(windTurbines.power(20) / 1000)] * n_wt hub_height_vector = [windTurbines.hub_height()] * n_wt def aep_func(x, y, **_): sim_res = windFarmModel(x, y) aep = sim_res.aep() return aep.sum(['wd', 'ws']).values * 10**6 def irr_func(aep, **_): return economic_evaluation(Drotor_vector, power_rated_vector, hub_height_vector, aep).calculate_irr() aep_comp = CostModelComponent(input_keys=['x', 'y'], n_wt=n_wt, cost_function=aep_func, output_key="aep", output_unit="GWh", objective=False, output_val=np.zeros(n_wt)) irr_comp = CostModelComponent(input_keys=['aep'], n_wt=n_wt, cost_function=irr_func, output_key="irr", output_unit="%", objective=True, income_model=True) group = TopFarmGroup([aep_comp, irr_comp]) problem = TopFarmProblem( design_vars=dict(zip('xy', site.initial_position.T)), cost_comp=group, driver=EasyRandomSearchDriver( randomize_func=RandomizeTurbinePosition_Circle(), max_iter=10), constraints=[ SpacingConstraint(min_spacing), XYBoundaryConstraint(site.boundary), ], plot_comp=plot_comp) cost, state, recorder = problem.optimize() problem.plot_comp.show()
def test_2level_turbineType_and_XYZ_optimization(): design_vars = {k: v for k, v in zip('xy', optimal.T)} design_vars['z'] = (optimal[:, 2], 0, 4) xyz_problem = TopFarmProblem(design_vars, cost_comp=DummyCost(optimal, ['x', 'y', 'z', 'type']), constraints=[ SpacingConstraint(2), XYBoundaryConstraint([(0, 0), (4, 4)], 'square') ], driver=EasyScipyOptimizeDriver(disp=False)) tf = TopFarmProblem({'type': ([0, 0], 0, 1)}, cost_comp=xyz_problem, driver=DOEDriver(FullFactorialGenerator(2))) cost = tf.optimize()[0] assert cost == 0
def get_tf(cost_comp): return TopFarmProblem(dict(zip('xy', initial.T)), cost_comp=cost_comp, constraints=[ SpacingConstraint(min_spacing), XYBoundaryConstraint(boundary) ], driver=EasyScipyOptimizeDriver(disp=False))
def _topfarm_obj(gradients, cost_comp=None, **kwargs): return TopFarmProblem( {'x': initial[:, 0], 'y': initial[:, 1]}, cost_comp=cost_comp or CostModelComponent(['x', 'y'], 4, cost, gradients), constraints=[SpacingConstraint(2), XYBoundaryConstraint(boundary)], driver=EasyScipyOptimizeDriver(), **kwargs)
def test_setup_as_constraint_xy(): # plot_comp = DummyCostPlotComp(desired) plot_comp = NoPlot() tf = TopFarmProblem({ 'x': initial[:, 0], 'y': initial[:, 1] }, DummyCost(desired[:, :2]), constraints=[XYBoundaryConstraint(boundary)], driver=EasyScipyOptimizeDriver(disp=False), plot_comp=plot_comp) tf.optimize() tb_pos = tf.turbine_positions[:, :2] tf.plot_comp.show() tol = 1e-4 assert tb_pos[1][0] < 6 + tol # check within border
def get_InitialXYZOptimizationProblem(driver): return TopFarmProblem( { 'x': [0, 2], 'y': [0, 2], 'z': ([0, 2], 3, 4) }, cost_comp=DummyCost([(1, 0, 4), (0, 1, 3)], 'xyz'), constraints=[XYBoundaryConstraint([(10, 6), (11, 8)], 'rectangle')], driver=driver)
def test_smart_start_aep_map_PyWakeAEP(): site = IEA37Site(16) n_wt = 4 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(wake_model=NOJ(site, 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, seed=1) 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)
def test_AEPMaxLoadCostModelComponent_constraint(): tf = TopFarmProblem( design_vars={ 'x': ([1]), 'y': (.1, 0, 2.5) }, # design_vars={'x': ([2.9], [1], [3])}, cost_comp=AEPMaxLoadCostModelComponent(input_keys='xy', n_wt=1, aep_load_function=lambda x, y: (np.hypot(x, y), x), max_loads=3), constraints=[CircleBoundaryConstraint((0, 0), 7)], ) tf.evaluate() cost, state, recorder = tf.optimize() npt.assert_allclose(state['x'], 3) # constrained by max_loads npt.assert_allclose(state['y'], 2.5) # constrained by design var lim
def testCostModelComponentDiffShapeInput(): def aep_cost(x, y, h): opt_x, opt_y = optimal.T return -np.sum((x - opt_x)**2 + (y - opt_y)**2) + h, { 'add_out': sum(x) } cost_comp = AEPCostModelComponent(['x', 'y', ('h', 0)], 4, aep_cost, additional_output=[('add_out', 0)]) tf = TopFarmProblem(dict(zip('xy', initial.T)), cost_comp=cost_comp, constraints=[ SpacingConstraint(min_spacing), XYBoundaryConstraint(boundary) ], driver=EasyScipyOptimizeDriver(disp=False), ext_vars={'h': 0}) cost0, _, _ = tf.optimize(state={'h': 0}) cost10, _, _ = tf.optimize(state={'h': 10}) npt.assert_almost_equal(cost10, cost0 - 10)
def test_smart_start_aep_map(seed, radius, resolution, tol): site = IEA37Site(16) n_wt = 4 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 wfm = NOJ(site, turbines) aep_comp = PyWakeAEPCostModelComponent(wfm, n_wt=n_wt) aep_1wt = wfm([0], [0]).aep().sum() tf = TopFarmProblem(design_vars={ 'x': x, 'y': y }, cost_comp=aep_comp, driver=EasyScipyOptimizeDriver(), constraints=[ SpacingConstraint(160), CircleBoundaryConstraint((0, 0), radius) ]) x = np.arange(-radius, radius, resolution) y = np.arange(-radius, radius, resolution) XX, YY = np.meshgrid(x, y) tf.smart_start(XX, YY, aep_comp.get_aep4smart_start(wd=wd_lst, ws=ws_lst), radius=40, plot=0, seed=seed) tf.evaluate() if 0: wt_x, wt_y = tf['x'], tf['y'] for i, _ in enumerate(wt_x, 1): print(wfm(wt_x[:i], wt_y[:i]).aep().sum(['wd', 'ws'])) aep_comp.windFarmModel(wt_x, wt_y, ws=ws_lst, wd=wd_lst).flow_map().aep_xy().plot() print(tf.evaluate()) import matplotlib.pyplot as plt 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'], tol)
def turbineTypeOptimizationProblem(): return TopFarmProblem( design_vars={'type': ([0, 0, 0], 0, 2)}, cost_comp=DummyCost(np.array([[2, 0, 1]]).T, ['type']), driver=DOEDriver(FullFactorialGenerator(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()
cost_comp = CostModelComponent(input_keys=[('x', x_init), ('y', y_init)], n_wt=n_wt, cost_function=aep_func, objective=True, maximize=True, output_keys=[('AEP', 0), ('water_depth', np.zeros(n_wt))]) problem = TopFarmProblem( design_vars={ 'x': x_init, 'y': y_init }, constraints=[ XYBoundaryConstraint(boundary), SpacingConstraint(min_spacing) ], post_constraints=[('water_depth', { 'lower': np.ones(n_wt) * maximum_water_depth })], cost_comp=cost_comp, driver=EasyScipyOptimizeDriver(optimizer='SLSQP', maxiter=maxiter, tol=tol), # driver=EasyRandomSearchDriver(RandomizeTurbinePosition()), plot_comp=XYPlotComp(), expected_cost=ec) if 1: tic = time.time() cost, state, recorder = problem.optimize() toc = time.time() print('Optimization took: {:.0f}s'.format(toc - tic))
aep_load_function=aep_load_func, aep_load_gradient=aep_load_gradient, max_loads=max_loads, objective=True, output_keys=[('AEP', 0), ('loads', np.zeros( (s, i)))]) yaw_init = np.zeros((i, l, k)) yaw_30 = np.full_like(yaw_init, 30) yaw_init_rand = np.random.rand(i, l, k) * 80 - 40 tol = 1e-8 ec = 1e-4 problem = TopFarmProblem(design_vars={'yaw_ilk': (yaw_init, yaw_min, yaw_max)}, cost_comp=cost_comp, driver=EasyScipyOptimizeDriver(optimizer='SLSQP', maxiter=maxiter, tol=tol), plot_comp=NoPlot(), expected_cost=ec) tic = time.time() if 1: cost, state, recorder = problem.optimize() toc = time.time() print('Optimization took: {:.0f}s'.format(toc - tic)) if 0: with open(f'./check_partials_{int(toc)}.txt', 'w') as fid: partials = problem.check_partials(out_stream=fid, compact_print=True, show_only_incorrect=False, step=step)
# aep_load_gradient = aep_load_gradient, max_loads=max_loads, objective=True, step={ 'x': step, 'y': step }, output_keys=[('AEP', 0), ('loads', np.zeros((s, i)))]) problem = TopFarmProblem( design_vars={ 'x': x_init, 'y': y_init }, constraints=[ XYBoundaryConstraint(boundary), SpacingConstraint(min_spacing) ], # post_constraints=[(ls, val * load_fact) for ls, val in loads_nom.items()], cost_comp=cost_comp, driver=EasyScipyOptimizeDriver(optimizer='SLSQP', maxiter=maxiter, tol=tol), plot_comp=NoPlot(), expected_cost=ec) tic = time.time() if 1: cost, state, recorder = problem.optimize() toc = time.time() print('Optimization took: {:.0f}s'.format(toc - tic)) if 0: with open(f'./check_partials_{int(toc)}_{ec}_{step}.txt', 'w') as fid:
def main(): if __name__ == '__main__': # ------------------------ INPUTS ------------------------ # define the conditions for the wind farm boundary = [(0, 0), (6, 0), (6, -10), (0, -10)] # turbine boundaries initial = np.array([[6, 0], [6, -8], [1, 1], [-1, -8]]) # initial turbine pos desired = np.array([[3, -3], [7, -7], [4, -3], [3, -7]]) # desired turbine pos optimal = np.array([[2.5, -3], [6, -7], [4.5, -3], [3, -7]]) # optimal layout min_spacing = 2 # min distance between turbines try: import matplotlib.pyplot as plt plt.gcf() plot_comp = DummyCostPlotComp(desired) plot = True except RuntimeError: plot_comp = NoPlot() plot = False # ------------------------ OPTIMIZATION ------------------------ # create the wind farm and run the optimization tf = TopFarmProblem(design_vars={ 'x': initial[:, 0], 'y': initial[:, 1] }, cost_comp=DummyCost(desired, ['x', 'y']), constraints=[ XYBoundaryConstraint(boundary), SpacingConstraint(min_spacing) ], plot_comp=plot_comp, driver=EasyScipyOptimizeDriver()) cost, state, recorder = tf.optimize() tf.plot_comp.show() # final position final_x, final_y = state['x'], state['y'] # get the positions tried during optimization from the recorder rec_x, rec_y = recorder['x'], recorder['y'] # get the final, optimal positions optimized = tf.turbine_positions # ------------------------ 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, closed=True, fill=False, label='Boundary')) # boundary plt.plot(desired[:, 0], desired[:, 1], 'ok', mfc='None', ms=10, label='Desired') # desired positions # plot the history of each turbine for i_turb in range(rec_x.shape[1]): l, = plt.plot(rec_x[0, i_turb], rec_y[0, i_turb], 'x', ms=8, label=f'Turbine {i_turb+1}') # initial plt.plot(rec_x[:, i_turb], rec_y[:, i_turb], c=l.get_color()) # tested values plt.plot(rec_x[-1, i_turb], rec_y[-1, i_turb], 'o', ms=8, c=l.get_color()) # final # 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'))
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
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 n_wt = 16 site = IEA37Site(n_wt) windTurbines = IEA37_WindTurbines() windFarmModel = IEA37SimpleBastankhahGaussian(site, windTurbines) Drotor_vector = [windTurbines.diameter()] * n_wt power_rated_vector = [float(windTurbines.power(20)) * 1e-6] * n_wt hub_height_vector = [windTurbines.hub_height()] * n_wt distance_from_shore = 10 # [km] energy_price = 0.1 # [Euro/kWh] What we get per kWh project_duration = 20 # [years] rated_rpm_array = [12] * n_wt # [rpm] water_depth_array = [15] * n_wt # [m] eco_eval = economic_evaluation(distance_from_shore, energy_price, project_duration) def irr_func(aep, **kwargs): eco_eval.calculate_irr( rated_rpm_array, Drotor_vector, power_rated_vector, hub_height_vector, water_depth_array, aep) print(eco_eval.IRR) return eco_eval.IRR aep_comp = CostModelComponent( input_keys=['x', 'y'], n_wt=n_wt, cost_function=lambda x, y, **_: windFarmModel(x=x, y=y).aep().sum(['wd', 'ws']) * 10**6, output_key="aep", output_unit="kWh", objective=False, output_val=np.zeros(n_wt)) irr_comp = CostModelComponent( input_keys=['aep'], n_wt=n_wt, cost_function=irr_func, output_key="irr", output_unit="%", objective=True, income_model=True) group = TopFarmGroup([aep_comp, irr_comp]) problem = TopFarmProblem( design_vars=dict(zip('xy', site.initial_position.T)), cost_comp=group, driver=EasyRandomSearchDriver(randomize_func=RandomizeTurbinePosition_Circle(), max_iter=5), constraints=[SpacingConstraint(200), CircleBoundaryConstraint([0, 0], 1300.1)], plot_comp=plot_comp) cost, state, recorder = problem.optimize()