Search code examples
openmdao

Discrete Independent/Design Variables ? openmdao 2.2.0


One can determine the lower and upper bounds of the design variable e.g. within the paraboloid sample :

top.model.add_design_var('p1.x', lower=-50, upper=50)

but is it possible to force the optimizer to sweep the design variables with a user input step?

something like

top.model.add_design_var('p1.x', lower=-50, upper=50, increment=2)

or maybe introduce it as an array

top.model.add_design_var('p1.x', [-50,-25,25,50])

Solution

  • Using a gradient based optimizer that is not possible. You would need to use a gradient free method. As over OpenMDAO 2.2 there is not any built in way to enforce that kind of discretization. You would need to use an external loop around the problem class to get that to work.

    Here is a simple example:

    import numpy as np
    from openmdao.api import Problem, ScipyOptimizeDriver, ExecComp, IndepVarComp
    
    # build the model
    prob = Problem()
    indeps = prob.model.add_subsystem('indeps', IndepVarComp())
    indeps.add_output('x', 3.0)
    indeps.add_output('y', -4.0)
    
    prob.model.add_subsystem('paraboloid', ExecComp('f = (x-3)**2 + x*y + (y+4)**2 - 3'))
    
    prob.model.connect('indeps.x', 'paraboloid.x')
    prob.model.connect('indeps.y', 'paraboloid.y')
    
    # setup the optimization
    prob.driver = ScipyOptimizeDriver()
    prob.driver.options['optimizer'] = 'SLSQP'
    
    prob.model.add_design_var('indeps.y', lower=-50, upper=50)
    prob.model.add_objective('paraboloid.f')
    
    prob.setup()
    
    
    for x in np.arange(-10,12,2): 
        prob['indeps.x'] = x
    
        # could call just run_model if no optimization was desired
        #prob.run_model()
    
        # for each value of x, optimize for y
        prob.run_driver()
    
        # minimum value
        print(prob['paraboloid.f'])
    
        # location of the minimum
        print(prob['indeps.x'])
        print(prob['indeps.y'])