Damper

model Damper "Linear (velocity dependent) damper"
    extends BaseClasses.TwoConnectorShapes;
    extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPort(final T = 293.15);

    parameter StateSelect stateSelect = StateSelect.default "Priority to use phi and w as states"
        annotation (
            HideResult = true,
            Dialog(tab = "Advanced"));
    parameter SI.TranslationalDampingConstant d = 1 "Damping constant";
    SI.Length r0[2](each final stateSelect = stateSelect, start = {0, 0});
    Real d0[2];
    SI.Velocity vx(start = 0);
    SI.Velocity vy(start = 0);
    SI.Velocity v;
    SI.Force f;
    parameter SI.Position s_small = 1e-10 "Prevent zero-division by regularization if distance between frame_a and frame_b is zero"
        annotation (Dialog(tab = "Advanced"));
    parameter Boolean enableAssert = false "Cause an assert when the distance between frame_a and frame_b < s_small"
        annotation (Dialog(tab = "Advanced"));
    parameter SI.Length length_a = planarWorld.defaultForceLength "Length of cylinder at frame_a side"
        annotation (Dialog(
            tab = "Animation",
            group = "Damper cylinders (if animation = true)",
            enable = animate));
    input SI.Diameter diameter_a = planarWorld.defaultForceWidth "Diameter of cylinder at frame_a side"
        annotation (Dialog(
            tab = "Animation",
            group = "Damper cylinders (if animation = true)",
            enable = animate));
    input SI.Diameter diameter_b = 0.6 * diameter_a "Diameter of cylinder at frame_b side"
        annotation (Dialog(
            tab = "Animation",
            group = "Damper cylinders (if animation = true)",
            enable = animate));
    input MB.Types.Color color_a = {0, 127, 255} "Color of cylinder at frame_a side"
        annotation (
            HideResult = true,
            Dialog(
                tab = "Animation",
                group = "Damper cylinders (if animation = true)",
                enable = animate,
                colorSelector = true));
    input MB.Types.Color color_b = {0, 64, 200} "Color of cylinder at frame_b side"
        annotation (
            HideResult = true,
            Dialog(
                tab = "Animation",
                group = "Damper cylinders (if animation = true)",
                enable = animate,
                colorSelector = true));
    SI.Distance length "Distance between the origin of frame_a and the origin of frame_b";
protected
    SI.Position r0_b[3] = {d0[1], d0[2], 0} * noEvent(min(length_a, length));
    MB.Visualizers.Advanced.Shape cylinder_a(shapeType = "cylinder", color = color_a, specularCoefficient = specularCoefficient, length = noEvent(min(length_a, length)), width = diameter_a, height = diameter_a, lengthDirection = {d0[1], d0[2], 0}, widthDirection = {0, 0, 1}, r = MB.Frames.resolve1(planarWorld.R, {frame_a.x, frame_a.y, zPosition}) + planarWorld.r_0, R = planarWorld.R) if planarWorld.enableAnimation and animate;
    MB.Visualizers.Advanced.Shape cylinder_b(shapeType = "cylinder", color = color_b, specularCoefficient = specularCoefficient, length = noEvent(max(length - length_a, 0)), width = diameter_b, height = diameter_b, lengthDirection = {r0[1], r0[2], 0}, widthDirection = {0, 0, 1}, r_shape = r0_b, r = MB.Frames.resolve1(planarWorld.R, {frame_a.x, frame_a.y, zPosition}) + planarWorld.r_0, R = planarWorld.R) if planarWorld.enableAnimation and animate;
