Open and run in Colab (interactive) Edit on Gitlab

External Drivers

OpenMDAO supports multiple external optimization libraries like Scipy, pyOptSparse, modOpt and pymoo. These are also available in Topfarm if the underlying libraries have heen installed. In this notebook we look at how drivers from external libraries are coupled to your Topfarm Problem.

Install TOPFARM if needed

[1]:
# Install TopFarm if needed
import importlib
if not importlib.util.find_spec("pyoptsparse"):
    %pip install git+https://github.com/mdolab/pyoptsparse
    import pyoptsparse
    pyoptsparse.__version__ = "999"
if not importlib.util.find_spec("topfarm"):
    %pip install git+https://gitlab.windenergy.dtu.dk/TOPFARM/TopFarm2.git
if not importlib.util.find_spec("modopt"):
    %pip install "modopt[open_source_optimizers] @ git+https://github.com/lsdolab/modopt.git@65c7e272b8d75b39c9360c15a95deb3d70753958"
if not importlib.util.find_spec("pymoo"):
    %pip install pymoo
%pip install openmdao>=3.44
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable.It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning.
Note: you may need to restart the kernel to use updated packages.
[2]:
import matplotlib
try: get_ipython().run_line_magic("matplotlib", "widget")
except: matplotlib.use("Agg")
[3]:
from topfarm.cost_models.dummy import DummyCost, DummyCostPlotComp
from topfarm.constraint_components.spacing import SpacingConstraint
from topfarm.constraint_components.boundary import XYBoundaryConstraint
from topfarm.easy_drivers import EasyScipyOptimizeDriver, EasySimpleGADriver, EasyDriverBase, EasySGDDriver, EasyRandomSearchDriver
from topfarm import TopFarmProblem
from topfarm.drivers.random_search_driver import RandomizeTurbinePosition_Circle
from topfarm.plotting import NoPlot
from topfarm.utils import plot_list_recorder

import numpy as np
import openmdao.api as om

Problem definition

First we set up the Topfarm Problem, and then we see how each optimization driver is configured.

[4]:
initial = np.array([[6, 0], [6, -8], [1, 1]])  # initial turbine layouts
optimal = np.array([[2.5, -3], [6, -7], [4.5, -3]])  # optimal turbine layouts
boundary = np.array([(0, 0), (6, 0), (6, -10), (0, -10)])  # turbine boundaries
desired = np.array([[3, -3], [7, -7], [4, -3]])  # desired turbine layouts
plot_comp = DummyCostPlotComp(optimal)
tf = TopFarmProblem(
    design_vars=dict(zip('xy', initial.T)),
    cost_comp=DummyCost(optimal_state=desired, inputs=['x', 'y']),
    constraints=[XYBoundaryConstraint(boundary),
                    SpacingConstraint(2)
                    ],
    plot_comp=plot_comp
)

Scipy

[5]:
tf.driver = om.ScipyOptimizeDriver()
tf.driver.options['optimizer'] = 'SLSQP'
tf.driver.options['tol'] = 1e-9
tf.driver.options['disp'] = True
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
<Figure size 640x480 with 1 Axes>
Optimization terminated successfully    (Exit mode 0)
            Current function value: 1.500000000116204
            Iterations: 16
            Function evaluations: 21
            Gradient evaluations: 16
Optimization Complete
-----------------------------------
[5]:
np.float64(1.500000000116204)

pyOptSparse

[6]:
tf.driver = om.pyOptSparseDriver(optimizer='SLSQP')
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
<Figure size 640x480 with 1 Axes>


Optimization Problem -- Optimization using pyOpt_sparse
================================================================================
    Objective Function: _objfunc

    Solution:
--------------------------------------------------------------------------------
    Total Time:                    1.5470
       User Objective Time :       1.3985
       User Sensitivity Time :     0.0313
       Interface Time :            0.0135
       Opt Solver Time:            0.1036
    Calls to Objective Function :      19
    Calls to Sens Function :           14


   Objectives
      Index  Name                  Value
          0  final_cost     1.500000E+00

   Variables (c - continuous, i - integer, d - discrete)
      Index  Name   Type      Lower Bound            Value      Upper Bound     Status
          0  x_0      c     0.000000E+00     2.500026E+00     6.000000E+00
          1  x_1      c     0.000000E+00     6.000000E+00     6.000000E+00          u
          2  x_2      c     0.000000E+00     4.500026E+00     6.000000E+00
          3  y_0      c    -1.000000E+01    -3.000045E+00     0.000000E+00
          4  y_1      c    -1.000000E+01    -7.000441E+00     0.000000E+00
          5  y_2      c    -1.000000E+01    -2.999987E+00     0.000000E+00

   Constraints (i - inequality, e - equality)
      Index  Name                Type          Lower           Value           Upper    Status  Lagrange Multiplier (N/A)
          0  boundaryDistances      i   0.000000E+00    3.000045E+00    1.000000E+30              9.00000E+100
          1  boundaryDistances      i   0.000000E+00    2.500026E+00    1.000000E+30              9.00000E+100
          2  boundaryDistances      i   0.000000E+00    6.999955E+00    1.000000E+30              9.00000E+100
          3  boundaryDistances      i   0.000000E+00    3.499974E+00    1.000000E+30              9.00000E+100
          4  boundaryDistances      i   0.000000E+00    7.000441E+00    1.000000E+30              9.00000E+100
          5  boundaryDistances      i   0.000000E+00    6.000000E+00    1.000000E+30              9.00000E+100
          6  boundaryDistances      i   0.000000E+00    2.999559E+00    1.000000E+30              9.00000E+100
          7  boundaryDistances      i   0.000000E+00    0.000000E+00    1.000000E+30         l    9.00000E+100
          8  boundaryDistances      i   0.000000E+00    2.999987E+00    1.000000E+30              9.00000E+100
          9  boundaryDistances      i   0.000000E+00    4.500026E+00    1.000000E+30              9.00000E+100
         10  boundaryDistances      i   0.000000E+00    7.000013E+00    1.000000E+30              9.00000E+100
         11  boundaryDistances      i   0.000000E+00    1.499974E+00    1.000000E+30              9.00000E+100
         12  wtSeparationSquared    i   4.000000E+00    2.825299E+01    1.000000E+30              9.00000E+100
         13  wtSeparationSquared    i   4.000000E+00    4.000000E+00    1.000000E+30         l    9.00000E+100
         14  wtSeparationSquared    i   4.000000E+00    1.825355E+01    1.000000E+30              9.00000E+100


   Exit Status
      Inform  Description
           0  Optimization terminated successfully.
