LineForceWithMass

model LineForceWithMass "General line force component with an optional point mass on the connection line"
    import Modelica.Mechanics.MultiBody.Types;

    extends Interfaces.LineForceBase;

    Modelica.Mechanics.Translational.Interfaces.Flange_a flange_b "1-dim. translational flange (connect force of Translational library between flange_a and flange_b)"
        annotation (Placement(transformation(
            origin = {60, 100},
            extent = {
                {-10, -10}, 
                {10, 10}},
            rotation = 90)));
    Modelica.Mechanics.Translational.Interfaces.Flange_b flange_a "1-dim. translational flange (connect force of Translational library between flange_a and flange_b)"
        annotation (Placement(transformation(
            origin = {-60, 100},
            extent = {
                {-10, -10}, 
                {10, 10}},
            rotation = 90)));
    parameter Boolean animateLine = true "= true, if a line shape between frame_a and frame_b shall be visualized";
    parameter Boolean animateMass = true "= true, if point mass shall be visualized as sphere provided m > 0";
    parameter SI.Mass m(min = 0) = 0 "Mass of point mass on the connection line between the origin of frame_a and the origin of frame_b";
    parameter Real lengthFraction(unit = "1", min = 0, max = 1) = 0.5 "Location of point mass with respect to frame_a as a fraction of the distance from frame_a to frame_b";
    input Types.SpecularCoefficient specularCoefficient = world.defaultSpecularCoefficient "Reflection of ambient light (= 0: light is completely absorbed)"
        annotation (Dialog(
            tab = "Animation",
            enable = animateLine or animateMass));
    parameter Types.ShapeType lineShapeType = "cylinder" "Type of shape visualizing the line from frame_a to frame_b"
        annotation (Dialog(
            tab = "Animation",
            group = "if animateLine = true",
            enable = animateLine));
    input SI.Length lineShapeWidth = world.defaultArrowDiameter "Width of shape"
        annotation (Dialog(
            tab = "Animation",
            group = "if animateLine = true",
            enable = animateLine));
    input SI.Length lineShapeHeight = lineShapeWidth "Height of shape"
        annotation (Dialog(
            tab = "Animation",
            group = "if animateLine = true",
            enable = animateLine));
    parameter Types.ShapeExtra lineShapeExtra = 0 "Extra parameter for shape"
        annotation (Dialog(
            tab = "Animation",
            group = "if animateLine = true",
            enable = animateLine));
    input Types.Color lineShapeColor = Modelica.Mechanics.MultiBody.Types.Defaults.SensorColor "Color of line shape"
        annotation (Dialog(
            colorSelector = true,
            tab = "Animation",
            group = "if animateLine = true",
            enable = animateLine));
    input Real massDiameter = world.defaultBodyDiameter "Diameter of point mass sphere"
        annotation (Dialog(
            tab = "Animation",
            group = "if animateMass = true",
            enable = animateMass));
    input Types.Color massColor = Modelica.Mechanics.MultiBody.Types.Defaults.BodyColor "Color of point mass"
        annotation (Dialog(
            colorSelector = true,
            tab = "Animation",
            group = "if animateMass = true",
            enable = animateMass));
protected
    SI.Force fa "Force from flange_a";
    SI.Force fb "Force from flange_b";
    SI.Position r_CM_0[3](each stateSelect = StateSelect.avoid) "Position vector from world frame to point mass, resolved in world frame";
    SI.Velocity v_CM_0[3](each stateSelect = StateSelect.avoid) "First derivative of r_CM_0";
    SI.Acceleration ag_CM_0[3] "der(v_CM_0) - gravityAcceleration";
    Visualizers.Advanced.Shape lineShape(shapeType = lineShapeType, color = lineShapeColor, specularCoefficient = specularCoefficient, length = length, width = lineShapeWidth, height = lineShapeHeight, lengthDirection = e_rel_0, widthDirection = Frames.resolve1(frame_a.R, {0, 1, 0}), extra = lineShapeExtra, r = frame_a.r_0) if world.enableAnimation and animateLine;
    Visualizers.Advanced.Shape massShape(shapeType = "sphere", color = massColor, specularCoefficient = specularCoefficient, length = massDiameter, width = massDiameter, height = massDiameter, lengthDirection = e_rel_0, widthDirection = {0, 1, 0}, r_shape = e_rel_0 * (length * lengthFraction - 0.5 * massDiameter), r = frame_a.r_0) if world.enableAnimation and animateMass and 0 < m;