equation
    if enableAssert then 
        assert(noEvent(s_small < length), "\n The distance between the origin of frame_a and the origin of frame_b\n of a Spring component became smaller as parameter s_small\n (= a small number, defined in the \"Advanced\" menu). The distance is\n set to s_small, although it is smaller, to avoid a division by zero\n when computing the direction of the line force. Possible reasons\n for this situation:\n - At initial time the distance may already be zero: Change the initial\n   positions of the bodies connected by this element.\n - Hardware stops are not modeled or are modeled not stiff enough.\n   Include stops, e.g., stiff springs, or increase the stiffness\n   if already present.\n - Another error in your model may lead to unrealistically large forces\n   and torques that would in reality destroy the stops.\n - The flange_b connector might be defined by a pre-defined motion,\n   e.g., with Modelica.Mechanics.Translational.Position and the\n   predefined flange_b.s is zero or negative.\n ");
    end if;
    frame_a.t + frame_b.t = 0;
    frame_a.x + r0[1] = frame_b.x;
    frame_a.y + r0[2] = frame_b.y;
    frame_a.fx + frame_b.fx = 0;
    frame_a.fy + frame_b.fy = 0;
    der(frame_a.x) + vx = der(frame_b.x);
    der(frame_a.y) + vy = der(frame_b.y);
    f = -d * v;
    v = {vx, vy} * d0;
    d0 = Modelica.Math.Vectors.normalize({r0[1], r0[2]}, s_small);
    length = Modelica.Math.Vectors.length(r0);
    lossPower = -f * v;
    frame_a.t = 0;
    frame_a.fx = d0[1] * f;
    frame_a.fy = d0[2] * f;

    annotation (
        Icon(graphics = {
            Line(points = {
                {-60, 30}, 
                {60, 30}}), 
            Line(points = {
                {-60, -30}, 
                {60, -30}}), 
            Line(points = {
                {-100, 0}, 
                {100, 0}}), 
            Rectangle(
                extent = {
                    {-60, 30}, 
                    {30, -30}},
                fillColor = {192, 192, 192},
                fillPattern = FillPattern.Solid), 
            Text(
                extent = {
                    {-150, 80}, 
                    {150, 40}},
                textString = "%name",
                textColor = {0, 0, 255}), 
            Text(
                extent = {
                    {-100, -50}, 
                    {100, -80}},
                textColor = {0, 0, 0},
                textString = "d=%d"), 
            Line(
                visible = useHeatPort,
                points = {
                    {-100, -100}, 
                    {-100, -80}, 
                    {-18, 0}},
                color = {191, 0, 0},
                pattern = LinePattern.Dot), 
            Ellipse(
                extent = {
                    {-90, 10}, 
                    {-70, -10}},
                lineColor = {0, 0, 0},
                fillColor = {255, 255, 255},
                fillPattern = FillPattern.Solid), 
            Ellipse(
                extent = {
                    {70, 10}, 
                    {90, -10}},
                lineColor = {0, 0, 0},
                fillColor = {255, 255, 255},
                fillPattern = FillPattern.Solid)}),
        Documentation(
            revisions = "<html>\n<p>\n<img src=\"modelica://PlanarMechanics/Resources/Images/dlr_logo.png\" alt=\"DLR logo\">\n<strong>Developed 2010 at the DLR Institute of System Dynamics and Control</strong>\n</p>\n</html>",
            info = "<html>\n<p>\nThis component is a <strong>linear damper</strong>, which acts as a line force between\n<code>frame_a</code> and <code>frame_b</code> (i.e. point-to-point). A&nbsp;<strong>force f</strong> is\nexerted on the origin of <code>frame_b</code> and with opposite sign on the origin\nof <code>frame_a</code> along the line from the origin of <code>frame_a</code> to\nthe origin of <code>frame_b</code> according to the equation:\n</p>\n\n<blockquote><pre>\nf = d*<strong>der</strong>(s);\n</pre></blockquote>\n\n<p>\nwhere <code>d</code> is the damping constant, <code>s</code>&nbsp;is the distance between\nthe origin of <code>frame_a</code> and origin of <code>frame_b</code>, and\n<code>der(s)</code> is the time derivative of&nbsp;<code>s</code>.\n</p>\n<p>\nIn the following figure a&nbsp;typical animation is shown where a&nbsp;mass is hanging\non a&nbsp;damper.\n</p>\n\n<div>\n<img src=\"modelica://PlanarMechanics/Resources/Images/Parts/Damper.png\" alt=\"Damper animation\">\n</div>\n</html>"));
end Damper;