在 Openmdao 中使用 ExternalCodeComp 的问题

Problem using ExternalCodeComp in Openmdao

我正在尝试在 openmdao docs.

中给出的 ExternalCodeComp 示例问题

优化代码为

import openmdao.api as om
from openmdao.components.tests.test_external_code_comp import ParaboloidExternalCodeCompFD

prob = om.Problem()
model = prob.model

model.add_subsystem('p', ParaboloidExternalCodeCompFD(), promotes_inputs=['x', 'y'])

# find optimal solution with SciPy optimize
# solution (minimum): x = 6.6667; y = -7.3333
prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'

prob.model.add_design_var('p.x', lower=-50, upper=50)
prob.model.add_design_var('p.y', lower=-50, upper=50)

prob.model.add_objective('p.f_xy')

prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True

prob.setup()

# Set input values
prob.set_val('p.x', 3.0)
prob.set_val('p.y', -4.0)

prob.run_driver()
print(prob.get_val('p.x'))
print(prob.get_val('p.y'))

但是,我在 prob.setup() 处收到以下错误。

Exception has occurred: RuntimeError
Group (<model>): Output not found for design variable 'p.x'.

这是什么意思?我不知道我是否缺少一些基本的东西。只有当我尝试优化它时才会出现问题。当我只在模型中使用外部代码时没有问题(如文档中所示)。

在这一行中,您提升了输入 xy

model.add_subsystem('p', ParaboloidExternalCodeCompFD(), promotes_inputs=['x', 'y'])

注意你没有提升输出f_xy

所以从模型的顶层开始,正确的路径是: p.f_xy 用于输出,但 xy 用于输入。

因此,添加设计变量和设置值的正确方法是使用 xy

import openmdao.api as om
from openmdao.components.tests.test_external_code_comp import ParaboloidExternalCodeCompFD

prob = om.Problem()
model = prob.model

model.add_subsystem('p', ParaboloidExternalCodeCompFD(), promotes_inputs=['x', 'y'])

# find optimal solution with SciPy optimize
# solution (minimum): x = 6.6667; y = -7.3333
prob.driver = om.ScipyOptimizeDriver()
prob.driver.options['optimizer'] = 'SLSQP'

prob.model.add_design_var('x', lower=-50, upper=50)
prob.model.add_design_var('y', lower=-50, upper=50)

prob.model.add_objective('p.f_xy')

prob.driver.options['tol'] = 1e-9
prob.driver.options['disp'] = True

prob.setup()

# Set input values
prob.set_val('x', 3.0)
prob.set_val('y', -4.0)

prob.run_driver()
print(prob.get_val('x'))
print(prob.get_val('y'))