非对称子空间优化(ASO)

时间:2018-04-03 01:25:02

标签: openmdao

我正在尝试为Sellar问题实施ASO,但“子问题”无法正常工作。我不知道如何解决这个问题。

虽然Sellar问题不是理解ASO架构的好例子(两个学科的计算成本几乎相同),但它是一个简单的公式,我在尝试使用问题之前将其用作基准测试我在学习。 我的代码是(OpenMDAO 1.7):

class low_order(Group):

 def __init__(self):
    super(low_order, self).__init__()

    self.add('plx', IndepVarComp('x', 1.0), promotes=['x'])
    self.add('plz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z'])


    self.add('d1', SellarDis1(), promotes=['x', 'z', 'y1', 'y2'])
    #self.add('d2', SellarDis2(), promotes=['z', 'y1', 'y2'])

    self.add('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)',
                                 z=np.array([0.0, 0.0]) ),
             promotes=['obj', 'x', 'z', 'y1', 'y2'])

    self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])


    self.deriv_options['type'] = 'fd'
    self.deriv_options['form'] = 'central'  


class SellarDerivatives(Group):


 def __init__(self):
    super(SellarDerivatives, self).__init__()

    self.add('ppx', IndepVarComp('x', 1.0), promotes=['x'])
    self.add('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z'])


    self.add('d2', SellarDis2(), promotes=['z', 'y1', 'y2'])

    self.add('obj_cmp1', ExecComp('obj1 = x**2 + z[1] + y1 + exp(-y2)',
                                 z=np.array([0.0, 0.0]) ),
             promotes=['obj1', 'x', 'z', 'y1', 'y2'])

    #self.add('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1'])
    self.add('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2'])

    self.nl_solver = NLGaussSeidel()
    self.nl_solver.options['atol'] = 1.0e-12
    self.ln_solver = ScipyGMRES()


    self.deriv_options['type'] = 'fd'
    self.deriv_options['form'] = 'central'


if __name__ == '__main__':

from openmdao.api import Problem, ScipyOptimizer, SqliteRecorder



sub = Problem()
sub.root = low_order()
sub.driver =ScipyOptimizer()# pyOptSparseDriver()
sub.driver.options['optimizer'] = 'SLSQP'
sub.driver.options['disp'] = False


sub.driver.add_desvar('x', lower=0.0, upper=10.0)

sub.driver.add_objective('obj')
sub.driver.add_constraint('con1', upper=0.0)
#sub.driver.add_constraint('con2', upper=0.0)



top = Problem()
top.root = SellarDerivatives()

top.driver = ScipyOptimizer()#pyOptSparseDriver()
top.driver.options['optimizer'] = 'SLSQP'



top.driver.add_desvar('z', lower=np.array([-10.0, 0.0]),
                     upper=np.array([10.0, 10.0]))


top.root.add('subprob1', SubProblem(sub, params=['z'],unknowns=['y1','x'])) 


top.root.connect('z','subprob1.z')



top.driver.add_objective('obj1')
#top.driver.add_constraint('con1', upper=0.0)
top.driver.add_constraint('con2', upper=0.0)


top.setup()
top.run()

当我查看迭代时,我看到只有Z1和Z2正如我预期的那样变化,我不知道X. 以下行是:X | Z1 | Z2

(8.881784197001252e-16, 5.000916977558285, 1.000912901563544)
(1.0000000008881784e-06, 5.000916977558285, 1.000912901563544)
(-9.999999991118215e-07, 5.000916977558285, 1.000912901563544)
(8.881784197001252e-16, 5.000912478379066, 1.0009120015635442)
(8.881784197001252e-16, 5.000912478379066, 1.0009120015635442)
(1.0000000008881784e-06, 5.000912478379066, 1.0009120015635442)
(-9.999999991118215e-07, 5.000912478379066, 1.0009120015635442)

最后的答案是(Z1,Z2,X):

Minimum found at (5.000912, 1.000912, 1.000000)
Coupling vars: 0.000000, 6.001824
('Minimum objective: ', 2.0033861370124493)

聚苯乙烯。由于Sellar问题不是我的主要目标,我在整个模型中使用FD,只是为了让我更容易。

谢谢!

1 个答案:

答案 0 :(得分:1)

我对此进行了一些更改(它对您发送的代码没有任何作用,但我们可能会收紧1.7和1.7.3之间的错误检查。)

您需要将y2传递给子问题才能完成循环:

top.root.add('subprob1', SubProblem(sub, params=['z', 'y2'], unknowns=['y1', 'x']), promotes=['*'])

你需要删除额外的IndepVarComp for variable' x'在顶部" SellarDerivatives"因为你让子问题成为最终来源。

#self.add('ppx', IndepVarComp('x', 1.0), promotes=['x'])

通过这些更改并使用pyoptsparse,我得到了sub:

Objectives:
    Name        Value        Optimum
    obj        3.18339             0

Variables (c - continuous, i - integer, d - discrete):
       Name      Type       Value       Lower Bound  Upper Bound
    x_0       c       0.000004       0.00e+00     1.00e+01 

主要问题:

Objectives:
    Name        Value        Optimum
    obj1       3.18339             0

Variables (c - continuous, i - integer, d - discrete):
       Name      Type       Value       Lower Bound  Upper Bound
    z_0       c       1.977638      -1.00e+01     1.00e+01 
    z_1       c       0.000000       0.00e+00     1.00e+01