Skip to content
LIBRARY
Machines.Tests.DoubleActingCylinder.md

Machines.Tests.DoubleActingCylinder

This test case simulates a Double Acting cylinder with an external mass connected to the piston via a flange. The piston starts at the center position, with higher initial pressure in the fixed volume on the right side causing the piston to move left and stop when it hits the left chamber end. At 1 second, the pressure at the left side is increased, causing the piston to move right and stop upon hitting the right chamber end. The connected mass follows the piston movement, demonstrating the dynamic response of the cylinder and the attached load

Usage

HydraulicComponents.Machines.Tests.DoubleActingCylinder()

Behavior

Behavior of this component cannot be rendered because it includes path variables.

Source

dyad
"""
This test case simulates a Double Acting cylinder with an external mass connected 
to the piston via a flange. The piston starts at the center position, with higher 
initial pressure in the fixed volume on the right side causing the piston to move 
left and stop when it hits the left chamber end. At 1 second, the pressure at the 
left side is increased, causing the piston to move right and stop upon hitting the 
right chamber end. The connected mass follows the piston movement, demonstrating 
the dynamic response of the cylinder and the attached load 
"""
test component DoubleActingCylinder
  double_acting_cylinder = HydraulicComponents.Machines.DoubleActingCylinder(L = 1.0, M = 0.2, area_a = 0.001, area_b = 0.001, s0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 450, "y1": 400, "x2": 550, "y2": 500}}}
  }
  port_a_side = HydraulicComponents.Sources.BoundaryPressure() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 290, "y1": 400, "x2": 190, "y2": 500, "rot": 180}
      },
      "tags": []
    }
  }
  fixed_volume = HydraulicComponents.Vessels.FixedVolume(p0 = 1e6, vol = 100) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 800, "y1": 400, "x2": 700, "y2": 500, "rot": 0}
      },
      "tags": []
    }
  }
  step = BlockComponents.Sources.Step(start_time = 1, height = 2e6) {
    "Dyad": {
      "placement": {
        "diagram": {"x1": 20, "y1": 180, "x2": 120, "y2": 280, "sw": 0.1, "sh": 0.1, "rot": 0}
      }
    }
  }
  mass = TranslationalComponents.Components.Mass(L = 1, m = 0.5) {
    "Dyad": {
      "placement": {
        "diagram": {"x1": 590, "x2": 690, "y1": 620, "y2": 720, "sh": 1, "sw": 1, "rot": 0}
      }
    }
  }
  path medium::HydraulicComponents.Interfaces.AbstractMedium = IsothermalCompressible(bulk_modulus = 1e9, let_gas = false)
relations
  initial double_acting_cylinder.port_a.m_flow = 0.0
  connect(port_a_side.port, double_acting_cylinder.port_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(step.y, port_a_side.p) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 156.5, "y": 230}, {"x": 156.5, "y": 450}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  continuity(medium, fixed_volume.port.medium)
  continuity(medium, port_a_side.port.medium)
  connect(double_acting_cylinder.flange, mass.flange_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 500, "y": 670}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(fixed_volume.port, double_acting_cylinder.port_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "experiments": {},
    "tests": {
      "case1": {
        "stop": 3,
        "atol": {"double_acting_cylinder.s": 0.01},
        "expect": {"signals": ["double_acting_cylinder.s"]}
      }
    },
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 1100,
        "rot": 0,
        "layer": "icon",
        "attrs": {}
      }
    ],
    "icons": {"default": "dyad://Dyad/Default.svg"},
    "path": {},
    "doc": {"behavior": true}
  }
}
end
Flattened Source
dyad
"""
This test case simulates a Double Acting cylinder with an external mass connected 
to the piston via a flange. The piston starts at the center position, with higher 
initial pressure in the fixed volume on the right side causing the piston to move 
left and stop when it hits the left chamber end. At 1 second, the pressure at the 
left side is increased, causing the piston to move right and stop upon hitting the 
right chamber end. The connected mass follows the piston movement, demonstrating 
the dynamic response of the cylinder and the attached load 
"""
test component DoubleActingCylinder
  double_acting_cylinder = HydraulicComponents.Machines.DoubleActingCylinder(L = 1.0, M = 0.2, area_a = 0.001, area_b = 0.001, s0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 450, "y1": 400, "x2": 550, "y2": 500}}}
  }
  port_a_side = HydraulicComponents.Sources.BoundaryPressure() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 290, "y1": 400, "x2": 190, "y2": 500, "rot": 180}
      },
      "tags": []
    }
  }
  fixed_volume = HydraulicComponents.Vessels.FixedVolume(p0 = 1e6, vol = 100) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 800, "y1": 400, "x2": 700, "y2": 500, "rot": 0}
      },
      "tags": []
    }
  }
  step = BlockComponents.Sources.Step(start_time = 1, height = 2e6) {
    "Dyad": {
      "placement": {
        "diagram": {"x1": 20, "y1": 180, "x2": 120, "y2": 280, "sw": 0.1, "sh": 0.1, "rot": 0}
      }
    }
  }
  mass = TranslationalComponents.Components.Mass(L = 1, m = 0.5) {
    "Dyad": {
      "placement": {
        "diagram": {"x1": 590, "x2": 690, "y1": 620, "y2": 720, "sh": 1, "sw": 1, "rot": 0}
      }
    }
  }
  path medium::HydraulicComponents.Interfaces.AbstractMedium = IsothermalCompressible(bulk_modulus = 1e9, let_gas = false)
