diff --git a/StructureHelper/Documentation/Manuals/Руководство пользователя.docx b/StructureHelper/Documentation/Manuals/Руководство пользователя.docx index b148c7d..4097deb 100644 Binary files a/StructureHelper/Documentation/Manuals/Руководство пользователя.docx and b/StructureHelper/Documentation/Manuals/Руководство пользователя.docx differ diff --git a/StructureHelper/Infrastructure/UI/GraphicalPrimitives/ConcentratedForcePrimitive.cs b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/ConcentratedForcePrimitive.cs new file mode 100644 index 0000000..a00aada --- /dev/null +++ b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/ConcentratedForcePrimitive.cs @@ -0,0 +1,32 @@ +using StructureHelper.Windows.UserControls; +using StructureHelperCommon.Models.Forces; +using System; +using System.Windows.Media; +using PrimitiveVisualProperty = StructureHelperCommon.Models.VisualProperties.PrimitiveVisualProperty; + +namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives +{ + public class ConcentratedForcePrimitive : IGraphicalPrimitive + { + private IConcentratedForce concentratedForce; + private readonly double scaleFactor; + + public double ScaleFactor + { + get + { + if (concentratedForce.ForceValue.Qy > 0) { return -1; } + return 1; + } + } + + public PrimitiveVisualPropertyViewModel VisualProperty { get; } = new(new PrimitiveVisualProperty(Guid.Empty)); + public IConcentratedForce ConcentratedForce => concentratedForce; + + public ConcentratedForcePrimitive(IConcentratedForce concentratedForce) + { + this.concentratedForce = concentratedForce; + VisualProperty.Color = (Color)ColorConverter.ConvertFromString("Black"); + } + } +} diff --git a/StructureHelper/Infrastructure/UI/GraphicalPrimitives/IGraphicPrimitive.cs b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/IGraphicPrimitive.cs index fe0ea33..13556de 100644 --- a/StructureHelper/Infrastructure/UI/GraphicalPrimitives/IGraphicPrimitive.cs +++ b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/IGraphicPrimitive.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives { - public interface IGraphicalPrimitive : ICenter + public interface IGraphicalPrimitive { PrimitiveVisualPropertyViewModel VisualProperty { get; } } diff --git a/StructureHelper/Infrastructure/UI/GraphicalPrimitives/InclinedSectionPrimitive.cs b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/InclinedSectionPrimitive.cs index 92dea09..983baee 100644 --- a/StructureHelper/Infrastructure/UI/GraphicalPrimitives/InclinedSectionPrimitive.cs +++ b/StructureHelper/Infrastructure/UI/GraphicalPrimitives/InclinedSectionPrimitive.cs @@ -26,9 +26,6 @@ namespace StructureHelper.Infrastructure.UI.GraphicalPrimitives public double ConcreteShearForce => Math.Round(source.ConcreteStrength); public double StirrupShearForce => Math.Round(source.StirrupStrength); - public double CenterX => 0; - public double CenterY => 0; - public PrimitiveVisualPropertyViewModel VisualProperty { get; } = new(new PrimitiveVisualProperty(Guid.Empty)); public InclinedSectionPrimitive(IBeamShearSectionLogicResult source) diff --git a/StructureHelper/Infrastructure/UI/Resources/BeamShearTemplate.xaml b/StructureHelper/Infrastructure/UI/Resources/BeamShearTemplate.xaml index 716bcf5..09ff19f 100644 --- a/StructureHelper/Infrastructure/UI/Resources/BeamShearTemplate.xaml +++ b/StructureHelper/Infrastructure/UI/Resources/BeamShearTemplate.xaml @@ -336,4 +336,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StructureHelper/Windows/BeamShears/InclinedSectionViewerViewModel.cs b/StructureHelper/Windows/BeamShears/InclinedSectionViewerViewModel.cs index 9a35dbf..26fc54b 100644 --- a/StructureHelper/Windows/BeamShears/InclinedSectionViewerViewModel.cs +++ b/StructureHelper/Windows/BeamShears/InclinedSectionViewerViewModel.cs @@ -3,11 +3,7 @@ using StructureHelper.Infrastructure.UI.GraphicalPrimitives; using StructureHelper.Windows.UserControls.WorkPlanes; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperLogics.Models.BeamShears; -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StructureHelper.Windows.BeamShears { diff --git a/StructureHelper/Windows/BeamShears/SectionResultToGraphicalPrimitivesConvertLogic.cs b/StructureHelper/Windows/BeamShears/SectionResultToGraphicalPrimitivesConvertLogic.cs index bf9cd60..d9ec536 100644 --- a/StructureHelper/Windows/BeamShears/SectionResultToGraphicalPrimitivesConvertLogic.cs +++ b/StructureHelper/Windows/BeamShears/SectionResultToGraphicalPrimitivesConvertLogic.cs @@ -1,6 +1,7 @@ using StructureHelper.Infrastructure.UI.GraphicalPrimitives; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Forces; using StructureHelperLogics.Models.BeamShears; using System; using System.Collections.Generic; @@ -17,9 +18,14 @@ namespace StructureHelper.Windows.BeamShears inclinedSection = source.InputData.InclinedSection; InitializeStrategies(); List graphicalPrimitives = new List(); - BeamShearSectionPrimitive beamShearSectionPrimitive = new(source.InputData.InclinedSection.BeamShearSection, inclinedSection); + BeamShearSectionPrimitive beamShearSectionPrimitive = new(source.ResultInputData.InclinedSection.BeamShearSection, inclinedSection); graphicalPrimitives.Add(beamShearSectionPrimitive); - graphicalPrimitives.AddRange(stirrupLogic.Convert(source.InputData.Stirrup)); + var supportInternalAction = source.ResultInputData.BeamShearAction.SupportAction.SupportForce.ForceTuple; + ConcentratedForce SupportForce = new(Guid.Empty); + SupportForce.ForceValue.Qy = supportInternalAction.Qy; + ConcentratedForcePrimitive concentratedForcePrimitive = new(SupportForce); + graphicalPrimitives.Add((concentratedForcePrimitive)); + graphicalPrimitives.AddRange(stirrupLogic.Convert(source.ResultInputData.Stirrup)); InclinedSectionPrimitive inclinedSectionPrimitive = new(source); graphicalPrimitives.Add((inclinedSectionPrimitive)); return graphicalPrimitives; diff --git a/StructureHelper/Windows/UserControls/WorkPlanes/PrimitiveTemplateSelector.cs b/StructureHelper/Windows/UserControls/WorkPlanes/PrimitiveTemplateSelector.cs index 411281c..bdc0fef 100644 --- a/StructureHelper/Windows/UserControls/WorkPlanes/PrimitiveTemplateSelector.cs +++ b/StructureHelper/Windows/UserControls/WorkPlanes/PrimitiveTemplateSelector.cs @@ -11,6 +11,7 @@ namespace StructureHelper.Windows.UserControls.WorkPlanes public DataTemplate StirrupByRebarTemplate { get; set; } public DataTemplate StirrupByDensityTemplate { get; set; } public DataTemplate StirrupByInclinedRebarTemplate { get; set; } + public DataTemplate ConcentratedForceTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { @@ -21,6 +22,7 @@ namespace StructureHelper.Windows.UserControls.WorkPlanes StirrupByRebarPrimitive => StirrupByRebarTemplate, StirrupByDensityPrimitive => StirrupByDensityTemplate, StirrupByInclinedRebarPrimitive => StirrupByInclinedRebarTemplate, + ConcentratedForcePrimitive => ConcentratedForceTemplate, _ => base.SelectTemplate(item, container) }; } diff --git a/StructureHelper/Windows/UserControls/WorkPlanes/WorkPlaneRoot.xaml b/StructureHelper/Windows/UserControls/WorkPlanes/WorkPlaneRoot.xaml index 793e938..4eb681a 100644 --- a/StructureHelper/Windows/UserControls/WorkPlanes/WorkPlaneRoot.xaml +++ b/StructureHelper/Windows/UserControls/WorkPlanes/WorkPlaneRoot.xaml @@ -66,6 +66,7 @@ StirrupByRebarTemplate="{StaticResource StirrupByRebarPrimitiveTemplate}" StirrupByDensityTemplate="{StaticResource StirrupByDensityPrimitiveTemplate}" StirrupByInclinedRebarTemplate="{StaticResource StirrupByInclinedRebarPrimitiveTemplate}" + ConcentratedForceTemplate="{StaticResource ConcentratedForcePrimitiveTemplate}" /> diff --git a/StructureHelperCommon/Services/Units/UnitsOfSI.cs b/StructureHelperCommon/Services/Units/UnitsOfSI.cs new file mode 100644 index 0000000..ae583f6 --- /dev/null +++ b/StructureHelperCommon/Services/Units/UnitsOfSI.cs @@ -0,0 +1,10 @@ +namespace StructureHelperCommon.Services.Units +{ + public static class UnitsOfSI + { + public const string Dimensionless = "(dimensionless)"; + public const string Meters = "(m)"; + public const string SquareMeters = "(m2)"; + public const string Newtons = "(N)"; + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs index 966b79c..8822680 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs @@ -12,7 +12,7 @@ namespace StructureHelperLogics.Models.BeamShears { private BeamShearSectionLogicResult result; private ISectionEffectiveness sectionEffectiveness; - private ConcreteStrengthLogic concreteLogic; + private ConcreteShearStrengthLogic concreteLogic; private StirrupStrengthLogic stirrupLogic; private IGetLongitudinalForceFactorLogic getLongitudinalForceFactorLogic; private string sectionMessage; @@ -92,8 +92,8 @@ namespace StructureHelperLogics.Models.BeamShears SetLongitudinalForce(); double factorOfLongitudinalForce = getLongitudinalForceFactorLogic.GetFactor(); localTraceLogger?.AddMessage($"Factor of longitudinal force = {factorOfLongitudinalForce}, (dimensionless)"); - concreteStrength = concreteLogic.GetShearStrength(); - stirrupStrength = stirrupLogic.GetShearStrength(); + concreteStrength = concreteLogic.CalculateShearStrength(); + stirrupStrength = stirrupLogic.CalculateShearStrength(); if (stirrupStrength > concreteStrength) { localTraceLogger?.AddMessage($"Shear reinforcement strength Qsw = {stirrupStrength} is greater than concrete strength for shear Qb = {concreteStrength}, shear reinforcement strength has to be restricted."); @@ -132,7 +132,7 @@ namespace StructureHelperLogics.Models.BeamShears InputData = result.ResultInputData, SectionEffectiveness = sectionEffectiveness }; - double stirrupStrength = logic.GetShearStrength(); + double stirrupStrength = logic.CalculateShearStrength(); localTraceLogger?.AddMessage($"Stirrup strength was restricted as Qsw,restricted = {stirrupStrength}(N)"); result.ResultInputData.InclinedCrack = logic.InclinedCrack; return stirrupStrength; diff --git a/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs deleted file mode 100644 index f34dd49..0000000 --- a/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs +++ /dev/null @@ -1,79 +0,0 @@ -using StructureHelperCommon.Models; -using StructureHelperCommon.Models.Loggers; -using StructureHelperLogics.Models.BeamShears.Logics; - -namespace StructureHelperLogics.Models.BeamShears -{ - public class ConcreteStrengthLogic : IBeamShearStrenghLogic - { - private readonly ISectionEffectiveness sectionEffectiveness; - private readonly IInclinedSection inclinedSection; - - - private double crackLength; - - public ConcreteStrengthLogic( - ISectionEffectiveness sectionEffectiveness, - IInclinedSection inclinedSection, - IShiftTraceLogger? traceLogger) - { - this.sectionEffectiveness = sectionEffectiveness; - this.inclinedSection = inclinedSection; - TraceLogger = traceLogger; - } - - public IShiftTraceLogger? TraceLogger { get; set; } - - public double GetShearStrength() - { - TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); - InitializeStrategies(); - 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($"Absolute crack length c = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}, (m)"); - TraceLogger?.AddMessage($"Relative crack length c/d = {crackLength} / {inclinedSection.EffectiveDepth} = {crackLength/ inclinedSection.EffectiveDepth},(dimensionless)"); - RestrictCrackLength(); - - - double concreteMoment = - sectionEffectiveness.BaseShapeFactor - * sectionEffectiveness.ShapeFactor - * inclinedSection.ConcreteTensionStrength - * inclinedSection.WebWidth - * inclinedSection.EffectiveDepth - * inclinedSection.EffectiveDepth; - double shearStrength = concreteMoment / crackLength; - TraceLogger?.AddMessage($"Shear strength of concrete = {sectionEffectiveness.BaseShapeFactor} * {sectionEffectiveness.ShapeFactor} * {inclinedSection.ConcreteTensionStrength} * {inclinedSection.WebWidth} * {inclinedSection.EffectiveDepth} ^ 2 / {crackLength} = {shearStrength}, (N)"); - return shearStrength; - } - - private void InitializeStrategies() - { - - } - - - - 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/Logics/IBeamShearStrenghLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrengthLogic.cs similarity index 85% rename from StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs rename to StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrengthLogic.cs index ab4ebe2..c60b879 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrengthLogic.cs @@ -10,12 +10,12 @@ namespace StructureHelperLogics.Models.BeamShears /// /// Implement logic for calculation of bearing capacity of inclined section for shear /// - public interface IBeamShearStrenghLogic : ILogic + public interface IBeamShearStrengthLogic : ILogic { /// /// Returns Bearing capacity of inclined section for shear /// /// Bearing capacity of inclined section for shear, N - double GetShearStrength(); + double CalculateShearStrength(); } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs index ba50b85..9e72e1e 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs @@ -4,9 +4,9 @@ using StructureHelperCommon.Models.Calculators; namespace StructureHelperLogics.Models.BeamShears { - internal class StirrupBySearchLogic : IBeamShearStrenghLogic + internal class StirrupBySearchLogic : IBeamShearStrengthLogic { - private ConcreteStrengthLogic concreteLogic; + private ConcreteShearStrengthLogic concreteLogic; private StirrupStrengthLogic stirrupLogic; private IFindParameterCalculator parameterCalculator; @@ -19,14 +19,14 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger = traceLogger; } - public double GetShearStrength() + public double CalculateShearStrength() { double parameter = GetCrackLengthRatio(); BeamShearSectionLogicInputData newInputData = GetNewInputDataByCrackLengthRatio(parameter); InclinedCrack = newInputData.InclinedCrack; TraceLogger?.AddMessage($"New value of dangerous inclinated crack has been obtained: start point Xstart = {newInputData.InclinedSection.StartCoord}(m), end point Xend = {newInputData.InclinedSection.EndCoord}(m)"); stirrupLogic = new(newInputData, TraceLogger); - double stirrupStrength = stirrupLogic.GetShearStrength(); + double stirrupStrength = stirrupLogic.CalculateShearStrength(); return stirrupStrength; } @@ -69,8 +69,8 @@ namespace StructureHelperLogics.Models.BeamShears BeamShearSectionLogicInputData newInputData = GetNewInputDataByCrackLengthRatio(crackLengthRatio); concreteLogic = new(SectionEffectiveness, newInputData.InclinedCrack, null); stirrupLogic = new(newInputData, null); - double concreteStrength = concreteLogic.GetShearStrength(); - double stirrupStrength = stirrupLogic.GetShearStrength(); + double concreteStrength = concreteLogic.CalculateShearStrength(); + double stirrupStrength = stirrupLogic.CalculateShearStrength(); bool predicateResult = stirrupStrength > concreteStrength; if (crackLengthRatio == 1 & predicateResult == false) { diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/ConcreteShearStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/ConcreteShearStrengthLogic.cs new file mode 100644 index 0000000..08f0e4c --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/ConcreteShearStrengthLogic.cs @@ -0,0 +1,74 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Services.Units; +using StructureHelperLogics.Models.BeamShears.Logics; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class ConcreteShearStrengthLogic : IBeamShearStrengthLogic + { + private readonly ISectionEffectiveness sectionEffectiveness; + private readonly IInclinedSection inclinedSection; + + public IShiftTraceLogger? TraceLogger { get; set; } + + public ConcreteShearStrengthLogic( + ISectionEffectiveness sectionEffectiveness, + IInclinedSection inclinedSection, + IShiftTraceLogger? traceLogger = null) + { + this.sectionEffectiveness = sectionEffectiveness ?? throw new StructureHelperException("Section effectiveness cannot be null."); + this.inclinedSection = inclinedSection ?? throw new StructureHelperException("Inclined section cannot be null."); + TraceLogger = traceLogger; + } + + public double CalculateShearStrength() + { + TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); + ValidateInput(); + + double rawCrackLength = inclinedSection.EndCoord - inclinedSection.StartCoord; + double crackLength = RestrictCrackLength(rawCrackLength); + + double concreteMoment = CalculateConcreteMoment(); + double shearStrength = concreteMoment / crackLength; + + TraceLogger?.AddMessage($"Shear strength = {concreteMoment} / {crackLength} = {shearStrength} {UnitsOfSI.Newtons}"); + return shearStrength; + } + + private double CalculateConcreteMoment() => + sectionEffectiveness.BaseShapeFactor + * sectionEffectiveness.ShapeFactor + * inclinedSection.ConcreteTensionStrength + * inclinedSection.WebWidth + * inclinedSection.EffectiveDepth + * inclinedSection.EffectiveDepth; + + private double RestrictCrackLength(double length) + { + double max = sectionEffectiveness.MaxCrackLengthRatio * inclinedSection.EffectiveDepth; + double min = sectionEffectiveness.MinCrackLengthRatio * inclinedSection.EffectiveDepth; + + if (length > max) + { + TraceLogger?.AddMessage($"Crack length reduced from {length} to {max}"); + return max; + } + if (length < min) + { + TraceLogger?.AddMessage($"Crack length increased from {length} to {min}"); + return min; + } + return length; + } + + private void ValidateInput() + { + if (inclinedSection.EffectiveDepth <= 0) + throw new StructureHelperException("Effective depth must be greater than zero."); + } + } + +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByDensityStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByDensityStrengthLogic.cs index bc1c647..dd5cc31 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByDensityStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByDensityStrengthLogic.cs @@ -9,7 +9,7 @@ using StructureHelperLogics.Models.BeamShears.Logics; namespace StructureHelperLogics.Models.BeamShears { /// - public class StirrupByDensityStrengthLogic : IBeamShearStrenghLogic + public class StirrupByDensityStrengthLogic : IBeamShearStrengthLogic { private readonly IStirrupEffectiveness stirrupEffectiveness; private readonly IStirrupByDensity stirrupByDensity; @@ -30,7 +30,7 @@ namespace StructureHelperLogics.Models.BeamShears public IShiftTraceLogger? TraceLogger { get; set; } /// - public double GetShearStrength() + public double CalculateShearStrength() { Check(); TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByInclinedRebarStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByInclinedRebarStrengthLogic.cs index bafd918..1860388 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByInclinedRebarStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByInclinedRebarStrengthLogic.cs @@ -6,7 +6,7 @@ using StructureHelperLogics.Models.Materials; namespace StructureHelperLogics.Models.BeamShears { - public class StirrupByInclinedRebarStrengthLogic : IBeamShearStrenghLogic + public class StirrupByInclinedRebarStrengthLogic : IBeamShearStrengthLogic { const double stirrupEffectivenessFactor = 0.75; private readonly IStirrupByInclinedRebar inclinedRebar; @@ -47,7 +47,7 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger = traceLogger; } - public double GetShearStrength() + public double CalculateShearStrength() { GetGeometry(); if (inclinedSection.StartCoord > rebarEndPoint) diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarStrengthLogic.cs index c4dd884..3588fa2 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarStrengthLogic.cs @@ -7,14 +7,14 @@ using StructureHelperCommon.Models.Forces; namespace StructureHelperLogics.Models.BeamShears { - public class StirrupByRebarStrengthLogic : IBeamShearStrenghLogic + public class StirrupByRebarStrengthLogic : IBeamShearStrengthLogic { private IStirrupEffectiveness stirrupEffectiveness; private IStirrupByRebar stirrupByRebar; private IInclinedSection inclinedSection; private readonly IForceTuple forceTuple; private StirrupByDensityStrengthLogic stirrupDensityStrengthLogic; - private IConvertStrategy convertStrategy; + private IObjectConvertStrategy convertStrategy; public IShiftTraceLogger? TraceLogger { get; set; } public StirrupByRebarStrengthLogic( @@ -23,7 +23,7 @@ namespace StructureHelperLogics.Models.BeamShears IInclinedSection inclinedSection, IForceTuple forceTuple, StirrupByDensityStrengthLogic stirrupDensityStrengthLogic, - IConvertStrategy convertStrategy, + IObjectConvertStrategy convertStrategy, IShiftTraceLogger? traceLogger) { this.stirrupEffectiveness = stirrupEffectiveness; @@ -49,7 +49,7 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger = traceLogger; } - public double GetShearStrength() + public double CalculateShearStrength() { InitializeStrategies(); if (stirrupByRebar.EndCoordinate < inclinedSection.StartCoord) @@ -76,7 +76,7 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger?.AddMessage($"Stirrup spacing S = {stirrupByRebar.Spacing}(m) is greater than max stirrup spacing Smax = {maxStirrupSpacingByEffectibeDepth}(m), stirrups are ignored", TraceLogStatuses.Warning); return 0; } - double shearStrength = stirrupDensityStrengthLogic.GetShearStrength(); + double shearStrength = stirrupDensityStrengthLogic.CalculateShearStrength(); return shearStrength; } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarToDensityConvertStrategy.cs similarity index 93% rename from StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs rename to StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarToDensityConvertStrategy.cs index 1a8e1e5..b5e1c8a 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupByRebarToDensityConvertStrategy.cs @@ -5,13 +5,12 @@ using StructureHelperCommon.Models; namespace StructureHelperLogics.Models.BeamShears { - public class StirrupByRebarToDensityConvertStrategy : IConvertStrategy + public class StirrupByRebarToDensityConvertStrategy : IObjectConvertStrategy { private const double stirrupStrengthFactor = 0.8d; private const double maxStirrupStrength = 3e8; private IInclinedSection inclinedSection; private IUpdateStrategy updateStrategy; - public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; } public IShiftTraceLogger TraceLogger { get; set; } public StirrupByRebarToDensityConvertStrategy(IShiftTraceLogger traceLogger, IInclinedSection inclinedSection) @@ -77,7 +76,7 @@ namespace StructureHelperLogics.Models.BeamShears TraceLogger?.AddMessage($"Spiral spacing = {spiralSpacing}(m)"); double spiralAng = Math.Atan2(spiralHeight, spiralSpacing); double spriralEffectiveness = Math.Sin(spiralAng); - double spiralAngInDegrees = 180 / (Math.PI) * spiralAng; + double spiralAngInDegrees = 57.29578 * spiralAng; // 180/PI TraceLogger?.AddMessage($"Spiral effectiveness factor = sin({spiralAngInDegrees}(deg)) = {spriralEffectiveness}"); return spriralEffectiveness; } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupGroupStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupGroupStrengthLogic.cs index 04d2315..aae1717 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupGroupStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupGroupStrengthLogic.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace StructureHelperLogics.Models.BeamShears { - internal class StirrupGroupStrengthLogic : IBeamShearStrenghLogic + internal class StirrupGroupStrengthLogic : IBeamShearStrengthLogic { private readonly IBeamShearSectionLogicInputData sourceInputData; private IBeamShearSectionLogicInputData localInputData; @@ -25,7 +25,7 @@ namespace StructureHelperLogics.Models.BeamShears public IShiftTraceLogger? TraceLogger { get; set; } - public double GetShearStrength() + public double CalculateShearStrength() { Check(); if (!stirrupGroup.Stirrups.Any()) { return 0.0; } @@ -35,7 +35,7 @@ namespace StructureHelperLogics.Models.BeamShears { localInputData.Stirrup = item; var stirrupSrengthLogic = new StirrupStrengthLogic(localInputData, TraceLogger?.GetSimilarTraceLogger(50)); - shearStrength += stirrupSrengthLogic.GetShearStrength(); + shearStrength += stirrupSrengthLogic.CalculateShearStrength(); } TraceLogger?.AddMessage($"Total bearing capacity of group {stirrupGroup.Name} for shear Vtot = {shearStrength}(N)"); return shearStrength; diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupStrengthLogic.cs index 4d1b718..9596821 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StrengthLogics/StirrupStrengthLogic.cs @@ -4,14 +4,14 @@ using StructureHelperCommon.Models.Shapes; namespace StructureHelperLogics.Models.BeamShears { - internal class StirrupStrengthLogic : IBeamShearStrenghLogic + internal class StirrupStrengthLogic : IBeamShearStrengthLogic { private readonly IBeamShearSectionLogicInputData inputData; private IStirrup stirrup => inputData.Stirrup; private IInclinedSection inclinedSection => inputData.InclinedCrack; - private IBeamShearStrenghLogic stirrupByDensityStrengthLogic; - private IBeamShearStrenghLogic stirrupGroupStrengthLogic; - private IBeamShearStrenghLogic stirrupByInclinedRebarStrengthLogic; + private IBeamShearStrengthLogic stirrupByDensityStrengthLogic; + private IBeamShearStrengthLogic stirrupGroupStrengthLogic; + private IBeamShearStrengthLogic stirrupByInclinedRebarStrengthLogic; private IStirrupEffectiveness stirrupEffectiveness; public StirrupStrengthLogic(IBeamShearSectionLogicInputData inputData, IShiftTraceLogger? traceLogger) @@ -22,32 +22,32 @@ namespace StructureHelperLogics.Models.BeamShears public IShiftTraceLogger? TraceLogger { get; set; } - public double GetShearStrength() + public double CalculateShearStrength() { GetStirrupEffectiveness(); if (stirrup is IStirrupByRebar stirrupByRebar) { TraceLogger?.AddMessage($"Stirrups type is stirrup by rebar Name = {stirrupByRebar.Name}"); stirrupByDensityStrengthLogic = new StirrupByRebarStrengthLogic(stirrupEffectiveness, stirrupByRebar, inclinedSection, inputData.ForceTuple, TraceLogger); - return stirrupByDensityStrengthLogic.GetShearStrength(); + return stirrupByDensityStrengthLogic.CalculateShearStrength(); } else if (stirrup is IStirrupGroup stirrupGroup) { TraceLogger?.AddMessage($"Stirrups type is stirrup group Name = {stirrupGroup.Name}"); stirrupGroupStrengthLogic ??= new StirrupGroupStrengthLogic(inputData, stirrupGroup, TraceLogger); - return stirrupGroupStrengthLogic.GetShearStrength(); + return stirrupGroupStrengthLogic.CalculateShearStrength(); } else if (stirrup is IStirrupByDensity stirrupByDensity) { TraceLogger?.AddMessage($"Stirrups type is stirrup by density Name = {stirrupByDensity.Name}"); stirrupByDensityStrengthLogic = new StirrupByDensityStrengthLogic(stirrupEffectiveness, stirrupByDensity, inclinedSection, TraceLogger); - return stirrupByDensityStrengthLogic.GetShearStrength(); + return stirrupByDensityStrengthLogic.CalculateShearStrength(); } else if (stirrup is IStirrupByInclinedRebar inclinedRebar) { TraceLogger?.AddMessage($"Stirrups type is inclined rebar Name = {inclinedRebar.Name}"); stirrupByInclinedRebarStrengthLogic ??= new StirrupByInclinedRebarStrengthLogic(inclinedSection, inclinedRebar, TraceLogger); - return stirrupByInclinedRebarStrengthLogic.GetShearStrength(); + return stirrupByInclinedRebarStrengthLogic.CalculateShearStrength(); } else { diff --git a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearCalculatorUpdateStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearCalculatorUpdateStrategy.cs similarity index 100% rename from StructureHelperLogics/Models/BeamShears/Logics/BeamShearCalculatorUpdateStrategy.cs rename to StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearCalculatorUpdateStrategy.cs diff --git a/StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearSectionLogicInputDataUpdateStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearSectionLogicInputDataUpdateStrategy.cs index 48c789c..b9e29f7 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearSectionLogicInputDataUpdateStrategy.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/UpdateLogics/BeamShearSectionLogicInputDataUpdateStrategy.cs @@ -11,6 +11,7 @@ namespace StructureHelperLogics.Models.BeamShears CheckObject.IsNull(sourceObject, ErrorStrings.SourceObject); CheckObject.IsNull(targetObject, ErrorStrings.TargetObject); if (ReferenceEquals(targetObject, sourceObject)) { return; } + targetObject.BeamShearAction = sourceObject.BeamShearAction; targetObject.InclinedSection = sourceObject.InclinedSection; targetObject.InclinedCrack = sourceObject.InclinedCrack; targetObject.Stirrup = sourceObject.Stirrup; diff --git a/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs index d4b0ab9..6775b9b 100644 --- a/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs +++ b/StructureHelperTests/UnitTests/BeamShearTests/BeamShearStrengthByStirrupDensityTests.cs @@ -54,7 +54,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests _mockStirrupByDensity.Setup(s => s.EndCoordinate).Returns(stirrupEnd); // Act - double result = _beamShearStrength.GetShearStrength(); + double result = _beamShearStrength.CalculateShearStrength(); // Assert Assert.That(result, Is.EqualTo(expectedStrength).Within(1e-6)); @@ -82,7 +82,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests _mockStirrupByDensity.Setup(s => s.EndCoordinate).Returns(100); // Act - double result = _beamShearStrength.GetShearStrength(); + double result = _beamShearStrength.CalculateShearStrength(); // Assert Assert.That(result, Is.EqualTo(expectedStrength).Within(1e-6)); @@ -109,7 +109,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests _mockStirrupByDensity.Setup(s => s.EndCoordinate).Returns(100); // Act - double result = _beamShearStrength.GetShearStrength(); + double result = _beamShearStrength.CalculateShearStrength(); // Assert Assert.That(result, Is.EqualTo(expectedStrength).Within(1e-6)); @@ -136,7 +136,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests _mockStirrupByDensity.Setup(s => s.EndCoordinate).Returns(100); // Act - double result = _beamShearStrength.GetShearStrength(); + double result = _beamShearStrength.CalculateShearStrength(); // Assert Assert.That(result, Is.EqualTo(expectedStrength).Within(1e-6)); @@ -155,7 +155,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests ); // Act & Assert - Assert.Throws(() => invalidInstance.GetShearStrength()); + Assert.Throws(() => invalidInstance.CalculateShearStrength()); } } diff --git a/StructureHelperTests/UnitTests/BeamShearTests/ConcreteShearStrengthLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/ConcreteShearStrengthLogicTests.cs new file mode 100644 index 0000000..a77c66e --- /dev/null +++ b/StructureHelperTests/UnitTests/BeamShearTests/ConcreteShearStrengthLogicTests.cs @@ -0,0 +1,134 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperLogics.Models.BeamShears; + +namespace StructureHelperTests.UnitTests.BeamShearTests +{ + + + [TestFixture] + public class ConcreteShearStrengthLogicTests + { + private Mock sectionEffectivenessMock; + private Mock inclinedSectionMock; + + [SetUp] + public void SetUp() + { + sectionEffectivenessMock = new Mock(); + inclinedSectionMock = new Mock(); + } + + [Test] + public void CalculateShearStrength_NormalCase_ReturnsExpectedValue() + { + // Arrange + sectionEffectivenessMock.SetupGet(s => s.BaseShapeFactor).Returns(0.9); + sectionEffectivenessMock.SetupGet(s => s.ShapeFactor).Returns(1.1); + sectionEffectivenessMock.SetupGet(s => s.MaxCrackLengthRatio).Returns(2.0); + sectionEffectivenessMock.SetupGet(s => s.MinCrackLengthRatio).Returns(0.1); + + inclinedSectionMock.SetupGet(s => s.ConcreteTensionStrength).Returns(2.5); + inclinedSectionMock.SetupGet(s => s.WebWidth).Returns(0.3); + inclinedSectionMock.SetupGet(s => s.EffectiveDepth).Returns(0.5); + inclinedSectionMock.SetupGet(s => s.StartCoord).Returns(0.0); + inclinedSectionMock.SetupGet(s => s.EndCoord).Returns(0.8); // crack length = 0.8m + + var logic = new ConcreteShearStrengthLogic( + sectionEffectivenessMock.Object, + inclinedSectionMock.Object, + null + ); + + // Expected shear strength + double concreteMoment = 0.9 * 1.1 * 2.5 * 0.3 * 0.5 * 0.5; + double expectedShear = concreteMoment / 0.8; + + // Act + double actual = logic.CalculateShearStrength(); + + // Assert + Assert.That(actual, Is.EqualTo(expectedShear).Within(1e-9)); + } + + [Test] + public void CalculateShearStrength_CrackLengthAboveMax_IsCapped() + { + // Arrange + sectionEffectivenessMock.SetupGet(s => s.BaseShapeFactor).Returns(1.0); + sectionEffectivenessMock.SetupGet(s => s.ShapeFactor).Returns(1.0); + sectionEffectivenessMock.SetupGet(s => s.MaxCrackLengthRatio).Returns(1.0); // max length = 0.5m + sectionEffectivenessMock.SetupGet(s => s.MinCrackLengthRatio).Returns(0.1); + + inclinedSectionMock.SetupGet(s => s.ConcreteTensionStrength).Returns(1.0); + inclinedSectionMock.SetupGet(s => s.WebWidth).Returns(1.0); + inclinedSectionMock.SetupGet(s => s.EffectiveDepth).Returns(0.5); + inclinedSectionMock.SetupGet(s => s.StartCoord).Returns(0.0); + inclinedSectionMock.SetupGet(s => s.EndCoord).Returns(2.0); // crack length = 2.0m > max + + var logic = new ConcreteShearStrengthLogic( + sectionEffectivenessMock.Object, + inclinedSectionMock.Object, + null + ); + + // Expected crack length should be capped to 0.5m + double expectedShear = (1.0 * 1.0 * 1.0 * 1.0 * 0.5 * 0.5) / 0.5; + + // Act + double actual = logic.CalculateShearStrength(); + + // Assert + Assert.That(actual, Is.EqualTo(expectedShear).Within(1e-9)); + } + + [Test] + public void CalculateShearStrength_CrackLengthBelowMin_IsRaised() + { + // Arrange + sectionEffectivenessMock.SetupGet(s => s.BaseShapeFactor).Returns(1.0); + sectionEffectivenessMock.SetupGet(s => s.ShapeFactor).Returns(1.0); + sectionEffectivenessMock.SetupGet(s => s.MaxCrackLengthRatio).Returns(2.0); + sectionEffectivenessMock.SetupGet(s => s.MinCrackLengthRatio).Returns(0.5); // min length = 0.25m + + inclinedSectionMock.SetupGet(s => s.ConcreteTensionStrength).Returns(1.0); + inclinedSectionMock.SetupGet(s => s.WebWidth).Returns(1.0); + inclinedSectionMock.SetupGet(s => s.EffectiveDepth).Returns(0.5); + inclinedSectionMock.SetupGet(s => s.StartCoord).Returns(0.0); + inclinedSectionMock.SetupGet(s => s.EndCoord).Returns(0.1); // crack length = 0.1m < min + + var logic = new ConcreteShearStrengthLogic( + sectionEffectivenessMock.Object, + inclinedSectionMock.Object, + null + ); + + // Expected crack length should be raised to 0.25m + double expectedShear = (1.0 * 1.0 * 1.0 * 1.0 * 0.5 * 0.5) / 0.25; + + // Act + double actual = logic.CalculateShearStrength(); + + // Assert + Assert.That(actual, Is.EqualTo(expectedShear).Within(1e-9)); + } + + [Test] + public void CalculateShearStrength_InvalidEffectiveDepth_Throws() + { + // Arrange + inclinedSectionMock.SetupGet(s => s.EffectiveDepth).Returns(0.0); + + var logic = new ConcreteShearStrengthLogic( + sectionEffectivenessMock.Object, + inclinedSectionMock.Object + ); + + // Act & Assert + Assert.Throws(() => logic.CalculateShearStrength()); + } + } + +} diff --git a/StructureHelperTests/UnitTests/StirrupByInclinedRebarStrengthLogicTests.cs b/StructureHelperTests/UnitTests/StirrupByInclinedRebarStrengthLogicTests.cs index 4a16a53..e46a783 100644 --- a/StructureHelperTests/UnitTests/StirrupByInclinedRebarStrengthLogicTests.cs +++ b/StructureHelperTests/UnitTests/StirrupByInclinedRebarStrengthLogicTests.cs @@ -53,7 +53,7 @@ namespace StructureHelperTests.UnitTests sectionMock.SetupGet(s => s.EndCoord).Returns(12.0); var logic = CreateLogic(); - var result = logic.GetShearStrength(); + var result = logic.CalculateShearStrength(); Assert.That(result, Is.EqualTo(0.0)); loggerMock.Verify(l => l.AddMessage(It.Is(msg => msg.Contains("has been ignored")))); @@ -66,7 +66,7 @@ namespace StructureHelperTests.UnitTests sectionMock.SetupGet(s => s.EndCoord).Returns(-1.0); var logic = CreateLogic(); - var result = logic.GetShearStrength(); + var result = logic.CalculateShearStrength(); Assert.That(result, Is.EqualTo(0.0)); loggerMock.Verify(l => l.AddMessage(It.Is(msg => msg.Contains("has been ignored")))); @@ -79,7 +79,7 @@ namespace StructureHelperTests.UnitTests sectionMock.SetupGet(s => s.EndCoord).Returns(0.05); // falls in start transfer zone var logic = CreateLogic(); - var result = logic.GetShearStrength(); + var result = logic.CalculateShearStrength(); Assert.That(result, Is.EqualTo(123.0)); // from interpolateMock interpolateMock.Verify(m => m.GetValueY(), Times.Once); @@ -92,7 +92,7 @@ namespace StructureHelperTests.UnitTests sectionMock.SetupGet(s => s.EndCoord).Returns(2.0); var logic = CreateLogic(); - var result = logic.GetShearStrength(); + var result = logic.CalculateShearStrength(); Assert.That(result, Is.EqualTo(123.0)); interpolateMock.Verify(m => m.GetValueY(), Times.Once); @@ -105,7 +105,7 @@ namespace StructureHelperTests.UnitTests sectionMock.SetupGet(s => s.EndCoord).Returns(1.0); var logic = CreateLogic(); - var result = logic.GetShearStrength(); + var result = logic.CalculateShearStrength(); // Strength = 0.75 * 1000 * sin(45°) * 2 var expected = 0.75 * 1000.0 * Math.Sin(Math.PI / 4) * 2; @@ -118,7 +118,7 @@ namespace StructureHelperTests.UnitTests rebarMock.SetupGet(r => r.TransferLength).Returns(5.0); // huge transfer length var logic = CreateLogic(); - Assert.Throws(() => logic.GetShearStrength()); + Assert.Throws(() => logic.CalculateShearStrength()); } private StirrupByInclinedRebarStrengthLogic CreateLogic()