Add beam section logic

This commit is contained in:
Evgeny Redikultsev
2025-02-09 17:28:33 +05:00
parent 91ccebf147
commit f60d031f91
26 changed files with 701 additions and 63 deletions

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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
{
/// <summary>
/// Properties of concrete cross-section for shear strength of beam
/// </summary>
public interface IBeamShearSection : ISaveable, ICloneable
{
string? Name { get; set; }
/// <summary>
/// Concrete of cross-section
/// </summary>
IConcreteLibMaterial Material { get; set; }
/// <summary>
/// Shape of cross-section
/// </summary>
IShape Shape {get;}
/// <summary>
/// Distance from edge of tension zone to center of the nearest reinforcement bar
/// </summary>
double CenterCover { get; set; }
}
}

View File

@@ -9,6 +9,7 @@ namespace StructureHelperLogics.Models.BeamShears
{
public interface IInclinedSection : IEffectiveDepth
{
double WebWidth { get; set; }
double StartCoord { get; set; }
double EndCoord { get; set; }
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
/// <summary>
/// Properties of concrete cross-section effectiveness for shear
/// </summary>
public interface ISectionEffectiveness
{
/// <summary>
/// Shape factor of shear strength of base form, dimensionless
/// </summary>
double BaseShapeFactor { get; set; }
/// <summary>
/// Maximum ratio of crack length to effective depth
/// </summary>
double MaxCrackLengthRatio { get; set; }
/// <summary>
/// Maximum ratio of crack length to effective depth
/// </summary>
double MinCrackLengthRatio { get; set; }
/// <summary>
/// Shape factor of shear strength of specific form, dimensionless
/// </summary>
double ShapeFactor { get; set; }
}
}

View File

@@ -12,6 +12,10 @@ namespace StructureHelperLogics.Models.BeamShears
/// </summary>
public interface IStirrup : ISaveable, ICloneable
{
string Name { get; set; }
string? Name { get; set; }
/// <summary>
/// Distance from axis of comressed rebar to edge of comressed zone, m
/// </summary>
double CompressedGap { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
/// <summary>
/// Implement logic for stirrup bearing capacity which does not depend on specific inclined section
/// </summary>
public interface IStirrupByDirectValue : IStirrup
{
/// <summary>
/// Direct value of bearing capacity which is applied for any inclined section, N
/// </summary>
double BearingCapacityValue { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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
{
/// <summary>
/// Implement properties for uniformly distributed stirrups
/// </summary>
public interface IStirrupByUniformRebar : IStirrup
{
/// <summary>
/// Material of stirrups
/// </summary>
IReinforcementLibMaterial Material { get; set; }
/// <summary>
/// Count of legs of stirrup in specific cross-section
/// </summary>
double LegCount { get; set; }
/// <summary>
/// Diameter of stirrup, m
/// </summary>
double Diameter { get; set; }
/// <summary>
/// Step of uniformly distibuted stirrup along axis of beam, m
/// </summary>
double Step { get; set; }
}
}

View File

@@ -6,10 +6,22 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
/// <summary>
/// Properties of stirrups effectiveness
/// </summary>
public interface IStirrupEffectiveness
{
double MaxCrackLengthFactor { get; set; }
/// <summary>
/// Ratio of maximum crack length to effective depth
/// </summary>
double MaxCrackLengthRatio { get; set; }
/// <summary>
/// Factor of effectiveness due to non-rectangle shape of stirrup
/// </summary>
double StirrupShapeFactor { get; set; }
/// <summary>
/// Factor of difference between real and uniform distribution
/// </summary>
double StirrupPlacementFactor { get; set; }
}
}

View File

@@ -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; }
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
/// <inheritdoc/>
public class SectionEffectiveness : ISectionEffectiveness
{
/// <inheritdoc/>
public double BaseShapeFactor { get; set; }
/// <inheritdoc/>
public double MaxCrackLengthRatio { get; set; }
/// <inheritdoc/>
public double MinCrackLengthRatio { get; set; }
/// <inheritdoc/>
public double ShapeFactor { get; set; }
}
}

View File

@@ -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)
{

View File

@@ -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();
}
}
}

