diff --git a/StructureHelperLogics/Models/BeamShears/BeamSectionShearStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/BeamSectionShearStrengthLogic.cs new file mode 100644 index 0000000..d54472e --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/BeamSectionShearStrengthLogic.cs @@ -0,0 +1,66 @@ +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + internal class BeamSectionShearStrengthLogic : IBeamShearStrenghLogic + { + private readonly ISectionEffectiveness sectionEffectiveness; + private readonly double concreteStrength; + private readonly IInclinedSection inclinedSection; + + private double crackLength; + + public BeamSectionShearStrengthLogic( + ISectionEffectiveness sectionEffectiveness, + double concreteStrength, + IInclinedSection inclinedSection, + IShiftTraceLogger? traceLogger) + { + this.sectionEffectiveness = sectionEffectiveness; + this.concreteStrength = concreteStrength; + this.inclinedSection = inclinedSection; + TraceLogger = traceLogger; + } + + public IShiftTraceLogger? TraceLogger { get; set; } + + public double GetShearStrength() + { + TraceLogger?.AddMessage($"Base shape factor = {sectionEffectiveness.BaseShapeFactor}, (dimensionless)"); + TraceLogger?.AddMessage($"Section shape factor = {sectionEffectiveness.ShapeFactor}, (dimensionless)"); + TraceLogger?.AddMessage($"Effective depth = {inclinedSection.EffectiveDepth}, (m)"); + crackLength = inclinedSection.EndCoord - inclinedSection.StartCoord; + TraceLogger?.AddMessage($"Crack length = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}, (m)"); + RestrictCrackLength(); + double concreteMoment = sectionEffectiveness.BaseShapeFactor * sectionEffectiveness.ShapeFactor * concreteStrength * inclinedSection.WebWidth * inclinedSection.EffectiveDepth * inclinedSection.EffectiveDepth; + double shearStrength = concreteMoment / crackLength; + TraceLogger?.AddMessage($"Shear strength of concrete = {shearStrength}, (N)"); + return shearStrength; + } + + private void RestrictCrackLength() + { + double maxCrackLength = sectionEffectiveness.MaxCrackLengthRatio * inclinedSection.EffectiveDepth; + if (crackLength > maxCrackLength) + { + TraceLogger?.AddMessage($"Crack length c = {crackLength} is greater than maximum crack length = {maxCrackLength}"); + crackLength = maxCrackLength; + TraceLogger?.AddMessage($"Crack length = {crackLength}"); + return; + } + double minCrackLength = sectionEffectiveness.MinCrackLengthRatio * inclinedSection.EffectiveDepth; + if (crackLength > minCrackLength) + { + TraceLogger?.AddMessage($"Crack length c = {crackLength} is less than minimum crack length = {minCrackLength}"); + crackLength = minCrackLength; + TraceLogger?.AddMessage($"Crack length = {crackLength}"); + } + return; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs b/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs new file mode 100644 index 0000000..7912a30 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs @@ -0,0 +1,32 @@ +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.Materials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class BeamShearSection : IBeamShearSection + { + public Guid Id { get; } + public string? Name { get; set; } + public IConcreteLibMaterial Material { get; set; } + + public IShape Shape { get; } + + public double CenterCover { get; set; } + + public BeamShearSection(Guid id, IShape shape) + { + Id = id; + Shape = shape; + } + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/BeamSheaStrengthByStirrupDensity.cs b/StructureHelperLogics/Models/BeamShears/BeamShearStrengthByStirrupDensityLogic.cs similarity index 90% rename from StructureHelperLogics/Models/BeamShears/BeamSheaStrengthByStirrupDensity.cs rename to StructureHelperLogics/Models/BeamShears/BeamShearStrengthByStirrupDensityLogic.cs index 9f1aeb8..a5cdf83 100644 --- a/StructureHelperLogics/Models/BeamShears/BeamSheaStrengthByStirrupDensity.cs +++ b/StructureHelperLogics/Models/BeamShears/BeamShearStrengthByStirrupDensityLogic.cs @@ -12,14 +12,14 @@ using System.Threading.Tasks; namespace StructureHelperLogics.Models.BeamShears { - public class BeamSheaStrengthByStirrupDensity : IBeamShearStrenghLogic + public class BeamShearStrengthByStirrupDensityLogic : IBeamShearStrenghLogic { private readonly IStirrupEffectiveness stirrupEffectiveness; private readonly IStirrupByDensity stirrupByDensity; private readonly IInclinedSection inclinedSection; - public BeamSheaStrengthByStirrupDensity( + public BeamShearStrengthByStirrupDensityLogic( IStirrupEffectiveness stirrupEffectiveness, IStirrupByDensity stirrupByDensity, IInclinedSection inclinedSection, @@ -40,8 +40,8 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger?.AddMessage("Calculation has been started", TraceLogStatuses.Debug); double crackLength = inclinedSection.EndCoord - inclinedSection.StartCoord; TraceLogger?.AddMessage($"Length of crack = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}(m)"); - double maxCrackLength = stirrupEffectiveness.MaxCrackLengthFactor * inclinedSection.EffectiveDepth; - TraceLogger?.AddMessage($"Max length of crack = {stirrupEffectiveness.MaxCrackLengthFactor} * {inclinedSection.EffectiveDepth} = {maxCrackLength}(m)"); + double maxCrackLength = stirrupEffectiveness.MaxCrackLengthRatio * inclinedSection.EffectiveDepth; + TraceLogger?.AddMessage($"Max length of crack = {stirrupEffectiveness.MaxCrackLengthRatio} * {inclinedSection.EffectiveDepth} = {maxCrackLength}(m)"); double finalCrackLength = Math.Min(crackLength, maxCrackLength); TraceLogger?.AddMessage($"Length of crack = Min({crackLength}, {maxCrackLength}) = {finalCrackLength}(m)"); double strength = stirrupEffectiveness.StirrupShapeFactor * stirrupEffectiveness.StirrupPlacementFactor * finalCrackLength * stirrupByDensity.StirrupDensity; diff --git a/StructureHelperLogics/Models/BeamShears/Factories/SectionEffectivenessFactory.cs b/StructureHelperLogics/Models/BeamShears/Factories/SectionEffectivenessFactory.cs new file mode 100644 index 0000000..09dc799 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Factories/SectionEffectivenessFactory.cs @@ -0,0 +1,52 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public static class SectionEffectivenessFactory + { + public static ISectionEffectiveness GetSheaEffectiveness(BeamShearSectionType sectionType) + { + if (sectionType == BeamShearSectionType.Rectangle) + { + return GetRectangleEffectiveness(); + } + else if (sectionType == BeamShearSectionType.Circle) + { + return GetCircleEffectiveness(); + } + else + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(sectionType)); + } + } + + private static ISectionEffectiveness GetCircleEffectiveness() + { + SectionEffectiveness sectionEffectiveness = new() + { + BaseShapeFactor = 1.5, + MaxCrackLengthRatio = 3, + MinCrackLengthRatio = 0.6, + ShapeFactor = 0.6 + }; + return sectionEffectiveness; + } + + private static ISectionEffectiveness GetRectangleEffectiveness() + { + SectionEffectiveness sectionEffectiveness = new() + { + BaseShapeFactor = 1.5, + MaxCrackLengthRatio = 3, + MinCrackLengthRatio = 0.6, + ShapeFactor = 1 + }; + return sectionEffectiveness; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Factories/StirrupEffectivenessFactory.cs b/StructureHelperLogics/Models/BeamShears/Factories/StirrupEffectivenessFactory.cs new file mode 100644 index 0000000..4b541ea --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Factories/StirrupEffectivenessFactory.cs @@ -0,0 +1,55 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public enum BeamShearSectionType + { + Rectangle, + Circle + } + public static class StirrupEffectivenessFactory + { + public static IStirrupEffectiveness GetEffectiveness(BeamShearSectionType sectionType) + { + if (sectionType == BeamShearSectionType.Rectangle) + { + return GetRectangleEffectiveness(); + } + else if (sectionType == BeamShearSectionType.Circle) + { + return GetCircleEffectiveness(); + } + else + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(sectionType)); + } + } + + private static IStirrupEffectiveness GetCircleEffectiveness() + { + StirrupEffectiveness stirrupEffectiveness = new() + { + MaxCrackLengthRatio = 1.5, + StirrupPlacementFactor = 0.75, + StirrupShapeFactor = 0.5 + }; + return stirrupEffectiveness; + } + + private static IStirrupEffectiveness GetRectangleEffectiveness() + { + StirrupEffectiveness stirrupEffectiveness = new() + { + MaxCrackLengthRatio = 2, + StirrupPlacementFactor = 0.75, + StirrupShapeFactor = 1 + }; + return stirrupEffectiveness; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs b/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs new file mode 100644 index 0000000..1e85e71 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs @@ -0,0 +1,31 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.Materials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + /// Properties of concrete cross-section for shear strength of beam + /// + public interface IBeamShearSection : ISaveable, ICloneable + { + string? Name { get; set; } + /// + /// Concrete of cross-section + /// + IConcreteLibMaterial Material { get; set; } + /// + /// Shape of cross-section + /// + IShape Shape {get;} + /// + /// Distance from edge of tension zone to center of the nearest reinforcement bar + /// + double CenterCover { get; set; } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs b/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs index d32c24d..d6b4ea1 100644 --- a/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs +++ b/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs @@ -9,6 +9,7 @@ namespace StructureHelperLogics.Models.BeamShears { public interface IInclinedSection : IEffectiveDepth { + double WebWidth { get; set; } double StartCoord { get; set; } double EndCoord { get; set; } } diff --git a/StructureHelperLogics/Models/BeamShears/ISectionEffectiveness.cs b/StructureHelperLogics/Models/BeamShears/ISectionEffectiveness.cs new file mode 100644 index 0000000..b164f47 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/ISectionEffectiveness.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + /// Properties of concrete cross-section effectiveness for shear + /// + public interface ISectionEffectiveness + { + /// + /// Shape factor of shear strength of base form, dimensionless + /// + double BaseShapeFactor { get; set; } + /// + /// Maximum ratio of crack length to effective depth + /// + double MaxCrackLengthRatio { get; set; } + /// + /// Maximum ratio of crack length to effective depth + /// + double MinCrackLengthRatio { get; set; } + /// + /// Shape factor of shear strength of specific form, dimensionless + /// + double ShapeFactor { get; set; } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/IStirrup.cs b/StructureHelperLogics/Models/BeamShears/IStirrup.cs index 791b996..2ca22e6 100644 --- a/StructureHelperLogics/Models/BeamShears/IStirrup.cs +++ b/StructureHelperLogics/Models/BeamShears/IStirrup.cs @@ -12,6 +12,10 @@ namespace StructureHelperLogics.Models.BeamShears /// public interface IStirrup : ISaveable, ICloneable { - string Name { get; set; } + string? Name { get; set; } + /// + /// Distance from axis of comressed rebar to edge of comressed zone, m + /// + double CompressedGap { get; set; } } } diff --git a/StructureHelperLogics/Models/BeamShears/IStirrupByDirectValue.cs b/StructureHelperLogics/Models/BeamShears/IStirrupByDirectValue.cs deleted file mode 100644 index 7b735f1..0000000 --- a/StructureHelperLogics/Models/BeamShears/IStirrupByDirectValue.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.Models.BeamShears -{ - /// - /// Implement logic for stirrup bearing capacity which does not depend on specific inclined section - /// - public interface IStirrupByDirectValue : IStirrup - { - /// - /// Direct value of bearing capacity which is applied for any inclined section, N - /// - double BearingCapacityValue { get; set; } - } -} diff --git a/StructureHelperLogics/Models/BeamShears/IStirrupByRebar.cs b/StructureHelperLogics/Models/BeamShears/IStirrupByRebar.cs deleted file mode 100644 index 36e62b7..0000000 --- a/StructureHelperLogics/Models/BeamShears/IStirrupByRebar.cs +++ /dev/null @@ -1,17 +0,0 @@ -using StructureHelperLogics.Models.Materials; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.Models.BeamShears -{ - public interface IStirrupByRebar : IStirrup - { - IReinforcementLibMaterial ReinforcementMaterial { get; set; } - double LegCount { get; set; } - double Diameter { get; set; } - double Step { get; set; } - } -} diff --git a/StructureHelperLogics/Models/BeamShears/IStirrupByUniformRebar.cs b/StructureHelperLogics/Models/BeamShears/IStirrupByUniformRebar.cs new file mode 100644 index 0000000..a84dbbb --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/IStirrupByUniformRebar.cs @@ -0,0 +1,32 @@ +using StructureHelperLogics.Models.Materials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + /// Implement properties for uniformly distributed stirrups + /// + public interface IStirrupByUniformRebar : IStirrup + { + /// + /// Material of stirrups + /// + IReinforcementLibMaterial Material { get; set; } + /// + /// Count of legs of stirrup in specific cross-section + /// + double LegCount { get; set; } + /// + /// Diameter of stirrup, m + /// + double Diameter { get; set; } + /// + /// Step of uniformly distibuted stirrup along axis of beam, m + /// + double Step { get; set; } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/IStirrupEffectiveness.cs b/StructureHelperLogics/Models/BeamShears/IStirrupEffectiveness.cs index 9c9c74b..11f3802 100644 --- a/StructureHelperLogics/Models/BeamShears/IStirrupEffectiveness.cs +++ b/StructureHelperLogics/Models/BeamShears/IStirrupEffectiveness.cs @@ -6,10 +6,22 @@ using System.Threading.Tasks; namespace StructureHelperLogics.Models.BeamShears { + /// + /// Properties of stirrups effectiveness + /// public interface IStirrupEffectiveness { - double MaxCrackLengthFactor { get; set; } + /// + /// Ratio of maximum crack length to effective depth + /// + double MaxCrackLengthRatio { get; set; } + /// + /// Factor of effectiveness due to non-rectangle shape of stirrup + /// double StirrupShapeFactor { get; set; } + /// + /// Factor of difference between real and uniform distribution + /// double StirrupPlacementFactor { get; set; } } } diff --git a/StructureHelperLogics/Models/BeamShears/InclinedSection.cs b/StructureHelperLogics/Models/BeamShears/InclinedSection.cs index 0530bc2..4f90628 100644 --- a/StructureHelperLogics/Models/BeamShears/InclinedSection.cs +++ b/StructureHelperLogics/Models/BeamShears/InclinedSection.cs @@ -8,8 +8,9 @@ namespace StructureHelperLogics.Models.BeamShears { public class InclinedSection : IInclinedSection { + public double EffectiveDepth { get; set; } + public double WebWidth { get; set; } public double StartCoord { get; set; } public double EndCoord { get; set; } - public double EffectiveDepth { get; set; } } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs new file mode 100644 index 0000000..6b95f7e --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs @@ -0,0 +1,84 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Shapes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class GetInclinedSectionLogic : IGetInclinedSectionLogic + { + private readonly IBeamShearSection beamShearSection; + private readonly double startCoord; + private readonly double endCoord; + private double width; + private double depth; + private double effectiveDepth; + + public GetInclinedSectionLogic( + IBeamShearSection beamShearSection, + double startCoord, + double endCoord, + IShiftTraceLogger? traceLogger) + { + this.beamShearSection = beamShearSection; + this.startCoord = startCoord; + this.endCoord = endCoord; + TraceLogger = traceLogger; + Check(); + } + + public GetInclinedSectionLogic(IShiftTraceLogger? traceLogger) + { + TraceLogger = traceLogger; + } + + public IShiftTraceLogger? TraceLogger { get; set; } + + public IInclinedSection GetInclinedSection() + { + if (beamShearSection.Shape is IRectangleShape rectangle) + { + width = rectangle.Width; + depth = rectangle.Height; + } + else if (beamShearSection.Shape is ICircleShape circle) + { + width = circle.Diameter; + depth = circle.Diameter; + } + else + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(beamShearSection.Shape)); + } + effectiveDepth = depth - beamShearSection.CenterCover; + InclinedSection inclinedSection = new() + { + EffectiveDepth = effectiveDepth, + StartCoord = startCoord, + EndCoord = endCoord, + WebWidth = width + }; + return inclinedSection; + } + + private void Check() + { + if (beamShearSection is null) + { + string errorString = ErrorStrings.ParameterIsNull + ": Beam shear section"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + if (beamShearSection.Shape is null) + { + string errorString = ErrorStrings.ParameterIsNull + ": Beam section shape"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs new file mode 100644 index 0000000..c73b4be --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public interface IGetInclinedSectionLogic : ILogic + { + IInclinedSection GetInclinedSection(); + } +} diff --git a/StructureHelperLogics/Models/BeamShears/SectionEffectiveness.cs b/StructureHelperLogics/Models/BeamShears/SectionEffectiveness.cs new file mode 100644 index 0000000..724e84f --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/SectionEffectiveness.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + public class SectionEffectiveness : ISectionEffectiveness + { + /// + public double BaseShapeFactor { get; set; } + /// + public double MaxCrackLengthRatio { get; set; } + /// + public double MinCrackLengthRatio { get; set; } + /// + public double ShapeFactor { get; set; } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/StirrupByDensity.cs b/StructureHelperLogics/Models/BeamShears/StirrupByDensity.cs index 8889bce..907db58 100644 --- a/StructureHelperLogics/Models/BeamShears/StirrupByDensity.cs +++ b/StructureHelperLogics/Models/BeamShears/StirrupByDensity.cs @@ -11,6 +11,7 @@ namespace StructureHelperLogics.Models.BeamShears public Guid Id { get; } public string Name { get; set; } = string.Empty; public double StirrupDensity { get; set; } + public double CompressedGap { get; set; } public StirrupByDensity(Guid id) { diff --git a/StructureHelperLogics/Models/BeamShears/StirrupByDirectValue.cs b/StructureHelperLogics/Models/BeamShears/StirrupByDirectValue.cs deleted file mode 100644 index 9ff836a..0000000 --- a/StructureHelperLogics/Models/BeamShears/StirrupByDirectValue.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperLogics.Models.BeamShears -{ - public class StirrupByDirectValue : IStirrupByDirectValue - { - public Guid Id { get; } - public string Name { get; set; } - public double BearingCapacityValue { get; set; } - - public object Clone() - { - throw new NotImplementedException(); - } - } -} diff --git a/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebar.cs b/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebar.cs new file mode 100644 index 0000000..6b79ad6 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebar.cs @@ -0,0 +1,33 @@ +using StructureHelperLogics.Models.Materials; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + public class StirrupByUniformRebar : IStirrupByUniformRebar + { + /// + public Guid Id { get; } + public string? Name { get; set; } + /// + public IReinforcementLibMaterial Material { get; set; } + /// + public double LegCount { get; set; } = 2; + /// + public double Diameter { get; set; } = 0.008; + /// + public double Step { get; set; } = 0.1; + /// + public double CompressedGap { get; set; } = 0; + + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebarToDensityConvertStrategy.cs b/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebarToDensityConvertStrategy.cs new file mode 100644 index 0000000..f1b0e14 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/StirrupByUniformRebarToDensityConvertStrategy.cs @@ -0,0 +1,48 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class StirrupByUniformRebarToDensityConvertStrategy : IConvertStrategy + { + private const double stirrupStrengthFactor = 1d; + private const double maxStirrupStrength = 3e8; + + private IUpdateStrategy updateStrategy; + public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; } + public IShiftTraceLogger TraceLogger { get; set; } + + public StirrupByUniformRebarToDensityConvertStrategy(IUpdateStrategy updateStrategy, IShiftTraceLogger traceLogger) + { + this.updateStrategy = updateStrategy; + TraceLogger = traceLogger; + } + + public IStirrupByDensity Convert(IStirrupByUniformRebar source) + { + updateStrategy ??= new StirrupUpdateStrategy(); + StirrupByDensity stirrupByDensity = new(Guid.NewGuid()); + updateStrategy.Update(stirrupByDensity, source); + stirrupByDensity.StirrupDensity = GetStirrupDensity(source); + return stirrupByDensity; + } + + private double GetStirrupDensity(IStirrupByUniformRebar source) + { + double area = Math.PI * source.Diameter * source.Diameter / 4d; + TraceLogger?.AddMessage($"Area of rebar = {Math.PI} * ({source.Diameter})^2 / 4 = {area}, m^2"); + double strength = stirrupStrengthFactor * source.Material.GetStrength(LimitStates.ULS, CalcTerms.ShortTerm).Tensile; + TraceLogger?.AddMessage($"Strength of rebar = {strength}, Pa"); + strength = Math.Min(strength, maxStirrupStrength); + double density = strength * area * source.LegCount / source.Step; + TraceLogger?.AddMessage($"Density of stirrups = {strength} * {area} * {source.LegCount} / {source.Step} = {density}, N/m"); + return density; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/StirrupEffectiveness.cs b/StructureHelperLogics/Models/BeamShears/StirrupEffectiveness.cs new file mode 100644 index 0000000..9067466 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/StirrupEffectiveness.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + /// + public class StirrupEffectiveness : IStirrupEffectiveness + { + /// + public double MaxCrackLengthRatio { get; set; } + /// + public double StirrupShapeFactor { get; set; } + /// + public double StirrupPlacementFactor { get; set; } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/StirrupGroup.cs b/StructureHelperLogics/Models/BeamShears/StirrupGroup.cs index 325b8b5..4b4a353 100644 --- a/StructureHelperLogics/Models/BeamShears/StirrupGroup.cs +++ b/StructureHelperLogics/Models/BeamShears/StirrupGroup.cs @@ -11,6 +11,7 @@ namespace StructureHelperLogics.Models.BeamShears public Guid Id { get; } public string Name { get; set; } public List Stirrups { get; } = new(); + public double CompressedGap { get; set; } public double GetShearBearingCapacity(IInclinedSection inclinedSection) { diff --git a/StructureHelperLogics/Models/BeamShears/StirrupUpdateStrategy.cs b/StructureHelperLogics/Models/BeamShears/StirrupUpdateStrategy.cs new file mode 100644 index 0000000..d26be37 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/StirrupUpdateStrategy.cs @@ -0,0 +1,23 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.Models.BeamShears +{ + internal class StirrupUpdateStrategy : IUpdateStrategy + { + public void Update(IStirrup targetObject, IStirrup sourceObject) + { + CheckObject.IsNull(sourceObject, ErrorStrings.SourceObject); + CheckObject.IsNull(targetObject, ErrorStrings.TargetObject); + if (ReferenceEquals(targetObject, sourceObject)) { return; }; + targetObject.CompressedGap = sourceObject.CompressedGap; + targetObject.Name = sourceObject.Name; + } + } +} diff --git a/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs new file mode 100644 index 0000000..a4a34ba --- /dev/null +++ b/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs @@ -0,0 +1,76 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperLogics.Models.BeamShears; + +namespace StructureHelperTests.UnitTests.BeamShearTests +{ + + + [TestFixture] + public class BeamShearStrengthByStirrupDensityTests + { + private Mock _mockStirrupEffectiveness; + private Mock _mockStirrupByDensity; + private Mock _mockInclinedSection; + private Mock _mockTraceLogger; + private BeamShearStrengthByStirrupDensityLogic _beamShearStrength; + + [SetUp] + public void Setup() + { + _mockStirrupEffectiveness = new Mock(); + _mockStirrupByDensity = new Mock(); + _mockInclinedSection = new Mock(); + _mockTraceLogger = new Mock(); + + _beamShearStrength = new BeamShearStrengthByStirrupDensityLogic( + _mockStirrupEffectiveness.Object, + _mockStirrupByDensity.Object, + _mockInclinedSection.Object, + _mockTraceLogger.Object + ); + } + + [Test] + public void GetShearStrength_CalculatesCorrectly() + { + // Arrange + _mockInclinedSection.Setup(s => s.StartCoord).Returns(1.0); + _mockInclinedSection.Setup(s => s.EndCoord).Returns(3.0); + _mockInclinedSection.Setup(s => s.EffectiveDepth).Returns(2.0); + + _mockStirrupEffectiveness.Setup(s => s.MaxCrackLengthRatio).Returns(0.5); + _mockStirrupEffectiveness.Setup(s => s.StirrupShapeFactor).Returns(1.2); + _mockStirrupEffectiveness.Setup(s => s.StirrupPlacementFactor).Returns(1.1); + + _mockStirrupByDensity.Setup(s => s.StirrupDensity).Returns(4.0); + + double expectedStrength = 1.2 * 1.1 * 1.0 * 4.0; // Min(2.0, 1.0) = 1.0 + + // Act + double result = _beamShearStrength.GetShearStrength(); + + // Assert + Assert.That(result, Is.EqualTo(expectedStrength).Within(1e-6)); + _mockTraceLogger.Verify(t => t.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce); + } + + [Test] + public void GetShearStrength_ThrowsException_WhenDependenciesAreNull() + { + // Arrange + var invalidInstance = new BeamShearStrengthByStirrupDensityLogic( + _mockStirrupEffectiveness.Object, + null, // Invalid + _mockInclinedSection.Object, + _mockTraceLogger.Object + ); + + // Act & Assert + Assert.Throws(() => invalidInstance.GetShearStrength()); + } + } + +} diff --git a/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs new file mode 100644 index 0000000..a151bf5 --- /dev/null +++ b/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs @@ -0,0 +1,57 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperLogics.Models.BeamShears; +using StructureHelperLogics.Models.Materials; +using System; +using System.Collections.Generic; + +namespace StructureHelperTests.UnitTests.BeamShearTests +{ + + + [TestFixture] + public class StirrupByUniformRebarToDensityConvertStrategyTests + { + private Mock> _mockUpdateStrategy; + private Mock _mockTraceLogger; + private StirrupByUniformRebarToDensityConvertStrategy _convertStrategy; + + [SetUp] + public void Setup() + { + _mockUpdateStrategy = new Mock>(); + _mockTraceLogger = new Mock(); + + _convertStrategy = new StirrupByUniformRebarToDensityConvertStrategy( + _mockUpdateStrategy.Object, + _mockTraceLogger.Object + ); + } + + [Test] + public void Convert_UpdatesAndCalculatesDensityCorrectly() + { + // Arrange + var mockMaterial = new Mock(); + mockMaterial.Setup(m => m.GetStrength(LimitStates.ULS, CalcTerms.ShortTerm)).Returns((2e8, 2e8)); + + var stirrupRebar = new Mock(); + stirrupRebar.Setup(s => s.Diameter).Returns(0.02); + stirrupRebar.Setup(s => s.Material).Returns(mockMaterial.Object); + stirrupRebar.Setup(s => s.LegCount).Returns(2); + stirrupRebar.Setup(s => s.Step).Returns(0.15); + + // Act + var result = _convertStrategy.Convert(stirrupRebar.Object); + + // Assert + _mockUpdateStrategy.Verify(u => u.Update(It.IsAny(), stirrupRebar.Object), Times.Once); + Assert.That(result.StirrupDensity, Is.EqualTo(837758.04095727834d).Within(0.00001)); + //_mockTraceLogger.Verify(t => t.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce); + } + } + +}