我正在尝试为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,只是为了让我更容易。
谢谢!
答案 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