Skip to content

Supercomponent

In this example, it is shown how it is possible to model a valve (supercomponent) to include it in the simulation of a complete circuit. The valve model can be called from multiple files and multiple times. Each instance creates an object with independent behavior.

Supercomponent

immagine_supercomponente

Show the model or download it
model CV
parameter SFPLibDyn.Units.Pressure param_pcrack = 10e5 "cracking pressure";
parameter SFPLibDyn.Units.Stiffness param_spring_k = 50e3 "spring rate";
SFPLibDyn.Units.VolFlowRate Q_flow "volume flow rate";
SFPLibDyn.Units.Pressure Delta_p "pressure drop";
SFPLibDyn.Components.Piston piston2(d_piston = 0.011, direction = -1, l_chamber_0 = 0.003) annotation(
    Placement(transformation(origin = {65, 1}, extent = {{-10, 10}, {10, -10}}, rotation = 90)));
SFPLibDyn.Components.Piston piston1(d_piston = 0.011, d_rod = 0.009, direction = +1) annotation(
    Placement(visible = true, transformation(origin = {65, -23}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
SFPLibDyn.Hydraulic.Orifices.Orifice OR_out(area = 7.536e-05, d_hydr = 0.004, or_model = SFPLibDyn.Units.Choices.orifice_type.DiamArea) annotation(
    Placement(transformation(origin = {-7, -29}, extent = {{-6, -12}, {6, 12}}, rotation = -90)));
SFPLibDyn.Mechanical.Translational.Spring Spring(preload = param_pcrack*SFPLibDyn.Constants.pi*((8e-3)^2)/4, spring_rate = param_spring_k) annotation(
    Placement(transformation(origin = {65, 51}, extent = {{-9, -9}, {9, 9}}, rotation = 90)));
SFPLibDyn.Mechanical.Translational.Sources.ZeroSpeed zero_s annotation(
    Placement(transformation(origin = {65, 69}, extent = {{-5, 5}, {5, -5}}, rotation = -90)));
SFPLibDyn.Components.PoppetSharpEdgeSeat Poppet(coeff_f_flow = 0, d_hole = 0.008, d_poppet = 0.009, direction = +1) annotation(
    Placement(transformation(origin = {65, -48}, extent = {{-10, -10}, {10, 10}}, rotation = -90)));
SFPLibDyn.Mechanical.Translational.Sources.ZeroForce zero_f annotation(
    Placement(transformation(origin = {65, -71}, extent = {{-7, 7}, {7, -7}}, rotation = 90)));
SFPLibDyn.Mechanical.Translational.Mass Mass(endstops_model = SFPLibDyn.Units.Choices.mass_type.Ideal, high_lim = 0.005, low_lim = 0, coeff_viscous = 10) annotation(
    Placement(transformation(origin = {65, 27}, extent = {{-11, -11}, {11, 11}}, rotation = 90)));
SFPLibDyn.Hydraulic.Nodes.Node3p n1 annotation(
    Placement(transformation(origin = {41, -29}, extent = {{-6, -6}, {6, 6}}, rotation = -90)));
SFPLibDyn.Hydraulic.Volumes.Volume2p Vol_int(pressure(start = 0)) annotation(
    Placement(transformation(origin = {19, -29}, extent = {{-9, -9}, {9, 9}}, rotation = -90)));
SFPLibDyn.Connectors.HydPinVol Port1 annotation(
    Placement(transformation(origin = {-49, -54}, extent = {{-6, -6}, {6, 6}}), iconTransformation(origin = {0, -120}, extent = {{-10, -10}, {10, 10}})));
SFPLibDyn.Connectors.HydPinVol Port2 annotation(
    Placement(transformation(origin = {-49, -29}, extent = {{-7, -7}, {7, 7}}), iconTransformation(origin = {0, 120}, extent = {{-10, -10}, {10, 10}})));
SFPLibDyn.Hydraulic.Nodes.Node3p n2 annotation(
    Placement(transformation(origin = {-30, -29}, extent = {{-6, 6}, {6, -6}}, rotation = 90)));
equation
Q_flow = Port1.q;
Delta_p = Port1.p - Port2.p;
connect(Port1, Poppet.h2) annotation(
    Line(points = {{-49, -54}, {55, -54}}));
connect(Vol_int.h1, OR_out.h2) annotation(
    Line(points = {{10, -29}, {5, -29}}));
connect(Mass.t1, piston2.t2) annotation(
    Line(points = {{65, 16}, {64.5, 16}, {64.5, 11}, {65, 11}}));
connect(piston2.t1, piston1.t1) annotation(
    Line(points = {{65, -9}, {65, -14}}));
connect(Spring.t1, Mass.t2) annotation(
    Line(points = {{65, 42}, {65, 38}}));
connect(Spring.t2, zero_s.t1) annotation(
    Line(points = {{65, 60}, {65, 64}}));
connect(piston1.t2, Poppet.t1) annotation(
    Line(points = {{65, -33}, {65, -38}}));
connect(Poppet.t2, zero_f.t1) annotation(
    Line(points = {{65, -58}, {65, -64}}));
connect(Vol_int.h2, n1.h1) annotation(
    Line(points = {{28, -29}, {34, -29}}));
connect(n2.h1, Port2) annotation(
    Line(points = {{-36, -29}, {-42, -29}, {-42, -28}, {-48, -28}}));
connect(n1.h2, piston1.h1) annotation(
    Line(points = {{47, -29}, {55, -29}}));
connect(OR_out.h1, n2.h2) annotation(
    Line(points = {{-19, -29}, {-24, -29}}));
connect(Poppet.h1, n1.h3) annotation(
    Line(points = {{55, -45}, {41, -45}, {41, -35}}));
connect(piston2.h1, n2.h3) annotation(
    Line(points = {{55, 7}, {-30, 7}, {-30, -23}}));
annotation(
    Icon(coordinateSystem(extent = {{-80, -120}, {80, 120}}, grid = {1, 1}), graphics = {Text(origin = {69, 5}, rotation = -90, extent = {{-38, 10}, {38, -10}}, textString = "%name"), Text(origin = {-25, -108}, rotation = 180, extent = {{-16, 10}, {16, -10}}, textString = "1"), Text(origin = {-24, 110}, rotation = 180, extent = {{-16, 10}, {16, -10}}, textString = "2"), Line(origin = {0, -61.21}, points = {{-30, 30}, {0, 0}, {30, 30}}), Line(origin = {0, -61.21}, rotation = 180, points = {{0, 0}, {0, 58.79}}), Line(origin = {0, -25}, rotation = 90, points = {{0, 0}, {6.25, -30}, {18.75, 30}, {31.25, -30}, {43.75, 30}, {56.25, -30}, {68.75, 30}, {75, 0}}), Line(origin = {0, -25}, points = {{0, 0}, {0, 145}}), Ellipse(origin = {0, -40}, extent = {{-15, -15}, {15, 15}})}),
    Diagram(coordinateSystem(extent = {{-90, 80}, {80, -80}}, grid = {1, 1}), graphics = {Text(origin = {-66, -28}, rotation = 180, extent = {{-16, 10}, {16, -10}}, textString = "2"), Text(origin = {-67, -52}, rotation = 180, extent = {{-16, 10}, {16, -10}}, textString = "1")}),
    __OpenModelica_commandLineOptions = "");
end CV;

First, it is necessary to build the valve model, in this case a unidirectional valve. The novelty of this example concerns the use of hydraulic pins HydPinVol found in SFPLibDyn.Connectors. These are necessary to add the interface ports needed by the valve to connect with the rest of the circuit.

Which pin to use

Attention, differently from what has been said so far, the rule of RED pin - BLUE pin must not be respected:

In this case, it is about "extending" the pin of the last internal component. In this way, only the depth level of the connection is changed, which from the internal circuit, of lower level, passes to the external circuit to the valve, of higher level (as can be noted in the supercomponent image pin 1 extends the blue pin of the poppet, while pin 2 extends the blue pin of the node).

immagine_icona_supercomponente

A supercomponent, to be complete, must be totally defined. (1) Verify it with the button model verification button icon.

  1. The number of equations must correspond to the number of variables.

An important aspect of supercomponents are their public parameters. Building the model of a valve, there is the need to leave some values settable, for example the spring calibration: we want to leave a parameter free to be modified for each single valve instantiated in the external circuit. This is possible with the first two lines of the model:

parameter SFPLibDyn.Units.Pressure param_pcrack = 10e5 "cracking pressure";
parameter SFPLibDyn.Units.Stiffness param_spring_k = 50e3 "spring rate";

Through the parameter prefix, it is possible to indicate the intention to create a public parameter, followed by the reference physical quantity, the name you want to assign to the parameter, a default value expressed in ISO units and a description.

Info

Unfortunately, this step can only be done via code.

Circuit

immagine_circuito

Show the model or download it
model Circuit
parameter SFPLibDyn.Units.Volume param_pump_displ = 1e-5 "pump displacement"; 
parameter SFPLibDyn.Units.Pressure param_RV_pcrack = 2e7 "relief valve rv cracking pressure";
parameter SFPLibDyn.Units.Force param_cyl_springF = 100 "cylinder spring preload";
parameter SFPLibDyn.Units.Stiffness param_cyl_springk = 1000 "cylinder spring rate";  
SFPLibDyn.Signals.Source.Constant rpm(k = 1000) annotation(
    Placement(transformation(origin = {-116, -110}, extent = {{-10, -10}, {10, 10}})));
SFPLibDyn.Mechanical.Translational.Mass mass(coeff_viscous(displayUnit = "N/(m/s)") = 1, endstops_model = SFPLibDyn.Units.Choices.mass_type.Ideal, high_lim = 0.3, low_lim = 0, mass(displayUnit = "kg") = 10) annotation(
    Placement(transformation(origin = {-83, 63}, extent = {{10, -10}, {-10, 10}}, rotation = -0)));
SFPLibDyn.Signals.Source.LinearStages pilot_4x2(stage1_duration = 1, stage1_end = 1, stage2_duration = 0.1, stage2_end = 0, stage3_end = 0, stage1_start = 1) annotation(
    Placement(transformation(origin = {-3, -53}, extent = {{-10, 10}, {10, -10}}, rotation = -180)));
SFPLibDyn.Mechanical.Rotational.Sources.Motor motor annotation(
    Placement(transformation(origin = {-87, -110}, extent = {{-14, -14}, {14, 14}})));
SFPLibDyn.Hydraulic.Sources.Pumps.FixedUniDirPump pump(is_set = false, max_displ = param_pump_displ) annotation(
    Placement(transformation(origin = {-48, -110}, extent = {{-15, -15}, {15, 15}})));
SFPLibDyn.Hydraulic.Sources.Tank tank annotation(
    Placement(transformation(origin = {-48, -142}, extent = {{-6, -3}, {6, 6}})));
SFPLibDyn.Hydraulic.Sources.Tank tank1 annotation(
    Placement(transformation(origin = {-141, -143}, extent = {{-6, -3}, {6, 6}})));
SFPLibDyn.Hydraulic.Volumes.Volume2p vol_A(vol_0 = 1e-5) annotation(
    Placement(transformation(origin = {-34, -14}, extent = {{-8, -8}, {8, 8}})));
SFPLibDyn.Hydraulic.Actuators.Cylinders.Cylinder cylinder( d_piston = 0.1, d_rod = 0.04, stroke = 0.3) annotation(
    Placement(transformation(origin = {-46, 63}, extent = {{17.5, -12}, {-19.5, 10}}, rotation = -0)));
SFPLibDyn.Hydraulic.Valves.DirControlValves.DirValves4x2.DirValv4x2C08 dirValve4x2( PT_q_ch = 1.6666666666666666e-4, BT_q_ch = 1.6666666666666666e-4, PA_q_ch = 1.6666666666666666e-4)  annotation(
    Placement(transformation(origin = {-45, -50}, extent = {{18, -12}, {-18, 12}})));
CV CV1(param_pcrack = 1e5, param_spring_k = 500)  annotation(
    Placement(transformation(origin = {-94.5, -80.75}, extent = {{-12.5, -18.75}, {12.5, 18.75}}, rotation = -90)));
SFPLibDyn.Hydraulic.Valves.DirControlValves.DirValves2x2.DirValv2x2C01 dirValve2x2(PA_q_ch = 1.6666666666666666e-4)  annotation(
    Placement(transformation(origin = {-64, 17}, extent = {{-18, -12}, {18, 12}})));
CV CV2(param_pcrack = 1e5)  annotation(
    Placement(transformation(origin = {-92.5, -13.75}, extent = {{-12.5, -18.75}, {12.5, 18.75}}, rotation = 90)));
SFPLibDyn.Hydraulic.Volumes.Volume3p vol_int(vol_0 = 1e-4) annotation(
    Placement(transformation(origin = {-133, -14}, extent = {{-8, -8}, {8, 8}}, rotation = 90)));
SFPLibDyn.Hydraulic.Volumes.Volume4p vol_pump(vol_0 = 1e-5) annotation(
    Placement(transformation(origin = {-48, -81}, extent = {{8, -8}, {-8, 8}}, rotation = 180)));
SFPLibDyn.Hydraulic.Nodes.Node3pAlt node annotation(
    Placement(transformation(origin = {-58, 40}, extent = {{-6, -6}, {6, 6}}, rotation = -90)));
SFPLibDyn.Hydraulic.Volumes.Volume3p vol_B(vol_0 = 1e-5) annotation(
    Placement(transformation(origin = {-58, -14}, extent = {{8, -8}, {-8, 8}}, rotation = -90)));
SFPLibDyn.Signals.Source.LinearStages pilot_2x2(stage1_duration = 4, stage1_end = 0, stage2_duration = 0.1, stage2_end = 1, stage3_end = 1, stage1_start = 0) annotation(
    Placement(transformation(origin = {-101, 14}, extent = {{10, 10}, {-10, -10}}, rotation = 180)));
SFPLibDyn.Mechanical.Translational.Spring spring(preload = param_cyl_springF, spring_rate = param_cyl_springk)  annotation(
    Placement(transformation(origin = {-112, 63}, extent = {{10, -10}, {-10, 10}}, rotation = -0)));
SFPLibDyn.Mechanical.Translational.Sources.ZeroSpeed zeroSpeed annotation(
    Placement(transformation(origin = {-139, 63}, extent = {{10, -10}, {-10, 10}}, rotation = -180)));
inner SFPLibDyn.Properties.Hydraulic.FluidProp fluidProp annotation(
    Placement(transformation(origin = {-3, 67}, extent = {{-10, -10}, {10, 10}})));
SFPLibDyn.Hydraulic.Valves.ReliefValve rv(p_crack = param_RV_pcrack)  annotation(
    Placement(transformation(origin = {-17, -113}, extent = {{-12, -12}, {12, 12}}, rotation = 180)));
SFPLibDyn.Hydraulic.Sources.Tank tank2 annotation(
    Placement(transformation(origin = {-17, -142}, extent = {{-6, -3}, {6, 6}})));
equation
connect(rpm.y1, motor.u1) annotation(
    Line(points = {{-106, -110}, {-101, -110}}));
connect(motor.r1, pump.r1) annotation(
    Line(points = {{-70.2, -110}, {-63.4, -110}}));
connect(pump.h1, tank.h1) annotation(
    Line(points = {{-48, -125}, {-48, -136}}));
connect(vol_int.h1, CV2.Port2) annotation(
    Line(points = {{-125, -14}, {-111, -14}}));
connect(vol_int.h2, CV1.Port1) annotation(
    Line(points = {{-133, -22}, {-133, -81}, {-113, -81}}));
connect(node.h3, dirValve2x2.hA) annotation(
    Line(points = {{-58, 34}, {-58, 29}}));
connect(node.h1, vol_int.h3) annotation(
    Line(points = {{-64, 40}, {-133, 40}, {-133, -6}}));
connect(CV2.Port1, vol_B.h1) annotation(
    Line(points = {{-74, -14}, {-66, -14}}));
connect(dirValve2x2.hP, vol_B.h3) annotation(
    Line(points = {{-58, 5}, {-58, -6}}));
connect(pilot_2x2.y1, dirValve2x2.u1) annotation(
    Line(points = {{-91, 14}, {-85, 14}}));
connect(cylinder.h2, node.h2) annotation(
    Line(points = {{-58, 51}, {-58, 46}}));
connect(mass.t1, cylinder.t1) annotation(
    Line(points = {{-71, 63}, {-65, 63}}));
connect(spring.t1, mass.t2) annotation(
    Line(points = {{-102, 63}, {-95, 63}}));
connect(zeroSpeed.t1, spring.t2) annotation(
    Line(points = {{-129, 63}, {-122, 63}}));
connect(dirValve4x2.hA, vol_A.h1) annotation(
    Line(points = {{-48, -38}, {-48, -30}, {-34, -30}, {-34, -22}}));
connect(vol_B.h2, dirValve4x2.hB) annotation(
    Line(points = {{-58, -22}, {-58, -30}, {-54, -30}, {-54, -38}}));
connect(dirValve4x2.hT, tank1.h1) annotation(
    Line(points = {{-54, -62}, {-54, -68}, {-141, -68}, {-141, -137}}));
connect(dirValve4x2.u1, pilot_4x2.y1) annotation(
    Line(points = {{-24, -53}, {-13, -53}}));
connect(cylinder.h1, vol_A.h2) annotation(
    Line(points = {{-34, 51}, {-34, -6}}));
connect(rv.h2, tank2.h1) annotation(
    Line(points = {{-17, -125}, {-17, -136}}));
connect(CV1.Port2, vol_pump.h3) annotation(
    Line(points = {{-76, -81}, {-56, -81}}));
connect(dirValve4x2.hP, vol_pump.h1) annotation(
    Line(points = {{-48, -62}, {-48, -73}}));
connect(vol_pump.h4, rv.h1) annotation(
    Line(points = {{-40, -81}, {-17, -81}, {-17, -101}}));
connect(vol_pump.h2, pump.h2) annotation(
    Line(points = {{-48, -89}, {-48, -95}}));
annotation(
    experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.001),
    Diagram(coordinateSystem(extent = {{-150, 80}, {10, -150}}, grid = {1, 1})),
    Icon(graphics = {Rectangle(origin = {2, 69}, fillColor = {122, 122, 122}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-74, 9}, {74, -39}}), Rectangle(origin = {-66, 4}, rotation = -90, fillColor = {122, 122, 122}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-67, 45}, {81, -7}}), Rectangle(origin = {0, -61}, rotation = 180, fillColor = {122, 122, 122}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-76, 17}, {72, -29}}), Line(origin = {2.16839, 1.4047}, points = {{75, 76.6263}, {-73, 76.6263}, {-73, -79.3737}, {75, -79.3737}, {75, -33.3737}, {-25, -33.3737}, {-25, 28.6263}, {75, 28.6263}, {75, 76.6263}}, thickness = 2)}, coordinateSystem(extent = {{-100, -100}, {100, 100}})));
end Circuit;

Once the supercomponent is ready, it is possible to model the circuit and insert the newly built valve. It is possible to do this simply by taking the model from the content tree and dragging it into a new diagram.

For the more tinkering ones

Analyzing the generated code, we can distinguish the structure:

CV CV1(param_pcrack = 1e5, param_spring_k = 500)  annotation(
    Placement(transformation(origin = {-94.5, -80.75}, extent = {{-12.5, -18.75}, {12.5, 18.75}}, rotation = -90)));

The valve model (CV) is called, the name assigned to the instantiated object (CV1), and then in parentheses the modified parameters and the annotation section concerning the graphic positioning of the icon in the diagram.

c:\Users\marco\Documents\GitHub\SFPLibDyn_manuale\docs\3_esempi\7_supercomponente.en.md