Refactoring of beam shear calculation, add test for beam shea

This commit is contained in:
Evgeny Redikultsev
2025-08-31 17:29:16 +05:00
parent 738ce5c433
commit 5e45be35b1
45 changed files with 923 additions and 302 deletions

View File

@@ -11,6 +11,10 @@ namespace StructureHelperLogics.Models.BeamShears
private ICheckInputDataLogic<IBeamShearCalculatorInputData> checkInputDataLogic;
private IGetResultByInputDataLogic<IBeamShearCalculatorInputData, IBeamShearCalculatorResult> calculationLogic;
private IBeamShearCalculatorResult result;
private IBeamShearSectionLogic beamShearSectionLogic;
private GetInclinedSectionListLogic getInclinedSectionListLogic;
private GetBeamShearSectionIputDatasLogic getBeamShearSectionIputDatasLogic;
private IInclinedSectionResultListLogic getInclinedSectionResultListLogic;
public Guid Id { get; }
public string Name { get; set; } = string.Empty;
@@ -70,8 +74,26 @@ namespace StructureHelperLogics.Models.BeamShears
private void InitializeStrategies()
{
checkInputDataLogic ??= new CheckBeamShearCalculatorInputDataLogic(InputData, TraceLogger);
calculationLogic ??= new BeamShearCalculatorLogic(TraceLogger);
checkInputDataLogic = new CheckBeamShearCalculatorInputDataLogic(InputData, TraceLogger);
ActionResultListLogic actionLogic = GetActionLogic();
calculationLogic = new BeamShearCalculatorLogic(actionLogic, TraceLogger);
}
private ActionResultListLogic GetActionLogic()
{
IGetSectionLogicFactory getSectionLogicFactory = new GetSectionLogicFactory(TraceLogger);
beamShearSectionLogic = getSectionLogicFactory.GetSectionLogic(InputData.CodeType);
getInclinedSectionListLogic = new GetInclinedSectionListLogic(null);
getBeamShearSectionIputDatasLogic = new GetBeamShearSectionIputDatasLogic();
getInclinedSectionResultListLogic = new InclinedSectionResultListLogic(beamShearSectionLogic);
var actionLogic = new ActionResultListLogic(
InputData,
getBeamShearSectionIputDatasLogic,
getInclinedSectionListLogic,
getInclinedSectionResultListLogic,
new TraceSectionLogic(TraceLogger),
TraceLogger);
return actionLogic;
}
private void PrepareNewResult()

View File

