计算雅可比矩阵时如何禁用非活跃输入输出变量?
在OpenMDAO中避免非活跃输出触发冗余梯度计算的方法
针对你遇到的风电涡轮机转子求解器在不同优化场景下存在冗余梯度计算的问题,以下是几种无需动态修改组件输入输出结构的解决方案:
1. 问题层面控制输出的Promotion
在组装优化问题时,仅promote当前场景下需要的输出变量,未被promote的输出不会被OpenMDAO纳入梯度计算流程。
以你的RotorSolver组件为例,针对优化问题2(仅最大化功率):
prob = Problem() # 仅promote需要的输入和输出,不包含Cl prob.model.add_subsystem('rotor', RotorSolver(), promotes=['c', 't', 'P']) # 定义目标和设计变量 prob.model.add_objective('P') prob.model.add_design_var('c') prob.model.add_design_var('t')
这种方式完全在问题层面配置,组件本身无需修改,可读性和维护性都很好。
2. 组件层面通过选项控制输出活跃状态
在组件定义时,给非必要输出添加可配置的active选项,实例化组件时根据场景决定是否激活该输出:
class RotorSolver(ExplicitComponent): def initialize(self): self.options.declare('activate_cl', types=bool, default=True) def setup(self): # 添加输入 self.add_input('c', shape=n_span) self.add_input('t', shape=n_span) # 添加输出,根据选项控制活跃状态 self.add_output('P') self.add_output('Cl', shape=n_span, active=self.options['activate_cl']) # 计算逻辑和AD梯度定义...
针对优化问题2,实例化组件时关闭Cl的激活:
prob.model.add_subsystem('rotor', RotorSolver(activate_cl=False), promotes=['*'])
该方法将配置逻辑封装在组件选项中,既保留了组件复用性,又能灵活控制输出是否参与计算。
3. 手动声明非依赖的偏导数对
如果组件已经固定,可在问题层面通过declare_partials手动标记不需要计算的偏导数对,设置dependent=False来跳过这些梯度的计算:
prob = Problem() prob.model.add_subsystem('rotor', RotorSolver(), promotes=['*']) # 标记Cl与c、t的偏导为非依赖,AD不会计算这些项 prob.model.declare_partials('Cl', ['c', 't'], dependent=False) # 定义目标和设计变量...
这种方法适合临时调整特定问题的梯度计算范围,无需修改组件代码。
内容的提问来源于stack exchange,提问作者Kenneth Lønbæk
相关产品推荐
相关产品推荐

