Source code for openmdao.examples.subproblem_example

import sys
from math import pi

from openmdao.api import Problem, Group, Component, IndepVarComp, ExecComp, \
                         ScipyOptimizer, SubProblem, CaseDriver


class MultiMinGroup(Group):
[docs] """ In the range -pi <= x <= pi function has 2 local minima, one is global global min is: f(x) = -1.31415926 at x = pi local min at: f(x) = -0.69084489952 at x = -3.041593 """ def __init__(self): super(MultiMinGroup, self).__init__() self.add('indep', IndepVarComp('x', 0.0)) self.add("comp", ExecComp("fx = cos(x)-x/10.")) self.connect("indep.x", "comp.x") def main(num_par_doe):
[docs] # First, define a Problem to be able to optimize our function. sub = Problem(root=MultiMinGroup()) # set up our SLSQP optimizer sub.driver = subdriver = ScipyOptimizer() subdriver.options['optimizer'] = 'SLSQP' subdriver.options['disp'] = False # disable optimizer output # In this case, our design variable is indep.x, which happens # to be connected to the x parameter on our 'comp' component. subdriver.add_desvar("indep.x", lower=-pi, upper=pi) # We are minimizing comp.fx, so that's our objective. subdriver.add_objective("comp.fx") # Now, create our top level problem prob = Problem(root=Group()) prob.root.add("top_indep", IndepVarComp('x', 0.0)) # add our subproblem. Note that 'indep.x' is actually an unknown # inside of the subproblem, but outside of the subproblem we're treating # it as a parameter. prob.root.add("subprob", SubProblem(sub, params=['indep.x'], unknowns=['comp.fx'])) prob.root.connect("top_indep.x", "subprob.indep.x") # use a CaseDriver as our top level driver so we can run multiple # separate optimizations concurrently. We'll run 'num_par_doe' # concurrent cases. In this case we need no more than 2 because # we're only running 2 total cases. prob.driver = CaseDriver(num_par_doe=num_par_doe) prob.driver.add_desvar('top_indep.x') prob.driver.add_response(['subprob.indep.x', 'subprob.comp.fx']) # these are the two cases we're going to run. The top_indep.x values of # -1 and 1 will end up at the local and global minima when we run the # concurrent subproblem optimizers. prob.driver.cases = [ [('top_indep.x', -1.0)], [('top_indep.x', 1.0)] ] prob.setup(check=False) # run the concurrent optimizations prob.run() # collect responses for all of our input cases optvals = [dict(resp) for resp, success, msg in prob.driver.get_responses()] # find the minimum value of subprob.comp.fx in our responses global_opt = sorted(optvals, key=lambda x: x['subprob.comp.fx'])[0] return global_opt if __name__ == '__main__':
global_opt = main(2) print("\nGlobal optimum:\n subprob.comp.fx = %s at subprob.indep.x = %s" % (global_opt['subprob.comp.fx'], global_opt['subprob.indep.x']))