Dymos技术问询:如何在Phase层约束ODE组的静态输出变量
在Phase层面约束ODESystem内标量输出的解决方案
以下几种方法可实现需求,同时保留Weight组件在ODESystem内(或合理关联):
方法1:将标量输出包装为零导数状态变量
因为W是不随时间变化的标量,可在ODESystem里把它定义为状态变量,同时设置零时间导数,让Phase能识别并添加边界约束:class ODESystem(om.Group): def setup(self): self.add_subsystem(name='weight', subsys=Weight(), promotes_output=['W']) # 绑定W到状态变量,指定零导数源 self.add_state('W_constraint', val=0.0, rate_source='weight.dW_dt') class Weight(om.ExplicitComponent): def setup(self): self.add_input('design_dim', val=1.0) # 设计变量 self.add_output('W', val=0.0) self.add_output('dW_dt', val=0.0) # 零导数输出 def compute(self, inputs, outputs): outputs['W'] = 0.5 * inputs['design_dim'] ** 3 # 自定义重量计算逻辑 outputs['dW_dt'] = 0.0 # 标量无时间变化率 # Phase层面添加约束 phase = dm.Phase(ode_class=ODESystem, ...) # 约束初始/末端节点均可,因状态变量值全程不变 phase.add_boundary_constraint('W_constraint', loc='initial', upper=4.0)方法2:利用路径约束的广播参数(Dymos 1.7+)
直接使用add_path_constraint,通过ref参数将标量W广播到配点节点维度,绕过维度检查:class ODESystem(om.Group): def setup(self): self.add_subsystem(name='weight', subsys=Weight(), promotes_output=['W']) # Phase层面添加约束 phase = dm.Phase(ode_class=ODESystem, ...) # 用ref参数将标量广播到配点节点维度 phase.add_path_constraint('W', upper=4.0, ref=np.ones(phase.num_nodes))由于
W是标量,所有节点上的值完全相同,约束路径上任意节点等价于约束该标量本身。方法3:将Weight设为Phase外部子系统
若不想修改原ODESystem,可把Weight组件作为外部子系统挂载到Phase,直接约束其输出:phase = dm.Phase(ode_class=ODESystem, ...) # 添加外部子系统,关联设计变量 phase.add_external_subsystem('weight', subsys=Weight(), inputs={'design_dim': 'des_vars.design_dim'}, outputs=['W']) # 直接约束外部子系统的输出 phase.add_constraint('weight.W', upper=4.0)
内容的提问来源于stack exchange,提问作者HMCheong
相关产品推荐
相关产品推荐

