OpenMDAO子迭代优化报错:Constraints or objectives cannot be impacted by the design variables of the problem 求助
OpenMDAO子迭代优化报错:Constraints or objectives cannot be impacted by the design variables of the problem 求助
嘿,我太懂你这种憋屈的感觉了——明明手动验证了数值、把偏导和总导都查了个遍,结果还是弹出这个“约束/目标不受问题设计变量影响”的报错,简直让人挠头!
结合你描述的场景和给出的compute_totals结果(能看到figure_of_merit_hvr确实对omega_hvr和collective_hvr有非零导数),问题大概率出在子迭代的结构设计、变量作用域或者导数链路的传播上,给你几个具体的排查方向:
- 检查子迭代的实现方式:你是用OpenMDAO官方的
SubProblem组件封装悬停优化,还是手动嵌套了另一个Problem实例?如果是手动嵌套的话,外层主问题根本无法识别内层子问题的设计变量和目标之间的依赖关系,导数也不会自动传播,这时候就会触发这个报错。建议换成SubProblem来封装悬停优化,让OpenMDAO自动处理导数链路。 - 核对变量路径的正确性:你在声明设计变量、目标的时候,变量的全路径(比如
'volume_constraint_comp.figure_of_merit_hvr')是不是在当前问题的作用域内?尤其是嵌套结构里,很容易出现命名空间混淆,比如子问题里的变量没正确promote到外层,或者路径写错导致外层找不到变量。可以用problem.list_inputs()和problem.list_outputs()分别打印主/子问题的变量列表,确认目标变量和设计变量的路径完全匹配。 - 验证导数链路的完整性:运行
problem.check_setup()工具,它会帮你自动检查变量连接、导数路径的问题,很多时候会给出具体的警告提示(比如某个变量没有连接到上游,或者导数路径断裂)。另外,也可以用compute_totals在完整的主问题层面计算目标对设计变量的导数,而不是只在子问题里单独计算——如果主问题层面的导数为零,那说明链路没打通。 - 排查子迭代的逻辑顺序:如果是手动实现的循环式子迭代,有没有确保每次子迭代前,子问题的输入参数已经正确更新?比如有没有不小心把悬停组件的输入固定死,导致设计变量变化时目标函数完全没反应?可以在子迭代里加个打印,每次修改
omega_hvr和collective_hvr后,输出figure_of_merit_hvr的数值,确认它确实会跟着变化。
举个简单的SubProblem使用示例,你可以参考下:
from openmdao.components.subproblem import SubProblem # 定义悬停优化的子问题模型 def create_hover_subproblem(): prob = Problem() prob.model.add_subsystem('hover_comp', HoverComponent()) prob.driver = ScipyOptimizeDriver() prob.driver.declare_objective('hover_comp.figure_of_merit_hvr') prob.driver.declare_desvar('hover_comp.omega_hvr') prob.driver.declare_desvar('hover_comp.collective_hvr') # 加上悬停相关的约束 prob.driver.declare_constraint('hover_comp.some_constraint', lower=0) prob.setup() return prob # 主问题 main_prob = Problem() # 添加巡航相关组件 main_prob.model.add_subsystem('cruise_comp', CruiseComponent()) # 添加悬停子问题组件 main_prob.model.add_subsystem('hover_subprob', SubProblem(create_hover_subproblem(), promotes_inputs=['cruise_comp.chord_dist', 'cruise_comp.twist_dist'], promotes_outputs=['hover_comp.figure_of_merit_hvr'])) # 主问题的目标和约束 main_prob.driver.declare_objective('cruise_comp.efficiency') main_prob.driver.declare_constraint('hover_subprob.figure_of_merit_hvr', lower=0.7) main_prob.setup() main_prob.run_driver()
这种方式下,OpenMDAO能自动处理子问题的导数传播,避免手动嵌套带来的链路断裂问题。
备注:内容来源于stack exchange,提问作者Lenny Lopes
相关产品推荐
相关产品推荐

