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

@@ -14,6 +14,9 @@ namespace DataAccess.DTOs
public List<IBeamShearSection> Sections { get; } = new();
[JsonProperty("Stirrups")]
public List<IStirrup> Stirrups { get; } = new();
[JsonProperty("ShearCodeType")]
public ShearCodeTypes CodeType { get; set; } = ShearCodeTypes.SP_63_13330_2018_3;
[JsonProperty("DesignRangeProperty")]
public IBeamShearDesignRangeProperty DesignRangeProperty { get; set; } = new BeamShearDesignRangePropertyDTO(Guid.NewGuid());
public BeamShearCalculatorInputDataDTO(Guid id)

View File

@@ -1,7 +1,8 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:core="clr-namespace:System;assembly=mscorlib"
xmlns:enums="clr-namespace:StructureHelperCommon.Infrastructures.Enums;assembly=StructureHelperCommon">
xmlns:enums="clr-namespace:StructureHelperCommon.Infrastructures.Enums;assembly=StructureHelperCommon"
xmlns:beamShear="clr-namespace:StructureHelperLogics.Models.BeamShears;assembly=StructureHelperLogics">
<ObjectDataProvider x:Key="StressStateEnum" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
@@ -18,4 +19,9 @@
<x:Type Type="enums:CalcTerms"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="ShearCodeTypesEnum" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type Type="beamShear:ShearCodeTypes"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>

View File

@@ -49,6 +49,7 @@ namespace StructureHelper.Windows.BeamShears
.Where(x => x is IDistributedLoad)
.Select(x => Math.Abs((x as IDistributedLoad).LoadValue.Qy))
.ToList();
if (! forceList.Any()) { return; }
maxDistributedLoadValue = forceList.Max();
}
@@ -82,6 +83,7 @@ namespace StructureHelper.Windows.BeamShears
.ToList();
forceList.Add(Math.Abs(source.ExternalForce.ForceTuple.Nz));
forceList.Add(Math.Abs(source.SupportAction.SupportForce.ForceTuple.Qy));
if (!forceList.Any()) { return; }
maxConcentratedForceValue = forceList.Max();
}
}

View File

