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()
示例#4
0
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)
示例#5
0
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()
示例#6
0
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)
示例#7
0
    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)
示例#8
0
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)
示例#9
0
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)
示例#10
0
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))
示例#11
0
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()
示例#12
0
def main():
    if __name__ == '__main__':
        try:
            import matplotlib.pyplot as plt
            plt.gcf()
            plot_comp = XYPlotComp()
            plot = True
        except RuntimeError:
            plot_comp = NoPlot()
            plot = False

        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()
示例#13
0
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()
示例#16
0
    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)
示例#17
0
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()
示例#18
0
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
示例#19
0
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
示例#20
0
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)
示例#21
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
示例#22
0
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()
示例#23
0
    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()
示例#25
0
    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)
示例#27
0
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'))
示例#28
0
def main():
    if __name__ == '__main__':
        try:
            import matplotlib.pyplot as plt
            plt.gcf()
            plot_comp = XYPlotComp()
            plot = True
        except RuntimeError:
            plot_comp = NoPlot()
            plot = False
        # ------------------------ INPUTS ------------------------

        # 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'))
示例#29
0
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()