You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SubmodelComp能否自带Driver?OpenMDAO使用疑问与异常排查

关于OpenMDAO SubmodelComp的用法与问题分析

核心疑问

我正在研究OpenMDAO的SubmodelComp,想确认其正确用法:SubmodelComp是否可以拥有自己的Driver和优化器? 我的应用场景是子模型采用基于梯度的优化,顶层问题使用无梯度优化器处理子问题的离散变量输入,无需获取子模型的梯度。

测试案例与结果

1. 无输入测试案例

import openmdao.api as om

sub_prob = om.Problem()

sub_prob.model.add_subsystem("paraboloid", om.ExecComp("f = (x-3)**2 + x*y + (y+4)**2 - 3"))

sub_prob.driver = om.ScipyOptimizeDriver()
sub_prob.driver.options["optimizer"] = "SLSQP"

sub_prob.model.add_design_var("paraboloid.x", lower=-50, upper=50)
sub_prob.model.add_design_var("paraboloid.y", lower=-50, upper=50)
sub_prob.model.add_objective("paraboloid.f")

top_prob = om.Problem()
submodel = om.SubmodelComp(problem=sub_prob, outputs=[("paraboloid.f", "g")])
top_prob.model.add_subsystem("submodel", submodel, promotes=["*"])
top_prob.setup()
top_prob.run_model()

print(sub_prob.get_val("paraboloid.f"))
print(sub_prob.get_val("paraboloid.x"))
print(sub_prob.get_val("paraboloid.y"))

输出符合预期:

Optimization terminated successfully    (Exit mode 0)
            Current function value: -27.333333074220675
            Iterations: 6
            Function evaluations: 6
            Gradient evaluations: 6
Optimization Complete
-----------------------------------
[-27.33333307]
[6.66712855]
[-7.33324946]

2. 添加输入后的测试案例

import openmdao.api as om

sub_prob = om.Problem()

# modify paraboloid eqn with parameter "a"
sub_prob.model.add_subsystem("paraboloid", om.ExecComp("f = (x-3)**2 + x*y + (y+4)**2 + a"))

sub_prob.driver = om.ScipyOptimizeDriver()
sub_prob.driver.options["optimizer"] = "SLSQP"

sub_prob.model.add_design_var("paraboloid.x", lower=-50, upper=50)
sub_prob.model.add_design_var("paraboloid.y", lower=-50, upper=50)
sub_prob.model.add_objective("paraboloid.f")

top_prob = om.Problem()
submodel = om.SubmodelComp(problem=sub_prob, inputs=[("paraboloid.a", "a")], outputs=[("paraboloid.f", "g")])
top_prob.model.add_subsystem("submodel", submodel, promotes=["*"])
top_prob.setup()
top_prob.set_val("a", val=-3)

top_prob.run_model()

print(sub_prob.get_val("paraboloid.f"))
print(sub_prob.get_val("paraboloid.x"))
print(sub_prob.get_val("paraboloid.y"))

优化失败:

Inequality constraints incompatible    (Exit mode 4)
            Current function value: -1e+30
            Iterations: 49
            Function evaluations: 49
            Gradient evaluations: 49
Optimization FAILED.
Inequality constraints incompatible
-----------------------------------
[-1.e+30]
[-50.]
[-50.]

3. 修改方程后的测试

将抛物面方程改为f = (x-3)**2 + x*y + (y+4)**2 + a -a,优化成功但出现警告:

Optimization terminated successfully    (Exit mode 0)
            Current function value: -24.333333074220675
            Iterations: 6
            Function evaluations: 6
            Gradient evaluations: 6
Optimization Complete
-----------------------------------
[-24.33333307]
[6.66712855]
[-7.33324946]
.......\openmdao\core\total_jac.py:1788: DerivativesWarning:Design variables [('paraboloid.a', inds=[0])] have no impact on the constraints or objective.

问题原因分析

SubmodelComp支持绑定自身的Driver,上述问题既不是功能不支持也不是程序bug,而是子问题的优化逻辑与输入参数的交互存在错误:

  1. 无输入测试成功的原因:子问题的设计变量(x、y)与目标函数逻辑自洽,存在有限最小值,SLSQP能正常找到最优解,SubmodelComp触发子问题Driver执行优化的流程完全正常。

  2. 添加输入后优化失败的原因:目标函数f = (x-3)**2 + x*y + (y+4)**2 + a在x、y取边界值-50时,函数值会无限趋近负无穷,SLSQP优化器试图突破边界最小化目标,但被设计变量的上下限约束限制,最终判定约束与目标无法兼容,导致优化失败。

  3. 修改方程后警告的原因:修改后的方程中a被抵消,子问题的目标函数与a无关,但OpenMDAO检测到a作为子问题的输入变量,却未对约束或目标产生任何影响,因此抛出警告提示该变量无效。

正确用法建议

  • 确保子问题的目标函数在设计变量的边界范围内存在有限最小值,避免优化器试图突破边界无限优化。
  • 子问题中的输入参数(如a)无需设为设计变量,仅通过SubmodelComp的inputs参数传递即可,避免无效变量警告。
  • 你的应用场景(子模型梯度优化+顶层无梯度优化)完全可行,只要保证子问题的优化逻辑自洽,顶层传入参数后,子问题能正确执行优化并返回结果。

内容的提问来源于stack exchange,提问作者Mark Garnett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:48:19