def test_optimize(tf): # plot_comp = DummyCostPlotComp(optimal) plot_comp = NoPlot() tf = tf(plot_comp=plot_comp) cost = tf.optimize()[0] plot_comp.show() assert cost < 1e6 np.testing.assert_array_almost_equal(tf.turbine_positions, optimal[:, :2], 3)
def testPolygonTwoRegionsStartInWrong(): optimal = [(1, 1), (4, 1)] boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 0), (2, 0), (2, 2), (0, 2), (0, 0)] plot_comp = NoPlot() # DummyCostPlotComp(optimal, delay=.1) initial = [(3.5, 1.5), (0.5, 1.5)] tf = get_tf(initial, optimal, boundary, plot_comp) tf.optimize() plot_comp.show() np.testing.assert_array_almost_equal(tf.turbine_positions[:, :2], optimal, 4)
def testPolygonConcave(): optimal = [(1.5, 1.3), (4, 1)] boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 1), (2, 1), (2, 2), (0, 2), (0, 0)] plot_comp = NoPlot() # DummyCostPlotComp(optimal) initial = [(-0, .1), (4, 1.5)][::-1] tf = get_tf(initial, optimal, boundary, plot_comp) tf.optimize() np.testing.assert_array_almost_equal(tf.turbine_positions[:, :2], optimal, 4) plot_comp.show()
def testAEP_topfarm_optimization_2tb_scale(get_fuga, scale): D = 80.0 B = 2 * D + 10 init_pos = np.array([(-10, 1 * D), (10, -D)]) wind_atlas = 'MyFarm/north_pm30_only.lib' pyFuga = get_fuga(init_pos[:1, 0], init_pos[:1, 1], wind_atlas=wind_atlas) AEP_pr_tb = pyFuga.get_aep()[1] pyFuga = get_fuga(init_pos[:, 0], init_pos[:, 1], wind_atlas=wind_atlas) boundary = [(-B, B), (B, B), (B, -B), (-B, -B), (-B, B)] plot_comp = NoPlot() # plot_comp = PlotComp() cost_comp = AEPCostModelComponent( 'xy', init_pos.shape[0], lambda x, y: scale * pyFuga.get_aep(np.array([x, y]).T)[0], # only aep lambda x, y: scale * pyFuga.get_aep_gradients(np.array([x, y]).T)[:2] ) # only dAEPdx and dAEPdy tf = TopFarmProblem( dict(zip('xy', init_pos.T)), cost_comp, constraints=[SpacingConstraint(2 * D), XYBoundaryConstraint(boundary)], plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(tol=1e-8, disp=False), expected_cost=AEP_pr_tb * 2 * scale) cost, _, rec = tf.optimize() tf.plot_comp.show() uta.assertAlmostEqual(-cost / scale, AEP_pr_tb * 2, delta=.02)
def test_TopFarmListRecorder_continue(tf_generator, load_case, n_rec, n_fev): D = 80.0 D2 = 2 * D + 10 init_pos = np.array([(0, 2 * D), (0, 0), (0, -2 * D)]) init_pos[:, 0] += [-40, 0, 40] pyFuga = test_pyfuga.get_fuga()(init_pos[:, 0], init_pos[:, 1], wind_atlas='MyFarm/north_pm45_only.lib') boundary = [(-D2, -D2), (D2, D2)] plot_comp = XYPlotComp() plot_comp = NoPlot() tf = TopFarmProblem( dict(zip('xy', init_pos.T)), cost_comp=pyFuga.get_TopFarm_cost_component(), constraints=[ SpacingConstraint(2 * D), XYBoundaryConstraint(boundary, 'square') ], driver=EasyScipyOptimizeDriver(tol=1e-10, disp=False), plot_comp=plot_comp, record_id=tfp + 'recordings/test_TopFarmListRecorder_continue:%s' % load_case, expected_cost=25) _, _, recorder = tf.optimize() # Create test file: # 1) delete file "test_files/recordings/test_TopFarmListRecorder_continue" # 2) Uncomment line below, run and recomment # if load_case=="": recorder.save() # create test file npt.assert_equal(recorder.driver_cases.num_cases, n_rec) npt.assert_equal(tf.driver.result['nfev'], n_fev) tf.plot_comp.show()
def test_turbine_Type_multistart_XYZ_optimization(): plot_comp = DummyCostPlotComp(optimal, delay=.5) plot_comp = NoPlot() xyz = [(0, 0, 0), (1, 1, 1)] p1 = DummyCost(optimal_state=optimal, inputs=['x', 'y', 'z', 'type']) p2 = TurbineXYZOptimizationProblem( cost_comp=p1, turbineXYZ=xyz, min_spacing=2, boundary_comp=get_boundary_comp(), plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(disp=True, optimizer='COBYLA', maxiter=10)) p3 = InitialXYZOptimizationProblem( cost_comp=p2, turbineXYZ=xyz, min_spacing=2, boundary_comp=get_boundary_comp(), driver=DOEDriver(ListGenerator([[('x', [0, 4]), ('y', [2, 2]), ('z', [4, 1])]]))) tf = TurbineTypeOptimizationProblem( cost_comp=p3, turbineTypes=[0, 0], lower=0, upper=1, driver=DOEDriver(FullFactorialGenerator(1))) case_gen = tf.driver.options['generator'] cost, state, recorder = tf.optimize() print(cost) # print (state) print(recorder.get('type')) print(recorder.get('cost')) 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 _topfarm_obj(driver, xy_scale=[1, 1], cost_scale=1, cost_offset=0, spacing=2): from topfarm.cost_models.dummy import DummyCostPlotComp # plot_comp = DummyCostPlotComp(desired[:,:2] * xy_scale, plot_improvements_only=True) plot_comp = NoPlot() class DummyCostScaled(DummyCost): def cost(self, **kwargs): opt = self.optimal_state return np.sum([(kwargs[n] - opt[:, i])**2 for i, n in enumerate(self.input_keys) ]) * cost_scale + cost_offset def grad(self, **kwargs): opt = self.optimal_state return [(2 * cost_scale * (kwargs[n] - opt[:, i])) for i, n in enumerate(self.input_keys)] return TopFarmProblem(dict(zip('xy', (initial[:, :2] * xy_scale).T)), DummyCostScaled(desired[:, :2] * xy_scale), constraints=[ SpacingConstraint(spacing * xy_scale[0]), XYBoundaryConstraint(boundary * xy_scale) ], driver=driver, plot_comp=plot_comp, expected_cost=1.5 * cost_scale)
def get_tf(**kwargs): k = {'cost_comp': DummyCost(desired[:, :2], [topfarm.x_key, topfarm.y_key]), 'design_vars': {topfarm.x_key: initial[:, 0], topfarm.y_key: initial[:, 1]}, 'driver': EasyScipyOptimizeDriver(disp=False), 'plot_comp': NoPlot(), 'constraints': [SpacingConstraint(2), XYBoundaryConstraint(boundary)]} k.update(kwargs) return TopFarmProblem(**k)
def testPolygonTwoRegionsStartInWrong(): optimal = [(1, 1), (4, 1)] boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 0), (2, 0), (2, 2), (0, 2), (0, 0)] plot_comp = NoPlot() # plot_comp = DummyCostPlotComp(optimal, delay=.1) initial = [(3.5, 1.5), (0.5, 1.5)] tf = TopFarm(initial, DummyCost(optimal, inputs=['x', 'y']), 0, boundary=boundary, boundary_type='polygon', plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(tol=1e-6, disp=False)) tf.optimize() plot_comp.show() np.testing.assert_array_almost_equal(tf.turbine_positions[:, :2], optimal, 4)
def get_tf(cost_comp, plot_comp=NoPlot()): return TopFarmProblem(dict(zip('xy', initial.T)), cost_comp=cost_comp, plot_comp=plot_comp, constraints=[ SpacingConstraint(min_spacing), XYBoundaryConstraint(boundary) ], driver=EasyScipyOptimizeDriver(disp=False))
def testPolygonConcave(): optimal = [(1.5, 1.3), (4, 1)] boundary = [(0, 0), (5, 0), (5, 2), (3, 2), (3, 1), (2, 1), (2, 2), (0, 2), (0, 0)] plot_comp = NoPlot() # DummyCostPlotComp(optimal) initial = [(-0, .1), (4, 1.5)][::-1] tf = TopFarm(initial, DummyCost(optimal, inputs=['x', 'y']), 0, boundary=boundary, boundary_type='polygon', plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(tol=1e-8, disp=False)) tf.evaluate() tf.optimize() np.testing.assert_array_almost_equal(tf.turbine_positions[:, :2], optimal, 4) plot_comp.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() 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 get_tf(initial, optimal, boundary, plot_comp=NoPlot()): initial, optimal = map(np.array, [initial, optimal]) return TopFarmProblem( { 'x': initial[:, 0], 'y': initial[:, 1] }, DummyCost(optimal), constraints=[XYBoundaryConstraint(boundary, 'polygon')], driver=EasyScipyOptimizeDriver(tol=1e-8, disp=False), plot_comp=plot_comp)
def test_TopFarmProblem_with_cirleboundary_gradients(): optimal = np.array([(0, 0)]) desvar = dict(zip('xy', optimal.T + 1.5)) plot_comp = NoPlot() b = CircleBoundaryConstraint([1, 2], 3) tf = TopFarmProblem(desvar, DummyCost(optimal, 'xy'), constraints=[b], plot_comp=plot_comp, driver=SimpleGADriver()) tf.check_gradients(True)
def main(): if __name__ == '__main__': # ------------------------ INPUTS ------------------------ # define the conditions for the wind farm positions = np.array([[0, 0], [6, 6]]) # initial turbine pos optimal_types = np.array([[2], [6]]) # optimal layout # =============================================================================== # Setup the problem and plotting # =============================================================================== try: import matplotlib.pyplot as plt plt.gcf() plot_comp = TurbineTypePlotComponent( turbine_type_names=["Turbine %d" % i for i in range(5)], plot_initial=False, delay=0.1, legendloc=0) plot = True except RuntimeError: plot_comp = NoPlot() plot = False # create the wind farm tf = TopFarmProblem( design_vars={'type': ([0, 0], 0, 4)}, cost_comp=DummyCost(optimal_types, ['type']), plot_comp=plot_comp, driver=FullFactorialGenerator(5), ext_vars={ 'x': positions[:, 0], 'y': positions[:, 1] }, ) # =============================================================================== # # Run the optimization # =============================================================================== state = {} cost, state, recorder = tf.optimize(state) # =============================================================================== # plot and prin the the final, optimal types # =============================================================================== print(state['type']) tf.evaluate(state) # save the figure if plot: folder, file = os.path.split(__file__) plt.savefig(folder + "/figures/" + file.replace('.py', '.png')) plt.show()
def _topfarm_obj(driver, spacing=2, keys='xy'): # from topfarm.cost_models.dummy import DummyCostPlotComp # plot_comp = DummyCostPlotComp(desired[:,:len(keys)], plot_improvements_only=True) plot_comp = NoPlot() return TopFarmProblem(dict(zip(keys, initial.T[:len(keys)])), DummyCost(desired[:, :len(keys)], keys), constraints=[ SpacingConstraint(spacing), XYBoundaryConstraint(boundary) ], plot_comp=plot_comp, driver=driver, expected_cost=1.5)
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 test_setup_as_constraint_xy(): from topfarm.cost_models.dummy import DummyCostPlotComp # plot_comp = DummyCostPlotComp(desired) plot_comp = NoPlot() tf = TurbineXYZOptimizationProblem(DummyCost(desired[:, :2], ['x', 'y']), initial[:, :2], boundary_comp=BoundaryComp(len(initial), boundary, None), 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 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 test_turbineType_and_XYZ_optimization(): plot_comp = DummyCostPlotComp(optimal) plot_comp = NoPlot() cost_comp = DummyCost( optimal_state=optimal, inputs=['x', 'y', 'z', 'type']) xyz_opt_problem = TurbineXYZOptimizationProblem( cost_comp, turbineXYZ=[(0, 0, 0), (1, 1, 1)], min_spacing=2, boundary_comp=get_boundary_comp(), plot_comp=plot_comp, driver=EasyScipyOptimizeDriver(disp=False)) tf = TurbineTypeOptimizationProblem( cost_comp=xyz_opt_problem, turbineTypes=[0, 0], lower=0, upper=1, driver=DOEDriver(FullFactorialGenerator(2))) cost = tf.optimize()[0] npt.assert_almost_equal(cost, 0)
def test_spacing(): from topfarm.cost_models.dummy import DummyCostPlotComp # plot_comp = DummyCostPlotComp(desired) plot_comp = NoPlot() tf = TurbineXYZOptimizationProblem(DummyCost(desired, ['x', 'y']), initial, boundary_comp=BoundaryComp( len(initial), boundary, None), min_spacing=2, plot_comp=plot_comp) tf.evaluate() tf.optimize() tb_pos = tf.turbine_positions[:, :2] tf.plot_comp.show() tol = 1e-4 assert sum((tb_pos[2] - tb_pos[0])**2) > 2**2 - tol # check min spacing
def testAEP_topfarm_optimization_4tb(get_fuga): D = 80.0 B = 3 * D + 10 init_pos = np.array([(0, 3 * D), (0, D), (0, -D), (0, -3 * D)]) init_pos[:, 0] += [-80, 0, 0, 80] wind_atlas = 'MyFarm/north_pm45_only.lib' pyFuga = get_fuga(init_pos[:1, 0], init_pos[:1, 1], wind_atlas=wind_atlas) AEP_pr_tb = pyFuga.get_aep()[1] pyFuga = get_fuga(init_pos[:, 0], init_pos[:, 1], wind_atlas=wind_atlas) boundary = [(-B, B), (B, B), (B, -B), (-B, -B), (-B, B)] plot_comp = NoPlot() # plot_comp= PlotComp() tf = get_tf(init_pos, pyFuga, boundary) cost, _, rec = tf.optimize() uta.assertAlmostEqual(-cost, AEP_pr_tb * 4, delta=.2) tf.plot_comp.show()
def __init__(self, design_vars, cost_comp=None, driver=EasyScipyOptimizeDriver(), constraints=[], plot_comp=NoPlot(), record_id=None, expected_cost=1, ext_vars={}, post_constraints=[], approx_totals=False): """Initialize TopFarmProblem Parameters ---------- design_vars : dict or list of key-initial_value-tuples Design variables for the problem.\n Ex: {'x': [1,2,3], 'y':([3,2,1],0,1), 'z':([4,5,6],[4,5,4], [6,7,6])}\n Ex: [('x', [1,2,3]), ('y',([3,2,1],0,1)), ('z',([4,5,6],[4,5,4], [6,7,6]))]\n Ex: [('x', ([1,2,3],0,3,'m')), ('y',([3,2,1],'m')), ('z',([4,5,6],[4,5,4], [6,7,6]))]\n Ex: zip('xy', pos.T)\n The keys (x, y, z) are the names of the design variable.\n The values are either\n - the initial value or\n - on of the following tuples: (initial value, unit) (initial value, lower bound, upper bound) (initial value, lower bound, upper bound, unit) cost_comp : ExplicitComponent or TopFarmProblem or TopFarmGroup Component that provides the cost function. It has to be the style of an OpenMDAO v2 ExplicitComponent. Pure python cost functions can be wrapped using ``CostModelComponent`` class in ``topfarm.cost_models.cost_model_wrappers``.\n ExplicitComponent are wrapped into a TopFarmGroup.\n For nested problems, the cost comp_comp is typically a TopFarmProblem driver : openmdao Driver, optinal Driver used to solve the optimization driver. For an example, see the ``EasyScipyOptimizeDriver`` class in ``topfarm.easy_drivers``. constraints : list of Constraint-objects E.g. XYBoundaryConstraint, SpacingConstraint plot_comp : ExplicitComponent, optional OpenMDAO ExplicitComponent used to plot the state (during optimization). For no plotting, pass in the ``topfarm.plotting.NoPlot`` class. record_id : string "<record_id>:<case>", optional Identifier for the optimization. Allows a user to restart an optimization where it left off.\n record_id can be name (saves as recordings/<name>.pkl), abs or relative path Case can be:\n - "", "latest", "-1": Continue from latest\n - "best": Continue from best case (minimum cost)\n - "0": Start from scratch (initial position)\n - "4": Start from case number 4\n expected_cost : int, float or None, optional Used to scale the cost, default is 1. This has influence on some drivers, e.g. SLSQP where it affects the step size\n If None, the value is found by evaluating the cost function ext_vars : dict or list of key-initial_value tuple Used for nested problems to propagate variables from parent problem\n Ex. {'type': [1,2,3]}\n Ex. [('type', [1,2,3])]\n post_constraints : list of Constraint-objects that needs the cost component to be evaluated, unlike (pre-)constraints which are evaluated before the cost component. E.g. LoadConstraint approx_totals : bool or dict If True, approximates the total derivative of the cost_comp group, skipping the partial ones. If it is a dictionary, it's elements are passed to the approx_totals function of an OpenMDAO Group. Examples -------- See main() in the bottom of this file """ if mpi.MPI: comm = None else: from openmdao.utils.mpi import FakeComm comm = FakeComm() Problem.__init__(self, comm=comm) if cost_comp: if isinstance(cost_comp, TopFarmProblem): cost_comp = cost_comp.as_component() elif isinstance(cost_comp, ExplicitComponent) and (len(post_constraints) > 0): cost_comp = TopFarmGroup([cost_comp]) cost_comp.parent = self self.cost_comp = cost_comp if isinstance(driver, list): driver = DOEDriver(ListGenerator(driver)) elif isinstance(driver, DOEGenerator): driver = DOEDriver(generator=driver) self.driver = driver self.driver.recording_options['record_desvars'] = True self.driver.recording_options['includes'] = ['*'] self.driver.recording_options['record_inputs'] = True self.plot_comp = plot_comp self.record_id = record_id self.load_recorder() if not isinstance(approx_totals, dict) and approx_totals: approx_totals = {'method': 'fd'} if not isinstance(design_vars, dict): design_vars = dict(design_vars) self.design_vars = design_vars self.indeps = self.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) for k, v in design_vars.items(): if isinstance(v, tuple): if (not isinstance(v[-1], str)) or (not v[-1]): design_vars[k] += (None, ) else: design_vars[k] = (design_vars[k], None) v = design_vars[k] self.indeps.add_output(k, v[0], units=v[-1]) for k in [topfarm.x_key, topfarm.y_key, topfarm.type_key]: if k in design_vars: self.n_wt = len(design_vars[k][0]) break else: self.n_wt = 0 constraints_as_penalty = ( (not self.driver.supports['inequality_constraints'] or isinstance(self.driver, SimpleGADriver) or isinstance(self.driver, EasySimpleGADriver)) and len(constraints) + len(post_constraints) > 0) if len(constraints) > 0: self.model.add_subsystem('pre_constraints', ParallelGroup(), promotes=['*']) for constr in constraints: if constraints_as_penalty: constr.setup_as_penalty(self) else: constr.setup_as_constraint(self) # Use the assembled Jacobian. self.model.pre_constraints.options[ 'assembled_jac_type'] = 'csc' self.model.pre_constraints.linear_solver.assemble_jac = True penalty_comp = PenaltyComponent(constraints, constraints_as_penalty) self.model.add_subsystem('penalty_comp', penalty_comp, promotes=['*']) self.model.constraint_components = [ constr.constraintComponent for constr in constraints ] for k, v in design_vars.items(): if isinstance(driver, EasyDriverBase): kwargs = driver.get_desvar_kwargs(self.model, k, v) else: kwargs = EasyDriverBase.get_desvar_kwargs( None, self.model, k, v) self.model.add_design_var(k, **kwargs) for k, v in ext_vars.items(): self.indeps.add_output(k, v) self.ext_vars = ext_vars if cost_comp: self.model.add_subsystem('cost_comp', cost_comp, promotes=['*']) if expected_cost is None: expected_cost = self.evaluate()[0] self._setup_status = 0 if isinstance( driver, EasyDriverBase) and driver.supports_expected_cost is False: expected_cost = 1 if isinstance(cost_comp, Group) and approx_totals: cost_comp.approx_totals(**approx_totals) # Use the assembled Jacobian. if 'assembled_jac_type' in self.model.cost_comp.options: self.model.cost_comp.options['assembled_jac_type'] = 'dense' self.model.cost_comp.linear_solver.assemble_jac = True else: self.indeps.add_output('cost') if len(post_constraints) > 0: if constraints_as_penalty: penalty_comp = PostPenaltyComponent(post_constraints, constraints_as_penalty) self.model.add_subsystem('post_penalty_comp', penalty_comp, promotes=['*']) else: for constr in post_constraints: self.model.add_constraint(constr[0], upper=np.full( self.n_wt, constr[1])) # Use the assembled Jacobian. # self.model.cost_comp.post_constraints.options['assembled_jac_type'] = 'csc' # self.model.cost_comp.post_constraints.linear_solver.assemble_jac = True aggr_comp = AggregatedCost(constraints_as_penalty, constraints, post_constraints) self.model.add_subsystem('aggr_comp', aggr_comp, promotes=['*']) self.model.add_objective('aggr_cost', scaler=1 / abs(expected_cost)) if plot_comp and not isinstance(plot_comp, NoPlot): self.model.add_subsystem('plot_comp', plot_comp, promotes=['*']) plot_comp.problem = self plot_comp.n_wt = self.n_wt self.setup()
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 __init__(self, design_vars, cost_comp, driver=EasyScipyOptimizeDriver(), constraints=[], plot_comp=NoPlot(), record_id=None, expected_cost=1, ext_vars={}): """Initialize TopFarmProblem Parameters ---------- design_vars : dict or list of key-initial_value-tuples Design variables for the problem.\n Ex: {'x': [1,2,3], 'y':([3,2,1],0,1), 'z':([4,5,6],[4,5,4], [6,7,6])}\n Ex: [('x', [1,2,3]), ('y',([3,2,1],0,1)), ('z',([4,5,6],[4,5,4], [6,7,6]))]\n Ex: zip('xy', pos.T)\n The keys (x, y, z) are the names of the design variable.\n The values are either\n - the initial value or\n - a tuple of (initial value, lower bound, upper bound) cost_comp : ExplicitComponent or TopFarmProblem A cost component in the style of an OpenMDAO v2 ExplicitComponent. Pure python cost functions can be wrapped using ``CostModelComponent`` class in ``topfarm.cost_models.cost_model_wrappers``.\n For nested problems, the cost comp_comp is typically a TopFarmProblem driver : openmdao Driver, optinal Driver used to solve the optimization driver. For an example, see the ``EasyScipyOptimizeDriver`` class in ``topfarm.easy_drivers``. constraints : list of Constraint-objects E.g. XYBoundaryConstraint, SpacingConstraint plot_comp : ExplicitComponent, optional OpenMDAO ExplicitComponent used to plot the state (during optimization). For no plotting, pass in the ``topfarm.plotting.NoPlot`` class. record_id : string "<record_id>:<case>", optional Identifier for the optimization. Allows a user to restart an optimization where it left off.\n record_id can be name (saves as recordings/<name>.pkl), abs or relative path Case can be:\n - "", "latest", "-1": Continue from latest\n - "best": Continue from best case (minimum cost)\n - "0": Start from scratch (initial position)\n - "4": Start from case number 4\n expected_cost : int or float Used to scale the cost. This has influence on some drivers, e.g. SLSQP where it affects the step size ext_vars : dict or list of key-initial_value tuple Used for nested problems to propagate variables from parent problem\n Ex. {'type': [1,2,3]}\n Ex. [('type', [1,2,3])]\n Examples -------- See main() in the bottom of this file """ if mpi.MPI: comm = None else: from openmdao.utils.mpi import FakeComm comm = FakeComm() Problem.__init__(self, comm=comm) if isinstance(cost_comp, TopFarmProblem): cost_comp = cost_comp.as_component() cost_comp.parent = self self.cost_comp = cost_comp if isinstance(driver, list): driver = DOEDriver(ListGenerator(driver)) elif isinstance(driver, DOEGenerator): driver = DOEDriver(generator=driver) self.driver = driver self.plot_comp = plot_comp self.record_id = record_id self.load_recorder() if not isinstance(design_vars, dict): design_vars = dict(design_vars) self.design_vars = design_vars self.indeps = self.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) for k in [topfarm.x_key, topfarm.y_key, topfarm.type_key]: if k in design_vars: if isinstance(design_vars[k], tuple): self.n_wt = len(design_vars[k][0]) else: self.n_wt = len(design_vars[k]) break else: self.n_wt = 0 for constr in constraints: if self.driver.supports['inequality_constraints']: if isinstance(self.driver, SimpleGADriver): constr.setup_as_penalty(self) else: constr.setup_as_constraint(self) else: constr.setup_as_penalty(self) self.model.constraint_components = [ constr.constraintComponent for constr in constraints ] do = self.driver.options for k, v in design_vars.items(): if isinstance(v, tuple): assert len( v ) == 3, "Design_vars values must be either value or (value, lower, upper)" self.indeps.add_output(k, v[0]) if ('optimizer' in do and do['optimizer'] == 'COBYLA'): ref0 = np.min(v[1]) ref1 = np.max(v[2]) l, u = [lu * (ref1 - ref0) + ref0 for lu in [v[1], v[2]]] kwargs = { 'ref0': ref0, 'ref': ref1, 'lower': l, 'upper': u } else: kwargs = {'lower': v[1], 'upper': v[2]} else: self.indeps.add_output(k, v) kwargs = {} if 'optimizer' in do and do['optimizer'] == 'SLSQP': # Upper and lower disturbs SLSQP when running with constraints. Add limits as constraints self.model.add_constraint(k, kwargs.get('lower', None), kwargs.get('upper', None)) kwargs = { 'lower': np.nan, 'upper': np.nan } # Default +/- sys.float_info.max does not work for SLSQP self.model.add_design_var(k, **kwargs) for k, v in ext_vars.items(): self.indeps.add_output(k, v) self.ext_vars = ext_vars self.model.add_subsystem('cost_comp', cost_comp, promotes=['*']) self.model.add_objective('cost', scaler=1 / abs(expected_cost)) if plot_comp: self.model.add_subsystem('plot_comp', plot_comp, promotes=['*']) plot_comp.problem = self plot_comp.n_wt = self.n_wt self.setup()
'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)
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 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 ------------------------ # paths to input files test_files_dir = os.path.dirname( test_files.__file__) + "/" # file locations wf_path = test_files_dir + 'wind_farms/3tb.yml' # path to wind farm # ------------------------ 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 ] wind_res = WindResource(f, a, k, np.zeros_like(k)) # ------------------------ 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(wake_model): return TopFarmProblem(design_vars=dict(zip('xy', init_pos.T)), cost_comp=AEPCalculator( wind_res, wake_model, wdir=np.arange( 0, 360, 12)).get_TopFarm_cost_component(), constraints=[ SpacingConstraint(min_spacing), XYBoundaryConstraint(boundary) ], driver=EasyScipyOptimizeDriver(), plot_comp=plot_comp) with warnings.catch_warnings(): warnings.filterwarnings( 'ignore') # temporarily disable fusedwake warnings # GCL: define the wake model and optimization problem wake_mod_gcl = FusedWakeGCLWakeModel(wf_path) tf_gcl = get_tf(wake_mod_gcl) # NOJ: define the wake model and optimization problem wake_mod_noj = FusedWakeNOJWakeModel(wf_path) tf_noj = get_tf(wake_mod_noj) # 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'))
def main(): if __name__ == '__main__': if not 'plantenergy' in topfarm.plugins: pass else: try: from plantenergy.GeneralWindFarmGroups import AEPGroup from plantenergy.floris import floris_wrapper, add_floris_params_IndepVarComps try: import matplotlib.pyplot as plt plt.gcf() plot_comp = XYPlotComp() plot = True except RuntimeError: plot_comp = NoPlot() plot = False # plot_comp = NoPlot() 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 differentiable = True prob = setup_prob(differentiable) # view_model(prob) cost_init, state_init = prob.evaluate() tic = time.time() cost, state, recorder = prob.optimize() toc = time.time() print( 'FLORIS calculation with differentiable = {0} took {1} sec.' .format(differentiable, toc - tic)) print(prob[topfarm.x_key]) # ######################################## # ## Setup Floris run without gradients ## # ######################################## # # differentiable = False # prob2 = setup_prob(differentiable) # cost_init, state_init = prob2.evaluate() # tic = time.time() # cost, state, recorder = prob2.optimize() # toc = time.time() # print('FLORIS calculation with differentiable = {0} took {1} sec.'.format(differentiable, toc-tic)) # # # # ######################################## # ## Setup Pywake run without gradients ## # ######################################## # # # # class PyWakeAEP(AEPCalculator): # """TOPFARM wrapper for PyWake AEP calculator""" # # def get_TopFarm_cost_component(self, n_wt, wd=None, ws=None): # """Create topfarm-style cost component # # Parameters # ---------- # n_wt : int # Number of wind turbines # """ # return AEPCostModelComponent( # input_keys=['turbineX', 'turbineY'], # n_wt=n_wt, # cost_function=lambda **kwargs: # self.calculate_AEP(x_i=kwargs[topfarm.x_key], # y_i=kwargs[topfarm.y_key], # h_i=kwargs.get(topfarm.z_key, None), # type_i=kwargs.get(topfarm.type_key, None), # wd=wd, ws=ws).sum(), # output_unit='GWh') # aep_calc = PyWakeAEP(site, wt, wake_model) # tf = TopFarmProblem( # design_vars={'turbineX': turbineX, 'turbineY': turbineY}, # cost_comp=aep_calc.get_TopFarm_cost_component(len(turbineX)), # driver=EasyScipyOptimizeDriver(optimizer='SLSQP'), # constraints=[SpacingConstraint(200), # XYBoundaryConstraint(boundary)], # plot_comp=plot_comp) # cost_init_pw, state_init_pw = tf.evaluate() # cost_pw, state_pw, recorder_pw = tf.optimize() # # # prob['turbineX'] = state_pw['turbineX'] # prob['turbineY'] = state_pw['turbineY'] # cost_pw_fl, state_pw_fl = prob.evaluate() # print('\n***Optimized by PyWake:***') # print('AEP FLORISSE initial: ', float(-cost_init/10**6)) # print('AEP FLORISSE optimized: ', float(-cost_pw_fl)/10**6) # print('AEP PyWake initial: ', float(-cost_init_pw)) # print('AEP PyWake optimized: ', float(-cost_pw)) # # print('***Optimized by FLORISSE:***') # print('AEP FLORISSE initial: ', float(-cost_init/10**6)) # print('AEP FLORISSE optimized: ', float(-cost)/10**6) # print('AEP Pywake initial: ', aep_calculator.calculate_AEP(turbineX, turbineY).sum()) # print('AEP Pywake optimized: ', aep_calculator.calculate_AEP(state['turbineX'], state['turbineY']).sum()) finally: topfarm.x_key = 'x' topfarm.y_key = 'y'
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()