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
相关产品推荐
相关产品推荐

