ScipyOptimizeDriver¶
ScipyOptimizeDriver wraps the optimizers in scipy.optimize.minimize. In this example, we use the SLSQP optimizer to find the minimum of the Paraboloid problem.
import openmdao.api as om from openmdao.test_suite.components.paraboloid import Paraboloid prob = om.Problem() model = prob.model model.add_subsystem('comp', Paraboloid(), promotes=['*']) prob.driver = om.ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' prob.driver.options['tol'] = 1e-9 prob.driver.options['disp'] = True model.add_design_var('x', lower=-50.0, upper=50.0) model.add_design_var('y', lower=-50.0, upper=50.0) model.add_objective('f_xy') prob.setup() prob.set_val('x', 50.0) prob.set_val('y', 50.0) prob.run_driver()Optimization terminated successfully. (Exit mode 0) Current function value: -27.33333333333333 Iterations: 3 Function evaluations: 4 Gradient evaluations: 3 Optimization Complete -----------------------------------print(prob.get_val('x'))[6.66666667]print(prob.get_val('y'))[-7.33333333]
ScipyOptimizeDriver Options¶
Option |
Default |
Acceptable Values |
Acceptable Types |
Description |
---|---|---|---|---|
debug_print |
[] |
N/A |
[‘list’] |
List of what type of Driver variables to print at each iteration. Valid items in list are ‘desvars’, ‘ln_cons’, ‘nl_cons’, ‘objs’, ‘totals’ |
disp |
True |
[True, False] |
[‘bool’] |
Set to False to prevent printing of Scipy convergence messages |
maxiter |
200 |
N/A |
N/A |
Maximum number of iterations. |
optimizer |
SLSQP |
[‘BFGS’, ‘Newton-CG’, ‘COBYLA’, ‘SLSQP’, ‘trust-constr’, ‘dual_annealing’, ‘shgo’, ‘differential_evolution’, ‘basinhopping’, ‘CG’, ‘L-BFGS-B’, ‘TNC’, ‘Nelder-Mead’, ‘Powell’] |
N/A |
Name of optimizer to use |
tol |
1e-06 |
N/A |
N/A |
Tolerance for termination. For detailed control, use solver-specific options. |
ScipyOptimizeDriver Constructor¶
The call signature for the ScipyOptimizeDriver constructor is:
-
ScipyOptimizeDriver.
__init__
(**kwargs)[source] Initialize the ScipyOptimizeDriver.
- Parameters
- **kwargsdict of keyword arguments
Keyword arguments that will be mapped into the Driver options.
ScipyOptimizeDriver Option Examples¶
optimizer
The “optimizer” option lets you choose which optimizer to use. ScipyOptimizeDriver supports all of the optimizers in scipy.optimize except for ‘dogleg’ and ‘trust-ncg’. Generally, the optimizers that you are most likely to use are “COBYLA” and “SLSQP”, as these are the only ones that support constraints. Only SLSQP supports equality constraints. SLSQP also uses gradients provided by OpenMDAO, while COBYLA is gradient-free. Also, SLSQP supports both equality and inequality constraints, but COBYLA only supports inequality constraints.
Here we pass the optimizer option as a keyword argument.
import openmdao.api as om from openmdao.test_suite.components.paraboloid import Paraboloid prob = om.Problem() model = prob.model model.add_subsystem('comp', Paraboloid(), promotes=['*']) prob.driver = om.ScipyOptimizeDriver(optimizer='COBYLA') model.add_design_var('x', lower=-50.0, upper=50.0) model.add_design_var('y', lower=-50.0, upper=50.0) model.add_objective('f_xy') prob.setup() prob.set_val('x', 50.0) prob.set_val('y', 50.0) prob.run_driver()Optimization Complete -----------------------------------print(prob.get_val('x'))[6.66666669]print(prob.get_val('y'))[-7.33333239]
maxiter
The “maxiter” option is used to specify the maximum number of major iterations before termination. It is generally a valid option across all of the available options.
import openmdao.api as om from openmdao.test_suite.components.paraboloid import Paraboloid prob = om.Problem() model = prob.model model.add_subsystem('comp', Paraboloid(), promotes=['*']) prob.driver = om.ScipyOptimizeDriver() prob.driver.options['maxiter'] = 20 model.add_design_var('x', lower=-50.0, upper=50.0) model.add_design_var('y', lower=-50.0, upper=50.0) model.add_objective('f_xy') prob.setup() prob.set_val('x', 50.0) prob.set_val('y', 50.0) prob.run_driver()Optimization terminated successfully. (Exit mode 0) Current function value: -27.33333333333333 Iterations: 3 Function evaluations: 4 Gradient evaluations: 3 Optimization Complete -----------------------------------print(prob.get_val('x'))[6.66666667]print(prob.get_val('y'))[-7.33333333]
tol
The “tol” option allows you to specify the tolerance for termination.
import openmdao.api as om from openmdao.test_suite.components.paraboloid import Paraboloid prob = om.Problem() model = prob.model model.add_subsystem('comp', Paraboloid(), promotes=['*']) prob.driver = om.ScipyOptimizeDriver() prob.driver.options['tol'] = 1.0e-9 model.add_design_var('x', lower=-50.0, upper=50.0) model.add_design_var('y', lower=-50.0, upper=50.0) model.add_objective('f_xy') prob.setup() prob.set_val('x', 50.0) prob.set_val('y', 50.0) prob.run_driver()Optimization terminated successfully. (Exit mode 0) Current function value: -27.33333333333333 Iterations: 3 Function evaluations: 4 Gradient evaluations: 3 Optimization Complete -----------------------------------print(prob.get_val('x'))[6.66666667]print(prob.get_val('y'))[-7.33333333]
ScipyOptimizeDriver Driver Specific Options¶
Optimizers in scipy.optimize.minimize have optimizer specific options. To let the user specify values for these options, OpenMDAO provides an option in the form of a dictionary named opt_settings. See the scipy.optimize.minimize documentation for more information about the driver specific options that are available.
As an example, here is code using some opt_settings for the shgo optimizer:
# Source of example: https://stefan-endres.github.io/shgo/ import numpy as np import openmdao.api as om size = 3 # size of the design variable def rastrigin(x): a = 10 # constant return np.sum(np.square(x) - a * np.cos(2 * np.pi * x)) + a * np.size(x) class Rastrigin(om.ExplicitComponent): def setup(self): self.add_input('x', np.ones(size)) self.add_output('f', 0.0) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): x = inputs['x'] outputs['f'] = rastrigin(x) prob = om.Problem() model = prob.model model.add_subsystem('rastrigin', Rastrigin(), promotes=['*']) prob.driver = driver = om.ScipyOptimizeDriver() driver.options['optimizer'] = 'shgo' driver.options['disp'] = False driver.opt_settings['maxtime'] = 10 # seconds driver.opt_settings['iters'] = 3 driver.opt_settings['maxiter'] = None model.add_design_var('x', lower=-5.12*np.ones(size), upper=5.12*np.ones(size)) model.add_objective('f') prob.setup() prob.set_val('x', np.ones(size)) prob.run_driver() print(prob.get_val('x'))[0. 0. 0.]print(prob.get_val('f'))[0.]
Notice that when using the shgo optimizer, setting the opt_settings[‘maxiter’] to None overrides ScipyOptimizeDriver’s options[‘maxiter’] value. It is not possible to set options[‘maxiter’] to anything other than an integer so the opt_settings[‘maxiter’] option provides a way to set the maxiter value for the shgo optimizer to None.