@@ -22,6 +22,7 @@ namespace StructureHelperLogics.Models.BeamShears
/// <inheritdoc/>
public List<IStirrup> Stirrups { get; } = new();
public IBeamShearDesignRangeProperty DesignRangeProperty { get; set; } = new BeamShearDesignRangeProperty(Guid.NewGuid());
public ShearCodeTypes CodeType { get; set; } = ShearCodeTypes.SP_63_13330_2018_3;
public BeamShearCalculatorInputData(Guid id)
{

View File

@@ -0,0 +1,61 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models;
namespace StructureHelperLogics.Models.BeamShears
{
public class GetSectionLogicFactory : IGetSectionLogicFactory
{
ShearCodeTypes shearCodeType;
private IBeamShearSectionLogic sectionLogic;
public IShiftTraceLogger? TraceLogger { get; set; }
public GetSectionLogicFactory(IShiftTraceLogger? traceLogger)
{
TraceLogger = traceLogger;
}
public IBeamShearSectionLogic GetSectionLogic(ShearCodeTypes shearCodeType)
{
this.shearCodeType = shearCodeType;
if (shearCodeType == ShearCodeTypes.SP_63_13330_2018_3)
{
GetSPLogic();
}
else if (shearCodeType == ShearCodeTypes.StructureHelper_0)
{
GetSHLogic();
}
else
{
string errorString = ErrorStrings.ObjectTypeIsUnknownObj(shearCodeType) + $": design code type {shearCodeType} for shear calculation is unknown";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
return sectionLogic;
}
private void GetSHLogic()
{
BeamShearSectionLogic logic = GetBaseLogic();
logic.RestrictStirrupCalculator = new RestrictStirrupBySearchCalculator();
sectionLogic = logic;
}
private void GetSPLogic()
{
BeamShearSectionLogic logic = GetBaseLogic();
logic.RestrictStirrupCalculator = new RestrictStirrupByValueCalculator();
sectionLogic = logic;
}
private BeamShearSectionLogic GetBaseLogic()
{
BeamShearSectionLogic logic = new(TraceLogger);
logic.ShearCodeType = shearCodeType;
logic.GetSectionEffectivenessLogic = new GetSectionEffectivenessLogic();
return logic;
}
}
}

View File

@@ -0,0 +1,9 @@
using StructureHelperCommon.Infrastructures.Interfaces;
namespace StructureHelperLogics.Models.BeamShears
{
public interface IGetSectionLogicFactory : ILogic
{
IBeamShearSectionLogic GetSectionLogic(ShearCodeTypes shearCodeTypes);
}
}

View File

@@ -0,0 +1,7 @@
namespace StructureHelperLogics.Models.BeamShears
{
public interface ISectionEffectivenessFactory
{
ISectionEffectiveness GetShearEffectiveness(BeamShearSectionType sectionType);
}
}

View File

@@ -1,15 +1,10 @@
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 class SectionEffectivenessFactorySH : ISectionEffectivenessFactory
{
public static ISectionEffectiveness GetShearEffectiveness(BeamShearSectionType sectionType)
public ISectionEffectiveness GetShearEffectiveness(BeamShearSectionType sectionType)
{
if (sectionType == BeamShearSectionType.Rectangle)
{

View File

@@ -0,0 +1,31 @@
using StructureHelperCommon.Infrastructures.Exceptions;
namespace StructureHelperLogics.Models.BeamShears
{
public class SectionEffectivenessFactorySP2018 : ISectionEffectivenessFactory
{
public ISectionEffectiveness GetShearEffectiveness(BeamShearSectionType sectionType)
{
if (sectionType == BeamShearSectionType.Rectangle)
{
return GetRectangleEffectiveness();
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(sectionType));
}
}
private static ISectionEffectiveness GetRectangleEffectiveness()
{
SectionEffectiveness sectionEffectiveness = new()
{
BaseShapeFactor = 1.5,
MaxCrackLengthRatio = 3,
MinCrackLengthRatio = 0.6,
ShapeFactor = 1
};
return sectionEffectiveness;
}
}
}

View File

@@ -9,8 +9,9 @@ namespace StructureHelperLogics.Models.BeamShears
{
public enum BeamShearSectionType
{
Rectangle,
Circle
Rectangle = 0,
Circle = 1,
TShape = 2
}
public static class StirrupEffectivenessFactory
{

View File

@@ -6,5 +6,6 @@ namespace StructureHelperLogics.Models.BeamShears
public interface IBeamShearCalculatorInputData : ISaveable, IInputData, IHasBeamShearActions, IHasBeamShearSections, IHasStirrups
{
IBeamShearDesignRangeProperty DesignRangeProperty { get; set; }
ShearCodeTypes CodeType { get; set; }
}
}

View File

@@ -0,0 +1,123 @@
using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Forces;
namespace StructureHelperLogics.Models.BeamShears
{
public class ActionResultListLogic : IActionResultListLogic
{
private const LimitStates CollapseLimitState = LimitStates.ULS;
private readonly List<CalcTerms> calcTerms = new() { CalcTerms.LongTerm, CalcTerms.ShortTerm };
private readonly IBeamShearCalculatorInputData inputData;
private readonly IGetBeamShearSectionIputDatasLogic getBeamShearSectionIputDatasLogic;
private readonly IGetInclinedSectionListLogic getInclinedSectionListLogic;
private readonly IInclinedSectionResultListLogic inclinedSectionResultListLogic;
private readonly ITraceSectionLogic traceSectionLogic;
private List<IInclinedSection> inclinedSections;
List<IBeamShearActionResult> actionResults;
List<IStirrup> stirrups;
public ActionResultListLogic(
IBeamShearCalculatorInputData inputData,
IGetBeamShearSectionIputDatasLogic getBeamShearSectionIputDatasLogic,
IGetInclinedSectionListLogic getInclinedSectionListLogic,
IInclinedSectionResultListLogic inclinedSectionResultListLogic,
ITraceSectionLogic traceSectionLogic,
IShiftTraceLogger? traceLogger
)
{
this.inputData = inputData;
this.getBeamShearSectionIputDatasLogic = getBeamShearSectionIputDatasLogic;
this.getInclinedSectionListLogic = getInclinedSectionListLogic;
this.inclinedSectionResultListLogic = inclinedSectionResultListLogic;
this.traceSectionLogic = traceSectionLogic;
TraceLogger = traceLogger;
}
public IShiftTraceLogger? TraceLogger { get; set; }
public List<IBeamShearActionResult> GetActionResults()
{
PrepareNewResult();
foreach (var beamShearAction in inputData.Actions)
{
getBeamShearSectionIputDatasLogic.Action = beamShearAction;
foreach (var calcTerm in calcTerms)
{
getBeamShearSectionIputDatasLogic.CalcTerm = calcTerm;
foreach (var section in inputData.Sections)
{
PrepareInclinedSectionList(section);
TraceLogger?.AddMessage($"Analysis for action: {beamShearAction.Name}, section: {section.Name}, calc turm {calcTerm} has been started");
traceSectionLogic.TraceSection(section);
foreach (var stirrup in stirrups)
{
List<IBeamShearSectionLogicResult> sectionResults = PrepareSectionResult(stirrup);
BeamShearActionResult actionResult = GetActionResult(beamShearAction, calcTerm, section, stirrup, sectionResults);
actionResults.Add(actionResult);
}
TraceLogger?.AddMessage($"Analysis for action: {beamShearAction.Name}, section: {section.Name}, calc term {calcTerm} has been finished sucessfull");
}
}
}
return actionResults;
}
private List<IBeamShearSectionLogicResult> PrepareSectionResult(IStirrup stirrup)
{
getBeamShearSectionIputDatasLogic.Stirrup = stirrup;
List<IBeamShearSectionLogicInputData> sectionInputDatas = getBeamShearSectionIputDatasLogic.GetBeamShearSectionInputDatas();
List<IBeamShearSectionLogicResult> sectionResults = inclinedSectionResultListLogic.GetInclinedSectionResults(sectionInputDatas);
return sectionResults;
}
private void PrepareInclinedSectionList(IBeamShearSection section)
{
getInclinedSectionListLogic.BeamShearSection = section;
getInclinedSectionListLogic.DesignRangeProperty = inputData.DesignRangeProperty;
inclinedSections = getInclinedSectionListLogic.GetInclinedSections();
getBeamShearSectionIputDatasLogic.Section = section;
getBeamShearSectionIputDatasLogic.InclinedSectionList = inclinedSections;
}
private void PrepareNewResult()
{
actionResults = new();
stirrups = inputData.Stirrups.ToList();
if (stirrups.Any() == false)
{
stirrups.Add(new StirrupByDensity(Guid.NewGuid()) { StirrupDensity = 0 });
}
}
private BeamShearActionResult GetActionResult(IBeamShearAction beamShearAction, CalcTerms calcTerm, IBeamShearSection section, IStirrup stirrup, List<IBeamShearSectionLogicResult> sectionResults)
{
BeamShearActionResult actionResult = PrepareNewActionResult(beamShearAction, calcTerm, section, stirrup);
if (sectionResults.Any(x => x.IsValid == false))
{
actionResult.IsValid = false;
if (actionResult.Description.Length > 0)
{
actionResult.Description += "\n";
}
actionResult.Description += $"There are {sectionResults.Count(x => x.IsValid == false)} invalid section result(s)";
}
actionResult.SectionResults = sectionResults;
return actionResult;
}
private static BeamShearActionResult PrepareNewActionResult(IBeamShearAction beamShearAction, CalcTerms calcTerm, IBeamShearSection section, IStirrup stirrup)
{
return new()
{
IsValid = true,
Description = string.Empty,
BeamShearAction = beamShearAction,
LimitState = CollapseLimitState,
CalcTerm = calcTerm,
Section = section,
Stirrup = stirrup
};
}
}
}

View File

@@ -1,29 +1,20 @@
using StructureHelper.Models.Materials;
using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Loggers;
using StructureHelperLogics.Models.Materials;
namespace StructureHelperLogics.Models.BeamShears
{
public class BeamShearCalculatorLogic : IGetResultByInputDataLogic<IBeamShearCalculatorInputData, IBeamShearCalculatorResult>
{
private const LimitStates CollapseLimitState = LimitStates.ULS;
private readonly List<CalcTerms> calcTerms = new() { CalcTerms.LongTerm, CalcTerms.ShortTerm };
private IBeamShearCalculatorResult result;
private List<IBeamShearActionResult> actionResults;
private IBeamShearCalculatorInputData inputData;
private List<IInclinedSection> inclinedSections;
private IBeamShearSectionLogic beamShearSectionLogic;
private IGetBeamShearSectionIputDatasLogic getBeamShearSectionIputDatasLogic;
private IGetInclinedSectionListLogic getInclinedSectionListLogic;
private readonly IActionResultListLogic getActionResultListLogic;
public IShiftTraceLogger? TraceLogger { get; set; }
public BeamShearCalculatorLogic(IShiftTraceLogger? traceLogger)
public BeamShearCalculatorLogic(IActionResultListLogic getActionResultListLogic, IShiftTraceLogger? traceLogger)
{
this.getActionResultListLogic = getActionResultListLogic;
TraceLogger = traceLogger;
}
@@ -31,10 +22,8 @@ namespace StructureHelperLogics.Models.BeamShears
public IBeamShearCalculatorResult GetResultByInputData(IBeamShearCalculatorInputData inputData)
{
TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
this.inputData = inputData;
PrepareNewResult();
InitializeStrategies();
try
{
GetActionResults();
@@ -50,42 +39,11 @@ namespace StructureHelperLogics.Models.BeamShears
return result;
}
private void TraceSection(IBeamShearSection section)
private void GetActionResults()
{
List<IHeadMaterial> headMaterials = new()
{
new HeadMaterial(Guid.Empty)
{
Name = $"{section.Name}.Concrete",
HelperMaterial = section.ConcreteMaterial
},
new HeadMaterial(Guid.Empty)
{
Name = $"{section.Name}.Reinforcement",
HelperMaterial = section.ReinforcementMaterial
},
};
var traceLogic = new TraceMaterialsFactory()
{
Collection = headMaterials
};
traceLogic.AddEntriesToTraceLogger(TraceLogger);
actionResults = getActionResultListLogic.GetActionResults();
}
private IBeamShearSectionLogicResult CalculateInclinedSectionResult(IBeamShearSectionLogicInputData sectionInputData)
{
beamShearSectionLogic.InputData = sectionInputData;
beamShearSectionLogic.Run();
var sectionResult = beamShearSectionLogic.Result as IBeamShearSectionLogicResult;
return sectionResult;
}
private void InitializeStrategies()
{
beamShearSectionLogic ??= new BeamShearSectionLogic(TraceLogger);
getInclinedSectionListLogic ??= new GetInclinedSectionListLogic(null);
getBeamShearSectionIputDatasLogic ??= new GetBeamShearSectionIputDatasLogic();
}
private void PrepareNewResult()
{
@@ -95,84 +53,5 @@ namespace StructureHelperLogics.Models.BeamShears
Description = string.Empty
};
}
private void GetActionResults()
{
actionResults = new();
List<IStirrup> stirrups = inputData.Stirrups.ToList();
if (stirrups.Any() == false)
{
stirrups.Add(new StirrupByDensity(Guid.NewGuid()) { StirrupDensity = 0 });
}
foreach (var beamShearAction in inputData.Actions)
{
getBeamShearSectionIputDatasLogic.Action = beamShearAction;
foreach (var calcTerm in calcTerms)
{
getBeamShearSectionIputDatasLogic.CalcTerm = calcTerm;
foreach (var section in inputData.Sections)
{
getInclinedSectionListLogic.BeamShearSection = section;
getInclinedSectionListLogic.DesignRangeProperty = inputData.DesignRangeProperty;
inclinedSections = getInclinedSectionListLogic.GetInclinedSections();
getBeamShearSectionIputDatasLogic.Section = section;
getBeamShearSectionIputDatasLogic.InclinedSectionList = inclinedSections;
TraceLogger?.AddMessage($"Analysis for action: {beamShearAction.Name}, section: {section.Name}, calc turm {calcTerm} has been started");
TraceSection(section);
foreach (var stirrup in stirrups)
{
getBeamShearSectionIputDatasLogic.Stirrup = stirrup;
List<IBeamShearSectionLogicInputData> sectionInputDatas = getBeamShearSectionIputDatasLogic.GetBeamShearSectionInputDatas();
List<IBeamShearSectionLogicResult> sectionResults = GetInclinedSectionResults(sectionInputDatas);
BeamShearActionResult actionResult = GetActionResult(beamShearAction, calcTerm, section, stirrup, sectionResults);
actionResults.Add(actionResult);
}
TraceLogger?.AddMessage($"Analysis for action: {beamShearAction.Name}, section: {section.Name}, calc term {calcTerm} has been finished sucessfull");
}
}
}
}
private BeamShearActionResult GetActionResult(IBeamShearAction beamShearAction, CalcTerms calcTerm, IBeamShearSection section, IStirrup stirrup, List<IBeamShearSectionLogicResult> sectionResults)
{
BeamShearActionResult actionResult = PrepareNewActionResult(beamShearAction, calcTerm, section, stirrup);
if (sectionResults.Any(x => x.IsValid == false))
{
actionResult.IsValid = false;
if (actionResult.Description.Length > 0)
{
actionResult.Description += "\n";
}
actionResult.Description += $"There are {sectionResults.Count(x => x.IsValid == false)} invalid section result(s)";
}
actionResult.SectionResults = sectionResults;
return actionResult;
}
private List<IBeamShearSectionLogicResult> GetInclinedSectionResults(List<IBeamShearSectionLogicInputData> sectionInputDatas)
{
List<IBeamShearSectionLogicResult> sectionResults = new();
foreach (var item in sectionInputDatas)
{
IBeamShearSectionLogicResult sectionResult = CalculateInclinedSectionResult(item);
sectionResults.Add(sectionResult);
}
return sectionResults;
}
private static BeamShearActionResult PrepareNewActionResult(IBeamShearAction beamShearAction, CalcTerms calcTerm, IBeamShearSection section, IStirrup stirrup)
{
return new()
{
IsValid = true,
Description = string.Empty,
BeamShearAction = beamShearAction,
LimitState = CollapseLimitState,
CalcTerm = calcTerm,
Section = section,
Stirrup = stirrup
};
}
}
}

View File

@@ -1,65 +0,0 @@
using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Services.Forces;
namespace StructureHelperLogics.Models.BeamShears
{
public class BeamShearCalculatorToLogicInputDataConvertStrategy
{
const LimitStates limitState = LimitStates.ULS;
private readonly IShiftTraceLogger? traceLogger;
private readonly List<CalcTerms> calcTerms = new() { CalcTerms.ShortTerm, CalcTerms.LongTerm };
public BeamShearCalculatorToLogicInputDataConvertStrategy(IShiftTraceLogger? traceLogger)
{
this.traceLogger = traceLogger;
}
public List<IBeamShearSectionLogicInputData> Convert(IBeamShearCalculatorInputData source)
{
List<IBeamShearSectionLogicInputData> result = new();
foreach (var section in source.Sections)
{
foreach (var action in source.Actions)
{
foreach (var stirrup in source.Stirrups)
{
foreach (var calcTerm in calcTerms)
{
IForceTuple forceTuple = GetForceTuple(action, limitState, calcTerm);
BeamShearSectionLogicInputData newItem = new(Guid.NewGuid())
{
//BeamShearSection = section,
ForceTuple = forceTuple,
Stirrup = stirrup,
LimitState = limitState,
CalcTerm = calcTerm
};
result.Add(newItem);
}
}
}
}
return result;
}
private IForceTuple GetForceTuple(IBeamShearAction action, LimitStates limitState, CalcTerms calcTerm)
{
IForceTuple externalForceTuple = GetExternalForceTuple(action.ExternalForce, limitState, calcTerm);
IForceTuple internalForceTuple = GetInternalForceTuple(action.SupportAction, limitState, calcTerm);
IForceTuple sumForceTuple = ForceTupleService.SumTuples(externalForceTuple, internalForceTuple);
return sumForceTuple;
}
private IForceTuple GetInternalForceTuple(IBeamShearAxisAction supportAction, LimitStates limitState, CalcTerms calcTerm)
{
throw new NotImplementedException();
}
private IForceTuple GetExternalForceTuple(IFactoredForceTuple externalForce, LimitStates limitState, CalcTerms calcTerm)
{
throw new NotImplementedException();
}
}
}

View File

@@ -21,7 +21,9 @@ namespace StructureHelperLogics.Models.BeamShears
private double stirrupStrength;
private ShiftTraceLogger? localTraceLogger { get; set; }
public ShearCodeTypes ShearCodeType { get; set; }
public IGetSectionEffectivenessLogic GetSectionEffectivenessLogic { get; set; }
public IRestrictStirrupCalculator RestrictStirrupCalculator { get; set; }
public IBeamShearSectionLogicInputData InputData { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; }
@@ -97,7 +99,7 @@ namespace StructureHelperLogics.Models.BeamShears
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.");
stirrupStrength = GetStirrupStrengthBySearch();
stirrupStrength = RestrictStirrupStrength();
}
concreteStrength *= factorOfLongitudinalForce;
localTraceLogger?.AddMessage($"Concrete strength Qb = {concreteStrength}(N)");
@@ -125,33 +127,32 @@ namespace StructureHelperLogics.Models.BeamShears
}
}
private double GetStirrupStrengthBySearch()
private double RestrictStirrupStrength()
{
var logic = new StirrupBySearchLogic(localTraceLogger.GetSimilarTraceLogger(100))
RestrictStirrupCalculator.TraceLogger = localTraceLogger.GetSimilarTraceLogger(100);
RestrictStirrupCalculator.InputData = result.ResultInputData;
RestrictStirrupCalculator.SectionEffectiveness = sectionEffectiveness;
RestrictStirrupCalculator.SourceStirrupStrength = stirrupStrength;
RestrictStirrupCalculator.SourceSection = result.ResultInputData.InclinedCrack;
RestrictStirrupCalculator.Run();
var calculatorResult = RestrictStirrupCalculator.Result as RestrictCalculatorResult;
if (calculatorResult.IsValid == false)
{
InputData = result.ResultInputData,
SectionEffectiveness = sectionEffectiveness
};
double stirrupStrength = logic.CalculateShearStrength();
localTraceLogger?.AddMessage($"Stirrup strength was restricted as Qsw,restricted = {stirrupStrength}(N)");
result.ResultInputData.InclinedCrack = logic.InclinedCrack;
return stirrupStrength;
result.IsValid = false;
result.Description += calculatorResult.Description;
return calculatorResult.StirrupStrength;
}
else
{
result.ResultInputData.InclinedCrack = calculatorResult.InclinedCrack;
return calculatorResult.StirrupStrength;
}
}
private void InitializeStrategies()
{
if (result.ResultInputData.InclinedSection.BeamShearSection.Shape is IRectangleShape)
{
sectionEffectiveness = SectionEffectivenessFactory.GetShearEffectiveness(BeamShearSectionType.Rectangle);
}
else if (result.ResultInputData.InclinedSection.BeamShearSection.Shape is ICircleShape)
{
sectionEffectiveness = SectionEffectivenessFactory.GetShearEffectiveness(BeamShearSectionType.Circle);
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(result.ResultInputData.InclinedSection.BeamShearSection.Shape));
}
IShape shape = result.ResultInputData.InclinedSection.BeamShearSection.Shape;
sectionEffectiveness = GetSectionEffectivenessLogic.GetSectionEffectiveness(ShearCodeType, shape);
concreteLogic = new(sectionEffectiveness, result.ResultInputData.InclinedSection, localTraceLogger);
stirrupLogic = new(result.ResultInputData, localTraceLogger);
getLongitudinalForceFactorLogic = new GetLongitudinalForceFactorLogic(localTraceLogger?.GetSimilarTraceLogger(100));

View File

@@ -83,7 +83,7 @@ namespace StructureHelperLogics.Models.BeamShears
}
else
{
checkSectionLogic ??= new CheckBeamShearSectionLogic(TraceLogger);
checkSectionLogic = new CheckBeamShearSectionLogic(InputData.CodeType, TraceLogger);
foreach (var item in InputData.Sections)
{
checkSectionLogic.Entity = item;

View File

@@ -10,11 +10,13 @@ namespace StructureHelperLogics.Models.BeamShears.Logics
private const double minValueOfCrossSectionWidth = 0.05;
private const double minValueOfCrossSectionHeight = 0.05;
private const double minCircleDiameter = 0.05;
private readonly ShearCodeTypes shearCodeType;
private bool result;
private string checkResult;
public CheckBeamShearSectionLogic(IShiftTraceLogger? traceLogger)
public CheckBeamShearSectionLogic(ShearCodeTypes shearCodeType, IShiftTraceLogger? traceLogger)
{
this.shearCodeType = shearCodeType;
TraceLogger = traceLogger;
}
@@ -36,6 +38,16 @@ namespace StructureHelperLogics.Models.BeamShears.Logics
}
else
{
try
{
var logic = new GetSectionEffectivenessLogic();
var factory = logic.GetSectionEffectiveness(shearCodeType, Entity.Shape);
}
catch (Exception ex)
{
result = false;
TraceMessage($"\nType of section {Entity.Name} is not suitable for design code {shearCodeType}");
}
if (Entity.ConcreteMaterial is null)
{
result = false;

View File

@@ -0,0 +1,63 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Shapes;
using StructureHelperLogics.Models.BeamShears.Logics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
public class GetSectionEffectivenessLogic : IGetSectionEffectivenessLogic
{
ISectionEffectivenessFactory sectionEffectivenessFactory;
public IShiftTraceLogger? TraceLogger { get; set; }
public ISectionEffectiveness GetSectionEffectiveness(ShearCodeTypes shearCodeTypes, IShape shape)
{
InitializeFactory(shearCodeTypes);
ISectionEffectiveness sectionEffectiveness = GetEffectiveness(shape);
return sectionEffectiveness;
}
private ISectionEffectiveness GetEffectiveness(IShape shape)
{
ISectionEffectiveness sectionEffectiveness;
if (shape is IRectangleShape)
{
sectionEffectiveness = sectionEffectivenessFactory.GetShearEffectiveness(BeamShearSectionType.Rectangle);
}
else if (shape is ICircleShape)
{
sectionEffectiveness = sectionEffectivenessFactory.GetShearEffectiveness(BeamShearSectionType.Circle);
}
else
{
throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(shape));
}
return sectionEffectiveness;
}
private void InitializeFactory(ShearCodeTypes shearCodeTypes)
{
if (shearCodeTypes == ShearCodeTypes.SP_63_13330_2018_3)
{
sectionEffectivenessFactory = new SectionEffectivenessFactorySP2018();
}
else if (shearCodeTypes == ShearCodeTypes.StructureHelper_0)
{
sectionEffectivenessFactory = new SectionEffectivenessFactorySH();
}
else
{
string errorString = ErrorStrings.ObjectTypeIsUnknownObj(shearCodeTypes) + $": design code type {shearCodeTypes} for shear calculation is unknown";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString);
}
}
}
}

