quaternio
quaternio

Reputation: 95

Model of pressure lifted valve in OpenModelica

I am trying to create a simple model of a valve which is lifted to allow fluid flow, when the force from the fluid pressure is greater than the force of the spring holding the mass down.

My general approach is based off of the sliding mass with stop element in the MSL. I have created a stopped state variable which should be -1 if stopped at the minimum, 1 if stopped at the maximum and 0 otherwise. If stopped at min and force is pushing towards the min direction the netforce is replaced with a value of 0 (and the same for the max stop)

The forces acting on the mass are

I was getting preoblems with chattering so I added a small "buffering" region for the value of netforce that it is replaced with 0.

This didnt really help, so I decided to add a sensor on the outlet side of the valve so that the pressure force doesnt decrease so rapidly when the valve opens.

Now I am getting problems with the fluid pressure and heat going outside the allowed region and have no idea what I can do to get this model to work..

Any help is deeply appreciated, below is the code containing the valve controller model and the testing rig I have been using.

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;

Upvotes: 2

Views: 62

Answers (1)

Dag B
Dag B

Reputation: 759

Have you tried building it from one of the MSL valves, such as Modelica.Fluid.Valves.ValveIncompressible, that take a control signal [0, 1] as input, and then calculate that signal from a pressure sensor on the upstream-side?

Upvotes: 1

Related Questions