--------------------------------------------------------------------------------

[6]:
np.float64(1.500000198978579)

modOpt

[7]:
tf.driver = om.modOptDriver()
tf.driver.options['optimizer'] = 'SLSQP'
tf.driver.options['maxiter'] = 200
tf.driver.options['disp'] = True
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[7], line 1
----> 1 tf.driver = om.modOptDriver()
      2 tf.driver.options['optimizer'] = 'SLSQP'
      3 tf.driver.options['maxiter'] = 200
      4 tf.driver.options['disp'] = True

AttributeError: module 'openmdao.api' has no attribute 'modOptDriver'

pymoo

[8]:
tf.driver = om.pymooDriver()
tf.driver.options['optimizer'] = 'DE'
tf.driver.options['disp'] = False
tf.driver.run_settings['seed'] = 11
tf.driver.run_settings['termination'] = ('n_gen', 100)
tf.plot_comp.plot_improvements_only = True
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[8], line 1
----> 1 tf.driver = om.pymooDriver()
      2 tf.driver.options['optimizer'] = 'DE'
      3 tf.driver.options['disp'] = False
      4 tf.driver.run_settings['seed'] = 11

AttributeError: module 'openmdao.api' has no attribute 'pymooDriver'

Simple Genetic Algorithm

[9]:
tf.driver = om.SimpleGADriver()
tf.driver.options['bits'] = {'x': 5, 'y': 5}
tf.driver.options['max_gen'] = 10
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
<Figure size 640x480 with 1 Axes>
[9]:
np.float64(2.5483870967741935)

Differential Evolution

[10]:
tf.driver = om.DifferentialEvolutionDriver()
tf.driver.options['max_gen'] = 10
tf.driver.options['Pc'] = 0.5
tf.driver.options['F'] = 0.5
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
<Figure size 640x480 with 1 Axes>
[10]:
np.float64(3.922034059487765)

Drivers that do not support constraints

In topfarm the problem is configured during instantiation for constraint handling. This means that for drivers that do not support constraints, these are being converted to penalties. In this case we it is important to indicate the driver already at the problem instantiation

[11]:
tf = TopFarmProblem(
    design_vars=dict(zip('xy', initial.T)),
    cost_comp=DummyCost(optimal_state=desired, inputs=['x', 'y']),
    constraints=[XYBoundaryConstraint(boundary),
                    SpacingConstraint(2)
                    ],
    plot_comp = DummyCostPlotComp(optimal, plot_improvements_only=True),
    driver=EasyRandomSearchDriver(RandomizeTurbinePosition_Circle(max_step=10), max_iter=1000, max_time=30)
)
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
<Figure size 640x480 with 1 Axes>
[11]:
np.float64(1.8106061127112252)

External drivers can also be given during instantiation of the problem

[12]:
tf = TopFarmProblem(
    design_vars=dict(zip('xy', initial.T)),
    cost_comp=DummyCost(optimal_state=desired, inputs=['x', 'y']),
    constraints=[XYBoundaryConstraint(boundary),
                    SpacingConstraint(2)
                    ],
    plot_comp=plot_comp,
    driver=om.modOptDriver(**{'optimizer': 'SLSQP',
                              'maxiter': 200,
                              'disp': True}),
)
cost, _, recorder = tf.optimize(state=dict(zip('xy', initial.T)))
cost
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[12], line 8
      4     constraints=[XYBoundaryConstraint(boundary),
      5                     SpacingConstraint(2)
      6                     ],
      7     plot_comp=plot_comp,
----> 8     driver=om.modOptDriver(**{'optimizer': 'SLSQP',
      9                               'maxiter': 200,
     10                               'disp': True}),
     11 )

AttributeError: module 'openmdao.api' has no attribute 'modOptDriver'
[ ]: