From 1ebe1bbcd16a196a302a88665de1f21f3063e2cd Mon Sep 17 00:00:00 2001 From: Evgeny Redikultsev Date: Sat, 21 Jun 2025 21:34:20 +0500 Subject: [PATCH] Change shear calculator add crack export to excel --- .../BeamShearSectionFromDTOConvertStrategy.cs | 19 +- .../BeamShearSectionToDTOConvertStrategy.cs | 12 +- .../BeamShears/BeamShearSectionDTO.cs | 9 +- .../UI/Resources/ButtonStyles.xaml | 2 + .../BeamShears/BeamShearActionResultView.xaml | 14 +- .../BeamShearActionResultViewModel.cs | 12 ++ .../Windows/BeamShears/SectionView.xaml | 24 ++- .../Windows/BeamShears/SectionViewModel.cs | 23 ++- .../Cracks/CrackResultView.xaml | 36 ++-- .../Cracks/CrackResultViewModel.cs | 31 ++- .../ForcesResultsViewModel.cs | 13 +- .../Calculators/FindParameterCalculator.cs | 6 + .../BeamShears/BeamShearCalculatorLogic.cs | 41 +++- .../Models/BeamShears/BeamShearSection.cs | 10 +- .../BeamShears/BeamShearSectionLogic.cs | 82 -------- .../BeamShears/BeamShearSectionLogicResult.cs | 10 +- .../Models/BeamShears/IBeamShearSection.cs | 10 +- .../IBeamShearSectionLogicResult.cs | 5 +- .../Models/BeamShears/IInclinedSection.cs | 20 +- .../Models/BeamShears/InclinedSection.cs | 9 +- .../Logics/BeamShearSectionLogic.cs | 142 +++++++++++++ .../Logics/BeamShearSectionUpdateStrategy.cs | 9 +- .../CheckBeamShearSectionLogic.cs | 2 +- .../CheckSectionLogicInputDataLogic.cs | 50 +++++ .../Logics/ConcreteStrengthLogic.cs | 33 ++- .../Logics/GetInclinedSectionLogic.cs | 1 + .../Logics/GetLongitudinalForceFactorLogic.cs | 84 +++++--- .../GetReducedAreaLogicSP63_2018_rev3.cs | 119 +++++++++++ .../Logics/IBeamShearStrenghLogic.cs | 2 +- .../IGetInclinedSectionListInputData.cs | 8 +- ...onLogic.cs => IGetInclinedSectionLogic.cs} | 5 - .../BeamShears/Logics/IGetReducedAreaLogic.cs | 9 + .../Logics/InclinedSectionUpdateStrategy.cs | 26 +++ .../Logics/StirrupByDensityStrengthLogic.cs | 4 +- .../Logics/StirrupByRebarStrengthLogic.cs | 8 +- .../StirrupByRebarToDensityConvertStrategy.cs | 18 +- .../BeamShears/Logics/StirrupBySearchLogic.cs | 78 ++++++++ .../BeamShears/Logics/StirrupStrengthLogic.cs | 7 +- .../Models/Materials/TraceMaterialsFactory.cs | 13 +- .../Analyses/ExportForcesResultToCSVLogic.cs | 17 +- .../NdmCalculations/Cracking/CrackResult.cs | 4 +- .../NdmCalculations/Cracking/ICrackResult.cs | 9 + .../Logics/ExportCrackResultToCSVLogic.cs | 72 +++++++ .../StructureHelperLogics.csproj | 4 - .../GetLongitudinalForceFactorLogicTests.cs | 188 ++++++++---------- .../GetReducedAreaLogicSP63_2018_rev3Tests.cs | 56 ++++++ ...iformRebarToDensityConvertStrategyTests.cs | 2 +- 47 files changed, 980 insertions(+), 378 deletions(-) delete mode 100644 StructureHelperLogics/Models/BeamShears/BeamShearSectionLogic.cs create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckSectionLogicInputDataLogic.cs create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/GetReducedAreaLogicSP63_2018_rev3.cs rename StructureHelperLogics/Models/BeamShears/Logics/{IGetInclinedSectionBySectionLogic.cs => IGetInclinedSectionLogic.cs} (79%) create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/IGetReducedAreaLogic.cs create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/InclinedSectionUpdateStrategy.cs create mode 100644 StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Cracking/ICrackResult.cs create mode 100644 StructureHelperLogics/NdmCalculations/Cracking/Logics/ExportCrackResultToCSVLogic.cs create mode 100644 StructureHelperTests/UnitTests/BeamShearTests/GetReducedAreaLogicSP63_2018_rev3Tests.cs diff --git a/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionFromDTOConvertStrategy.cs b/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionFromDTOConvertStrategy.cs index b121b84..f8b4248 100644 --- a/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionFromDTOConvertStrategy.cs +++ b/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionFromDTOConvertStrategy.cs @@ -13,6 +13,7 @@ namespace DataAccess.DTOs private IUpdateStrategy updateStrategy; private IConvertStrategy shapeConvertStrategy; private IConvertStrategy concreteConvertStrategy; + private IConvertStrategy reinforcementConvertStrategy; private IUpdateStrategy safetyFactorUpdateStrategy; @@ -26,12 +27,17 @@ namespace DataAccess.DTOs NewItem = new(source.Id); updateStrategy.Update(NewItem, source); NewItem.Shape = shapeConvertStrategy.Convert(source.Shape); - if (source.Material is not ConcreteLibMaterialDTO concreteDTO) + if (source.ConcreteMaterial is not ConcreteLibMaterialDTO concreteDTO) { - throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(source.Material)); + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(source.ConcreteMaterial)); } - NewItem.Material = concreteConvertStrategy.Convert(concreteDTO); - safetyFactorUpdateStrategy.Update(NewItem.Material, concreteDTO); + NewItem.ConcreteMaterial = concreteConvertStrategy.Convert(concreteDTO); + safetyFactorUpdateStrategy.Update(NewItem.ConcreteMaterial, concreteDTO); + if (source.ReinforcementMaterial is not ReinforcementLibMaterialDTO reinforcement) + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(source.ReinforcementMaterial)); + } + NewItem.ReinforcementMaterial = reinforcementConvertStrategy.Convert(reinforcement); return NewItem; } @@ -45,6 +51,11 @@ namespace DataAccess.DTOs ReferenceDictionary = ReferenceDictionary, TraceLogger = TraceLogger }; + reinforcementConvertStrategy = new ReinforcementLibMaterialFromDTOConvertStrategy() + { + ReferenceDictionary = ReferenceDictionary, + TraceLogger = TraceLogger + }; safetyFactorUpdateStrategy = new HelperMaterialDTOSafetyFactorUpdateStrategy(new MaterialSafetyFactorsFromDTOLogic()); } } diff --git a/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionToDTOConvertStrategy.cs b/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionToDTOConvertStrategy.cs index af80f0b..1f73c35 100644 --- a/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionToDTOConvertStrategy.cs +++ b/DataAccess/DTOs/Converters/BeamShears/BeamShearSectionToDTOConvertStrategy.cs @@ -12,6 +12,7 @@ namespace DataAccess.DTOs private IUpdateStrategy updateStrategy; private IConvertStrategy shapeConvertStrategy; private IConvertStrategy concreteConvertStrategy; + private ReinforcementLibMaterialToDTOConvertStrategy reinforcementConvertStrategy; private IUpdateStrategy safetyFactorUpdateStrategy; public BeamShearSectionToDTOConvertStrategy(Dictionary<(Guid id, Type type), ISaveable> referenceDictionary, IShiftTraceLogger traceLogger) @@ -40,8 +41,10 @@ namespace DataAccess.DTOs NewItem = new(source.Id); updateStrategy.Update(NewItem, source); NewItem.Shape = shapeConvertStrategy.Convert(source.Shape); - NewItem.Material = concreteConvertStrategy.Convert(source.Material); - safetyFactorUpdateStrategy.Update(NewItem.Material, source.Material); + NewItem.ConcreteMaterial = concreteConvertStrategy.Convert(source.ConcreteMaterial); + safetyFactorUpdateStrategy.Update(NewItem.ConcreteMaterial, source.ConcreteMaterial); + NewItem.ReinforcementMaterial = reinforcementConvertStrategy.Convert(source.ReinforcementMaterial); + safetyFactorUpdateStrategy.Update(NewItem.ReinforcementMaterial, source.ReinforcementMaterial); TraceLogger?.AddMessage($"Beam shear section converting Id = {NewItem.Id} has been finished succesfully", TraceLogStatuses.Debug); } @@ -53,6 +56,11 @@ namespace DataAccess.DTOs concreteConvertStrategy = new ConcreteLibMaterialToDTOConvertStrategy() { ReferenceDictionary = ReferenceDictionary, TraceLogger = TraceLogger}; + reinforcementConvertStrategy = new ReinforcementLibMaterialToDTOConvertStrategy() + { + ReferenceDictionary = ReferenceDictionary, + TraceLogger = TraceLogger + }; safetyFactorUpdateStrategy = new HelperMaterialDTOSafetyFactorUpdateStrategy(new MaterialSafetyFactorToDTOLogic()); } } diff --git a/DataAccess/DTOs/DTOEntities/BeamShears/BeamShearSectionDTO.cs b/DataAccess/DTOs/DTOEntities/BeamShears/BeamShearSectionDTO.cs index 4368e4f..489f452 100644 --- a/DataAccess/DTOs/DTOEntities/BeamShears/BeamShearSectionDTO.cs +++ b/DataAccess/DTOs/DTOEntities/BeamShears/BeamShearSectionDTO.cs @@ -16,10 +16,15 @@ namespace DataAccess.DTOs public string? Name { get; set; } [JsonProperty("Shape")] public IShape Shape { get; set; } = new RectangleShapeDTO(Guid.Empty); - [JsonProperty("Material")] - public IConcreteLibMaterial Material { get; set; } + [JsonProperty("ConcreteMaterial")] + public IConcreteLibMaterial ConcreteMaterial { get; set; } [JsonProperty("CenterCover")] public double CenterCover { get; set; } + [JsonProperty("ReinforcementArea")] + public double ReinforcementArea { get; set; } + [JsonProperty("ReinforcementMaterial")] + public IReinforcementLibMaterial ReinforcementMaterial { get; set; } + public BeamShearSectionDTO(Guid id) { Id = id; diff --git a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml index fa99944..730396a 100644 --- a/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml +++ b/StructureHelper/Infrastructure/UI/Resources/ButtonStyles.xaml @@ -158,6 +158,7 @@ + @@ -168,6 +169,7 @@ + diff --git a/StructureHelper/Windows/BeamShears/BeamShearActionResultView.xaml b/StructureHelper/Windows/BeamShears/BeamShearActionResultView.xaml index e72d845..a86d924 100644 --- a/StructureHelper/Windows/BeamShears/BeamShearActionResultView.xaml +++ b/StructureHelper/Windows/BeamShears/BeamShearActionResultView.xaml @@ -10,18 +10,18 @@ Title="Shear sections result" Height="450" Width="800" MinHeight="400" MinWidth="600" MaxHeight="900" MaxWidth="1200" WindowStartupLocation="CenterScreen"> - + diff --git a/StructureHelper/Windows/BeamShears/BeamShearActionResultViewModel.cs b/StructureHelper/Windows/BeamShears/BeamShearActionResultViewModel.cs index 7b92a47..66f58a5 100644 --- a/StructureHelper/Windows/BeamShears/BeamShearActionResultViewModel.cs +++ b/StructureHelper/Windows/BeamShears/BeamShearActionResultViewModel.cs @@ -1,17 +1,21 @@ using StructureHelper.Infrastructure; using StructureHelper.Windows.CalculationWindows.CalculatorsViews; +using StructureHelper.Windows.CalculationWindows.ProgressViews; using StructureHelperLogics.Models.BeamShears; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Input; namespace StructureHelper.Windows.BeamShears { public class BeamShearActionResultViewModel : ViewModelBase { private IBeamShearActionResult result; + private RelayCommand showTraceCommand; + public IBeamShearSectionLogicResult SelectedResult { get; set; } public List SectionResults => result.SectionResults; public ValidResultCounterVM ValidResultCounter { get; } @@ -22,5 +26,13 @@ namespace StructureHelper.Windows.BeamShears ValidResultCounter = new(this.result.SectionResults); } + public ICommand ShowTraceCommand => showTraceCommand ??= new RelayCommand(ShowTrace, o => SelectedResult != null); + + private void ShowTrace(object obj) + { + if (SelectedResult.TraceLogger is null) { return; } + var traceWindows = new TraceDocumentView(SelectedResult.TraceLogger); + traceWindows.ShowDialog(); + } } } diff --git a/StructureHelper/Windows/BeamShears/SectionView.xaml b/StructureHelper/Windows/BeamShears/SectionView.xaml index 778fc27..95a4fe6 100644 --- a/StructureHelper/Windows/BeamShears/SectionView.xaml +++ b/StructureHelper/Windows/BeamShears/SectionView.xaml @@ -24,24 +24,38 @@ - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/StructureHelper/Windows/BeamShears/SectionViewModel.cs b/StructureHelper/Windows/BeamShears/SectionViewModel.cs index 20177f9..cd0ad5a 100644 --- a/StructureHelper/Windows/BeamShears/SectionViewModel.cs +++ b/StructureHelper/Windows/BeamShears/SectionViewModel.cs @@ -2,6 +2,7 @@ using StructureHelper.Windows.ViewModels.Materials; using StructureHelperCommon.Models.Shapes; using StructureHelperLogics.Models.BeamShears; +using System; //Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia //All rights reserved. @@ -18,6 +19,17 @@ namespace StructureHelper.Windows.BeamShears set { beamShearSection.Name = value; + OnPropertyChanged(nameof(Name)); + } + } + public double ReinforcementArea + { + get => beamShearSection.ReinforcementArea; + set + { + value = Math.Max(value, 0); + beamShearSection.ReinforcementArea = value; + OnPropertyChanged(nameof(ReinforcementArea)); } } public double CenterCover @@ -25,20 +37,18 @@ namespace StructureHelper.Windows.BeamShears get => beamShearSection.CenterCover; set { - if (value < 0) - { - value = 0; - } + value = Math.Max(value, 0); beamShearSection.CenterCover = value; } } public IRectangleShape Shape { get; } - public ConcreteViewModel Material { get; } + public ConcreteViewModel ConcreteMaterial { get; } + public ReinforcementViewModel ReinforcementMaterial { get; } public SectionViewModel(IBeamShearSection beamShearSection) { this.beamShearSection = beamShearSection; - Material = new(beamShearSection.Material) + ConcreteMaterial = new(beamShearSection.ConcreteMaterial) { MaterialLogicVisibility = false, TensionForULSVisibility = false, @@ -46,6 +56,7 @@ namespace StructureHelper.Windows.BeamShears HumidityVisibility = false }; Shape = beamShearSection.Shape as IRectangleShape; + ReinforcementMaterial = new(beamShearSection.ReinforcementMaterial) { MaterialLogicVisibility = false }; } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml index af65392..2b157b3 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml @@ -4,6 +4,7 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.CalculatorsViews" + xmlns:uc="clr-namespace:StructureHelper.Windows.UserControls" d:DataContext="{d:DesignInstance local:CrackResultViewModel}" mc:Ignorable="d" Title="Result of calculations of crack" Height="450" Width="800" MinHeight="300" MinWidth="600" MaxHeight="800" MaxWidth="1000" WindowStartupLocation="CenterScreen"> @@ -16,7 +17,7 @@ - + + + + @@ -115,26 +128,7 @@ - - - - - - - - - - - - - - - - - - - - + diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs index 5e839fa..e327943 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultViewModel.cs @@ -1,10 +1,9 @@ using StructureHelper.Infrastructure; +using StructureHelper.Services.Exports; +using StructureHelperLogics.NdmCalculations.Analyses; using StructureHelperLogics.NdmCalculations.Cracking; -using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Input; namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews @@ -12,16 +11,14 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews public class CrackResultViewModel : ViewModelBase { IShowCrackIsoFieldsLogic showCrackIsoFieldsLogic => new ShowCrackIsoFieldsLogic(); - private CrackResult resultModel; + private ICrackResult resultModel; private RelayCommand? showIsoFieldCommand; private RelayCommand? showRebarsCommand; - - public int ValidResultCount => resultModel.TupleResults.Count(x => x.IsValid == true); - public int InvalidResultCount => resultModel.TupleResults.Count(x => x.IsValid == false); - public int TotalResultCount => resultModel.TupleResults.Count; + private RelayCommand exportToCSVCommand; public TupleCrackResult SelectedResult { get; set; } public List TupleResults => CrackResult.TupleResults; + public ValidResultCounterVM ValidResultCounter { get; } public ICommand ShowRebarsCommand { get @@ -45,11 +42,25 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews } } - public CrackResult CrackResult => resultModel; + public ICrackResult CrackResult => resultModel; - public CrackResultViewModel(CrackResult crackResult) + public CrackResultViewModel(ICrackResult crackResult) { this.resultModel = crackResult; + ValidResultCounter = new(resultModel.TupleResults); + } + + public ICommand ExportToCSVCommand => exportToCSVCommand ??= new RelayCommand(o => { ExportToCSV(); }); + private void ExportToCSV() + { + var inputData = new ExportToFileInputData + { + Filter = "csv |*.csv", + Title = "Save in *.csv File" + }; + var logic = new ExportCrackResultToCSVLogic(resultModel); + var exportService = new ExportToFileService(inputData, logic); + exportService.Export(); } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs index df3a9d4..0d43516 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs @@ -131,18 +131,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu }, o => SelectedResult != null && SelectedResult.IsValid)); } } - public ICommand ExportToCSVCommand - { - get - { - return exportToCSVCommand ?? - (exportToCSVCommand = new RelayCommand(o => - { - ExportToCSV(); - } - )); - } - } + public ICommand ExportToCSVCommand => exportToCSVCommand ??= new RelayCommand(o => { ExportToCSV();}); private void ExportToCSV() { var inputData = new ExportToFileInputData diff --git a/StructureHelperCommon/Models/Calculators/FindParameterCalculator.cs b/StructureHelperCommon/Models/Calculators/FindParameterCalculator.cs index 48593c7..4990578 100644 --- a/StructureHelperCommon/Models/Calculators/FindParameterCalculator.cs +++ b/StructureHelperCommon/Models/Calculators/FindParameterCalculator.cs @@ -32,6 +32,12 @@ namespace StructureHelperCommon.Models.Calculators MaxIterationCount = 1000 }; } + + public FindParameterCalculator(IShiftTraceLogger? traceLogger) : this() + { + TraceLogger = traceLogger; + } + public void Run() { result = new(); diff --git a/StructureHelperLogics/Models/BeamShears/BeamShearCalculatorLogic.cs b/StructureHelperLogics/Models/BeamShears/BeamShearCalculatorLogic.cs index 04d95ca..79db3d2 100644 --- a/StructureHelperLogics/Models/BeamShears/BeamShearCalculatorLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/BeamShearCalculatorLogic.cs @@ -1,8 +1,12 @@ -using StructureHelperCommon.Infrastructures.Enums; +using StructureHelper.Models.Materials; +using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.NdmCalculations.Primitives; namespace StructureHelperLogics.Models.BeamShears { @@ -27,6 +31,7 @@ namespace StructureHelperLogics.Models.BeamShears { TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); this.inputData = inputData; + PrepareNewResult(); InitializeStrategies(); try @@ -38,12 +43,35 @@ namespace StructureHelperLogics.Models.BeamShears { TraceLogger?.AddMessage(ex.Message, TraceLogStatuses.Error); result.IsValid = false; + result.Description += "\n" + ex.Message; } return result; } - private IBeamShearSectionLogicResult CalculateResult(IBeamShearSectionLogicInputData sectionInputData) + private void TraceSection(IBeamShearSection section) + { + List 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); + } + + private IBeamShearSectionLogicResult CalculateInclinedSectionResult(IBeamShearSectionLogicInputData sectionInputData) { beamShearSectionLogic.InputData = sectionInputData; beamShearSectionLogic.Run(); @@ -79,6 +107,8 @@ namespace StructureHelperLogics.Models.BeamShears { foreach (var section in inputData.Sections) { + TraceLogger?.AddMessage($"Analysis for action: {beamShearAction.Name}, section: {section.Name}, calc turm {calcTerm} has been started"); + TraceSection(section); foreach (var stirrup in stirrups) { List inclinedSections = GetInclinedSections(section); @@ -87,6 +117,7 @@ namespace StructureHelperLogics.Models.BeamShears 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"); } } } @@ -113,7 +144,7 @@ namespace StructureHelperLogics.Models.BeamShears List sectionResults = new(); foreach (var item in sectionInputDatas) { - IBeamShearSectionLogicResult sectionResult = CalculateResult(item); + IBeamShearSectionLogicResult sectionResult = CalculateInclinedSectionResult(item); sectionResults.Add(sectionResult); } @@ -123,10 +154,12 @@ namespace StructureHelperLogics.Models.BeamShears private List GetSectionInputDatas(IBeamShearAction beamShearAction, CalcTerms calcTerm, IBeamShearSection section, IStirrup stirrup, List inclinedSections) { List sectionInputDatas = new(); - var material = section.Material; + var material = section.ConcreteMaterial; var strength = material.GetStrength(CollapseLimitState, calcTerm); foreach (var inclinedSection in inclinedSections) { + inclinedSection.LimitState = CollapseLimitState; + inclinedSection.CalcTerm = calcTerm; inclinedSection.ConcreteCompressionStrength = strength.Compressive; inclinedSection.ConcreteTensionStrength = strength.Tensile; DirectShearForceLogicInputData inputData = new() diff --git a/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs b/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs index 3f9e95c..e4447d0 100644 --- a/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs +++ b/StructureHelperLogics/Models/BeamShears/BeamShearSection.cs @@ -10,18 +10,20 @@ namespace StructureHelperLogics.Models.BeamShears public Guid Id { get; } public string? Name { get; set; } /// - public IConcreteLibMaterial Material { get; set; } + public IConcreteLibMaterial ConcreteMaterial { get; set; } /// public IShape Shape { get; set; } = new RectangleShape(Guid.NewGuid()) { Height = 0.6, Width = 0.4}; public double CenterCover { get; set; } = 0.05; - + public double ReinforcementArea { get; set; } = 0; + public IReinforcementLibMaterial ReinforcementMaterial { get; set; } public BeamShearSection(Guid id) { Id = id; - Material = ConcreteLibMaterialFactory.GetConcreteLibMaterial(ConcreteLibTypes.Concrete25); - Material.TensionForULS = true; + ConcreteMaterial = ConcreteLibMaterialFactory.GetConcreteLibMaterial(ConcreteLibTypes.Concrete25); + ReinforcementMaterial = HeadMaterialFactory.GetHeadMaterial(HeadmaterialType.Reinforcement500).HelperMaterial as IReinforcementLibMaterial; + ConcreteMaterial.TensionForULS = true; } public object Clone() diff --git a/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogic.cs deleted file mode 100644 index b65bccf..0000000 --- a/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogic.cs +++ /dev/null @@ -1,82 +0,0 @@ -using StructureHelperCommon.Models; -using StructureHelperCommon.Models.Calculators; -using StructureHelperCommon.Models.Loggers; -using StructureHelperLogics.Models.BeamShears.Logics; - -namespace StructureHelperLogics.Models.BeamShears -{ - public class BeamShearSectionLogic : IBeamShearSectionLogic - { - private BeamShearSectionLogicResult result; - private ConcreteStrengthLogic concreteLogic; - private StirrupStrengthLogic stirrupLogic; - - public IBeamShearSectionLogicInputData InputData { get; set; } - public IShiftTraceLogger? TraceLogger { get; set; } - - public BeamShearSectionLogic(IShiftTraceLogger? traceLogger) - { - TraceLogger = traceLogger; - } - - public IResult Result => result; - - - public void Run() - { - TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); - PrepareNewResult(); - InitializeStrategies(); - try - { - CalculateResult(); - } - catch (Exception ex) - { - result.IsValid = false; - result.Description += ex.Message; - } - } - - private void CalculateResult() - { - double concreteStrength = concreteLogic.GetShearStrength(); - result.ConcreteStrength = concreteStrength; - double stirrupStrength = stirrupLogic.GetShearStrength(); - result.StirrupStrength = stirrupStrength; - double totalStrength = concreteStrength + stirrupStrength; - result.TotalStrength = totalStrength; - double actualShearForce = InputData.ForceTuple.Qy; - if (actualShearForce > totalStrength) - { - result.IsValid = false; - string message = $"Actual shear force Qa = {actualShearForce}(N), greater than bearing capacity Olim = {totalStrength}(N)"; - result.Description += message; - TraceLogger?.AddMessage(message, TraceLogStatuses.Error); - } - else - { - string message = $"Actual shear force Qa = {actualShearForce}(N), not greater than bearing capacity Olim = {totalStrength}(N)"; - TraceLogger?.AddMessage(message); - } - } - - private void InitializeStrategies() - { - var sectionEffectiveness = SectionEffectivenessFactory.GetSheaEffectiveness(BeamShearSectionType.Rectangle); - double longitudinalForce = InputData.ForceTuple.Nz; - concreteLogic = new(sectionEffectiveness, InputData.InclinedSection, longitudinalForce, TraceLogger); - stirrupLogic = new(InputData, TraceLogger); - } - - private void PrepareNewResult() - { - result = new() - { - IsValid = true, - Description = string.Empty, - InputData = InputData - }; - } - } -} diff --git a/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogicResult.cs b/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogicResult.cs index d91bf1b..ecce7d1 100644 --- a/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogicResult.cs +++ b/StructureHelperLogics/Models/BeamShears/BeamShearSectionLogicResult.cs @@ -1,4 +1,5 @@ -using System; +using StructureHelperCommon.Models; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -15,5 +16,12 @@ namespace StructureHelperLogics.Models.BeamShears public double StirrupStrength { get; set; } public double TotalStrength { get; set; } public double FactorOfUsing { get => InputData.ForceTuple.Qy / TotalStrength; } + + public IShiftTraceLogger TraceLogger { get; } + + public BeamShearSectionLogicResult(IShiftTraceLogger traceLogger) + { + TraceLogger = traceLogger; + } } } diff --git a/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs b/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs index 69866ad..e6a5e02 100644 --- a/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs +++ b/StructureHelperLogics/Models/BeamShears/IBeamShearSection.cs @@ -13,7 +13,7 @@ namespace StructureHelperLogics.Models.BeamShears /// /// Concrete of cross-section /// - IConcreteLibMaterial Material { get; set; } + IConcreteLibMaterial ConcreteMaterial { get; set; } /// /// Shape of cross-section /// @@ -22,5 +22,13 @@ namespace StructureHelperLogics.Models.BeamShears /// Distance from edge of tension zone to center of the nearest reinforcement bar /// double CenterCover { get; set; } + /// + /// Area of reinforcement in tension zone, m^2 + /// + double ReinforcementArea { get; set; } + /// + /// Material of reinforcement in tension zone + /// + IReinforcementLibMaterial ReinforcementMaterial { get; set; } } } diff --git a/StructureHelperLogics/Models/BeamShears/IBeamShearSectionLogicResult.cs b/StructureHelperLogics/Models/BeamShears/IBeamShearSectionLogicResult.cs index f3d70c8..9672325 100644 --- a/StructureHelperLogics/Models/BeamShears/IBeamShearSectionLogicResult.cs +++ b/StructureHelperLogics/Models/BeamShears/IBeamShearSectionLogicResult.cs @@ -1,7 +1,9 @@ -using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; using System; using System.Collections.Generic; using System.Linq; +using System.Security.Policy; using System.Text; using System.Threading.Tasks; @@ -14,5 +16,6 @@ namespace StructureHelperLogics.Models.BeamShears public double StirrupStrength { get; set; } public double TotalStrength { get; set; } public double FactorOfUsing { get; } + public IShiftTraceLogger TraceLogger { get; } } } diff --git a/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs b/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs index dee041f..470fb39 100644 --- a/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs +++ b/StructureHelperLogics/Models/BeamShears/IInclinedSection.cs @@ -1,9 +1,5 @@ -using StructureHelperCommon.Infrastructures.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; namespace StructureHelperLogics.Models.BeamShears { @@ -12,6 +8,18 @@ namespace StructureHelperLogics.Models.BeamShears /// public interface IInclinedSection : IEffectiveDepth { + /// + /// Reference to source beam shear section + /// + IBeamShearSection BeamShearSection { get; set; } + /// + /// Type of limite state for calculating + /// + LimitStates LimitState { get; set; } + /// + /// Type od calc term for calculating + /// + CalcTerms CalcTerm { get; set; } /// /// Width of cross-section /// diff --git a/StructureHelperLogics/Models/BeamShears/InclinedSection.cs b/StructureHelperLogics/Models/BeamShears/InclinedSection.cs index 47d2358..1599743 100644 --- a/StructureHelperLogics/Models/BeamShears/InclinedSection.cs +++ b/StructureHelperLogics/Models/BeamShears/InclinedSection.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using StructureHelperCommon.Infrastructures.Enums; namespace StructureHelperLogics.Models.BeamShears { @@ -21,5 +17,8 @@ namespace StructureHelperLogics.Models.BeamShears public double EndCoord { get; set; } public double ConcreteCompressionStrength { get; set; } public double ConcreteTensionStrength { get; set; } + public IBeamShearSection BeamShearSection { get; set; } + public LimitStates LimitState { get; set; } + public CalcTerms CalcTerm { get; set; } } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs new file mode 100644 index 0000000..57b25c2 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionLogic.cs @@ -0,0 +1,142 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Loggers; +using StructureHelperLogics.Models.BeamShears.Logics; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class BeamShearSectionLogic : IBeamShearSectionLogic + { + private BeamShearSectionLogicResult result; + private ISectionEffectiveness sectionEffectiveness; + private ConcreteStrengthLogic concreteLogic; + private StirrupStrengthLogic stirrupLogic; + private IGetLongitudinalForceFactorLogic getLongitudinalForceFactorLogic; + private string sectionMessage; + private ICheckInputDataLogic checkInputDataLogic; + + private ShiftTraceLogger? localTraceLogger { get; set; } + + public IBeamShearSectionLogicInputData InputData { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + + public BeamShearSectionLogic(IShiftTraceLogger? traceLogger) + { + TraceLogger = traceLogger; + } + + public IResult Result => result; + + + public void Run() + { + TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); + sectionMessage = $"Inclined section: start xstart = {InputData.InclinedSection.StartCoord}(m), end xend = {InputData.InclinedSection.EndCoord}(m). "; + PrepareNewResult(); + if (Check() == false) { return; } + localTraceLogger?.AddMessage(sectionMessage); + InitializeStrategies(); + try + { + CalculateResult(); + } + catch (Exception ex) + { + result.IsValid = false; + result.Description += ex.Message; + } + } + + private bool Check() + { + bool checkResult = true; + checkInputDataLogic ??= new CheckSectionLogicInputDataLogic(TraceLogger); + checkInputDataLogic.InputData = InputData; + if (checkInputDataLogic.Check() == false) + { + checkResult = false; + result.IsValid = false; + string errorMessage = checkInputDataLogic.CheckResult; + result.Description += errorMessage; + localTraceLogger?.AddMessage(errorMessage, TraceLogStatuses.Error); + } + return checkResult; + } + + private void CalculateResult() + { + SetLongitudinalForce(); + double factorOfLongitudinalForce = getLongitudinalForceFactorLogic.GetFactor(); + localTraceLogger?.AddMessage($"Factor of longitudinal force = {factorOfLongitudinalForce}, (dimensionless)"); + double concreteStrength = concreteLogic.GetShearStrength(); + double stirrupStrength = stirrupLogic.GetShearStrength(); + if (stirrupStrength > concreteStrength) + { + stirrupStrength = GetStirrupStrengthBySearch(); + } + concreteStrength *= factorOfLongitudinalForce; + localTraceLogger?.AddMessage($"Concrete strength Qb = {concreteStrength}(N)"); + result.ConcreteStrength = concreteStrength; + stirrupStrength *= factorOfLongitudinalForce; + localTraceLogger?.AddMessage($"Stirrup strength Qsw = {stirrupStrength}(N)"); + result.StirrupStrength = stirrupStrength; + double totalStrength = concreteStrength + stirrupStrength; + localTraceLogger?.AddMessage($"Total strength = {concreteStrength} + {stirrupStrength} = {totalStrength}(N)"); + result.TotalStrength = totalStrength; + double actualShearForce = InputData.ForceTuple.Qy; + if (actualShearForce > totalStrength) + { + result.IsValid = false; + string message = $"Actual shear force Qa = {actualShearForce}(N), greater than bearing capacity Olim = {totalStrength}(N)"; + result.Description += message; + localTraceLogger?.AddMessage(message, TraceLogStatuses.Error); + TraceLogger?.AddMessage(sectionMessage + message, TraceLogStatuses.Error); + } + else + { + string message = $"Actual shear force Qa = {actualShearForce}(N), not greater than bearing capacity Olim = {totalStrength}(N)"; + localTraceLogger?.AddMessage(message); + TraceLogger?.AddMessage(sectionMessage + message); + } + } + + private double GetStirrupStrengthBySearch() + { + var logic = new StirrupBySearchLogic(TraceLogger) + { + InputData = InputData, + SectionEffectiveness = sectionEffectiveness + }; + double stirrupStrength = logic.GetShearStrength(); + localTraceLogger?.AddMessage($"Stirrup strength was restricted as Qsw,restricted = {stirrupStrength}(N)"); + return stirrupStrength; + } + + private void InitializeStrategies() + { + sectionEffectiveness = SectionEffectivenessFactory.GetSheaEffectiveness(BeamShearSectionType.Rectangle); + concreteLogic = new(sectionEffectiveness, InputData.InclinedSection, localTraceLogger); + stirrupLogic = new(InputData, localTraceLogger); + getLongitudinalForceFactorLogic = new GetLongitudinalForceFactorLogic(localTraceLogger?.GetSimilarTraceLogger(100)); + } + + private void SetLongitudinalForce() + { + getLongitudinalForceFactorLogic.LongitudinalForce = InputData.ForceTuple.Nz; + getLongitudinalForceFactorLogic.InclinedSection = InputData.InclinedSection; + } + + private void PrepareNewResult() + { + localTraceLogger = new(); + result = new(localTraceLogger) + { + IsValid = true, + Description = string.Empty, + InputData = InputData, + }; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionUpdateStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionUpdateStrategy.cs index 41c591d..bf1da08 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionUpdateStrategy.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/BeamShearSectionUpdateStrategy.cs @@ -15,6 +15,7 @@ namespace StructureHelperLogics.Models.BeamShears { private IUpdateStrategy shapeUpdateStrategy; private IUpdateStrategy concreteUpdateStrategy; + private IUpdateStrategy reinforcementUpdateStrategy; public void Update(IBeamShearSection targetObject, IBeamShearSection sourceObject) { CheckObject.IsNull(targetObject); @@ -22,9 +23,12 @@ namespace StructureHelperLogics.Models.BeamShears if (ReferenceEquals(targetObject, sourceObject)) { return; } InitializeStrategies(); targetObject.Name = sourceObject.Name; + targetObject.ReinforcementArea = sourceObject.ReinforcementArea; shapeUpdateStrategy.Update(targetObject.Shape, sourceObject.Shape); - targetObject.Material ??= new ConcreteLibMaterial(); - concreteUpdateStrategy.Update(targetObject.Material, sourceObject.Material); + targetObject.ConcreteMaterial ??= new ConcreteLibMaterial(); + concreteUpdateStrategy.Update(targetObject.ConcreteMaterial, sourceObject.ConcreteMaterial); + targetObject.ReinforcementMaterial ??= new ReinforcementLibMaterial(Guid.NewGuid()); + reinforcementUpdateStrategy.Update(targetObject.ReinforcementMaterial, sourceObject.ReinforcementMaterial); targetObject.CenterCover = sourceObject.CenterCover; } @@ -32,6 +36,7 @@ namespace StructureHelperLogics.Models.BeamShears { shapeUpdateStrategy ??= new ShapeUpdateStrategy(); concreteUpdateStrategy ??= new ConcreteLibUpdateStrategy(); + reinforcementUpdateStrategy ??= new ReinforcementLibUpdateStrategy(); } } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckBeamShearSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckBeamShearSectionLogic.cs index 2eb1ad5..d5c1645 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckBeamShearSectionLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckBeamShearSectionLogic.cs @@ -35,7 +35,7 @@ namespace StructureHelperLogics.Models.BeamShears.Logics } else { - if (Entity.Material is null) + if (Entity.ConcreteMaterial is null) { result = false; TraceMessage($"\nMaterial of cross-section is not assigned"); diff --git a/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckSectionLogicInputDataLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckSectionLogicInputDataLogic.cs new file mode 100644 index 0000000..00e1332 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/CheckStrategies/CheckSectionLogicInputDataLogic.cs @@ -0,0 +1,50 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; + +namespace StructureHelperLogics.Models.BeamShears +{ + internal class CheckSectionLogicInputDataLogic : ICheckInputDataLogic + { + private bool result; + private string checkResult; + public CheckSectionLogicInputDataLogic(IShiftTraceLogger? traceLogger) + { + TraceLogger = traceLogger; + } + + public IBeamShearSectionLogicInputData InputData { get; set; } + + public string CheckResult => checkResult; + + public IShiftTraceLogger? TraceLogger { get; set; } + + public bool Check() + { + result = true; + checkResult = string.Empty; + if (InputData is null) + { + result = false; + string errorString = ErrorStrings.ParameterIsNull + ": Input data"; + throw new StructureHelperException(errorString); + } + if (InputData.ForceTuple is null) + { + result = false; + TraceMessage("Force tuple is null"); + } + if (InputData.ForceTuple.Qy < 0) + { + result = false; + TraceMessage($"Shear force Qy = {InputData.ForceTuple.Qy} must be positive"); + } + return result; + } + private void TraceMessage(string errorString) + { + checkResult += errorString; + TraceLogger?.AddMessage(errorString); + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs index d59054a..f34dd49 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/ConcreteStrengthLogic.cs @@ -6,22 +6,19 @@ 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; } @@ -35,27 +32,29 @@ namespace StructureHelperLogics.Models.BeamShears 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)"); + TraceLogger?.AddMessage($"Absolute crack length c = {inclinedSection.EndCoord} - {inclinedSection.StartCoord} = {crackLength}, (m)"); + TraceLogger?.AddMessage($"Relative crack length c/d = {crackLength} / {inclinedSection.EffectiveDepth} = {crackLength/ inclinedSection.EffectiveDepth},(dimensionless)"); RestrictCrackLength(); - 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)"); + + + double concreteMoment = + sectionEffectiveness.BaseShapeFactor + * sectionEffectiveness.ShapeFactor + * inclinedSection.ConcreteTensionStrength + * inclinedSection.WebWidth + * inclinedSection.EffectiveDepth + * inclinedSection.EffectiveDepth; + double shearStrength = concreteMoment / crackLength; + TraceLogger?.AddMessage($"Shear strength of concrete = {sectionEffectiveness.BaseShapeFactor} * {sectionEffectiveness.ShapeFactor} * {inclinedSection.ConcreteTensionStrength} * {inclinedSection.WebWidth} * {inclinedSection.EffectiveDepth} ^ 2 / {crackLength} = {shearStrength}, (N)"); return shearStrength; } private void InitializeStrategies() { - getLongitudinalForceFactorLogic ??= new GetLongitudinalForceFactorLogic(TraceLogger?.GetSimilarTraceLogger(100)); + } - private void SetLongitudinalForce() - { - getLongitudinalForceFactorLogic.LongitudinalForce = longitudinalForce; - getLongitudinalForceFactorLogic.InclinedSection = inclinedSection; - } + private void RestrictCrackLength() { diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs index cf1ad34..a41755d 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/GetInclinedSectionLogic.cs @@ -41,6 +41,7 @@ namespace StructureHelperLogics.Models.BeamShears effectiveDepth = depth - beamShearSection.CenterCover; inclinedSection = new() { + BeamShearSection = beamShearSection, FullDepth = depth, EffectiveDepth = effectiveDepth, StartCoord = startCoord, diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetLongitudinalForceFactorLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetLongitudinalForceFactorLogic.cs index f09f86c..96a86a2 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/GetLongitudinalForceFactorLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/GetLongitudinalForceFactorLogic.cs @@ -7,10 +7,13 @@ namespace StructureHelperLogics.Models.BeamShears.Logics { public class GetLongitudinalForceFactorLogic : IGetLongitudinalForceFactorLogic { - private const double fstRatioInCompression = 0.25; - private const double sndRatioInCompression = 0.75; + private const double sndRatioInCompression = 0.5; + private const double maxFactor = 1.25; + private double sectionArea; + private ShiftTraceLogger localTraceLogger; private ICheckEntityLogic checkInclinedSectionLogic; + private IGetReducedAreaLogic getReducedAreaLogic; public IShiftTraceLogger? TraceLogger { get; set; } public IInclinedSection InclinedSection { get; set; } @@ -21,39 +24,62 @@ namespace StructureHelperLogics.Models.BeamShears.Logics TraceLogger = traceLogger; } + public GetLongitudinalForceFactorLogic( + ICheckEntityLogic checkInclinedSectionLogic, + IGetReducedAreaLogic getReducedAreaLogic, + IShiftTraceLogger? traceLogger) + { + this.checkInclinedSectionLogic = checkInclinedSectionLogic; + this.getReducedAreaLogic = getReducedAreaLogic; + 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"); + localTraceLogger = new(); + localTraceLogger.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); + localTraceLogger.AddMessage("Logic of calculating of factor of influence of longitudinal force according to SP 63.13330.2018"); Check(); + double result; 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(); + localTraceLogger.AddMessage("Longitudinal force is zero", TraceLogStatuses.Service); + result = 1; } else { - TraceLogger?.AddMessage($"Longitudinal force N={LongitudinalForce}(N) is positive (tension)", TraceLogStatuses.Service); - return GetPosForceResult(); + result = GetFactorByForce(); } + localTraceLogger.TraceLoggerEntries.ForEach(x => TraceLogger?.TraceLoggerEntries.Add(x)); + return result; + } + + private double GetFactorByForce() + { + double result; + getReducedAreaLogic ??= new GetReducedAreaLogicSP63_2018_rev3(LongitudinalForce, InclinedSection, localTraceLogger); + sectionArea = getReducedAreaLogic.GetArea(); + if (LongitudinalForce < 0) + { + localTraceLogger.AddMessage($"Longitudinal force N={LongitudinalForce}(N) is negative (compression)", TraceLogStatuses.Service); + result = GetNegForceResult(); + } + else + { + localTraceLogger.AddMessage($"Longitudinal force N={LongitudinalForce}(N) is positive (tension)", TraceLogStatuses.Service); + result = GetPosForceResult(); + } + return result; } private void Check() { - checkInclinedSectionLogic ??= new CheckInclinedSectionLogic(TraceLogger); + checkInclinedSectionLogic ??= new CheckInclinedSectionLogic(localTraceLogger); checkInclinedSectionLogic.Entity = InclinedSection; if (checkInclinedSectionLogic.Check() == false) { string errorString = checkInclinedSectionLogic.CheckResult; - TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + localTraceLogger.AddMessage(errorString, TraceLogStatuses.Error); throw new StructureHelperException(errorString); } } @@ -61,41 +87,43 @@ namespace StructureHelperLogics.Models.BeamShears.Logics private double GetPosForceResult() { double stressInConcrete = LongitudinalForce / sectionArea; - TraceLogger?.AddMessage($"Average stress in concrete (positive in tension) Sigma = {LongitudinalForce}(N) / {sectionArea}(m^2) = {stressInConcrete}(Pa)"); + localTraceLogger.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)"); + localTraceLogger.AddMessage($"Concrete strength Rbt = {concreteStrength}(Pa)"); double stressRatio = stressInConcrete / concreteStrength; - TraceLogger?.AddMessage($"Stress ratio rt = {stressInConcrete} / {concreteStrength} = {stressRatio}(dimensionless)"); + localTraceLogger.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)"); + localTraceLogger.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)"); + localTraceLogger.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)"); + localTraceLogger.AddMessage($"Concrete strength Rb = {concreteStrength}(Pa)"); double stressRatio = stressInConcrete / concreteStrength; - TraceLogger?.AddMessage($"Stress ratio rc = {stressInConcrete} / {concreteStrength} = {stressRatio}(dimensionless)"); + localTraceLogger.AddMessage($"Stress ratio rc = {stressInConcrete} / {concreteStrength} = {stressRatio}(dimensionless)"); double factor; + double fstRatioInCompression = maxFactor-1; if (stressRatio < fstRatioInCompression) { - TraceLogger?.AddMessage($"Stress ratio rc = {stressRatio} < {fstRatioInCompression}"); + localTraceLogger.AddMessage($"Stress ratio rc = {stressRatio} < {fstRatioInCompression}"); factor = 1 + stressRatio; } else if (stressRatio > sndRatioInCompression) { - factor = 5 * (1 - stressRatio); + double stressFactor = maxFactor / (1 - sndRatioInCompression); + factor = stressFactor * (1 - stressRatio); factor = Math.Max(factor, 0); } else { - factor = 1 + fstRatioInCompression; + factor = maxFactor; } - TraceLogger?.AddMessage($"Factor value fi_n = {factor}(dimensionless)"); + localTraceLogger.AddMessage($"Factor value fi_n = {factor}(dimensionless)"); return factor; } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetReducedAreaLogicSP63_2018_rev3.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetReducedAreaLogicSP63_2018_rev3.cs new file mode 100644 index 0000000..c9dc991 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/GetReducedAreaLogicSP63_2018_rev3.cs @@ -0,0 +1,119 @@ +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Loggers; + +namespace StructureHelperLogics.Models.BeamShears +{ + public class GetReducedAreaLogicSP63_2018_rev3 : IGetReducedAreaLogic + { + private const double epsilon_b0 = 0.002; + private const double epsilon_bt0 = 0.0001; + + private double longitudinalForce; + private IInclinedSection inclinedSection; + private (double Compressive, double Tensile) concreteStrength; + private double reinforcementModulus; + private double concreteModulus; + private double reducingFactor; + private double concreteArea; + private double reinforcementArea; + + public IShiftTraceLogger? TraceLogger { get; set; } + public GetReducedAreaLogicSP63_2018_rev3(double longitudinalForce, IInclinedSection inclinedSection, IShiftTraceLogger? traceLogger) + { + this.longitudinalForce = longitudinalForce; + this.inclinedSection = inclinedSection; + TraceLogger = traceLogger; + } + + public double GetArea() + { + TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage($"Calculting of reduced area of cross-section according to SP 63.13330.2018 rev.3"); + GetSuplimentaryParemeters(); + double area = GetReducedArea(); + return area; + } + + private double GetReducedArea() + { + if (longitudinalForce <= 0) + { + TraceLogger?.AddMessage($"Longitudinal force Nz = {longitudinalForce} is negative, section under compression"); + return GetNegForceArea(); + } + else + { + TraceLogger?.AddMessage($"Longitudinal force Nz = {longitudinalForce} is positive, section under tension"); + return GetPosForceArea(); + } + } + + private void GetSuplimentaryParemeters() + { + GetConcreteModulus(); + GetReinforcementModulus(); + GetConcreteStrength(); + GetAreas(); + } + + private double GetPosForceArea() + { + double tensileStrength = concreteStrength.Tensile; + TraceLogger?.AddMessage($"Modulus of elasticity of reinforcement Es = {reinforcementModulus }(Pa)"); + TraceLogger?.AddMessage($"Modulus of elasticity of concrete Eb = {concreteModulus }(Pa)"); + TraceLogger?.AddMessage($"Ratio of modulus of elasticity alpha = {reducingFactor }(dimensionless)"); + TraceLogger?.AddMessage($"Tensile strength of concrete Rbt = {tensileStrength }(Pa)"); + TraceLogger?.AddMessage($"Reference strain of concrete Epsilonbt0 = {epsilon_bt0 }(dimensionless)"); + double factorOfInelasticity = tensileStrength / (epsilon_bt0 * concreteModulus); + TraceLogger?.AddMessage($"Factor of inelastisity nu = Rbt / (Epsilon_bt0 * Eb) = {tensileStrength } / ({epsilon_bt0} * {concreteModulus}) = {factorOfInelasticity}(dimensionless)"); + double factor = reducingFactor / factorOfInelasticity; + double area = concreteArea + reinforcementArea * factor; + TraceLogger?.AddMessage($"Reduced area Ared = {concreteArea} + {reducingFactor} / {factorOfInelasticity} * {reinforcementArea} = {area}(m^2)"); + return area; + } + + private double GetNegForceArea() + { + double compressiveStrength = concreteStrength.Compressive; + TraceLogger?.AddMessage($"Modulus of elasticity of reinforcement Es = {reinforcementModulus }(Pa)"); + TraceLogger?.AddMessage($"Modulus of elasticity of concrete Eb = {concreteModulus }(Pa)"); + TraceLogger?.AddMessage($"Ratio of modulus of elasticity alpha = {reducingFactor }(dimensionless)"); + TraceLogger?.AddMessage($"Compressive strength of concrete Rb = {compressiveStrength }(Pa)"); + TraceLogger?.AddMessage($"Reference strain of concrete Epsilonb0 = {epsilon_b0 }(dimensionless)"); + double factorOfInelasticity = compressiveStrength / (epsilon_b0 * concreteModulus); + TraceLogger?.AddMessage($"Factor of inelastisity nu = Rb / (Epsilon_b0 * Eb) = {compressiveStrength } / ({epsilon_b0} * {concreteModulus}) = {factorOfInelasticity}(dimensionless)"); + double factor = reducingFactor / factorOfInelasticity; + double area = concreteArea + reinforcementArea * factor; + TraceLogger?.AddMessage($"Reduced area Ared = {concreteArea} + {reducingFactor} / {factorOfInelasticity} * {reinforcementArea} = {area}(m^2)"); + return area; + } + + private void GetAreas() + { + reducingFactor = reinforcementModulus / concreteModulus; + concreteArea = inclinedSection.WebWidth * inclinedSection.FullDepth; + TraceLogger?.AddMessage($"Concrete area Ac = {concreteArea}(m^2)"); + reinforcementArea = inclinedSection.BeamShearSection.ReinforcementArea; + TraceLogger?.AddMessage($"Reinforcement area As = {reinforcementArea}(m^2)"); + } + + private void GetConcreteModulus() + { + var concreteMaterial = inclinedSection.BeamShearSection.ConcreteMaterial; + var loaderMaterial = concreteMaterial.GetLoaderMaterial(inclinedSection.LimitState, inclinedSection.CalcTerm); + concreteModulus = loaderMaterial.InitModulus; + } + + private void GetReinforcementModulus() + { + var reinforcementMaterial = inclinedSection.BeamShearSection.ReinforcementMaterial; + var loaderMaterial = reinforcementMaterial.GetLoaderMaterial(inclinedSection.LimitState, inclinedSection.CalcTerm); + reinforcementModulus = loaderMaterial.InitModulus; + } + + private void GetConcreteStrength() + { + concreteStrength = inclinedSection.BeamShearSection.ConcreteMaterial.GetStrength(inclinedSection.LimitState, inclinedSection.CalcTerm); + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs index 5f1f43a..ab4ebe2 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/IBeamShearStrenghLogic.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StructureHelperLogics.Models.BeamShears.Logics +namespace StructureHelperLogics.Models.BeamShears { /// /// Implement logic for calculation of bearing capacity of inclined section for shear diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionListInputData.cs b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionListInputData.cs index 17053d8..eec7120 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionListInputData.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionListInputData.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using StructureHelperCommon.Models.Calculators; namespace StructureHelperLogics.Models.BeamShears { - public interface IGetInclinedSectionListInputData + public interface IGetInclinedSectionListInputData : IInputData { int StepCount { get; set; } double MaxInclinedSectionLegthFactor { get; set; } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionLogic.cs similarity index 79% rename from StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs rename to StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionLogic.cs index 6bf0512..2c2aa15 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionBySectionLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/IGetInclinedSectionLogic.cs @@ -1,9 +1,4 @@ using StructureHelperCommon.Infrastructures.Interfaces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace StructureHelperLogics.Models.BeamShears { diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetReducedAreaLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IGetReducedAreaLogic.cs new file mode 100644 index 0000000..d5bb6b0 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/IGetReducedAreaLogic.cs @@ -0,0 +1,9 @@ +using StructureHelperCommon.Infrastructures.Interfaces; + +namespace StructureHelperLogics.Models.BeamShears +{ + public interface IGetReducedAreaLogic : ILogic + { + double GetArea(); + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/InclinedSectionUpdateStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/InclinedSectionUpdateStrategy.cs new file mode 100644 index 0000000..5b17fb8 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/InclinedSectionUpdateStrategy.cs @@ -0,0 +1,26 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Services; + +namespace StructureHelperLogics.Models.BeamShears +{ + internal class InclinedSectionUpdateStrategy : IUpdateStrategy + { + public void Update(IInclinedSection targetObject, IInclinedSection sourceObject) + { + CheckObject.IsNull(sourceObject, ErrorStrings.SourceObject); + CheckObject.IsNull(targetObject, ErrorStrings.TargetObject); + if (ReferenceEquals(targetObject, sourceObject)) { return; }; + targetObject.StartCoord = sourceObject.StartCoord; + targetObject.EndCoord = sourceObject.EndCoord; + targetObject.EffectiveDepth = sourceObject.EffectiveDepth; + targetObject.FullDepth = sourceObject.FullDepth; + targetObject.LimitState = sourceObject.LimitState; + targetObject.CalcTerm = sourceObject.CalcTerm; + targetObject.ConcreteCompressionStrength = sourceObject.ConcreteCompressionStrength; + targetObject.ConcreteTensionStrength = sourceObject.ConcreteTensionStrength; + targetObject.WebWidth = sourceObject.WebWidth; + targetObject.BeamShearSection = sourceObject.BeamShearSection.Clone() as IBeamShearSection; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByDensityStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByDensityStrengthLogic.cs index 9eeefdc..5ae5181 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByDensityStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByDensityStrengthLogic.cs @@ -43,11 +43,11 @@ namespace StructureHelperLogics.Models.BeamShears double finalCrackLength = Math.Min(crackLength, maxCrackLength); TraceLogger?.AddMessage($"Length of crack = Min({crackLength}, {maxCrackLength}) = {finalCrackLength}(m)"); double finalDensity = stirrupEffectiveness.StirrupShapeFactor * stirrupEffectiveness.StirrupPlacementFactor * stirrupByDensity.StirrupDensity; - TraceLogger?.AddMessage($"Stirrups design density qsw = {finalDensity}(N/m)"); + TraceLogger?.AddMessage($"Stirrups design density qsw = {stirrupEffectiveness.StirrupShapeFactor} * {stirrupEffectiveness.StirrupPlacementFactor} * {stirrupByDensity.StirrupDensity} = {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"); + TraceLogger?.AddMessage($"Since stirrups design density qsw = {finalDensity}(N/m) less than {minStirrupRatio} * {concreteDensity}, final density is equal to zero", TraceLogStatuses.Warning); finalDensity = 0; } double strength = finalDensity * finalCrackLength; diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarStrengthLogic.cs index 3667d62..0b7af27 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarStrengthLogic.cs @@ -5,7 +5,7 @@ using StructureHelperCommon.Models.Forces; //Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia //All rights reserved. -namespace StructureHelperLogics.Models.BeamShears.Logics +namespace StructureHelperLogics.Models.BeamShears { public class StirrupByRebarStrengthLogic : IBeamShearStrenghLogic { @@ -52,9 +52,15 @@ namespace StructureHelperLogics.Models.BeamShears.Logics public double GetShearStrength() { InitializeStrategies(); + TraceLogger?.AddMessage($"Stirrup diameter d = {stirrupByRebar.Diameter}(m)"); + TraceLogger?.AddMessage($"Stirrup leg number n = {stirrupByRebar.LegCount}"); + TraceLogger?.AddMessage($"Stirrup spacing S = {stirrupByRebar.Spacing}(m)"); double maxSpacingRatio = inclinedSection.ConcreteTensionStrength * inclinedSection.WebWidth * inclinedSection.EffectiveDepth / forceTuple.Qy; + TraceLogger?.AddMessage($"Maximum spacing ratio due to strength beetwen hoops Sr,max = {maxSpacingRatio}(dimensionless)"); maxSpacingRatio = Math.Min(maxSpacingRatio, 0.5); + TraceLogger?.AddMessage($"Maximum spacing ratio Sr,max = {maxSpacingRatio}(dimensionless)"); double maxStirrupSpacingByEffectibeDepth = maxSpacingRatio * inclinedSection.EffectiveDepth; + TraceLogger?.AddMessage($"Maximum spacing S,max = {maxStirrupSpacingByEffectibeDepth}(m)"); if (stirrupByRebar.Spacing > maxStirrupSpacingByEffectibeDepth) { TraceLogger?.AddMessage($"Stirrup spacing S = {stirrupByRebar.Spacing}(m) is greater than max stirrup spacing Smax = {maxStirrupSpacingByEffectibeDepth}(m), stirrups are ignored", TraceLogStatuses.Warning); diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs index 26e1c37..2953d35 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupByRebarToDensityConvertStrategy.cs @@ -6,9 +6,8 @@ namespace StructureHelperLogics.Models.BeamShears { public class StirrupByRebarToDensityConvertStrategy : IConvertStrategy { - private const double stirrupStrengthFactor = 1d; + private const double stirrupStrengthFactor = 0.8d; private const double maxStirrupStrength = 3e8; - private IUpdateStrategy updateStrategy; public Dictionary<(Guid id, Type type), ISaveable> ReferenceDictionary { get; set; } public IShiftTraceLogger TraceLogger { get; set; } @@ -36,12 +35,15 @@ namespace StructureHelperLogics.Models.BeamShears private double GetStirrupDensity(IStirrupByRebar source) { double area = Math.PI * source.Diameter * source.Diameter / 4d; - TraceLogger?.AddMessage($"Area of rebar = {Math.PI} * ({source.Diameter})^2 / 4 = {area}, m^2"); - double strength = stirrupStrengthFactor * source.Material.GetStrength(LimitStates.ULS, CalcTerms.ShortTerm).Tensile; - TraceLogger?.AddMessage($"Strength of rebar = {strength}, Pa"); - strength = Math.Min(strength, maxStirrupStrength); - double density = strength * area * source.LegCount / source.Spacing; - TraceLogger?.AddMessage($"Density of stirrups = {strength} * {area} * {source.LegCount} / {source.Spacing} = {density}, N/m"); + TraceLogger?.AddMessage($"Area of rebar = {Math.PI} * ({source.Diameter})^2 / 4 = {area}(m^2)"); + double materialStrength = source.Material.GetStrength(LimitStates.ULS, CalcTerms.ShortTerm).Tensile; + TraceLogger?.AddMessage($"Stirrup material strength Rsw = {materialStrength}"); + double stirrupStrength = stirrupStrengthFactor * materialStrength; + TraceLogger?.AddMessage($"Strength of rebar Rsw = {stirrupStrengthFactor} * {materialStrength} = {stirrupStrength}(Pa)"); + double minimizedStrength = Math.Min(stirrupStrength, maxStirrupStrength); + TraceLogger?.AddMessage($"Strength of rebar Rsw = Min({stirrupStrength}, {maxStirrupStrength})= {minimizedStrength}(Pa)"); + double density = minimizedStrength * area * source.LegCount / source.Spacing; + TraceLogger?.AddMessage($"Density of stirrups = {minimizedStrength} * {area} * {source.LegCount} / {source.Spacing} = {density}(N/m)"); return density; } } diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs new file mode 100644 index 0000000..ea37ac1 --- /dev/null +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupBySearchLogic.cs @@ -0,0 +1,78 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperLogics.Models.BeamShears.Logics; + +namespace StructureHelperLogics.Models.BeamShears +{ + internal class StirrupBySearchLogic : IBeamShearStrenghLogic + { + private ConcreteStrengthLogic concreteLogic; + private StirrupStrengthLogic stirrupLogic; + private ShiftTraceLogger? localTraceLogger { get; set; } + + public StirrupBySearchLogic(IShiftTraceLogger? traceLogger) + { + TraceLogger = traceLogger; + } + + public IShiftTraceLogger? TraceLogger { get; set; } + public IBeamShearSectionLogicInputData InputData { get; internal set; } + public ISectionEffectiveness SectionEffectiveness { get; internal set; } + + public double GetShearStrength() + { + double parameter = GetParameter(); + BeamShearSectionLogicInputData newInputData = GetNewInputData(parameter); + stirrupLogic = new(newInputData, localTraceLogger); + double stirrupStrength = stirrupLogic.GetShearStrength(); + return stirrupStrength; + } + + public double GetParameter() + { + var parameterCalculator = new FindParameterCalculator(TraceLogger); + parameterCalculator.InputData.Predicate = GetPredicate; + parameterCalculator.Accuracy.IterationAccuracy = 0.0001d; + parameterCalculator.Accuracy.MaxIterationCount = 1000; + parameterCalculator.Run(); + if (parameterCalculator.Result.IsValid == false) + { + throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": predicate error"); + } + var result = parameterCalculator.Result as FindParameterResult; + var parameter = result.Parameter; + return parameter; + } + + private bool GetPredicate(double factor) + { + BeamShearSectionLogicInputData newInputData = GetNewInputData(factor); + concreteLogic = new(SectionEffectiveness, newInputData.InclinedSection, localTraceLogger); + stirrupLogic = new(newInputData, localTraceLogger); + double concreteStrength = concreteLogic.GetShearStrength(); + double stirrupStrength = stirrupLogic.GetShearStrength(); + return stirrupStrength > concreteStrength; + } + + private BeamShearSectionLogicInputData GetNewInputData(double factor) + { + double sourceCrackLength = InputData.InclinedSection.EndCoord - InputData.InclinedSection.StartCoord; + double newCrackLength = sourceCrackLength * factor; + double newStartCoord = InputData.InclinedSection.EndCoord - newCrackLength; + InclinedSection newSection = new(); + var updateStrategy = new InclinedSectionUpdateStrategy(); + updateStrategy.Update(newSection, InputData.InclinedSection); + newSection.StartCoord = newStartCoord; + BeamShearSectionLogicInputData newInputData = new(Guid.Empty) + { + InclinedSection = newSection, + LimitState = InputData.LimitState, + CalcTerm = InputData.CalcTerm, + Stirrup = InputData.Stirrup, + ForceTuple = InputData.ForceTuple + }; + return newInputData; + } + } +} diff --git a/StructureHelperLogics/Models/BeamShears/Logics/StirrupStrengthLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/StirrupStrengthLogic.cs index 32362af..47b9028 100644 --- a/StructureHelperLogics/Models/BeamShears/Logics/StirrupStrengthLogic.cs +++ b/StructureHelperLogics/Models/BeamShears/Logics/StirrupStrengthLogic.cs @@ -1,12 +1,7 @@ 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 +namespace StructureHelperLogics.Models.BeamShears { internal class StirrupStrengthLogic : IBeamShearStrenghLogic { diff --git a/StructureHelperLogics/Models/Materials/TraceMaterialsFactory.cs b/StructureHelperLogics/Models/Materials/TraceMaterialsFactory.cs index 4b7af43..bf8bef8 100644 --- a/StructureHelperLogics/Models/Materials/TraceMaterialsFactory.cs +++ b/StructureHelperLogics/Models/Materials/TraceMaterialsFactory.cs @@ -30,6 +30,11 @@ namespace StructureHelperLogics.Models.Materials ProcessCollection(); return traceLoggerEntries; } + public void AddEntriesToTraceLogger(IShiftTraceLogger traceLogger) + { + var entries = GetTraceEntries(); + entries.ForEach(x => traceLogger?.AddEntry(x)); + } private void ProcessCollection() { @@ -45,7 +50,6 @@ namespace StructureHelperLogics.Models.Materials } traceLoggerEntries.Add(table); } - private List> ProcessLibMaterial(ILibMaterial libMaterial) { List> rows = new(); @@ -76,7 +80,6 @@ namespace StructureHelperLogics.Models.Materials rows.Add(ndmRow); return rows; } - private void Check() { if (Collection is null) @@ -84,7 +87,6 @@ namespace StructureHelperLogics.Models.Materials throw new StructureHelperException(ErrorStrings.ParameterIsNull + ": Collection of primitives"); } } - private IShTableRow GetHeader(IHeadMaterial headMaterial) { const CellRole cellRole = CellRole.Header; @@ -263,10 +265,5 @@ namespace StructureHelperLogics.Models.Materials return rows; } - public void AddEntriesToTraceLogger(IShiftTraceLogger traceLogger) - { - var entries = GetTraceEntries(); - entries.ForEach(x => traceLogger?.AddEntry(x)); - } } } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ExportForcesResultToCSVLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ExportForcesResultToCSVLogic.cs index 75f655c..123ac72 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ExportForcesResultToCSVLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ExportForcesResultToCSVLogic.cs @@ -5,6 +5,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses { public class ExportForcesResultToCSVLogic : ExportToCSVLogicBase { + private const string errorString = "-error-"; IForcesResults results; public ExportForcesResultToCSVLogic(IForcesResults results) @@ -45,14 +46,14 @@ namespace StructureHelperLogics.NdmCalculations.Analyses } string[] newLine = { - item.DesignForceTuple.LimitState.ToString(), - item.DesignForceTuple.CalcTerm.ToString(), - tuple.Mx.ToString(), - tuple.My.ToString(), - tuple.Nz.ToString(), - strainMatrix?.Kx.ToString(), - strainMatrix?.Ky.ToString(), - strainMatrix?.EpsZ.ToString() + item.DesignForceTuple.LimitState.ToString() ?? errorString, + item.DesignForceTuple.CalcTerm.ToString() ?? errorString, + tuple.Mx.ToString() ?? errorString, + tuple.My.ToString() ?? errorString, + tuple.Nz.ToString() ?? errorString, + strainMatrix?.Kx.ToString() ?? errorString, + strainMatrix?.Ky.ToString() ?? errorString, + strainMatrix?.EpsZ.ToString() ?? errorString }; output.AppendLine(string.Join(separator, newLine)); } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs index 0035e11..7587b8a 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackResult.cs @@ -10,11 +10,11 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { - public class CrackResult : IResult + public class CrackResult : ICrackResult { public bool IsValid { get; set; } public string? Description { get; set; } - public List TupleResults {get;set;} + public List TupleResults { get; set; } public CrackResult() { TupleResults = new(); diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackResult.cs new file mode 100644 index 0000000..b78b1d2 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/ICrackResult.cs @@ -0,0 +1,9 @@ +using StructureHelperCommon.Models.Calculators; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public interface ICrackResult : IResult + { + List TupleResults { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Cracking/Logics/ExportCrackResultToCSVLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/Logics/ExportCrackResultToCSVLogic.cs new file mode 100644 index 0000000..0ea7479 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/Logics/ExportCrackResultToCSVLogic.cs @@ -0,0 +1,72 @@ +using StructureHelperCommon.Models.Calculators; +using StructureHelperLogics.NdmCalculations.Analyses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + public class ExportCrackResultToCSVLogic : ExportToCSVLogicBase + { + private const string errorString = "-error-"; + private ICrackResult crackResult; + + public ExportCrackResultToCSVLogic(ICrackResult crackResult) + { + this.crackResult = crackResult; + } + + public override void ExportHeadings() + { + string[] headings = + { + "Action name", + "Long Nz", + "Long Mx", + "Long My", + "Long CrackWidth", + "Long UltimateCrackWidth", + "Long IsGood", + "Long Uf", + "Short Nz", + "Short Mx", + "Short My", + "Short CrackWidth", + "Short UltimateCrackWidth", + "Short IsGood", + "Short Uf", + }; + output.AppendLine(string.Join(separator, headings)); + } + public override void ExportBoby() + { + foreach (var item in crackResult.TupleResults) + { + //if (item.IsValid == true) + { + string[] newLine = + { + item?.InputData?.TupleName ?? errorString, + item?.InputData?.LongTermTuple?.Nz.ToString() ?? errorString, + item?.InputData?.LongTermTuple?.Mx.ToString() ?? errorString, + item?.InputData?.LongTermTuple?.My.ToString() ?? errorString, + item?.LongTermResult?.CrackWidth.ToString() ?? errorString, + item?.LongTermResult ?.UltimateCrackWidth.ToString() ?? errorString, + item?.LongTermResult ?.IsCrackLessThanUltimate.ToString() ?? errorString, + (item?.LongTermResult ?.CrackWidth / item?.LongTermResult?.UltimateCrackWidth).ToString() ?? errorString, + item?.InputData?.ShortTermTuple?.Nz.ToString() ?? errorString, + item?.InputData?.ShortTermTuple?.Mx.ToString() ?? errorString, + item ?.InputData?.ShortTermTuple?.My.ToString() ?? errorString, + item?.ShortTermResult?.CrackWidth.ToString() ?? errorString, + item?.ShortTermResult?.UltimateCrackWidth.ToString() ?? errorString, + item?.ShortTermResult?.IsCrackLessThanUltimate.ToString() ?? errorString, + (item?.ShortTermResult?.CrackWidth / item?.ShortTermResult?.UltimateCrackWidth).ToString() ?? errorString, + }; + output.AppendLine(string.Join(separator, newLine)); + } + } + } + } +} diff --git a/StructureHelperLogics/StructureHelperLogics.csproj b/StructureHelperLogics/StructureHelperLogics.csproj index 7c6c612..c221750 100644 --- a/StructureHelperLogics/StructureHelperLogics.csproj +++ b/StructureHelperLogics/StructureHelperLogics.csproj @@ -16,8 +16,4 @@ - - - - diff --git a/StructureHelperTests/UnitTests/BeamShearTests/GetLongitudinalForceFactorLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/GetLongitudinalForceFactorLogicTests.cs index 2b20656..d279cf3 100644 --- a/StructureHelperTests/UnitTests/BeamShearTests/GetLongitudinalForceFactorLogicTests.cs +++ b/StructureHelperTests/UnitTests/BeamShearTests/GetLongitudinalForceFactorLogicTests.cs @@ -3,135 +3,113 @@ using NUnit.Framework; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Infrastructures.Interfaces; using StructureHelperCommon.Models; -using StructureHelperLogics.Models.BeamShears.Logics; using StructureHelperLogics.Models.BeamShears; +using StructureHelperLogics.Models.BeamShears.Logics; +using System; namespace StructureHelperTests.UnitTests.BeamShearTests { - - - [TestFixture] - public class GetLongitudinalForceFactorLogicTests - { - private Mock _mockSection; - private Mock> _mockCheckLogic; - private Mock _mockLogger; - private GetLongitudinalForceFactorLogic _logic; - - [SetUp] - public void SetUp() + [TestFixture] + public class GetLongitudinalForceFactorLogicTests { - _mockSection = new Mock(); - _mockCheckLogic = new Mock>(); - _mockLogger = new Mock(); - - _logic = new GetLongitudinalForceFactorLogic(_mockLogger.Object) + [Test] + public void GetFactor_When_LongitudinalForceIsZero_ReturnsOne() { - InclinedSection = _mockSection.Object, - LongitudinalForce = 0 - }; + var traceLogger = new Mock(); + var inclinedSection = new Mock(); + var mockCheckLogic = new Mock>(); + mockCheckLogic.Setup(x => x.Check()).Returns(true); + List traceLoggerEntries = new(); + traceLogger.Setup(x => x.TraceLoggerEntries).Returns(traceLoggerEntries); - // Inject mock check logic - typeof(GetLongitudinalForceFactorLogic) - .GetField("checkInclinedSectionLogic", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) - ?.SetValue(_logic, _mockCheckLogic.Object); - } + var mockReducedAreaLogic = new Mock(); + var logic = new GetLongitudinalForceFactorLogic(mockCheckLogic.Object, mockReducedAreaLogic.Object, traceLogger.Object) + { + InclinedSection = inclinedSection.Object, + LongitudinalForce = 0 + }; - [Test] - public void GetFactor_Returns1_WhenLongitudinalForceIsZero() - { - // Arrange - _mockCheckLogic.Setup(c => c.Check()).Returns(true); + var result = logic.GetFactor(); - // Act - var result = _logic.GetFactor(); + Assert.That(result, Is.EqualTo(1)); + } - // Assert - Assert.That(result, Is.EqualTo(1)); - } + [Test] + public void GetFactor_When_CheckFails_ThrowsStructureHelperException() + { + var traceLogger = new Mock(); + var inclinedSection = new Mock(); + var mockCheckLogic = new Mock>(); + List traceLoggerEntries = new(); + traceLogger.Setup(x => x.TraceLoggerEntries).Returns(traceLoggerEntries); - [Test] - public void GetFactor_ComputesCorrectly_ForTension() - { - // Arrange - _logic.LongitudinalForce = 100000; // tension - _mockSection.Setup(s => s.WebWidth).Returns(0.3); - _mockSection.Setup(s => s.FullDepth).Returns(0.5); - _mockSection.Setup(s => s.ConcreteTensionStrength).Returns(2000000); - _mockCheckLogic.Setup(c => c.Check()).Returns(true); + mockCheckLogic.Setup(x => x.Check()).Returns(false); + mockCheckLogic.Setup(x => x.CheckResult).Returns("Check failed"); - double area = 0.3 * 0.5; - double stress = 100000 / area; - double ratio = stress / 2000000; - double expected = Math.Max(1 - 0.5 * ratio, 0); + var mockReducedAreaLogic = new Mock(); + var logic = new GetLongitudinalForceFactorLogic(mockCheckLogic.Object, mockReducedAreaLogic.Object, traceLogger.Object) + { + InclinedSection = inclinedSection.Object, + LongitudinalForce = 1000 + }; - // Act - var result = _logic.GetFactor(); + Assert.That(() => logic.GetFactor(), Throws.TypeOf()); + } - // Assert - Assert.That(result, Is.EqualTo(expected).Within(1e-6)); - } + [TestCase(-1, 1.0000000333333334d)] //1N + [TestCase(-1000000, 1.0333333333333334d)] //1MN + [TestCase(-10000000, 1.25d)] //10MN + [TestCase(-20000000, 0.83333333333333348d)] //20MN + [TestCase(-100000000, 0)] //100MN + public void GetFactor_When_Compression_ReturnsExpectedResult(double force, double expectedFactor) + { + var traceLogger = new Mock(); + var inclinedSection = new Mock(); + var mockCheckLogic = new Mock>(); + var mockReducedAreaLogic = new Mock(); + List traceLoggerEntries = new(); + traceLogger.Setup(x => x.TraceLoggerEntries).Returns(traceLoggerEntries); - [Test] - public void GetFactor_ComputesCorrectly_ForCompression_WithinFirstLimit() - { - // Arrange - _logic.LongitudinalForce = -10000; // compression - _mockSection.Setup(s => s.WebWidth).Returns(0.3); - _mockSection.Setup(s => s.FullDepth).Returns(0.5); - _mockSection.Setup(s => s.ConcreteCompressionStrength).Returns(25000000); - _mockCheckLogic.Setup(c => c.Check()).Returns(true); + mockCheckLogic.Setup(x => x.Check()).Returns(true); + mockReducedAreaLogic.Setup(x => x.GetArea()).Returns(1.0); - double area = 0.3 * 0.5; - double stress = 10000 / area; - double ratio = stress / 25000000; - double expected = 1 + ratio; + inclinedSection.Setup(x => x.ConcreteCompressionStrength).Returns(30e6); - // Act - var result = _logic.GetFactor(); + var logic = new GetLongitudinalForceFactorLogic(mockCheckLogic.Object, mockReducedAreaLogic.Object, traceLogger.Object) + { + InclinedSection = inclinedSection.Object, + LongitudinalForce = force + }; - // Assert - Assert.That(result, Is.EqualTo(expected).Within(1e-6)); - } + var result = logic.GetFactor(); - [TestCase(-11250000 / 3.99)] - [TestCase(-11250000 / 3)] - [TestCase(-11250000)] - public void GetFactor_ComputesCorrectly_ForCompression_HighRatio(double force) - { - // Arrange - _logic.LongitudinalForce = force; // compression - _mockSection.Setup(s => s.WebWidth).Returns(0.3); - _mockSection.Setup(s => s.FullDepth).Returns(0.5); - _mockSection.Setup(s => s.ConcreteCompressionStrength).Returns(25000000); - _mockCheckLogic.Setup(c => c.Check()).Returns(true); + Assert.That(result, Is.EqualTo(expectedFactor).Within(1e-6)); + } - double area = 0.3 * 0.5; - double stress = - force / area; - double ratio = stress / 25000000; + [Test] + public void GetFactor_When_Tension_ReturnsExpectedResult() + { + var traceLogger = new Mock(); + var inclinedSection = new Mock(); + var mockCheckLogic = new Mock>(); + var mockReducedAreaLogic = new Mock(); + List traceLoggerEntries = new(); + traceLogger.Setup(x => x.TraceLoggerEntries).Returns(traceLoggerEntries); - Assert.That(ratio, Is.GreaterThan(0.75)); // high compression branch + mockCheckLogic.Setup(x => x.Check()).Returns(true); + mockReducedAreaLogic.Setup(x => x.GetArea()).Returns(1.0); - double expected = Math.Max(5 * (1 - ratio), 0); + inclinedSection.Setup(x => x.ConcreteTensionStrength).Returns(3e6); - // Act - var result = _logic.GetFactor(); + var logic = new GetLongitudinalForceFactorLogic(mockCheckLogic.Object, mockReducedAreaLogic.Object, traceLogger.Object) + { + InclinedSection = inclinedSection.Object, + LongitudinalForce = 1000000 // +1MN + }; - // Assert - Assert.That(result, Is.EqualTo(expected).Within(1e-6)); - } + var result = logic.GetFactor(); - [Test] - public void GetFactor_Throws_WhenCheckFails() - { - // Arrange - _mockCheckLogic.Setup(c => c.Check()).Returns(false); - _mockCheckLogic.Setup(c => c.CheckResult).Returns("Invalid section"); - - // Act & Assert - var ex = Assert.Throws(() => _logic.GetFactor()); - Assert.That(ex.Message, Does.Contain("Invalid section")); + Assert.That(result, Is.GreaterThanOrEqualTo(0)); + } } } - -} diff --git a/StructureHelperTests/UnitTests/BeamShearTests/GetReducedAreaLogicSP63_2018_rev3Tests.cs b/StructureHelperTests/UnitTests/BeamShearTests/GetReducedAreaLogicSP63_2018_rev3Tests.cs new file mode 100644 index 0000000..9baff4f --- /dev/null +++ b/StructureHelperTests/UnitTests/BeamShearTests/GetReducedAreaLogicSP63_2018_rev3Tests.cs @@ -0,0 +1,56 @@ +using LoaderCalculator.Data.Materials; +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.Models.BeamShears; +using StructureHelperLogics.Models.Materials; +using System; + +namespace StructureHelperTests.UnitTests.BeamShearTests +{ + [TestFixture] + public class GetReducedAreaLogicSP63_2018_rev3Tests + { + [TestCase(-500, 0.3, 0.5, 0.001, 0.16999999999999998d)] + [TestCase(-500, 0.3, 0.5, 0.002, 0.19d)] + [TestCase(1000, 0.3, 0.5, 0.001, 0.16666666666666666d)] + [TestCase(1000, 0.3, 0.5, 0.002, 0.18333333333333335d)] + public void GetArea_ReturnsCorrectResult(double force, double width, double depth, double reinforcementArea, double expectedArea) + { + + // Arrange + var mockConcreteMaterial = new Mock(); + mockConcreteMaterial.Setup(m => m.GetLoaderMaterial(It.IsAny(), It.IsAny())) + .Returns(new Material { InitModulus = 3e10 }); + mockConcreteMaterial.Setup(m => m.GetStrength(It.IsAny(), It.IsAny())) + .Returns((20e6, 1.2e6)); + + var mockReinforcementMaterial = new Mock(); + mockReinforcementMaterial.Setup(m => m.GetLoaderMaterial(It.IsAny(), It.IsAny())) + .Returns(new Material { InitModulus = 2e11 }); + mockReinforcementMaterial.Setup(m => m.GetStrength(It.IsAny(), It.IsAny())) + .Returns((200e6, 200e6)); + + var mockSection = new Mock(); + mockSection.Setup(s => s.ConcreteMaterial).Returns(mockConcreteMaterial.Object); + mockSection.Setup(s => s.ReinforcementMaterial).Returns(mockReinforcementMaterial.Object); + mockSection.Setup(s => s.ReinforcementArea).Returns(reinforcementArea); + + var mockInclSection = new Mock(); + mockInclSection.Setup(s => s.WebWidth).Returns(width); + mockInclSection.Setup(s => s.FullDepth).Returns(depth); + mockInclSection.Setup(s => s.BeamShearSection).Returns(mockSection.Object); + mockInclSection.Setup(s => s.LimitState).Returns(LimitStates.ULS); + mockInclSection.Setup(s => s.CalcTerm).Returns(CalcTerms.ShortTerm); + + var logic = new GetReducedAreaLogicSP63_2018_rev3(force, mockInclSection.Object, null); + + // Act + var result = logic.GetArea(); + + // Assert + Assert.That(result, Is.EqualTo(expectedArea).Within(1e-6)); + } + } + } diff --git a/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs index dd6132e..2244fcb 100644 --- a/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs +++ b/StructureHelperTests/UnitTests/BeamShearTests/StirrupByUniformRebarToDensityConvertStrategyTests.cs @@ -49,7 +49,7 @@ namespace StructureHelperTests.UnitTests.BeamShearTests // Assert _mockUpdateStrategy.Verify(u => u.Update(It.IsAny(), stirrupRebar.Object), Times.Once); - Assert.That(result.StirrupDensity, Is.EqualTo(837758.04095727834d).Within(0.00001)); + Assert.That(result.StirrupDensity, Is.EqualTo(670206.43276582274d).Within(0.00001)); //_mockTraceLogger.Verify(t => t.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce); } }