Fix beam shear force calculator

This commit is contained in:
Evgeny Redikultsev
2025-05-24 20:26:44 +05:00
parent d108c52cac
commit f127594b5c
53 changed files with 920 additions and 121 deletions

View File

@@ -16,6 +16,7 @@ namespace StructureHelperLogics.Models.BeamShears
if (ReferenceEquals(targetObject, sourceObject)) { return; };
InitializeStrategies();
hasActionUpdateStrategy?.Update(targetObject, sourceObject);
hasSectionsUpdateStrategy?.Update(targetObject, sourceObject);
hasStirrupsUpdateStrategy?.Update(targetObject, sourceObject);
}

View File

@@ -13,6 +13,7 @@ namespace StructureHelperLogics.Models.BeamShears
CheckObject.IsNull(targetObject, ErrorStrings.TargetObject);
if (ReferenceEquals(targetObject, sourceObject)) { return; };
targetObject.Name = sourceObject.Name;
targetObject.ShowTraceData = sourceObject.ShowTraceData;
targetObject.InputData ??= new BeamShearCalculatorInputData(Guid.NewGuid());
InitializeStrategies();
inputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData);

View File

@@ -0,0 +1,80 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Loggers;
using StructureHelperLogics.Models.BeamShears.Logics;
namespace StructureHelperLogics.Models.BeamShears
{
public class ConcreteStrengthLogic : IBeamShearStrenghLogic
{
private readonly double longitudinalForce;
private readonly ISectionEffectiveness sectionEffectiveness;
private readonly IInclinedSection inclinedSection;
private IGetLongitudinalForceFactorLogic getLongitudinalForceFactorLogic;
private double crackLength;
public ConcreteStrengthLogic(
ISectionEffectiveness sectionEffectiveness,
IInclinedSection inclinedSection,
double longitudinalForce,
IShiftTraceLogger? traceLogger)
{
this.sectionEffectiveness = sectionEffectiveness;
this.inclinedSection = inclinedSection;
this.longitudinalForce = longitudinalForce;
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($"Crack length = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}, (m)");
RestrictCrackLength();
SetLongitudinalForce();
double factorOfLongitudinalForce = getLongitudinalForceFactorLogic.GetFactor();
TraceLogger?.AddMessage($"Factor of longitudinal force = {factorOfLongitudinalForce}, (dimensionless)");
double concreteMoment = sectionEffectiveness.BaseShapeFactor * sectionEffectiveness.ShapeFactor * inclinedSection.ConcreteTensionStrength * inclinedSection.WebWidth * inclinedSection.EffectiveDepth * inclinedSection.EffectiveDepth;
double shearStrength = factorOfLongitudinalForce * concreteMoment / crackLength;
TraceLogger?.AddMessage($"Shear strength of concrete = {shearStrength}, (N)");
return shearStrength;
}
private void InitializeStrategies()
{
getLongitudinalForceFactorLogic ??= new GetLogitudinalForceFactorLogic(TraceLogger?.GetSimilarTraceLogger(100));
}
private void SetLongitudinalForce()
{
getLongitudinalForceFactorLogic.LongitudinalForce = longitudinalForce;
getLongitudinalForceFactorLogic.InclinedSection = inclinedSection;
}
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

@@ -51,7 +51,8 @@ namespace StructureHelperLogics.Models.BeamShears
for (int i = 0; i < inputData.StepCount + 1; i++)
{
double endCoord = step * i;
coordinates.Add(endCoord);
double roundedEndCoord = Math.Round(endCoord, 6);
coordinates.Add(roundedEndCoord);
}
}
private void Check()

View File

@@ -0,0 +1,109 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Loggers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears.Logics
{
public class GetLogitudinalForceFactorLogic : IGetLongitudinalForceFactorLogic
{
private const double fstRatioInCompression = 1.25;
private const double sndRationInCompression = 0.75;
private double sectionArea;
public IShiftTraceLogger? TraceLogger { get; set; }
public IInclinedSection InclinedSection { get; set; }
public double LongitudinalForce { get; set; }
public GetLogitudinalForceFactorLogic(IShiftTraceLogger? traceLogger)
{
TraceLogger = traceLogger;
}
public double GetFactor()
{
TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
TraceLogger?.AddMessage("Logic of calculating of factor of influence of longitudinal force according to SP 63.13330.2018");
Check();
if (LongitudinalForce == 0)
{
TraceLogger?.AddMessage("Longitudinal force is zero", TraceLogStatuses.Service);
return 1;
}
sectionArea = InclinedSection.WebWidth * InclinedSection.FullDepth;
TraceLogger?.AddMessage($"Area of cross-section Ac = {InclinedSection.WebWidth} * {InclinedSection.FullDepth} = {sectionArea}(m^2)");
if (LongitudinalForce < 0)
{
TraceLogger?.AddMessage($"Longitudinal force N={LongitudinalForce}(N) is negative (compression)", TraceLogStatuses.Service);
return GetNegForceResult();
}
else
{
TraceLogger?.AddMessage("Longitudinal force N={LongitudinalForce}(N) is positive (tension)", TraceLogStatuses.Service);
return GetPosForceResult();
}
}
private void Check()
{
if (InclinedSection is null)
{
string errorString = ErrorStrings.DataIsInCorrect + "Inclined section is null";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
if (InclinedSection.WebWidth <= 0 || InclinedSection.FullDepth <= 0)
{
string errorString = ErrorStrings.DataIsInCorrect + $"Inclined section width = {InclinedSection.WebWidth}(m), and full depth = {InclinedSection.FullDepth}, but both of them must be greater than zero";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
}
private double GetPosForceResult()
{
double stressInConcrete = LongitudinalForce / sectionArea;
TraceLogger?.AddMessage($"Average stress in concrete (positive in tension) Sigma = {LongitudinalForce}(N) / {sectionArea}(m^2) = {stressInConcrete}(Pa)");
double concreteStrength = InclinedSection.ConcreteTensionStrength;
TraceLogger?.AddMessage($"Concrete strength Rbt = {concreteStrength}(Pa)");
double stressRatio = stressInConcrete / concreteStrength;
TraceLogger?.AddMessage($"Stress ratio rt = {stressInConcrete} / {concreteStrength} = {stressRatio}(dimensionless)");
double factor = 1 - 0.5 * stressRatio;
factor = Math.Max(factor, 0);
TraceLogger?.AddMessage($"Factor value fi_n = {factor}(dimensionless)");
return factor;
}
private double GetNegForceResult()
{
double stressInConcrete = (-1) * LongitudinalForce / sectionArea;
TraceLogger?.AddMessage($"Average stress in concrete (positive in compression) Sigma = {LongitudinalForce}(N) / {sectionArea}(m^2) = {stressInConcrete}(Pa)");
double concreteStrength = InclinedSection.ConcreteCompressionStrength;
TraceLogger?.AddMessage($"Concrete strength Rb = {concreteStrength}(Pa)");
double stressRatio = stressInConcrete / concreteStrength;
TraceLogger?.AddMessage($"Stress ratio rc = {stressInConcrete} / {concreteStrength} = {stressRatio}(dimensionless)");
double factor;
if (stressRatio < fstRatioInCompression)
{
TraceLogger?.AddMessage($"Stress ratio rc = {stressRatio} < {fstRatioInCompression}");
factor = 1 + stressRatio;
}
else if (stressRatio > sndRationInCompression)
{
factor = 5 * (1 - stressRatio);
factor = Math.Max(factor, 0);
}
else
{
factor = 1;
}
TraceLogger?.AddMessage($"Factor value fi_n = {factor}(dimensionless)");
return factor;
}
}
}

View File

@@ -0,0 +1,21 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears.Logics
{
/// <summary>
/// Implement logic for calculation of bearing capacity of inclined section for shear
/// </summary>
public interface IBeamShearStrenghLogic : ILogic
{
/// <summary>
/// Returns Bearing capacity of inclined section for shear
/// </summary>
/// <returns>Bearing capacity of inclined section for shear, N</returns>
double GetShearStrength();
}
}

View File

@@ -0,0 +1,15 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears.Logics
{
public interface IGetLongitudinalForceFactorLogic : IGetFactorLogic
{
public double LongitudinalForce { get; set; }
public IInclinedSection InclinedSection { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Loggers;
using StructureHelperCommon.Services;
using StructureHelperLogics.Models.BeamShears.Logics;
//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
@@ -8,14 +9,15 @@ using StructureHelperCommon.Services;
namespace StructureHelperLogics.Models.BeamShears
{
/// <inheritdoc/>
public class BeamShearStrengthByStirrupDensityLogic : IBeamShearStrenghLogic
public class StirrupByDensityStrengthLogic : IBeamShearStrenghLogic
{
private const double minStirrupRatio = 0.25;
private readonly IStirrupEffectiveness stirrupEffectiveness;
private readonly IStirrupByDensity stirrupByDensity;
private readonly IInclinedSection inclinedSection;
public BeamShearStrengthByStirrupDensityLogic(
public StirrupByDensityStrengthLogic(
IStirrupEffectiveness stirrupEffectiveness,
IStirrupByDensity stirrupByDensity,
IInclinedSection inclinedSection,
@@ -40,8 +42,16 @@ namespace StructureHelperLogics.Models.BeamShears
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;
TraceLogger?.AddMessage($"Bearing capacity of stirrups V = {stirrupEffectiveness.StirrupShapeFactor} * {stirrupEffectiveness.StirrupPlacementFactor} * {finalCrackLength} * {stirrupByDensity.StirrupDensity} = {strength}(N)");
double finalDensity = stirrupEffectiveness.StirrupShapeFactor * stirrupEffectiveness.StirrupPlacementFactor * stirrupByDensity.StirrupDensity;
TraceLogger?.AddMessage($"Stirrups design density qsw = {finalDensity}(N/m)");
double concreteDensity = inclinedSection.WebWidth * inclinedSection.ConcreteTensionStrength;
if (finalDensity < minStirrupRatio * concreteDensity)
{
TraceLogger?.AddMessage($"Since stirrups design density qsw = {finalDensity}(N/m) less than {minStirrupRatio} * {concreteDensity}, final density is equal to zero");
finalDensity = 0;
}
double strength = finalDensity * finalCrackLength;
TraceLogger?.AddMessage($"Bearing capacity of stirrups V = {finalDensity} * {finalCrackLength} = {strength}(N)");
TraceLogger?.AddMessage("Calculation has been finished successfully", TraceLogStatuses.Debug);
return strength;
}

View File

@@ -0,0 +1,60 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
//All rights reserved.
namespace StructureHelperLogics.Models.BeamShears.Logics
{
public class StirrupByRebarStrengthLogic : IBeamShearStrenghLogic
{
private IStirrupEffectiveness stirrupEffectiveness;
private IStirrupByRebar stirrupByRebar;
private IInclinedSection inclinedSection;
private StirrupByDensityStrengthLogic stirrupDensityStrengthLogic;
private IConvertStrategy<IStirrupByDensity, IStirrupByRebar> convertStrategy;
public IShiftTraceLogger? TraceLogger { get; set; }
public StirrupByRebarStrengthLogic(
IStirrupEffectiveness stirrupEffectiveness,
IStirrupByRebar stirrupByRebar,
IInclinedSection inclinedSection,
StirrupByDensityStrengthLogic stirrupDensityStrengthLogic,
IConvertStrategy<IStirrupByDensity, IStirrupByRebar> convertStrategy,
IShiftTraceLogger? traceLogger)
{
this.stirrupEffectiveness = stirrupEffectiveness;
this.stirrupByRebar = stirrupByRebar;
this.inclinedSection = inclinedSection;
this.stirrupDensityStrengthLogic = stirrupDensityStrengthLogic;
this.convertStrategy = convertStrategy;
TraceLogger = traceLogger;
}
public StirrupByRebarStrengthLogic(
IStirrupEffectiveness stirrupEffectiveness,
IStirrupByRebar stirrupByRebar,
IInclinedSection inclinedSection,
IShiftTraceLogger? traceLogger)
{
this.stirrupEffectiveness = stirrupEffectiveness;
this.stirrupByRebar = stirrupByRebar;
this.inclinedSection = inclinedSection;
TraceLogger = traceLogger;
}
public double GetShearStrength()
{
InitializeStrategies();
double shearStrength = stirrupDensityStrengthLogic.GetShearStrength();
return shearStrength;
}
private void InitializeStrategies()
{
convertStrategy ??= new StirrupByRebarToDensityConvertStrategy(TraceLogger);
IStirrupByDensity stirrupByDensity = convertStrategy.Convert(stirrupByRebar);
stirrupDensityStrengthLogic ??= new(stirrupEffectiveness, stirrupByDensity, inclinedSection, TraceLogger);
}
}
}

View File

@@ -13,6 +13,11 @@ namespace StructureHelperLogics.Models.BeamShears
public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; }
public IShiftTraceLogger TraceLogger { get; set; }
public StirrupByRebarToDensityConvertStrategy(IShiftTraceLogger traceLogger)
{
TraceLogger = traceLogger;
}
public StirrupByRebarToDensityConvertStrategy(IUpdateStrategy<IStirrup> updateStrategy, IShiftTraceLogger traceLogger)
{
this.updateStrategy = updateStrategy;

View File

@@ -0,0 +1,48 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears.Logics
{
internal class StirrupStrengthLogic : IBeamShearStrenghLogic
{
private IStirrup stirrup;
private IInclinedSection inclinedSection;
private IBeamShearStrenghLogic stirrupDensityStrengthLogic;
public StirrupStrengthLogic(IStirrup stirrup, IInclinedSection inclinedSection, IShiftTraceLogger? traceLogger)
{
this.stirrup = stirrup;
this.inclinedSection = inclinedSection;
TraceLogger = traceLogger;
}
public IShiftTraceLogger? TraceLogger { get; set; }
public double GetShearStrength()
{
var stirrupEffectiveness = StirrupEffectivenessFactory.GetEffectiveness(BeamShearSectionType.Rectangle);
if (stirrup is IStirrupByDensity stirrupByDensity)
{
TraceLogger?.AddMessage("Stirrups type is stirrup by density");
stirrupDensityStrengthLogic = new StirrupByDensityStrengthLogic(stirrupEffectiveness, stirrupByDensity, inclinedSection,TraceLogger);
return stirrupDensityStrengthLogic.GetShearStrength();
}
else if (stirrup is IStirrupByRebar stirrupByRebar)
{
TraceLogger?.AddMessage("Stirrups type is stirrup by rebar");
stirrupDensityStrengthLogic = new StirrupByRebarStrengthLogic(stirrupEffectiveness, stirrupByRebar, inclinedSection, TraceLogger);
return stirrupDensityStrengthLogic.GetShearStrength();
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(stirrup));
}
}
}
}