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 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_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_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 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 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 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 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 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()
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()
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'))
'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: partials = problem.check_partials(out_stream=fid, compact_print=True, show_only_incorrect=True, step=step)