@@ -3,6 +3,7 @@ using StructureHelper.Windows.ViewModels;
using StructureHelperCommon.Models.Forces;
using StructureHelperLogics.Models.BeamShears;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
@@ -12,11 +13,25 @@ namespace StructureHelper.Windows.BeamShears
{
private readonly IBeamShearRepository shearRepository;
private readonly IBeamShearCalculatorInputData inputData;
private readonly List<ShearCodeTypes> shearCodeTypeList = new List<ShearCodeTypes>
{
ShearCodeTypes.SP_63_13330_2018_3,
ShearCodeTypes.StructureHelper_0
};
public SourceTargetVM<IBeamShearAction> ActionSourceTarget { get; } = new();
public SourceTargetVM<IStirrup> StirrupSourceTarget { get; } = new();
public SourceTargetVM<IBeamShearSection> SectionSourceTarget { get; } = new();
public BeamShearDesignRangePropertyViewModel DesignRangePropertyViewModel { get; private set; }
public List<ShearCodeTypes> ShearCodeTypeList => shearCodeTypeList;
public ShearCodeTypes SelectedCodeType
{
get { return inputData.CodeType; }
set
{
inputData.CodeType = value;
}
}
public BeamShearCalculatorInputDataViewModel(IBeamShearRepository shearRepository, IBeamShearCalculatorInputData inputData)
{

View File

@@ -35,6 +35,15 @@
<TabItem Header="Actions">
<ContentControl ContentTemplate="{StaticResource SourceToTarget}" Content="{Binding ActionSourceTarget}"/>
</TabItem>
<TabItem Header="Design code">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ComboBox ItemsSource="{Binding ShearCodeTypeList}" SelectedItem="{Binding SelectedCodeType}"/>
</Grid>
</TabItem>
<TabItem Header="Design range" DataContext="{Binding DesignRangePropertyViewModel}">
<Grid>
<Grid.ColumnDefinitions>

View File

@@ -9,8 +9,6 @@
d:DataContext="{d:DesignInstance vm:ForceCombinationViewModel}"
mc:Ignorable="d"
Title="Force Combination" Height="350" Width="550" MinHeight="300" MinWidth="450" MaxWidth="500" WindowStartupLocation="CenterScreen">
<Window.Resources>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>

View File

@@ -1,5 +1,4 @@
using StructureHelper.Windows.ViewModels.Forces;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
using System.Linq;

View File

@@ -1,4 +1,5 @@
using StructureHelper.Infrastructure;
using StructureHelper.Windows.ViewModels.Forces;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
@@ -6,7 +7,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelper.Windows.ViewModels.Forces
namespace StructureHelper.Windows.Forces
{
public class ForceCombinationViewModel : ForceActionVMBase
{

View File

@@ -5,10 +5,7 @@ using StructureHelperCommon.Models.Materials;
using StructureHelperCommon.Models.Materials.Libraries;
using StructureHelperCommon.Models.Projects;
using System.Collections.Generic;
using System.ComponentModel.Design.Serialization;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Navigation;
namespace StructureHelperCommon.Infrastructures.Settings
{
@@ -16,6 +13,7 @@ namespace StructureHelperCommon.Infrastructures.Settings
{
private static List<IMaterialLogic> materialLogics;
private static List<ICodeEntity> codesList;
private static List<ICodeRevision> codesRevisions;
private static IMaterialRepository materialRepository;
private static NatSystems natSystem;
private static GeometryNames geometryNames;
@@ -28,10 +26,7 @@ namespace StructureHelperCommon.Infrastructures.Settings
set
{
natSystem = value;
codesList ??= CodeFactory
.GetCodeEntities()
.Where(x => x.NatSystem == natSystem)
.ToList();
SetCodeList();
materialRepository ??= new MaterialRepository(codesList);
}
}
@@ -41,22 +36,30 @@ namespace StructureHelperCommon.Infrastructures.Settings
public static List<ICodeEntity> CodesList
{ get
{
codesList ??= CodeFactory
.GetCodeEntities()
.Where(x => x.NatSystem == NatSystem)
.ToList();
SetCodeList();
return codesList;
}
}
private static void SetCodeList()
{
if (codesList is null)
{
var codes = CodeFactory.GetCodeEntities();
codesList = codes.codes
.Where(x => x.NatSystem == NatSystem)
.ToList();
codesRevisions = codes.codeRevisions
.Where(x => codesList.Contains(x.CodeEntity))
.ToList();
}
}
public static IMaterialRepository MaterialRepository
{
get
{
codesList ??= CodeFactory
.GetCodeEntities()
.Where(x => x.NatSystem == NatSystem)
.ToList();
SetCodeList();
materialRepository ??= new MaterialRepository(codesList);
return materialRepository;
}
@@ -78,6 +81,9 @@ namespace StructureHelperCommon.Infrastructures.Settings
return materialLogics;
}
}
public static List<ICodeRevision> CodesRevisions { get => codesRevisions; set => codesRevisions = value; }
public static void SetCurrentProjectToNotActual()
{
if (CurrentProject is null)

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Codes
{
public class CodeRevision : ICodeRevision
{
public Guid Id { get; }
public ICodeEntity CodeEntity { get; set; }
public string RevisionNumber { get; set; }
public DateOnly PublicationDate { get; set; }
public RevisionStatus RevisionStatus { get; set; }
public string FullName => $"{CodeEntity.FullName} Rev. {RevisionNumber} ({PublicationDate})";
public CodeRevision(Guid id)
{
Id = id;
}
}
}

View File

@@ -9,42 +9,93 @@ namespace StructureHelperCommon.Models.Codes.Factories
{
public static class CodeFactory
{
public static List<ICodeEntity> GetCodeEntities()
public static (List<ICodeEntity> codes, List<ICodeRevision> codeRevisions) GetCodeEntities()
{
List<ICodeEntity> items = new List<ICodeEntity>();
items.AddRange(GetRussianCodes());
items.AddRange(GetEuropeanCodes());
return items;
List<ICodeEntity> codes = new List<ICodeEntity>();
List<ICodeRevision> codeRevisions = new();
(List<ICodeEntity> codes, List<ICodeRevision> codeRevisions) russianCodes = GetRussianCodes();
codes.AddRange(russianCodes.codes);
codeRevisions.AddRange(russianCodes.codeRevisions);
codes.AddRange(GetEuropeanCodes());
return (codes, codeRevisions);
}
private static List<ICodeEntity> GetRussianCodes()
private static (List<ICodeEntity> codes, List<ICodeRevision> codeRevisions) GetRussianCodes()
{
const NatSystems natSystem = NatSystems.RU;
return new List<ICodeEntity>
List<ICodeEntity> codeEntities = new();
List<ICodeRevision> codeRevisions = new();
ICodeEntity codeEntity;
ICodeRevision codeRevision;
var code = GetSP63_13330_2018(natSystem);
codeEntities.Add(code.code);
codeRevisions.AddRange(code.codeRevisions);
codeEntity = new CodeEntity(new Guid("1a717049-cee7-40e0-923c-7a32a573a303"), natSystem)
{
new CodeEntity(new Guid("d4ab402a-ce2f-46db-8b3b-a5a66fb384e1"), natSystem)
{
Name = "SP 63.13330.2018",
FullName = "Plain concrete and reinforced concrete structures"
},
new CodeEntity(new Guid("1a717049-cee7-40e0-923c-7a32a573a303"), natSystem)
{
Name = "GOST 26633-2015",
FullName = "Heavy-weight and sand concretes. Specifications"
},
new CodeEntity(new Guid("c7c0f60f-2c82-45d1-8786-4c340fb5fb98"), natSystem)
{
Name = "GOST 34028-2016",
FullName = "Reinforcing rolled products for reinforced concrete constructions. Specifications"
}
,
new CodeEntity(new Guid("d934763d-4cb4-4923-ad15-2e78b0fe3b37"), natSystem)
{
Name = "GOST 53772-2010",
FullName = "Reinforced steel low-relaxation 7-wire strands. Specifications"
}
Name = "GOST 26633-2015",
FullName = "Heavy-weight and sand concretes. Specifications"
};
codeEntities.Add(codeEntity);
codeEntity = new CodeEntity(new Guid("c7c0f60f-2c82-45d1-8786-4c340fb5fb98"), natSystem)
{
Name = "GOST 34028-2016",
FullName = "Reinforcing rolled products for reinforced concrete constructions. Specifications"
};
codeEntities.Add(codeEntity);
codeEntity = new CodeEntity(new Guid("d934763d-4cb4-4923-ad15-2e78b0fe3b37"), natSystem)
{
Name = "GOST 53772-2010",
FullName = "Reinforced steel low-relaxation 7-wire strands. Specifications"
};
codeEntities.Add(codeEntity);
return (codeEntities, codeRevisions);
}
private static (ICodeEntity code, List<ICodeRevision> codeRevisions) GetSP63_13330_2018(NatSystems natSystem)
{
ICodeEntity codeEntity;
ICodeRevision codeRevision;
List<ICodeRevision> codeRevisions = new();
codeEntity = new CodeEntity(new Guid("d4ab402a-ce2f-46db-8b3b-a5a66fb384e1"), natSystem)
{
Name = "SP 63.13330.2018",
FullName = "Plain concrete and reinforced concrete structures"
};
codeRevision = new CodeRevision(new Guid("1c6047df-cc40-413e-8ed1-c0043182fe0a"))
{
CodeEntity = codeEntity,
RevisionNumber = "0",
PublicationDate = new DateOnly(2018, 1, 1),
RevisionStatus = RevisionStatus.Withdrawn
};
codeRevisions.Add(codeRevision);
codeRevision = new CodeRevision(new Guid("f9f66a43-e50d-40bf-8a82-0359b54a3ab0"))
{
CodeEntity = codeEntity,
RevisionNumber = "1",
PublicationDate = new DateOnly(2019, 1, 1),
RevisionStatus = RevisionStatus.Withdrawn
};
codeRevisions.Add(codeRevision);
codeRevision = new CodeRevision(new Guid("010325ae-5182-4d8e-9b30-7a3ec4860745"))
{
CodeEntity = codeEntity,
RevisionNumber = "2",
PublicationDate = new DateOnly(2020, 1, 1),
RevisionStatus = RevisionStatus.Withdrawn
};
codeRevisions.Add(codeRevision);
codeRevision = new CodeRevision(new Guid("17b6fb62-97b3-4c13-bf38-b91ea16af819"))
{
CodeEntity = codeEntity,
RevisionNumber = "3",
PublicationDate = new DateOnly(2021, 1, 1),
RevisionStatus = RevisionStatus.Official
};
codeRevisions.Add(codeRevision);
return (codeEntity, codeRevisions);
}
private static List<ICodeEntity> GetEuropeanCodes()
{
const NatSystems natSystem = NatSystems.EU;

View File

@@ -0,0 +1,21 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System;
namespace StructureHelperCommon.Models.Codes
{
public enum RevisionStatus
{
Draft,
Official,
Withdrawn
}
public interface ICodeRevision : ISaveable
{
ICodeEntity CodeEntity { get; set; }
string RevisionNumber { get; set; }
string FullName { get; }
DateOnly PublicationDate { get; set; }
RevisionStatus RevisionStatus { get; set; }
}
}

View File

@@ -35,7 +35,7 @@ namespace StructureHelperCommon.Models.Projects
}
if (currentVersion.SubVersionNumber < FileVersion.SubVersionNumber)
{
string message = $"File version {FileVersion.VersionNumber}.{FileVersion.SubVersionNumber} is bigger than suitable version {currentVersion.VersionNumber}.{currentVersion.VersionNumber}";
string message = $"File version {FileVersion.VersionNumber}.{FileVersion.SubVersionNumber} is bigger than suitable version {currentVersion.VersionNumber}.{currentVersion.SubVersionNumber}";
TraceLogger?.AddMessage(message, TraceLogStatuses.Error);
CheckResult += message;
return false;

View File

@@ -6,5 +6,7 @@
public const string Meters = "(m)";
public const string SquareMeters = "(m2)";
public const string Newtons = "(N)";
public const string Pa = "(Pa)";
public const string NewtonMeters = $"{Newtons}*{Meters}";
}
}

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,
}
}

View File

@@ -0,0 +1,53 @@
using NUnit.Framework;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperLogics.Models.BeamShears;
namespace StructureHelperTests.UnitTests.BeamShearTests
{
[TestFixture]
public class SectionEffectivenessFactorySHTests
{
private SectionEffectivenessFactorySH factory;
[SetUp]
public void SetUp()
{
factory = new SectionEffectivenessFactorySH();
}
[Test]
public void GetShearEffectiveness_WhenRectangle_ReturnsExpectedValues()
{
// Act
var result = factory.GetShearEffectiveness(BeamShearSectionType.Rectangle);
// Assert
Assert.That(result.BaseShapeFactor, Is.EqualTo(1.5));
Assert.That(result.ShapeFactor, Is.EqualTo(1.0));
Assert.That(result.MaxCrackLengthRatio, Is.EqualTo(3.0));
Assert.That(result.MinCrackLengthRatio, Is.EqualTo(0.6));
}
[Test]
public void GetShearEffectiveness_WhenCircle_ReturnsExpectedValues()
{
// Act
var result = factory.GetShearEffectiveness(BeamShearSectionType.Circle);
// Assert
Assert.That(result.BaseShapeFactor, Is.EqualTo(1.5));
Assert.That(result.ShapeFactor, Is.EqualTo(0.6));
Assert.That(result.MaxCrackLengthRatio, Is.EqualTo(3.0));
Assert.That(result.MinCrackLengthRatio, Is.EqualTo(0.6));
}
[Test]
public void GetShearEffectiveness_WhenUnsupportedType_Throws()
{
// Act & Assert
Assert.Throws<StructureHelperException>(() =>
factory.GetShearEffectiveness((BeamShearSectionType)999));
}
}
}

View File

@@ -0,0 +1,40 @@
using NUnit.Framework;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperLogics.Models.BeamShears;
namespace StructureHelperTests.UnitTests.BeamShearTests
{
[TestFixture]
public class SectionEffectivenessFactorySP2018Tests
{
private SectionEffectivenessFactorySP2018 factory;
[SetUp]
public void SetUp()
{
factory = new SectionEffectivenessFactorySP2018();
}
[Test]
public void GetShearEffectiveness_WhenRectangle_ReturnsExpectedValues()
{
// Act
var result = factory.GetShearEffectiveness(BeamShearSectionType.Rectangle);
// Assert
Assert.That(result.BaseShapeFactor, Is.EqualTo(1.5));
Assert.That(result.ShapeFactor, Is.EqualTo(1.0));
Assert.That(result.MaxCrackLengthRatio, Is.EqualTo(3.0));
Assert.That(result.MinCrackLengthRatio, Is.EqualTo(0.6));
}
[Test]
public void GetShearEffectiveness_WhenUnsupportedType_Throws()
{
// Act & Assert
Assert.Throws<StructureHelperException>(() =>
factory.GetShearEffectiveness((BeamShearSectionType)999));
}
}
}