/// <summary> /// Debug Code: Beam with simple supports at left and right ends that has triangular uniform load across beam length. /// Load is 0 at left end and increases towards right end. /// Calculate results from User entered values and send output to Debug. /// </summary> /// <param name="loadUniformValue">Uniform load values.</param> public static void CheckResultsSampleBeam06(LoadUniformValues loadUniformValue) { Debug.WriteLine("\nBeam with simple supports at left and right ends that has triangular uniform load across beam length. Load is 0 at left end and increases towards right end:"); double E = CommonItems.doubleYoungsModulus; double I = CommonItems.doubleInertia; double l = CommonItems.doubleBeamLength; double wL = loadUniformValue.DoubleForceLeft; double wR = loadUniformValue.DoubleForceRight; double xL = loadUniformValue.DoublePositionLeft; double xR = loadUniformValue.DoublePositionRight; Debug.WriteLine($"Inputs: wL={wL}, wR={wR}, xL={xL}, xRL={xR}"); if ((wL == 0d) && (Abs(wR) > 0d) && (xL == 0d) && (xR == l)) //Check input. { Debug.WriteLine($"Inputs: E={E}, I={I}, l={l}, wL={wL}, wR={wR}"); // Reverse signs, upward forces are positive, downward forces are negative. double W = wR * l / 2d; // Total load. double Rleft = -(W / 3d); double Rright = -(W * 2d / 3d); double Mmax = -(W * l * 2d / (9d * Sqrt(3d))); double Dmax = W * l * l * l * 0.01304 / (E * I); Debug.WriteLine($"Reaction left={Rleft}, reaction right={Rright}"); Debug.WriteLine($"Shear left={-Rleft}, Shear right={Rright}"); Debug.WriteLine($"Maximum moment={Mmax} at x={l * 0.5774}"); Debug.WriteLine($"Maximum deflection={Dmax} at x={l * 0.5193}"); } else { Debug.WriteLine($"Skipped results since entered uniform load values not proper or not across beam length."); } }
/// <summary> /// Debug Code: Beam with simple supports at left and right ends that has triangular uniform load across beam length. Peak is at beam center. /// Calculate results from User entered values and send output to Debug. /// </summary> /// <param name="loadUniformValue">Uniform load values.</param> public static void CheckResultsSampleBeam07(LoadUniformValues loadUniformValue) { Debug.WriteLine("\nBeam with simple supports at left and right ends that has triangular uniform load across beam length. Peak is at beam center:"); double E = CommonItems.doubleYoungsModulus; double I = CommonItems.doubleInertia; double l = CommonItems.doubleBeamLength; // Following input is for left trianglular load. double wL = loadUniformValue.DoubleForceLeft; double wR = loadUniformValue.DoubleForceRight; double xL = loadUniformValue.DoublePositionLeft; double xR = loadUniformValue.DoublePositionRight; Debug.WriteLine($"Inputs: wL={wL}, wR={wR}, xL={xL}, xR={xR}"); double center = l / 2d; // Beam midpoint. if ((wL == 0d) && (Abs(wR) > 0d) && (xL == 0d) && (xR == center)) //Check input. { Debug.WriteLine($"Inputs: E={E}, I={I}, l={l}, wL={wL}, wR={wR}, xR={xR}"); // Reverse signs, upward forces are positive, downward forces are negative. double W = wR * center; // Total load. double Rleft = -(W / 2d); double Rright = Rleft; double Mmax = -(W * l / 6d); double Dmax = W * l * l * l / (E * I * 60d); Debug.WriteLine($"Reaction left={Rleft}, reaction right={Rright}"); Debug.WriteLine($"Shear left={-Rleft}, Shear right={Rright}, Shear center=0.0"); Debug.WriteLine($"Maximum moment={Mmax} at x={center}"); Debug.WriteLine($"Maximum deflection={Dmax} at x={center}"); } else { Debug.WriteLine($"Skipped results since entered uniform load values not proper."); } }
/// <summary> /// Debug Code: Beam with simple supports at left and right ends that has rectangular uniform load across beam length. /// Calculate results from User entered values and send output to Debug. /// </summary> /// <param name="loadUniformValue">Uniform load values.</param> public static void CheckResultsSampleBeam05(LoadUniformValues loadUniformValue) { Debug.WriteLine("\nBeam with simple supports at left and right ends that has rectangular uniform load across beam length:"); double E = CommonItems.doubleYoungsModulus; double I = CommonItems.doubleInertia; double l = CommonItems.doubleBeamLength; double wL = loadUniformValue.DoubleForceLeft; double wR = loadUniformValue.DoubleForceRight; double xL = loadUniformValue.DoublePositionLeft; double xR = loadUniformValue.DoublePositionRight; if ((wL == wR) && (xL == 0d) && (xR == l)) //Check input. { Debug.WriteLine($"Inputs: E={E}, I={I}, l={l}, w={wL}"); // Reverse signs, upward forces are positive, downward forces are negative. double R = -(wL * l / 2d); double Mmax = -(wL * l * l / 8d); // Mmax occurs at midpoint of beam. double Dmax = (wL * l * l * l * l * 5d / (384d * E * I)); // Dmax occurs at midpoint of beam. Debug.WriteLine($"Reactions left and right={R}"); Debug.WriteLine($"Shear left={-R}, Shear right={R}"); Debug.WriteLine($"Maximum moment={Mmax} at x={l / 2d}"); Debug.WriteLine($"Maximum deflection={Dmax} at x={l / 2d}"); } else { Debug.WriteLine($"Skipped results since entered uniform load values not equal or not across beam length."); } }
/// <summary> /// Add uniform load to list listLoadUniformValues after generating simulated load list for uniform load. /// </summary> /// <param name="doubleLoadUniformPositionLeft">Left uniform load position from left end of beam. Minimum value is 0d. Maximum value is doubleBeamLength.</param> /// <param name="doubleLoadUniformPositionRight">Right uniform load position from left end of beam. Value must be > DoublePositionLeft and <= doubleBeamLength.</param> /// <param name="doubleLoadUniformForceLeft">Left uniform load force. Uniform forces are distributed via straight line from left to right. Downward forces are negative.</param> /// <param name="doubleLoadUniformForceRight">Right uniform load force. Uniform forces are distributed via straight line from left to right. Downward forces are negative.</param> public static void AddLoadUniformToList(double doubleLoadUniformPositionLeft, double doubleLoadUniformPositionRight, double doubleLoadUniformForceLeft, double doubleLoadUniformForceRight) { //Debug.WriteLine($"CommonItems.AddLoadUniformToList(): Method entered."); LoadUniformValues loadUniformValues = new LoadUniformValues { }; UniformLoadSimulate(ref loadUniformValues, doubleLoadUniformPositionLeft, doubleLoadUniformPositionRight, doubleLoadUniformForceLeft, doubleLoadUniformForceRight); listLoadUniformValues.Add(loadUniformValues); if (listLoadUniformValues.Count > 1) { // More than one uniform load entered so sort by DoublePositionLeft. listLoadUniformValues.Sort((x, y) => x.DoublePositionLeft.CompareTo(y.DoublePositionLeft)); } boolEnteredLoadUniform = true; }
/*** private static methods follow *************************************************************************************/ /// <summary> /// Calculate list of concentrated loads that simulate a uniform load. Concentrated loads are derived from segments of uniform load. /// The area of each segment is calculated and an equivalent concentrated load is placed at centroid of each segment. /// Parameters used to keep method independent from equivalent CommonItems values. /// </summary> /// <param name="loadUniformValues">Class used to save User entered uniform loads.</param> /// <param name="doubleLoadUniformPositionLeft">Left uniform load position from left end of beam. Minimum value is 0d. Maximum value is doubleBeamLength.</param> /// <param name="doubleLoadUniformPositionRight">Right uniform load position from left end of beam. Value must be > DoublePositionLeft and <= doubleBeamLength.</param> /// <param name="doubleLoadUniformForceLeft">Left uniform load force. Uniform forces are distributed via straight line from left to right. Downward forces are negative.</param> /// <param name="doubleLoadUniformForceRight">Right uniform load force. Uniform forces are distributed via straight line from left to right. Downward forces are negative.</param> private static void UniformLoadSimulate(ref LoadUniformValues loadUniformValues, double doubleLoadUniformPositionLeft, double doubleLoadUniformPositionRight, double doubleLoadUniformForceLeft, double doubleLoadUniformForceRight) { loadUniformValues.DoublePositionLeft = doubleLoadUniformPositionLeft; loadUniformValues.DoublePositionRight = doubleLoadUniformPositionRight; loadUniformValues.DoubleForceLeft = doubleLoadUniformForceLeft; loadUniformValues.DoubleForceRight = doubleLoadUniformForceRight; loadUniformValues.DoubleLoadLength = doubleLoadUniformPositionRight - doubleLoadUniformPositionLeft; if (doubleOutputSegmentLength == 0d) { // Case if doubleOutputSegmentLength was not entered or set to 0. loadUniformValues.IntNumberOfSegments = 1; loadUniformValues.DoubleSegmentLength = loadUniformValues.DoubleLoadLength; } else { // Calculate number of beam segments to spread uniform load across beam length. int intBeamSegments = (int)Round(doubleBeamLength / doubleOutputSegmentLength, MidpointRounding.AwayFromZero); double doubleBeamSegmentLength = doubleBeamLength / intBeamSegments; //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): doubleBeamLength={doubleBeamLength}, intBeamSegments={intBeamSegments}, doubleBeamSegmentLength={doubleBeamSegmentLength}"); // Use beam segment length as starting value to calculate load segment length. if (doubleBeamSegmentLength >= loadUniformValues.DoubleLoadLength) { loadUniformValues.IntNumberOfSegments = 1; loadUniformValues.DoubleSegmentLength = loadUniformValues.DoubleLoadLength; } else { loadUniformValues.IntNumberOfSegments = (int)Round(loadUniformValues.DoubleLoadLength / doubleBeamSegmentLength, MidpointRounding.AwayFromZero); loadUniformValues.DoubleSegmentLength = loadUniformValues.DoubleLoadLength / loadUniformValues.IntNumberOfSegments; } } //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): loadUniformValues.IntNumberOfSegments={loadUniformValues.IntNumberOfSegments}, loadUniformValues.DoubleSegmentLength={loadUniformValues.DoubleSegmentLength}"); // Total uniform load force is area of uniform load. Absolute values need to be considered since forces can be positive or negative. // Next two variables are used as 'ref' variables if uniform load is triangle or trapazoid. Therefore they need to be initialized to 0d. double doubleArea = 0d; // Calculated segment area (force) of rectangle, triangle, or trapazoid. double doubleCentroid = 0d; // Calculated segment centroid of rectangle, triangle, or trapazoid. loadUniformValues.ListSimulatedLoads = new List <LoadConcentratedValues> { }; // Case #1: Uniform load is a rectangle. bool boolLoadIsRectangle = false; if (loadUniformValues.DoubleForceLeft == loadUniformValues.DoubleForceRight) { //Debug.WriteLine($"EnterLoadsUniform.UniformLoadSimulate(): Uniform load is a rectangle."); boolLoadIsRectangle = true; doubleCentroid = loadUniformValues.DoublePositionLeft + loadUniformValues.DoubleSegmentLength / 2d; doubleArea = loadUniformValues.DoubleForceLeft * loadUniformValues.DoubleLoadLength / loadUniformValues.IntNumberOfSegments; if (loadUniformValues.IntNumberOfSegments == 1) // Applied single rectangle load. { //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Applied single rectangle load, doubleCentroid={doubleCentroid}, doubleArea={doubleArea}"); LoadConcentratedValues loadConcentratedValues = new LoadConcentratedValues { DoubleLoadConcentratedPosition = doubleCentroid, DoubleLoadConcentratedForce = doubleArea, DoubleLoadConcentratedMoment = 0d // Moment always zero if uniform load. }; loadUniformValues.ListSimulatedLoads.Add(loadConcentratedValues); } else { doubleCentroid -= loadUniformValues.DoubleSegmentLength; // Initialize doubleCentroid value for first pass in next loop. for (int i = 0; i < loadUniformValues.IntNumberOfSegments; i++) { doubleCentroid += loadUniformValues.DoubleSegmentLength; //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Applied multiple rectangle loads, doubleCentroid={doubleCentroid}, doubleArea={doubleArea}"); LoadConcentratedValues loadConcentratedValues = new LoadConcentratedValues { DoubleLoadConcentratedPosition = doubleCentroid, DoubleLoadConcentratedForce = doubleArea, DoubleLoadConcentratedMoment = 0d // Moment always zero if uniform load. }; loadUniformValues.ListSimulatedLoads.Add(loadConcentratedValues); } } } // Case #2: Uniform load is a triangle or trapazoid. double doubleTriangleHeight; // Difference of ForceLeft and ForceRight is triangle height. if (!boolLoadIsRectangle) { //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Uniform load is a triangle or trapazoid."); if (loadUniformValues.IntNumberOfSegments == 1) // Applied single triangle or trapazoid uniform load. { doubleTriangleHeight = CalcTriangleHeight(loadUniformValues.DoubleForceLeft, loadUniformValues.DoubleForceRight); if (Abs(loadUniformValues.DoubleForceLeft) > Abs(loadUniformValues.DoubleForceRight)) { CalcCentroidValues(ref doubleArea, ref doubleCentroid, loadUniformValues.DoubleLoadLength, loadUniformValues.DoubleForceRight, doubleTriangleHeight, true); //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Case: Abs(DoubleForceLeft) > Abs(DoubleForceRight), doubleArea={doubleArea}, doubleCentroid={doubleCentroid}"); } else { CalcCentroidValues(ref doubleArea, ref doubleCentroid, loadUniformValues.DoubleLoadLength, loadUniformValues.DoubleForceLeft, doubleTriangleHeight, false); //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Case: Abs(DoubleForceLeft) < Abs(DoubleForceRight), doubleArea={doubleArea}, doubleCentroid={doubleCentroid}"); } doubleCentroid = loadUniformValues.DoublePositionLeft + doubleCentroid; //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Case: Applied single triangle or trapazoid uniform load, doubleCentroid={doubleCentroid}, doubleArea={doubleArea}"); LoadConcentratedValues loadConcentratedValues = new LoadConcentratedValues { DoubleLoadConcentratedPosition = doubleCentroid, DoubleLoadConcentratedForce = doubleArea, DoubleLoadConcentratedMoment = 0d // Moment always zero if uniform load. }; loadUniformValues.ListSimulatedLoads.Add(loadConcentratedValues); } else { // Equation of slope is m=(y2-y1)/(x2-x1) where m is the slope. More at: https://cls.syr.edu/mathtuneup/grapha/Unit4/Unit4a.html double doubleSlope = (loadUniformValues.DoubleForceRight - loadUniformValues.DoubleForceLeft) / loadUniformValues.DoubleLoadLength; // Equation of a line is y=mx+b where m is the slope and b is the y-intercept. double doubleInterceptForce = loadUniformValues.DoubleForceLeft; // Save value for use below. double doubleInterceptPosition = loadUniformValues.DoublePositionLeft; // Save value for use below. double doubleLoadSegmentPositionLeft = loadUniformValues.DoublePositionLeft - loadUniformValues.DoubleSegmentLength; // Initialize value for first pass in next loop. double doubleSegmentPositionLeft; // Initialize value for first pass in next loop. double doubleSegmentForceLeft; // Initialize value for first pass in next loop. double doubleSegmentPositionRight = loadUniformValues.DoublePositionLeft; // Initialize value for first pass in next loop. double doubleSegmentForceRight = loadUniformValues.DoubleForceLeft; // Initialize value for first pass in next loop. //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): doubleSlope={doubleSlope}, doubleInterceptPosition={doubleInterceptPosition}, doubleInterceptForce={doubleInterceptForce}, loadUniformValues.DoubleSegmentLength={loadUniformValues.DoubleSegmentLength}"); for (int i = 0; i < loadUniformValues.IntNumberOfSegments; i++) { doubleSegmentPositionLeft = doubleSegmentPositionRight; doubleSegmentPositionRight = doubleSegmentPositionLeft + loadUniformValues.DoubleSegmentLength; doubleSegmentForceLeft = doubleSegmentForceRight; doubleSegmentForceRight = doubleSlope * (doubleSegmentPositionRight - doubleInterceptPosition) + doubleInterceptForce; //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Segment {i + 1} of {loadUniformValues.IntNumberOfSegments}: Line points are (doubleSegmentPositionLeft={doubleSegmentPositionLeft}, doubleSegmentForceLeft={doubleSegmentForceLeft}), (doubleSegmentPositionRight={doubleSegmentPositionRight}, doubleSegmentForceRight={doubleSegmentForceRight})"); doubleTriangleHeight = CalcTriangleHeight(doubleSegmentForceLeft, doubleSegmentForceRight); if (Abs(doubleSegmentForceLeft) > Abs(doubleSegmentForceRight)) { CalcCentroidValues(ref doubleArea, ref doubleCentroid, loadUniformValues.DoubleSegmentLength, doubleSegmentForceRight, doubleTriangleHeight, true); //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Abs(doubleSegmentForceLeft) > Abs(doubleSegmentForceRight), doubleArea={doubleArea}, doubleCentroid={doubleCentroid}"); } else { CalcCentroidValues(ref doubleArea, ref doubleCentroid, loadUniformValues.DoubleSegmentLength, doubleSegmentForceLeft, doubleTriangleHeight, false); //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Abs(doubleSegmentForceLeft) < Abs(doubleSegmentForceRight), doubleArea={doubleArea}, doubleCentroid={doubleCentroid}"); } doubleLoadSegmentPositionLeft += loadUniformValues.DoubleSegmentLength; doubleCentroid = doubleLoadSegmentPositionLeft + doubleCentroid; //Debug.WriteLine($"CommonItems.UniformLoadSimulate(): Applied sloping uniform loads {i + 1} of {loadUniformValues.IntNumberOfSegments}, doubleCentroid={doubleCentroid}, doubleArea={doubleArea}"); LoadConcentratedValues loadConcentratedValues = new LoadConcentratedValues { DoubleLoadConcentratedPosition = doubleCentroid, DoubleLoadConcentratedForce = doubleArea, DoubleLoadConcentratedMoment = 0d // Moment always zero if uniform load. }; loadUniformValues.ListSimulatedLoads.Add(loadConcentratedValues); } } } }