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

OpenModelica中压力提升阀建模问题技术求助

压力提升阀模型问题:颤振与流体参数超限修复

问题描述

我正在尝试创建一个简单的压力提升阀模型:当流体压力产生的力大于弹簧下压阀芯的力时,阀芯抬起以允许流体流动。建模思路基于MSL(Modelica标准库)中的带限位滑动质量元件,定义了状态变量stopped(-1表示停在最小位移、1表示停在最大位移、0表示未限位),当阀芯处于限位状态且受力方向与限位方向一致时,将净力设为0。

作用在阀芯上的力包括:

  • 入口侧管道压力乘以入口侧活塞面积(参数)
  • 弹簧力,由阀芯位移乘以弹簧刚度(参数)加上预紧力计算得出

最初模型出现颤振问题,我为净力添加了一个小的缓冲区域,将特定范围内的净力设为0,但并未解决问题。随后我在阀出口侧添加了压力传感器,以避免阀开启时压力力下降过快,现在却出现了流体压力和热量超出允许范围的问题,不知如何修复该模型。

模型代码

阀控制器与测试台代码

package ValveCompIdeas
  
  model ValveCompSlideMass
    
    replaceable package Medium = Modelica.Media.Water.StandardWater "Medium in the component" annotation(
          choicesAllMatching = true);
    //parameters
    parameter Real eps = 1e-2 "stopped sensor error";
    parameter Modelica.Units.SI.Mass m=0.15 "mass of moving parts";
    parameter Modelica.Units.SI.Length smax=0.0033 "max displacement";
    parameter Modelica.Units.SI.Length smin=0 "min displacement";
    parameter Modelica.Units.SI.TranslationalSpringConstant k=19.8e3 "spring constant";
    //parameter Modelica.Units.SI.Length s0=0.0033 "Spring free height";
    parameter Modelica.Units.SI.Area SAIn=90e-6 "piston surface area - Inlet side";
    parameter Modelica.Units.SI.Area SAOut=30e-6 "piston surface area - Outlet side";
    parameter Modelica.Units.SI.Force preload = -171 "Spring preload (PreComp = Negative N)";
    //variables
    Integer stopped(start = 0) "-1 stopped at min, 0 not stopped, 1 stopped at max";
    Modelica.Units.SI.Position s(start = 0) "spring end position";
    Modelica.Units.SI.Velocity v "spring end velocity";
    Modelica.Units.SI.Acceleration a "spring end acceleration";
    Modelica.Units.SI.Force sprf "spring force";
    Modelica.Units.SI.Force prsf "Pressure force";
    Modelica.Units.SI.Force nf "Net Force on mass";
    Modelica.Units.SI.Pressure pIn "Inletside pressure";
    Modelica.Units.SI.Pressure pOut "Outletside pressure";
    Modelica.Fluid.Interfaces.FluidPort_a port_In(redeclare package Medium = Medium) annotation(
          Placement(transformation(origin = {100, 0}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {102, 100}, extent = {{-10, -10}, {10, 10}})));
    Modelica.Blocks.Interfaces.RealOutput y annotation(
          Placement(transformation(origin = {2, -96}, extent = {{-10, -10}, {10, 10}}, rotation = -90), iconTransformation(origin = {110, -2}, extent = {{-10, -10}, {10, 10}})));
  Modelica.Fluid.Sensors.Pressure pressureIn(redeclare package Medium = Medium) annotation(
      Placement(transformation(origin = {12, 10}, extent = {{10, -10}, {-10, 10}})));
Modelica.Fluid.Interfaces.FluidPort_a port_Out(redeclare package Medium = Medium) annotation(
      Placement(transformation(origin = {100, -82}, extent = {{-10, -10}, {10, 10}}), iconTransformation(origin = {98, -98}, extent = {{-10, -10}, {10, 10}})));
Modelica.Fluid.Sensors.Pressure pressureOut(redeclare package Medium = Medium) annotation(
      Placement(transformation(origin = {38, -62}, extent = {{10, -10}, {-10, 10}})));
  initial equation
    nf = prsf + sprf;
  equation
//I-O definitions
    pressureIn.p = pIn;
    pressureOut.p = pOut;
//  port_a.m_flow = 0;
//  port_a.h_outflow = Medium.h_default;
//  port_a.Xi_outflow = Medium.X_default[1:Medium.nXi];
//  port_a.C_outflow = zeros(Medium.nC);
    y = if (s <= smin) then 0 else if (s >= smax) then 1 else 1 - (smax-s)/(smax-smin);
//mass mechanics
    v = der(s);
    a = der(v);
    m * a = nf;
//forces on mass
    sprf = k * (smin - s) + preload;
    prsf = pIn * SAIn + pOut * SAOut;
//stop state
    stopped = if s <= smin then -1 elseif s >= smax then 1 else 0;
//stop contact
    when stopped <> 0 then
      reinit(s,if stopped < 0 then smin else smax);
      reinit(v,0);
    end when;
    nf = if (stopped < 0 and prsf + sprf < -eps) or (stopped > 0 and prsf + sprf > eps) then 0 else sprf + prsf;
    connect(pressureIn.port, port_In) annotation(
      Line(points = {{12, 0}, {100, 0}}, color = {0, 127, 255}, thickness = 0.5));
  connect(pressureOut.port, port_Out) annotation(
      Line(points = {{98, -80}, {99, -80}, {99, -82}, {100, -82}}, thickness = 0.5));