View File

@@ -0,0 +1,9 @@
using StructureHelperCommon.Infrastructures.Interfaces;
namespace StructureHelperLogics.Models.BeamShears
{
public interface IActionResultListLogic : ILogic
{
List<IBeamShearActionResult> GetActionResults();
}
}

View File

@@ -0,0 +1,10 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Shapes;
namespace StructureHelperLogics.Models.BeamShears.Logics
{
public interface IGetSectionEffectivenessLogic : ILogic
{
ISectionEffectiveness GetSectionEffectiveness(ShearCodeTypes shearCodeTypes, IShape shape);
}
}

View File

@@ -0,0 +1,7 @@
namespace StructureHelperLogics.Models.BeamShears
{
public interface IInclinedSectionResultListLogic
{
List<IBeamShearSectionLogicResult> GetInclinedSectionResults(List<IBeamShearSectionLogicInputData> sectionInputDatas);
}
}

View File

@@ -0,0 +1,11 @@
using StructureHelperCommon.Infrastructures.Interfaces;
namespace StructureHelperLogics.Models.BeamShears
{
public interface ITraceSectionLogic : ILogic
{
void TraceSection(IBeamShearSection section);
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
public class InclinedSectionResultListLogic : IInclinedSectionResultListLogic
{
private IBeamShearSectionLogic beamShearSectionLogic;
public InclinedSectionResultListLogic(IBeamShearSectionLogic beamShearSectionLogic)
{
this.beamShearSectionLogic = beamShearSectionLogic;
}
public List<IBeamShearSectionLogicResult> GetInclinedSectionResults(List<IBeamShearSectionLogicInputData> sectionInputDatas)
{
List<IBeamShearSectionLogicResult> sectionResults = new();
foreach (var item in sectionInputDatas)
{
IBeamShearSectionLogicResult sectionResult = CalculateInclinedSectionResult(item);
sectionResults.Add(sectionResult);
}
return sectionResults;
}
private IBeamShearSectionLogicResult CalculateInclinedSectionResult(IBeamShearSectionLogicInputData sectionInputData)
{
beamShearSectionLogic.InputData = sectionInputData;
beamShearSectionLogic.Run();
var sectionResult = beamShearSectionLogic.Result as IBeamShearSectionLogicResult;
return sectionResult;
}
}
}

View File

@@ -2,7 +2,6 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Loggers;
using StructureHelperCommon.Services.Units;
using StructureHelperLogics.Models.BeamShears.Logics;
namespace StructureHelperLogics.Models.BeamShears
{
@@ -18,8 +17,10 @@ namespace StructureHelperLogics.Models.BeamShears
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.");
this.sectionEffectiveness = sectionEffectiveness
?? throw new StructureHelperException("Section effectiveness cannot be null.");
this.inclinedSection = inclinedSection
?? throw new StructureHelperException("Inclined section cannot be null.");
TraceLogger = traceLogger;
}
@@ -27,39 +28,48 @@ namespace StructureHelperLogics.Models.BeamShears
{
TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
ValidateInput();
TraceLogger?.AddMessage($"Section effectiveness base shape factor phi_b2 = {sectionEffectiveness.BaseShapeFactor}{UnitsOfSI.Dimensionless}");
TraceLogger?.AddMessage($"Section effectiveness shape factor phi_shp = {sectionEffectiveness.ShapeFactor}{UnitsOfSI.Dimensionless}");
TraceLogger?.AddMessage($"Concrete tension strength Rbt = {inclinedSection.ConcreteTensionStrength}{UnitsOfSI.Pa}");
TraceLogger?.AddMessage($"Design width of cross-section b = {inclinedSection.WebWidth}{UnitsOfSI.Meters}");
TraceLogger?.AddMessage($"Effective depth of cross-section ho = {inclinedSection.EffectiveDepth}{UnitsOfSI.Meters}");
double rawCrackLength = inclinedSection.EndCoord - inclinedSection.StartCoord;
TraceLogger?.AddMessage($"Inclination section length c = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {rawCrackLength}{UnitsOfSI.Meters}");
double crackLength = RestrictCrackLength(rawCrackLength);
double concreteMoment = CalculateConcreteMoment();
double shearStrength = concreteMoment / crackLength;
TraceLogger?.AddMessage($"Shear strength = {concreteMoment} / {crackLength} = {shearStrength} {UnitsOfSI.Newtons}");
TraceLogger?.AddMessage($"Shear strength = Mb / c = {concreteMoment}{UnitsOfSI.NewtonMeters} / {crackLength}{UnitsOfSI.Meters} = {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)
private double CalculateConcreteMoment()
{
double max = sectionEffectiveness.MaxCrackLengthRatio * inclinedSection.EffectiveDepth;
double min = sectionEffectiveness.MinCrackLengthRatio * inclinedSection.EffectiveDepth;
double concreteMoment = sectionEffectiveness.BaseShapeFactor
* sectionEffectiveness.ShapeFactor
* inclinedSection.ConcreteTensionStrength
* inclinedSection.WebWidth
* inclinedSection.EffectiveDepth
* inclinedSection.EffectiveDepth;
TraceLogger?.AddMessage($"Concrete moment Mb = {sectionEffectiveness.BaseShapeFactor} * {sectionEffectiveness.ShapeFactor} * {inclinedSection.ConcreteTensionStrength}{UnitsOfSI.Pa} * {inclinedSection.WebWidth}{UnitsOfSI.Meters} * ({inclinedSection.EffectiveDepth}{UnitsOfSI.Meters})^2 = {concreteMoment}{UnitsOfSI.NewtonMeters}");
return concreteMoment;
}
if (length > max)
private double RestrictCrackLength(double sourceLength)
{
double length = sourceLength;
double maxLength = sectionEffectiveness.MaxCrackLengthRatio * inclinedSection.EffectiveDepth;
double minLength = sectionEffectiveness.MinCrackLengthRatio * inclinedSection.EffectiveDepth;
if (length > maxLength)
{
TraceLogger?.AddMessage($"Crack length reduced from {length} to {max}");
return max;
TraceLogger?.AddMessage($"Max design crack length cmax = {sectionEffectiveness.MaxCrackLengthRatio} * {inclinedSection.EffectiveDepth}{UnitsOfSI.Meters} = {maxLength}{UnitsOfSI.Meters}. Crack length has been reduced from {length}{UnitsOfSI.Meters} to {maxLength}{UnitsOfSI.Meters}");
return maxLength;
}
if (length < min)
if (length < minLength)
{
TraceLogger?.AddMessage($"Crack length increased from {length} to {min}");
return min;
TraceLogger?.AddMessage($"Min design crack length cmin = {sectionEffectiveness.MinCrackLengthRatio} * {inclinedSection.EffectiveDepth}{UnitsOfSI.Meters} = {minLength}{UnitsOfSI.Meters}. Crack length has been increased from {length}{UnitsOfSI.Meters} to {minLength}{UnitsOfSI.Meters}");
return minLength;
}
return length;
}
@@ -68,6 +78,8 @@ namespace StructureHelperLogics.Models.BeamShears
{
if (inclinedSection.EffectiveDepth <= 0)
throw new StructureHelperException("Effective depth must be greater than zero.");
if (inclinedSection.WebWidth <= 0)
throw new StructureHelperException("Width of cross-section must be greater than zero.");
}
}

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
namespace StructureHelperLogics.Models.BeamShears
{
public interface IRestrictStirrupCalculator : ILogicCalculator
{
IBeamShearSectionLogicInputData InputData { get; set; }
ISectionEffectiveness SectionEffectiveness { get; set; }
double SourceStirrupStrength { get; set; }
IInclinedSection SourceSection { get; set; }
}
}

View File

@@ -0,0 +1,12 @@
using StructureHelperCommon.Models.Calculators;
namespace StructureHelperLogics.Models.BeamShears
{
public class RestrictCalculatorResult : IResult
{
public bool IsValid { get; set; } = true;
public string? Description { get; set; } = string.Empty;
public IInclinedSection InclinedCrack { get; set; }
public double StirrupStrength { get; set; }
}
}

View File

@@ -0,0 +1,47 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
namespace StructureHelperLogics.Models.BeamShears
{
public class RestrictStirrupBySearchCalculator : IRestrictStirrupCalculator
{
RestrictCalculatorResult result;
public Guid Id => Guid.Empty;
public IShiftTraceLogger? TraceLogger { get; set; }
public IResult Result => result;
public IBeamShearSectionLogicInputData InputData { get; set; }
public ISectionEffectiveness SectionEffectiveness { get; set; }
public double SourceStirrupStrength { get; set; }
public IInclinedSection SourceSection { get; set; }
public object Clone()
{
throw new NotImplementedException();
}
public void Run()
{
result = new();
try
{
var logic = new StirrupBySearchLogic(TraceLogger?.GetSimilarTraceLogger(100))
{
InputData = InputData,
SectionEffectiveness = SectionEffectiveness
};
double stirrupStrength = logic.CalculateShearStrength();
TraceLogger?.AddMessage($"Stirrup strength was restricted as Qsw,restricted = {stirrupStrength}(N)");
result.InclinedCrack = logic.InclinedCrack;
result.StirrupStrength = stirrupStrength;
}
catch (Exception ex)
{
result.IsValid = false;
TraceLogger?.AddMessage(ex.Message, TraceLogStatuses.Error);
result.Description += ex.Message;
}
}
}
}

View File

@@ -0,0 +1,37 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.Models.BeamShears
{
public class RestrictStirrupByValueCalculator : IRestrictStirrupCalculator
{
RestrictCalculatorResult result;
public Guid Id => Guid.Empty;
public double RestrictionValue { get; set; } = double.PositiveInfinity;
public IBeamShearSectionLogicInputData InputData { get; set; }
public ISectionEffectiveness SectionEffectiveness { get; set; }
public IResult Result => result;
public IShiftTraceLogger? TraceLogger { get; set; }
public double SourceStirrupStrength { get; set; }
public IInclinedSection SourceSection { get; set; }
public object Clone()
{
throw new NotImplementedException();
}
public void Run()
{
result = new();
result.InclinedCrack = SourceSection;
result.StirrupStrength = Math.Min(SourceStirrupStrength, RestrictionValue);
}
}
}

View File

@@ -0,0 +1,43 @@
using StructureHelper.Models.Materials;
using StructureHelperCommon.Models;
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 TraceSectionLogic : ITraceSectionLogic
{
public TraceSectionLogic(IShiftTraceLogger? traceLogger)
{
TraceLogger = traceLogger;
}
public IShiftTraceLogger? TraceLogger { get; set; }
public void TraceSection(IBeamShearSection section)
{
List<IHeadMaterial> headMaterials = new()
{
new HeadMaterial(Guid.Empty)
{
Name = $"{section.Name}.Concrete",
HelperMaterial = section.ConcreteMaterial
},
new HeadMaterial(Guid.Empty)
{
Name = $"{section.Name}.Reinforcement",
HelperMaterial = section.ReinforcementMaterial
},
};
var traceLogic = new TraceMaterialsFactory()
{
Collection = headMaterials
};
traceLogic.AddEntriesToTraceLogger(TraceLogger);
}
}
}

View File

@@ -28,7 +28,7 @@ namespace StructureHelperLogics.Models.BeamShears
CheckObject.IsNull(targetObject.DesignRangeProperty);
designRangeUpdateStrategy.Update(targetObject.DesignRangeProperty, sourceObject.DesignRangeProperty);
}
targetObject.CodeType = sourceObject.CodeType;
}
private void InitializeStrategies()

View File

@@ -0,0 +1,12 @@
namespace StructureHelperLogics.Models.BeamShears
{
public enum ShearCodeTypes
{
//SNIP_2_03_01_84_1 = 0,
//SP_63_13330_2018_0 = 11,
//SP_63_13330_2018_1 = 12,
//SP_63_13330_2018_2 = 13,
SP_63_13330_2018_3 = 14,
StructureHelper_0 = 101,
}
}