relations
  initial double_acting_cylinder.port_a.m_flow = 0.0
  connect(port_a_side.port, double_acting_cylinder.port_a) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
  connect(step.y, port_a_side.p) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 156.5, "y": 230}, {"x": 156.5, "y": 450}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  continuity(medium, fixed_volume.port.medium)
  continuity(medium, port_a_side.port.medium)
  connect(double_acting_cylinder.flange, mass.flange_a) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 500, "y": 670}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  connect(fixed_volume.port, double_acting_cylinder.port_b) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "renderStyle": "standard"}}
metadata {
  "Dyad": {
    "experiments": {},
    "tests": {
      "case1": {
        "stop": 3,
        "atol": {"double_acting_cylinder.s": 0.01},
        "expect": {"signals": ["double_acting_cylinder.s"]}
      }
    },
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 1100,
        "rot": 0,
        "layer": "icon",
        "attrs": {}
      }
    ],
    "icons": {"default": "dyad://Dyad/Default.svg"},
    "path": {},
    "doc": {"behavior": true}
  }
}
end


Test Cases

julia
using HydraulicComponents
using DyadInterface: TransientAnalysis, rebuild_sol, ODEAlg
using ModelingToolkit: toggle_namespacing, get_initial_conditions, @named
using CSV, DataFrames, Plots

snapshotsdir = joinpath(dirname(dirname(pathof(HydraulicComponents))), "test", "snapshots")
<< @setup-block not executed in draft mode >>

Test Case case1

julia
@named model_case1 = HydraulicComponents.Machines.Tests.DoubleActingCylinder()
model_case1 = toggle_namespacing(model_case1, false)

model_case1 = toggle_namespacing(model_case1, true)
result_case1 = TransientAnalysis(; model = model_case1, alg = ODEAlg.Auto(), start = 0e+0, stop = 3e+0, abstol=1e-6, reltol=1e-6)
sol_case1 = rebuild_sol(result_case1)
<< @setup-block not executed in draft mode >>
julia
df_case1 = DataFrame(:t => sol_case1[:t], :actual => sol_case1[model_case1.double_acting_cylinder.s])
dfr_case1 = try CSV.read(joinpath(snapshotsdir, "HydraulicComponents.Machines.Tests.DoubleActingCylinder_case1_sig0.ref"), DataFrame); catch e; nothing; end
plt = plot(sol_case1, idxs=[model_case1.double_acting_cylinder.s], width=2, label="Actual value of double_acting_cylinder.s")
if !isnothing(dfr_case1)
  scatter!(plt, dfr_case1.t, dfr_case1.expected, mc=:red, ms=3, label="Expected value of double_acting_cylinder.s")
end
<< @setup-block not executed in draft mode >>
julia
plt
<< @example-block not executed in draft mode >>