end ValveCompSlideMass;
  
  model NRVtest
replaceable package Medium = Modelica.Media.Water.StandardWater constrainedby Modelica.Media.Interfaces.PartialMedium;
    Modelica.Fluid.Sources.Boundary_pT boundaryOut(p(displayUnit = "bar") = 1e5, nPorts = 1, redeclare package Medium = Medium) annotation(
      Placement(transformation(origin = {0, -90}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
    inner Modelica.Fluid.System system(p_ambient = 1e5, energyDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, massDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, momentumDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial) annotation(
      Placement(transformation(origin = {-130, 90}, extent = {{-10, -10}, {10, 10}})));
    Modelica.Fluid.Sources.Boundary_pT boundary(redeclare package Medium = Medium, use_p_in = true, nPorts = 1, p = 5e6) annotation(
      Placement(transformation(origin = {-10, 90}, extent = {{-10, -10}, {10, 10}})));
    Modelica.Fluid.Pipes.DynamicPipe pipe(redeclare package Medium = Medium, length = 0.15, diameter = 0.008, height_ab = 0.15) annotation(
      Placement(transformation(origin = {0, 50}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
    Modelica.Fluid.Valves.ValveLinear valveLinear(redeclare package Medium = Medium, dp_nominal = 1, m_flow_nominal = 10) annotation(
      Placement(transformation(extent = {{-10, 10}, {10, -10}}, rotation = -90)));
    Modelica.Fluid.Pipes.DynamicPipe pipe1(redeclare package Medium = Medium, diameter = 0.008, height_ab = 0.15, length = 0.15) annotation(
      Placement(transformation(origin = {0, -40}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
    Modelica.Blocks.Sources.Trapezoid trapezoid(amplitude = 100e5, rising = 5, width = 10, falling = 5, period = 30, offset = 1e5) annotation(
      Placement(transformation(origin = {-70, 86}, extent = {{-10, -10}, {10, 10}}, rotation = 90)));
    ValveCompSlideMass valveCompSlideMass(redeclare package Medium = Medium, s(fixed = true), stopped(fixed = false)) annotation(
      Placement(transformation(origin = {-56, 0}, extent = {{-10, -10}, {10, 10}})));
  equation
    connect(boundary.ports[1], pipe.port_a) annotation(
      Line(points = {{0, 90}, {0, 60}}, color = {0, 127, 255}));
    connect(pipe.port_b, valveLinear.port_a) annotation(
      Line(points = {{0, 40}, {0, 10}}, color = {0, 127, 255}));
    connect(valveLinear.port_b, pipe1.port_a) annotation(
      Line(points = {{0, -10}, {0, -30}}, color = {0, 127, 255}, thickness = 0.5));
    connect(pipe1.port_b, boundaryOut.ports[1]) annotation(
      Line(points = {{0, -50}, {0, -80}}, color = {0, 127, 255}, thickness = 0.5));
    connect(trapezoid.y, boundary.p_in) annotation(
      Line(points = {{-70, 97}, {-70, 98}, {-22, 98}}, color = {0, 0, 127}, thickness = 0.5));
    connect(valveCompSlideMass.port_In, pipe.port_b) annotation(
      Line(points = {{-46, 10}, {-46, 40}, {0, 40}}, color = {0, 127, 255}));
    connect(valveCompSlideMass.port_Out, pipe1.port_a) annotation(
      Line(points = {{-46, -10}, {-46, -30}, {0, -30}}, color = {0, 127, 255}));
    connect(valveCompSlideMass.y, valveLinear.opening) annotation(
      Line(points = {{-44, 0}, {-8, 0}}, color = {0, 0, 127}));
    annotation(
      Diagram);
  end NRVtest;
end ValveCompIdeas;

修复建议

1. 解决颤振问题

  • 替换当前的stopped状态判断逻辑,改用连续的接触力模型而非硬限位+条件净力设置。可以参考MSL中的Modelica.Mechanics.Translational.Components.Stopper元件,它采用弹性接触方式,避免状态突变导致的颤振。
  • 移除when语句中的reinit操作,硬重置状态变量容易引发数值不稳定。改为通过接触力方程约束位移范围:当s < smin时添加向上的弹性接触力;当s > smax时添加向下的弹性接触力,接触刚度设为远大于弹簧刚度的值。

2. 解决流体参数超限问题

  • 调整ValveLinear的参数:当前dp_nominal=1和m_flow_nominal=10与实际工况(入口压力最高110bar)不匹配,导致流量计算异常。建议设置dp_nominal=1e5(1bar),m_flow_nominal根据管道尺寸和压力差计算合理值。
  • 优化DynamicPipe参数:适当增加管道长度或直径,或调整momentumDynamics为SteadyState简化计算,先验证阀的机械部分逻辑。
  • 移除冗余压力传感器:直接通过port_In.p和port_Out.p获取压力,额外传感器可能引入不必要的动态延迟。

3. 弹簧力公式修正

当前弹簧力公式sprf = k * (smin - s) + preload逻辑有误:当s = smin时弹簧力为preload,但预紧力应是弹簧初始位置的压缩力。正确公式应为sprf = k*(s0 - s) + preload(s0为弹簧自由长度),或调整为sprf = k*(smin - s) - preload(若preload为压缩力大小),确保初始状态弹簧力与预紧力匹配。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:30:53