【发布时间】:2021-04-05 18:58:18
【问题描述】:
最近,我开始从事多学科设计优化领域的工作。我在 MDO 测试服中使用 OpenMDAO 框架对 Golinski 的减速器进行重量优化。我想为这个问题应用 MDF 架构。我指的是 Tedford 和 Martins 的论文“Benchmarking Multidisciplinary Design Optimization Algorithms”,用于问题的制定和分解。他们将这个问题分解为三个学科及其各自的约束条件。
在编码时,我参考了 OpenMDAO 文档中的卖方问题。我做了三个学科和一个组(speed_mda())来实现多学科分析。我在 speed_mda() 组中添加了目标函数和约束作为子系统。我已经将它们与学科输出(耦合变量)联系起来。但是我没有将这些限制应用于个别学科(实际上,我不知道该怎么做)。因此,我已将所有这些都应用于顶级组。我违反了一些约束,得到了输出 2713.678。
这是我的代码:
# Discipline 1
class speed_1(om.ExplicitComponent):
def setup(self):
self.add_input('z1', val = 0)
self.add_input('z2', val = 0)
self.add_output('y1', val = 1)
def setup_partials(self):
# Finite difference all partials.
self.declare_partials('*', '*', method='fd')
def compute(self,inputs,outputs):
outputs['y1'] = max(27/(inputs['z1']**2*(inputs['z2'])),397.5/(inputs['z1']**2*inputs['z2']**2), 5*inputs['z1'], 2.6)
# Discipline 2
class speed_2(om.ExplicitComponent):
def setup(self):
self.add_input('z1', val = 0)
self.add_input('z2', val = 0)
self.add_input('x21', val = 0)
self.add_output('y2', val = 0)
def setup_partials(self):
self.declare_partials('*', '*', method='fd')
def compute(self,inputs,outputs):
outputs['y2'] = max((1.93*inputs['x21']**3/(inputs['z1']*inputs['z2']))**0.25, 1/(0.5*(((1.69*10**7)**2)*inputs['x21']**2/(inputs['z1']**2*inputs['z2']**2) + 745)**0.5)**(0.3333), 2.9)
# Discipline 3
class speed_3(om.ExplicitComponent):
def setup(self):
self.add_input('z1', val = 0)
self.add_input('z2', val = 0)
self.add_input('x31', val = 0)
self.add_output('y3', val = 0)
def setup_partials(self):
self.declare_partials('*', '*', method='fd')
def compute(self,inputs,outputs):
outputs['y3'] = max((1.93*inputs['x31']**3/(inputs['z1']*inputs['z2']))**0.25, 1/(85*(((1.69*10**7)**2)*inputs['x31']**2/(inputs['z1']**2*inputs['z2']**2) + 1.575*(10**8))**0.5)**(0.3333), 5)
class speed_mda(om.Group):
def setup(self):
# Adding all discipline to MDA
cycle = self.add_subsystem('cycle',om.Group(),promotes_inputs=['z1', 'z2', 'x21', 'x31'])
cycle.add_subsystem('d1', speed_1(), promotes_inputs = ['z1', 'z2'])
cycle.add_subsystem('d2', speed_2(), promotes_inputs=['z1','z2', 'x21'])
cycle.add_subsystem('d3', speed_3(), promotes_inputs=['z1','z2', 'x31'])
# No need of connections for the discipline
cycle.set_input_defaults('x21', 7.8)
cycle.set_input_defaults('x31', 8.3)
cycle.set_input_defaults('z1', 0.75)
cycle.set_input_defaults('z2', 22.0)
# Add solver to MDA: Nonlinear Block Gauss Seidel is a gradient free solver
cycle.nonlinear_solver = om.NonlinearBlockGS()
# Adding obj. function and constraints as a subsystem
self.add_subsystem('obj_fun',om.ExecComp('obj = (0.7854*y1*z1**2)*(3.3333*z2**2+14.933*z2-43.0934) - 1.5079*y1*(y2**2+y3**2)+7.477*(y2**3+y3**3)+0.7854*(x21*y2**2+x31*y3**2)', z1=0.0,z2=0.0,x21=0.0,x31=0.0), promotes=['x21','x31','z2','z1','obj'])
self.add_subsystem('con1',om.ExecComp('c1 = z1*z2 - 40.0'), promotes=['c1']) # Global
self.add_subsystem('con10',om.ExecComp('c10 = y1 - 12.0*z1'), promotes=['c10']) # 1
self.add_subsystem('con11',om.ExecComp('c11 = y1 - 3.6'), promotes=['c11'])
self.add_subsystem('con12',om.ExecComp('c12 = y2 - 3.9'), promotes=['c12']) # 2
self.add_subsystem('con13',om.ExecComp('c13 = 2.85*y2 - x21'), promotes=['c13'])
self.add_subsystem('con14',om.ExecComp('c14 = y3 - 5.5'), promotes=['c14']) # 3
self.add_subsystem('con15',om.ExecComp('c15 = 2.09*y3 - x31'), promotes=['c15'])
# Connect outputs from MDA (coupled variables) to obj. function and constraints
self.connect('cycle.d1.y1',['obj_fun.y1','con10.y1','con11.y1'])
self.connect('cycle.d2.y2',['obj_fun.y2','con12.y2','con13.y2'])
self.connect('cycle.d3.y3',['obj_fun.y3','con14.y3','con15.y3'])
# Form topmost group (Problem) and add above MDF model to it
prob = om.Problem()
model = prob.model = speed_mda()
prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'
prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True
model.add_design_var('x21', lower=7.3, upper=8.3)
model.add_design_var('x31', lower=7.3, upper=8.3)
model.add_design_var('z1', lower=0.7, upper=0.8)
model.add_design_var('z2', lower=17.0, upper=28.0)
model.add_objective('obj')
model.add_constraint('c1', upper = 0)
model.add_constraint('c10',upper = 0)
model.add_constraint('c11',upper = 0)
model.add_constraint('c12',upper = 0)
model.add_constraint('c13',upper = 0)
model.add_constraint('c14',upper = 0)
model.add_constraint('c15',upper = 0)
prob.model.approx_totals()
prob.setup()
prob.set_solver_print(level=0)
prob.set_val('x21', 7.8)
prob.set_val('x31', 8.3)
prob.set_val('z1', 0.75)
prob.set_val('z2', 22.0)
prob.run_model()
prob.run_driver()
print('minimum found at')
print((prob.get_val('z1')[0],prob.get_val('z2')[0],prob.get_val('x21')[0],prob.get_val('x31')[0],prob.get_val('cycle.d1.y1')[0], prob.get_val('cycle.d2.y2')[0],prob.get_val('cycle.d3.y3')[0]))
print('minumum objective')
print(prob.get_val('obj')[0])
我得到以下输出:
Positive directional derivative for linesearch (Exit mode 8)
Current function value: [2713.67806668]
Iterations: 8
Function evaluations: 4
Gradient evaluations: 4
Optimization FAILED.
Positive directional derivative for linesearch
-----------------------------------
minimum found at
(0.7, 17.00007920093152, 7.300007915120889, 7.300015825246984, 3.5, 2.9, 5.0)
minumum objective
2713.6780666813797
这里,目标值远小于实际值,表示优化失败。我寻找上述错误,但我最初的猜测是在界限内。我的所有问题约束都不满足。我也尝试对个别学科施加限制,但我做不到。我不知道实际问题是什么,可能我犯了一些基本的概念错误。谁能帮我解决这个问题。
【问题讨论】:
标签: openmdao