equation
    if 0 < m then 
        r_CM_0 = frame_a.r_0 + r_rel_0 * lengthFraction;
        v_CM_0 = der(r_CM_0);
        ag_CM_0 = der(v_CM_0) - world.gravityAcceleration(r_CM_0);
        frame_a.f = Frames.resolve2(frame_a.R, m * (1 - lengthFraction) * ag_CM_0 - e_rel_0 * fa);
        frame_b.f = Frames.resolve2(frame_b.R, m * lengthFraction * ag_CM_0 - e_rel_0 * fb);
    else 
        r_CM_0 = zeros(3);
        v_CM_0 = zeros(3);
        ag_CM_0 = zeros(3);
        frame_a.f = -Frames.resolve2(frame_a.R, e_rel_0 * fa);
        frame_b.f = -Frames.resolve2(frame_b.R, e_rel_0 * fb);
    end if;
    if 0 < cardinality(flange_a) and 0 < cardinality(flange_b) then 
        fa = flange_a.f;
        fb = flange_b.f;
    elseif 0 < cardinality(flange_a) and cardinality(flange_b) == 0 then 
        fa = flange_a.f;
        fb = -fa;
    elseif cardinality(flange_a) == 0 and 0 < cardinality(flange_b) then 
        fa = -fb;
        fb = flange_b.f;
    else 
        fa = 0;
        fb = 0;
    end if;
    flange_a.s = 0;
    flange_b.s = length;

    annotation (
        Icon(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Ellipse(
                    extent = {
                        {-95, -40}, 
                        {-15, 40}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {-85, -30}, 
                        {-25, 30}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    extent = {
                        {15, -40}, 
                        {95, 40}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {23, -30}, 
                        {83, 29}},
                    lineColor = {128, 128, 128},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-150, -50}, 
                        {150, -90}},
                    textString = "%name",
                    lineColor = {0, 0, 255}), 
                Rectangle(
                    extent = {
                        {-40, 41}, 
                        {44, -40}},
                    lineColor = {255, 255, 255},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    extent = {
                        {-70, 15}, 
                        {-41, -13}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {40, 14}, 
                        {69, -14}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Line(points = {
                    {-56, 0}, 
                    {-56, 23}, 
                    {-30, 23}, 
                    {-30, 70}, 
                    {-60, 70}, 
                    {-60, 101}}), 
                Line(points = {
                    {55, -1}, 
                    {55, 20}, 
                    {30, 20}, 
                    {30, 70}, 
                    {60, 70}, 
                    {60, 100}}), 
                Line(
                    points = {
                        {-56, 0}, 
                        {55, -1}},
                    pattern = LinePattern.Dot), 
                Ellipse(
                    extent = {
                        {-8, 8}, 
                        {8, -8}},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    visible = fixedRotationAtFrame_a,
                    extent = {
                        {-70, 30}, 
                        {-130, -30}},
                    lineColor = {255, 0, 0}), 
                Text(
                    visible = fixedRotationAtFrame_a,
                    extent = {
                        {-62, 50}, 
                        {-140, 30}},
                    lineColor = {255, 0, 0},
                    textString = "R=0"), 
                Ellipse(
                    visible = fixedRotationAtFrame_b,
                    extent = {
                        {70, 30}, 
                        {130, -30}},
                    lineColor = {255, 0, 0}), 
                Text(
                    visible = fixedRotationAtFrame_b,
                    extent = {
                        {62, 50}, 
                        {140, 30}},
                    lineColor = {255, 0, 0},
                    textString = "R=0")}),
        Diagram(
            coordinateSystem(
                preserveAspectRatio = true,
                extent = {
                    {-100, -100}, 
                    {100, 100}}),
            graphics = {
                Line(
                    points = {
                        {-60, 80}, 
                        {46, 80}},
                    color = {0, 0, 255}), 
                Polygon(
                    points = {
                        {60, 80}, 
                        {45, 86}, 
                        {45, 74}, 
                        {60, 80}},
                    lineColor = {0, 0, 255},
                    fillColor = {0, 0, 255},
                    fillPattern = FillPattern.Solid), 
                Text(
                    extent = {
                        {-40, 98}, 
                        {40, 82}},
                    textString = "length",
                    lineColor = {0, 0, 255}), 
                Ellipse(
                    extent = {
                        {-100, -40}, 
                        {-20, 40}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {-90, -30}, 
                        {-30, 30}},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    extent = {
                        {20, -40}, 
                        {100, 40}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {31, -29}, 
                        {91, 30}},
                    lineColor = {128, 128, 128},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Rectangle(
                    extent = {
                        {-50, 39}, 
                        {50, -41}},
                    lineColor = {255, 255, 255},
                    fillColor = {255, 255, 255},
                    fillPattern = FillPattern.Solid), 
                Ellipse(
                    extent = {
                        {-74, 15}, 
                        {-45, -13}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Ellipse(
                    extent = {
                        {45, 15}, 
                        {74, -13}},
                    fillPattern = FillPattern.Sphere,
                    fillColor = {192, 192, 192}), 
                Line(points = {
                    {-60, 0}, 
                    {-60, 24}, 
                    {-40, 24}, 
                    {-40, 60}, 
                    {-60, 60}, 
                    {-60, 100}}), 
                Line(points = {
                    {60, 1}, 
                    {60, 21}, 
                    {40, 21}, 
                    {40, 60}, 
                    {60, 60}, 
                    {60, 100}}), 
                Line(
                    points = {
                        {-60, 0}, 
                        {60, 0}},
                    pattern = LinePattern.Dot), 
                Ellipse(
                    extent = {
                        {-8, 8}, 
                        {8, -8}},
                    fillPattern = FillPattern.Solid), 
                Line(
                    points = {
                        {-60, 0}, 
                        {-31, 0}},
                    color = {0, 0, 255}), 
                Polygon(
                    points = {
                        {-19, 0}, 
                        {-31, 3}, 
                        {-31, -3}, 
                        {-19, 0}},
                    lineColor = {0, 0, 255}), 
                Line(
                    points = {
                        {-60, 16}, 
                        {0, 16}},
                    color = {0, 0, 255}), 
                Line(
                    points = {
                        {0, 0}, 
                        {0, 20}},
                    color = {0, 0, 255}), 
                Text(
                    extent = {
                        {-49, -11}, 
                        {-8, -21}},
                    textString = "e_rel_0"), 
                Polygon(
                    points = {
                        {0, 16}, 
                        {-12, 19}, 
                        {-12, 13}, 
                        {0, 16}},
                    lineColor = {0, 0, 255}), 
                Text(
                    extent = {
                        {-50, 35}, 
                        {51, 26}},
                    textString = "length*lengthFraction"), 
                Line(
                    points = {
                        {-17, 26}, 
                        {-26, 16}},
                    pattern = LinePattern.Dot,
                    color = {0, 0, 255}), 
                Line(
                    points = {
                        {-31, -13}, 
                        {-40, 0}},
                    pattern = LinePattern.Dot,
                    color = {0, 0, 255})}),
        Documentation(info = "<html>\n<p>\nThis component is used to exert a <strong>line force</strong>\nbetween the origin of frame_a and the origin of frame_b\nby attaching components of the <strong>1-dimensional translational</strong>\nmechanical library of Modelica (Modelica.Mechanics.Translational)\nbetween the two flange connectors <strong>flange_a</strong> and\n<strong>flange_b</strong>. Optionally, there is a <strong>point mass</strong> on the line\nconnecting the origin of frame_a and the origin of frame_b.\nThis point mass approximates the <strong>mass</strong> of the <strong>force element</strong>.\nThe distance of the point mass from frame_a as a fraction of the\ndistance between frame_a and frame_b is defined via\nparameter <strong>lengthFraction</strong> (default is 0.5, i.e., the point\nmass is in the middle of the line).\n</p>\n<p>\nIn the translational library there is the implicit assumption that\nforces of components that have only one flange connector act with\nopposite sign on the bearings of the component. This assumption\nis also used in the LineForceWithMass component: If a connection\nis present to only one of the flange connectors, then the force\nin this flange connector acts implicitly with opposite sign also\nin the other flange connector.\n</p>\n</html>"));
end LineForceWithMass;