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 __init__(self, n_wt, length_key='elnet_length', **kwargs): self.n_wt = n_wt self.length_key = length_key CostModelComponent.__init__(self, [(self.length_key, 0.0)], self.n_wt, self.cost, self.grad, objective=False, input_units=['m'], **kwargs)
def testTopFarmProblem_check_gradients_Income(turbineXYZOptimizationProblem_generator): # Check that gradients check does not raise exception for correct gradients cost_comp = CostModelComponent('xy', 4, income, income_gradients, income_model=True) tf = turbineXYZOptimizationProblem_generator(None, cost_comp) tf.check_gradients(True) # Check that gradients check raises an exception for incorrect gradients cost_comp = CostModelComponent('xy', 4, income, wrong_gradients, income_model=True) tf = turbineXYZOptimizationProblem_generator(None, cost_comp) with pytest.raises(Warning, match="Mismatch between finite difference derivative of 'cost' wrt. 'y' and derivative computed in 'cost_comp' is"): tf.check_gradients()
def main(): if __name__ == '__main__': # 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 # ------------------------ OPTIMIZATION ------------------------ # create the wind farm and run the optimization def wt_cost(i, x, y): time.sleep(0.01) return (desired[i, 0] - x[i])**2 + (desired[i, 1] - y[i])**2 n_wt = len(initial) comps = [CostModelComponent('xy', 4, cost_function=lambda x, y, i=i:wt_cost(i, x, y), objective=False, output_key='cost%d' % i) for i in range(n_wt)] def sum_map(**kwargs): return np.sum([kwargs['cost%d' % i] for i in range(n_wt)]) comps.append(CostModelComponent(['cost%d' % i for i in range(n_wt)], 1, cost_function=sum_map, objective=True)) cost_comp = TopFarmParallelGroup(comps) tf = TopFarmProblem( design_vars={'x': initial[:, 0], 'y': initial[:, 1]}, cost_comp=cost_comp, constraints=[XYBoundaryConstraint(boundary), SpacingConstraint(min_spacing)], # plot_comp=DummyCostPlotComp(desired), plot_comp=NoPlot(), driver=EasyScipyOptimizeDriver() ) # view_model(tf) #print(tf.evaluate({'x': desired[:, 0], 'y': desired[:, 1]})) print(tf.evaluate({'x': optimal[:, 0], 'y': optimal[:, 1]}, disp=False)) #print(tf.evaluate({'x': initial[:, 0], 'y': initial[:, 1]})) # tic = time.time() cost, state, recorder = tf.optimize() # toc = time.time() # print('optimized in {:.3f}s '.format(toc-tic)) tf.plot_comp.show()
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 _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_random_search_driver_randomize_all_uniform(): np.random.seed(1) class Cost(): i = 0 def __call__(self, *args, **kwargs): self.i += 1 return self.i cost_comp = CostModelComponent(input_keys=['x', 'y', 'type'], n_wt=2, cost_function=Cost(), income_model=True) tf = TopFarmProblem( { 'x': ([1, 6], [0, 1], [5, 6]), 'y': ([-1., 0], -6, 0), 'type': ([3, 3], 3, 8) }, cost_comp=cost_comp, constraints=[], driver=EasyRandomSearchDriver(randomize_func=RandomizeAllUniform( ['x', 'type']), max_iter=600, disp=False), ) _, state, recorder = tf.optimize() # check that integer design variables are somewhat evenly distributed x, y, t = recorder['x'], recorder['y'], recorder['type'] for arr, l, u in [(x[:, 0], 0, 5), (x[:, 1], 1, 6), (t[:, 0], 3, 8)]: count = [(arr == i).sum() for i in range(l, u + 1)] npt.assert_equal(601, sum(count)) npt.assert_array_less(600 / len(count) * .70, count) count, _ = np.histogram(y[:, 0], np.arange(-6, 1)) npt.assert_equal(y.shape[0], sum(count)) npt.assert_array_less(600 / len(count) * .70, count)
def _topfarm_obj(gradients, **kwargs): return TopFarm(initial, CostModelComponent(['x', 'y'], 4, cost, gradients), min_spacing=2, boundary=boundary, record_id=None, **kwargs)
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 testCostModelComponent_no_gradients(): tf = get_tf(CostModelComponent(['x', 'y'], 4, cost, None)) tf.optimize() np.testing.assert_array_almost_equal(tf.turbine_positions[:, :2], optimal_with_constraints, 5)
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 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 aep_func(x, y, **kwargs): simres = wfm(x, y, wd=wdir, ws=wsp) aep = simres.aep().values.sum() water_depth = np.diag(wfm.site.ds.interp(x=x, y=y)['water_depth']) return [aep, water_depth] tol = 1e-8 ec = 1e-2 min_spacing = 260 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 })],