View File

@@ -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
{
/// <inheritdoc/>
public class StirrupByUniformRebar : IStirrupByUniformRebar
{
/// <inheritdoc/>
public Guid Id { get; }
public string? Name { get; set; }
/// <inheritdoc/>
public IReinforcementLibMaterial Material { get; set; }
/// <inheritdoc/>
public double LegCount { get; set; } = 2;
/// <inheritdoc/>
public double Diameter { get; set; } = 0.008;
/// <inheritdoc/>
public double Step { get; set; } = 0.1;
/// <inheritdoc/>
public double CompressedGap { get; set; } = 0;
public object Clone()
{
throw new NotImplementedException();
}
}
}

View File

@@ -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<IStirrupByDensity, IStirrupByUniformRebar>
{
private const double stirrupStrengthFactor = 1d;
private const double maxStirrupStrength = 3e8;
private IUpdateStrategy<IStirrup> updateStrategy;
public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; }
public IShiftTraceLogger TraceLogger { get; set; }
public StirrupByUniformRebarToDensityConvertStrategy(IUpdateStrategy<IStirrup> 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;
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
/// <inheritdoc/>
public class StirrupEffectiveness : IStirrupEffectiveness
{
/// <inheritdoc/>
public double MaxCrackLengthRatio { get; set; }
/// <inheritdoc/>
public double StirrupShapeFactor { get; set; }
/// <inheritdoc/>
public double StirrupPlacementFactor { get; set; }
}
}

View File

@@ -11,6 +11,7 @@ namespace StructureHelperLogics.Models.BeamShears
public Guid Id { get; }
public string Name { get; set; }
public List<IStirrup> Stirrups { get; } = new();
public double CompressedGap { get; set; }
public double GetShearBearingCapacity(IInclinedSection inclinedSection)
{

View File

@@ -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<IStirrup>
{
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;
}
}
}

View File

@@ -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<IStirrupEffectiveness> _mockStirrupEffectiveness;
private Mock<IStirrupByDensity> _mockStirrupByDensity;
private Mock<IInclinedSection> _mockInclinedSection;
private Mock<IShiftTraceLogger> _mockTraceLogger;
private BeamShearStrengthByStirrupDensityLogic _beamShearStrength;
[SetUp]
public void Setup()
{
_mockStirrupEffectiveness = new Mock<IStirrupEffectiveness>();
_mockStirrupByDensity = new Mock<IStirrupByDensity>();
_mockInclinedSection = new Mock<IInclinedSection>();
_mockTraceLogger = new Mock<IShiftTraceLogger>();
_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<string>(), It.IsAny<TraceLogStatuses>()), 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<StructureHelperException>(() => invalidInstance.GetShearStrength());
}
}
}

View File

@@ -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<IUpdateStrategy<IStirrup>> _mockUpdateStrategy;
private Mock<IShiftTraceLogger> _mockTraceLogger;
private StirrupByUniformRebarToDensityConvertStrategy _convertStrategy;
[SetUp]
public void Setup()
{
_mockUpdateStrategy = new Mock<IUpdateStrategy<IStirrup>>();
_mockTraceLogger = new Mock<IShiftTraceLogger>();
_convertStrategy = new StirrupByUniformRebarToDensityConvertStrategy(
_mockUpdateStrategy.Object,
_mockTraceLogger.Object
);
}
[Test]
public void Convert_UpdatesAndCalculatesDensityCorrectly()
{
// Arrange
var mockMaterial = new Mock<IReinforcementLibMaterial>();
mockMaterial.Setup(m => m.GetStrength(LimitStates.ULS, CalcTerms.ShortTerm)).Returns((2e8, 2e8));
var stirrupRebar = new Mock<IStirrupByUniformRebar>();
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<IStirrupByDensity>(), stirrupRebar.Object), Times.Once);
Assert.That(result.StirrupDensity, Is.EqualTo(837758.04095727834d).Within(0.00001));
//_mockTraceLogger.Verify(t => t.AddMessage(It.IsAny<string>(), It.IsAny<TraceLogStatuses>()), Times.AtLeastOnce);
}
}
}