An almost similar question was asked but subproblem class was implemented in OpenMDAO to tackle this issue but does not seem to work in my case
I am trying to solve Sellar in CO architecture , starting from subproblem example on 1.7.3 version and sellar classes It runs but it doesn't converge. My guess is that it is coming from initial value of each optimization (always restarting from "cold" start)
If anyone can help, i would be gratful ! here is the code (I guess I could have made it more compact using promotes of variables but I was a bit afraid to get lost for debug :-))
class CO1(Group):
"""
"""
def __init__(self):
super(CO1, self).__init__()
self.add('indep1x', IndepVarComp('x', 0.0))
self.add('indep1z', IndepVarComp('z', np.array([5.0, 2.0])))
self.add('indep1y2', IndepVarComp('y2', 10.0))
self.add('indep1zt', IndepVarComp('zt', np.array([5.0, 2.0])))
self.add('indep1xt', IndepVarComp('xt', 0.0))
self.add('indep1y2t', IndepVarComp('y2t', 10.0))
self.add('indep1y1t', IndepVarComp('y1t', 10.0))
self.add('d1', SellarDis1withDerivatives())
self.connect('indep1z.z', 'd1.z')
self.connect('indep1x.x', 'd1.x')
self.connect('indep1y2.y2', 'd1.y2')
self.add('obj1',ExecComp('obj1 = (zt[0] - z[0])**2 +(zt[1] - z[1])**2 + (xt - x)**2 +(y1t - y1)**2 + (y2t - y2)**2'
, z=np.array([5.0, 2.0]),zt=np.array([0.0, 0.0]), x=0.0, y1=10.0, y2=10.0,xt=0.0, y1t=10.0, y2t=10.0), promotes=['obj1'])
self.connect('d1.z','obj1.z')
self.connect('d1.x','obj1.x')
self.connect('d1.y2','obj1.y2')
self.connect('d1.y1','obj1.y1')
self.connect('indep1zt.zt', "obj1.zt")
self.connect('indep1xt.xt', "obj1.xt")
self.connect('indep1y2t.y2t', "obj1.y2t")
self.connect('indep1y1t.y1t', "obj1.y1t")
self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1'])
self.connect('d1.y1', 'con_cmp1.y1')
class CO2(Group):
"""
"""
def __init__(self):
super(CO2, self).__init__()
self.add('indep2z', IndepVarComp('z', np.array([5.0, 2.0])))
self.add('indep2y1', IndepVarComp('y1', 10.0))
self.add('indep2zt', IndepVarComp('zt', np.array([5.0, 2.0])))
self.add('indep2y2t', IndepVarComp('y2t', 10.0))
self.add('indep2y1t', IndepVarComp('y1t', 10.0))
self.add('d2', SellarDis2withDerivatives())
self.connect("indep2z.z", "d2.z")
self.connect("indep2y1.y1", "d2.y1")
self.add('obj2',ExecComp('obj2 = (zt[0] - z[0])**2 +(zt[1] - z[1])**2 + (y1t - y1)**2 +(y2t - y2)**2'
,z=np.array([5.0, 2.0]),zt=np.array([0.0, 0.0]), y1=10.0, y2=10.0, y1t=10.0, y2t=10.0), promotes=['obj2'] )
self.connect('d2.z','obj2.z')
self.connect('d2.y2','obj2.y2')
self.connect('d2.y1','obj2.y1')
self.connect("indep2zt.zt", "obj2.zt")
self.connect("indep2y2t.y2t", "obj2.y2t")
self.connect("indep2y1t.y1t", "obj2.y1t")
self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2'])
self.connect('d2.y2', 'con_cmp2.y2')
#######################################
CO test case
#
################################################
# First, define a Problem to be able to optimize Discipline 1.
################################################
sub1 = Problem(root=CO1())
# set up our SLSQP optimizer
sub1.driver = ScipyOptimizer()
sub1.driver.options['optimizer'] = 'SLSQP'
#sub1.driver.options['disp'] = False # disable optimizer output
sub1.driver.add_desvar("indep1z.z", lower=np.array([-10.0,0.0]), upper=np.array([10.0,10.0]))
sub1.driver.add_desvar("indep1x.x", lower=0.0, upper=10.0)
sub1.driver.add_desvar("indep1y2.y2", lower=-100.0, upper=100.0)
# We are minimizing comp.fx, so that's our objective.
sub1.driver.add_objective("obj1")
sub1.driver.add_constraint('con1', upper=0.0)
################################################
# Second, define a Problem to be able to optimize Discipline 2.
################################################
sub2 = Problem(root=CO2())
# set up our SLSQP optimizer
sub2.driver = ScipyOptimizer()
sub2.driver.options['optimizer'] = 'SLSQP'
#sub2.driver.options['disp'] = False # disable optimizer output
sub2.driver.add_desvar("indep2z.z", lower=np.array([-10.0,0.0]), upper=np.array([10.0,10.0]))
sub2.driver.add_desvar("indep2y1.y1", lower=-100.0, upper=100.0)
# We are minimizing comp.fx, so that's our objective.
sub2.driver.add_objective("obj2")
sub2.driver.add_constraint('con2', upper=0.0)
################################################
# Thirs, create our top level problem
################################################
prob = Problem(root=Group())
prob.root.add("top_indepxt", IndepVarComp('xt', 0.0))
prob.root.add("top_indepzt", IndepVarComp('zt', np.array([5.0, 2.0])))
prob.root.add("top_indepy1t", IndepVarComp('y1t', 10.0))
prob.root.add("top_indepy2t", IndepVarComp('y2t', 10.0))
prob.root.add("subprob1", SubProblem(sub1, params=['indep1z.z','indep1x.x','indep1y2.y2','indep1xt.xt','indep1zt.zt','indep1y1t.y1t','indep1y2t.y2t'],
unknowns=['obj1','con1' ,'d1.y1']))
prob.root.add("subprob2", SubProblem(sub2, params=['indep2z.z','indep2y1.y1','indep2zt.zt','indep2y1t.y1t','indep2y2t.y2t'],
unknowns=['obj2','con2','d2.y2' ]))
prob.root.connect("top_indepxt.xt", "subprob1.indep1xt.xt")
prob.root.connect("top_indepzt.zt", "subprob1.indep1zt.zt")
prob.root.connect("top_indepy1t.y1t", "subprob1.indep1y1t.y1t")
prob.root.connect("top_indepy2t.y2t", "subprob1.indep1y2t.y2t")
prob.root.connect("top_indepzt.zt", "subprob2.indep2zt.zt")
prob.root.connect("top_indepy1t.y1t", "subprob2.indep2y1t.y1t")
prob.root.connect("top_indepy2t.y2t", "subprob2.indep2y2t.y2t")
prob.driver=ScipyOptimizer()
prob.driver.options['optimizer']='SLSQP'
prob.driver.add_desvar('top_indepzt.zt', lower=np.array([-10.0,0.0]), upper=np.array([10.0,10.0]))
prob.driver.add_desvar('top_indepxt.xt',lower=0.0, upper=10.0)
prob.driver.add_desvar('top_indepy1t.y1t',lower=-100.0, upper=100.0)
prob.driver.add_desvar('top_indepy2t.y2t',lower=-100.0, upper=100.0)
prob.root.add('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
z=np.array([5.0, 2.0]), x=0.0),
promotes=['obj'])
prob.root.connect("top_indepzt.zt", "obj_cmp.z")
prob.root.connect("top_indepxt.xt", "obj_cmp.x")
prob.root.connect("top_indepy1t.y1t", "obj_cmp.y1")
prob.root.connect("top_indepy2t.y2t", "obj_cmp.y2")
prob.driver.add_objective('obj')
prob.root.add('con1_cmpt',ExecComp('con1t = (zt[0] - z[0])**2 +'
'(zt[1] - z[1])**2 + '
'(xt - x)**2 + '
'(y1t - y1)**2 + '
'(y2t - y2)**2', z=np.array([5.0, 2.0]),zt=np.array([5.0, 2.0]), x=0.0, y1=10.0, y2=10.0,xt=0.0, y1t=10.0, y2t=10.0), promotes=['con1t'])
prob.root.connect("top_indepzt.zt", "con1_cmpt.zt")
prob.root.connect("top_indepxt.xt", "con1_cmpt.xt")
prob.root.connect("top_indepy1t.y1t", "con1_cmpt.y1t")
prob.root.connect("top_indepy2t.y2t", "con1_cmpt.y2t")
prob.root.connect("subprob1.indep1z.z", "con1_cmpt.z")
prob.root.connect("subprob1.indep1x.x", "con1_cmpt.x")
prob.root.connect("subprob1.d1.y1", "con1_cmpt.y1")
prob.root.connect("subprob1.indep1y2.y2", "con1_cmpt.y2")
prob.driver.add_constraint('con1t', upper=0.0)
prob.root.add('con2_cmpt',ExecComp('con2t = (zt[0] - z[0])**2 +'
'(zt[1] - z[1])**2 + '
'(xt - x)**2 + '
'(y1t - y1)**2 + '
'(y2t - y2)**2', z=np.array([5.0, 2.0]),zt=np.array([5.0, 2.0]), x=0.0, y1=10.0, y2=10.0,xt=0.0, y1t=0.0, y2t=10.0), promotes=['con2t'])
prob.root.connect("top_indepzt.zt", "con2_cmpt.zt")
prob.root.connect("top_indepy1t.y1t", "con2_cmpt.y1t")
prob.root.connect("top_indepy2t.y2t", "con2_cmpt.y2t")
prob.root.connect("subprob2.indep2z.z", "con2_cmpt.z")
prob.root.connect("subprob2.indep2y1.y1", "con2_cmpt.y1")
prob.root.connect("subprob2.d2.y2", "con2_cmpt.y2")
prob.driver.add_constraint('con2t', upper=0.0)
prob.setup()
# run the concurrent optimizations
prob.run()
print("\n")
print("Design var at convergence (%f,%f,%f)"% (prob['top_indepzt.zt'][0],prob['top_indepzt.zt'][1],prob['top_indepxt.xt']))
print("Coupling var at convergence (%f,%f) "% (prob['top_indepy1t.y1t'],prob['top_indepy2t.y2t']))
print("Objective and constraints at (%f, %f,%f)"% (prob['obj'],prob['con1t'],prob['con2t']))
print("Sub1 : Design var at convergence (%f,%f,%f)"% (prob['subprob1.indep1z.z'][0],prob['subprob1.indep1z.z'][1],prob['subprob1.indep1x.x']))
print("Sub2 : Design var at convergence (%f,%f)"% (prob['subprob2.indep2z.z'][0],prob['subprob2.indep2z.z'][1]))