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

Dymos/OpenMDAO仿真高压瓶排液时Vb参数无效报错求助

Dymos高压瓶排液仿真报错修复方案

核心报错根因

报错提示找不到pressure_rate.Vb输入,是因为你在BottleModelODE组组件中通过promotes_inputs将pressure_rate子系统的Vb、p等输入提升到了ODE组的顶层命名空间,此时这些输入的访问路径不再带子系统前缀,直接以变量名存在于ODE组层级,原代码中写的带前缀的target路径自然无法匹配到对应输入。

全量修复点

  • 修正状态、参数的target路径:所有被promote到组顶层的变量,target直接写变量名即可,不需要带pressure_rate./volume_flow_rate.前缀;同时rate_source也直接写提升后的输出名(如p_dot、Vl_dot)即可。
  • 删除BottleModelODE中多余的connect语句:p、Vl_dot已经被提升到组顶层,两个子系统的同名输入会自动连接到同一个组级变量,手动重复连接会触发OpenMDAO重复连接报错。
  • 修复VolumeFlowRate类的重复定义问题:类中写了两个setup方法,第二个会覆盖第一个,导致num_nodes配置失效、所有输入未设置向量化形状。删除冗余setup,将num_nodes读取、输入shape配置(所有输入shape设为(nn,),和PressureRate保持一致)合并到同一个setup方法中。
  • 修正拼写错误:后续set_val时把phase名expulsion错写为explusion(字母l、s顺序颠倒),会导致赋值路径不存在。
  • 修复语法错误:bottle_params字典中pinit键名前缺失双引号,会触发Python语法报错;同时字典中缺失deltap键值,后续赋值会触发键不存在错误。
  • 修正单位不匹配问题:状态p定义单位为bar,但初始值、出口压力等参数传入的都是Pa单位的数值,量级差1e5,直接仿真会得到完全错误的结果,统一将压力相关单位设为Pa即可。
  • 修正物理公式错误:PressureRate中压力变化率公式符号反了——定义流出流量为正的情况下,液体流出导致液位降低、气相体积膨胀,瓶内压力应该下降,公式需要补负号;另外流量计算时要对压差做非负截断,避免瓶内压力低于出口压力时根号内出现负数,导致仿真出现NaN。
  • 修正数值错误:调用trajectory时传入的环境压力误写为100*10*3(结果为10kPa),和定义的100kPa环境压力不符,改为100*10**3。
  • 移除不必要的优化配置:你使用solve_segments='forward'做正向积分仿真,没有将终止时间设为设计变量,不需要配置SLSQP驱动和时间目标,直接调用prob.run_model()即可运行仿真,多余的优化配置反而可能引入未知错误。

修复后的关键代码片段

修复后的VolumeFlowRate组件

class VolumeFlowRate(om.ExplicitComponent):

    def initialize(self):
        self.options.declare('num_nodes', types=int)

    def setup(self):
        nn = self.options['num_nodes']
        # 所有输入配置向量化shape
        self.add_input('p', shape=(nn,), desc='Pressure inside the nox_bottle', units='Pa')
        self.add_input('pout', shape=(nn,), desc='Pressure outside the nox_bottle', units='Pa')
        self.add_input('deltap', shape=(nn,), desc='Nox bottle pressure losses', units='Pa')
        self.add_input('rhol', shape=(nn,), desc='Liquid density', units='kg/m**3')
        self.add_input('Aout', shape=(nn,), desc='Output nox_bottle area', units='m**2')

        self.add_output('Vl_dot', shape=(nn,), desc='Volume flow rate', units='m**3/s')
        self.declare_partials(of='*', wrt='*', method='fd')

    def compute(self, inputs, outputs):
        p = inputs['p']
        pout = inputs['pout']
        deltap = inputs['deltap']
        rhol = inputs['rhol']
        Aout = inputs['Aout']
        # 压差做非负截断,避免根号出负数
        dp = np.maximum(p - pout - deltap, 0)
        outputs['Vl_dot'] = Aout*np.sqrt(2/rhol*dp)

修复后的PressureRate组件compute方法

def compute(self, inputs, outputs):
    p = inputs['p']
    Vb = inputs['Vb']
    Vl = inputs['Vl']
    Vl_dot = inputs['Vl_dot']
    gamma = inputs['gamma']
    # 补负号,流出为正时压力下降
    outputs['p_dot'] = - gamma * p/(Vb - Vl) * Vl_dot

修复后的BottleModelODE组

class BottleModelODE(om.Group):

    def initialize(self):
        self.options.declare('num_nodes', types=int)

    def setup(self):
        nn = self.options['num_nodes']

        self.add_subsystem('pressure_rate', subsys=PressureRate(num_nodes=nn),
                           promotes_inputs=['p', "Vb", "Vl", "Vl_dot", "gamma"], promotes_outputs=['p_dot'])
        self.add_subsystem('volume_flow_rate', subsys=VolumeFlowRate(num_nodes=nn),
                           promotes_inputs=['p', "pout", 'deltap', 'rhol', "Aout"], promotes_outputs=['Vl_dot'])
        # 删除冗余connect语句,promote后变量自动连通

修复后的相配置

phase.add_state('p', units='Pa', rate_source='p_dot',
                targets=['p'], fix_initial=True, fix_final=False, lower=pamb)
phase.add_state('Vl', units='m**3', rate_source='Vl_dot', targets=['Vl'],
                fix_initial=True, fix_final=False, lower=0)

phase.add_parameter('Vb', targets=['Vb'], units='m**3')
phase.add_parameter('gamma', targets=['gamma'])
phase.add_parameter('rhol', targets=['rhol'], units='kg/m**3')
phase.add_parameter('Aout', targets=['Aout'], units='m**2')
phase.add_parameter('pout', targets=['pout'], units="Pa")
phase.add_parameter('deltap', targets=['deltap'], units="Pa")

修复后的问题配置与赋值

def launch_compt():
    pamb = 100*10**3
    # 补全参数字典,修正语法错误
    bottle_params = {
        "Vb": 5*10**-3, 
        "gamma": 1.4, 
        "Aout": 3*10**-2, 
        "rhol": 1000, 
        "pout": pamb, 
        "pinit": 300*10**3, 
        "Vl": 1*10**-3,
        "deltap": 0
    }

    prob = om.Problem(model=om.Group())
    # 移除不必要的优化驱动,正向仿真直接用默认驱动即可
    traj, phase = trajectory(pamb=pamb)

    prob.model.add_subsystem("traj", traj)
    prob.setup()

    # 修正phase名拼写错误
    prob.set_val('traj.expulsion.t_initial', 0.0)
    prob.set_val('traj.expulsion.t_duration', 200.0)

    prob.set_val('traj.expulsion.states:p', bottle_params["pinit"])
    prob.set_val('traj.expulsion.states:Vl', bottle_params["Vl"])

    prob.set_val('traj.expulsion.parameters:Vb', bottle_params["Vb"])
    prob.set_val('traj.expulsion.parameters:gamma', bottle_params["gamma"])
    prob.set_val('traj.expulsion.parameters:rhol', bottle_params["rhol"])
    prob.set_val('traj.expulsion.parameters:Aout', bottle_params["Aout"])
    prob.set_val('traj.expulsion.parameters:pout', bottle_params["pout"])
    prob.set_val('traj.expulsion.parameters:deltap', bottle_params["deltap"])

    # 正向仿真直接调用run_model
    prob.run_model()

内容的提问来源于stack exchange,提问作者Quentin Tiefaine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:27:18