From d13304fe06c75aceaabe565f583a3d117db5b805 Mon Sep 17 00:00:00 2001 From: Evgeny Redikultsev Date: Sun, 26 May 2024 11:35:48 +0500 Subject: [PATCH] Checkig Iput data of crack calculator was changed --- StructureHelper/App.xaml | 1 + .../Infrastructure/UI/Resources/Cracks.xaml | 27 ++++ .../UI/Resources/ServiceColors.xaml | 7 ++ .../Libraries/LoaderCalculator.dll | Bin 88064 -> 88576 bytes .../Services/ResultViewers/CrackResultFunc.cs | 20 +++ .../ResultViewers/CrackResultFuncFactory.cs | 82 ++++++++++++ .../{ResultFunc.cs => ForceResultFunc.cs} | 4 +- .../ResultViewers/ForceResultFuncFactory.cs | 83 ++++++++++++ .../Services/ResultViewers/IResultFunc.cs | 4 +- .../ResultViewers/ResultFuncFactory.cs | 82 ------------ .../ResultViewers/ShowIsoFieldResult.cs | 89 ++++++++++--- StructureHelper/StructureHelper.csproj.user | 9 ++ .../Cracks/CrackResultView.xaml | 43 ++----- .../Cracks/CrackResultViewModel.cs | 29 ++++- .../CalculatorsViews/Cracks/Cracks.xaml | 27 ++++ .../Cracks/IShowCrackIsoFieldsLogic.cs | 10 ++ .../Cracks/ShowCrackIsoFieldsLogic.cs | 37 ++++++ .../Cracks/TupleCrackResultView.xaml | 103 ++++++++++++++- .../Cracks/TupleCrackResultView.xaml.cs | 12 +- .../Cracks/TupleCrackResultViewModel.cs | 37 +++++- .../ForceResultLogic/ShowCrackWidthLogic.cs | 2 +- .../ValuePointDiagramLogic.cs | 4 +- .../ForcesResultsViewModel.cs | 3 +- .../Windows/Forces/ValueDelegatesLogic.cs | 10 +- .../CalculationResultViewModel.cs | 2 +- .../AnalysisViewModelLogic.cs | 9 +- .../Interfaces/ICheckInputDataLogic.cs | 14 +++ .../Infrastructures/Interfaces/ICheckLogic.cs | 14 +++ .../Models/Materials/ConcreteCurveLogic.cs | 12 +- .../Materials/ReinforcementByBuilderLogic.cs | 15 ++- .../ByForces/LimitCurve/LimitCurveLogic.cs | 8 +- .../Logics/ForceTupleTraceResultLogic.cs | 2 +- .../Buckling/ConcreteBucklingCalculator.cs | 2 +- .../CheckCrackCalculatorInputDataLogic.cs | 119 ++++++++++++++++++ .../Cracking/CrackCalculator.cs | 15 +++ .../Cracking/CrackWidthLogicSP63.cs | 2 +- .../Cracking/GetTupleInputDatasLogic.cs | 3 +- .../Cracking/ICrackWidthTupleResult.cs | 3 + .../Cracking/LengthBetweenCracksLogicSP63.cs | 2 +- .../Cracking/RebarCrackResult.cs | 14 +++ .../Cracking/RebarStressCalculator.cs | 6 +- .../Cracking/RebarStressResult.cs | 2 + .../Cracking/TensileConcreteAreaLogicSP63.cs | 2 +- .../Cracking/TensionRebarAreaByStrainLogic.cs | 6 +- .../TensionRebarAreaSimpleSumLogic.cs | 5 +- .../Cracking/TupleCrackCalculator.cs | 75 ++++++++--- .../Cracking/TupleCrackInputData.cs | 22 +++- .../Cracking/TupleCrackResult.cs | 12 +- .../Cracks/TensionREbarAreaSumLogicTest.cs | 8 +- .../TensionRebarAreaByStrainLogicTest.cs | 8 +- 50 files changed, 901 insertions(+), 206 deletions(-) create mode 100644 StructureHelper/Infrastructure/UI/Resources/Cracks.xaml create mode 100644 StructureHelper/Infrastructure/UI/Resources/ServiceColors.xaml create mode 100644 StructureHelper/Services/ResultViewers/CrackResultFunc.cs create mode 100644 StructureHelper/Services/ResultViewers/CrackResultFuncFactory.cs rename StructureHelper/Services/ResultViewers/{ResultFunc.cs => ForceResultFunc.cs} (81%) create mode 100644 StructureHelper/Services/ResultViewers/ForceResultFuncFactory.cs delete mode 100644 StructureHelper/Services/ResultViewers/ResultFuncFactory.cs create mode 100644 StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/Cracks.xaml create mode 100644 StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/IShowCrackIsoFieldsLogic.cs create mode 100644 StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/ShowCrackIsoFieldsLogic.cs create mode 100644 StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs create mode 100644 StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs diff --git a/StructureHelper/App.xaml b/StructureHelper/App.xaml index 04fc9ba..70db8cc 100644 --- a/StructureHelper/App.xaml +++ b/StructureHelper/App.xaml @@ -19,6 +19,7 @@ + diff --git a/StructureHelper/Infrastructure/UI/Resources/Cracks.xaml b/StructureHelper/Infrastructure/UI/Resources/Cracks.xaml new file mode 100644 index 0000000..0e11fa7 --- /dev/null +++ b/StructureHelper/Infrastructure/UI/Resources/Cracks.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/StructureHelper/Infrastructure/UI/Resources/ServiceColors.xaml b/StructureHelper/Infrastructure/UI/Resources/ServiceColors.xaml new file mode 100644 index 0000000..782b8b2 --- /dev/null +++ b/StructureHelper/Infrastructure/UI/Resources/ServiceColors.xaml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/StructureHelper/Libraries/LoaderCalculator.dll b/StructureHelper/Libraries/LoaderCalculator.dll index 53f5bf2d4c9c35e3dd03816dee9a5fced6df7b6a..09353ee4d75505194a175b31bba85d68f24d0c9d 100644 GIT binary patch literal 88576 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 literal 88064 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%0A&9a`+EJO8G>*#pS6oMBN*3J$ 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 + { + public string Name { get; set; } + + public Func ResultFunction { get; set; } + + public string UnitName { get; set; } + + public double UnitFactor { get; set; } + } +} diff --git a/StructureHelper/Services/ResultViewers/CrackResultFuncFactory.cs b/StructureHelper/Services/ResultViewers/CrackResultFuncFactory.cs new file mode 100644 index 0000000..9b3fbab --- /dev/null +++ b/StructureHelper/Services/ResultViewers/CrackResultFuncFactory.cs @@ -0,0 +1,82 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Services.Units; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelper.Services.ResultViewers +{ + + public static class CrackResultFuncFactory + { + static IUnit unitStress = CommonOperation.GetUnit(UnitTypes.Stress); + static IUnit unitLength = CommonOperation.GetUnit(UnitTypes.Length, "mm"); + + public static List GetResultFuncs() + { + List results = new() + { + new() + { + Name = "Long crack width", + ResultFunction = (RebarCrackResult rebar) => rebar.LongTermResult.CrackWidth, + UnitFactor = unitLength.Multiplyer, + UnitName = unitLength.Name + }, + new() + { + Name = "Short crack width", + ResultFunction = (RebarCrackResult rebar) => rebar.ShortTermResult.CrackWidth, + UnitFactor = unitLength.Multiplyer, + UnitName = unitLength.Name + }, + new() + { + Name = "Long rebar stress", + ResultFunction = (RebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.RebarStress, + UnitFactor = unitStress.Multiplyer, + UnitName = unitStress.Name + }, + new() + { + Name = "Short rebar stress", + ResultFunction = (RebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.RebarStress, + UnitFactor = unitStress.Multiplyer, + UnitName = unitStress.Name + }, + new() + { + Name = "Long rebar strain", + ResultFunction = (RebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.RebarStrain, + UnitFactor = 1d, + UnitName = string.Empty + }, + new() + { + Name = "Short rebar strain", + ResultFunction = (RebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.RebarStrain, + UnitFactor = 1d, + UnitName = string.Empty + }, + new() + { + Name = "Long concrete strain", + ResultFunction = (RebarCrackResult rebar) => rebar.LongTermResult.RebarStressResult.ConcreteStrain, + UnitFactor = 1d, + UnitName = string.Empty + }, + new() + { + Name = "Short concrete strain", + ResultFunction = (RebarCrackResult rebar) => rebar.ShortTermResult.RebarStressResult.ConcreteStrain, + UnitFactor = 1d, + UnitName = string.Empty + } + }; + return results; + } + } +} diff --git a/StructureHelper/Services/ResultViewers/ResultFunc.cs b/StructureHelper/Services/ResultViewers/ForceResultFunc.cs similarity index 81% rename from StructureHelper/Services/ResultViewers/ResultFunc.cs rename to StructureHelper/Services/ResultViewers/ForceResultFunc.cs index 129e705..724374f 100644 --- a/StructureHelper/Services/ResultViewers/ResultFunc.cs +++ b/StructureHelper/Services/ResultViewers/ForceResultFunc.cs @@ -8,14 +8,14 @@ using System.Threading.Tasks; namespace StructureHelper.Services.ResultViewers { - public class ResultFunc : IResultFunc + public class ForceResultFunc : IResultFunc> { public string Name { get; set; } public Func ResultFunction { get; set; } public string UnitName { get; set; } public double UnitFactor { get; set; } - public ResultFunc() + public ForceResultFunc() { UnitFactor = 1d; } diff --git a/StructureHelper/Services/ResultViewers/ForceResultFuncFactory.cs b/StructureHelper/Services/ResultViewers/ForceResultFuncFactory.cs new file mode 100644 index 0000000..3935460 --- /dev/null +++ b/StructureHelper/Services/ResultViewers/ForceResultFuncFactory.cs @@ -0,0 +1,83 @@ +using LoaderCalculator.Logics; +using StructureHelper.Infrastructure.UI.Converters.Units; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Services.Units; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelper.Services.ResultViewers +{ + public enum FuncsTypes + { + Strain, + Stress, + Forces, + Full, + } + public static class ForceResultFuncFactory + { + static IUnit unitForce = CommonOperation.GetUnit(UnitTypes.Force); + static IUnit unitStress = CommonOperation.GetUnit(UnitTypes.Stress); + static IUnit unitMoment = CommonOperation.GetUnit(UnitTypes.Moment); + static IUnit unitCurvature = CommonOperation.GetUnit(UnitTypes.Curvature); + + static readonly IStressLogic stressLogic = new StressLogic(); + public static List GetResultFuncs(FuncsTypes funcsType = FuncsTypes.Full) + { + List results = new(); + if (funcsType == FuncsTypes.Strain) + { + results.AddRange(GetStrainResultFuncs()); + } + else if (funcsType == FuncsTypes.Stress) + { + results.AddRange(GetStressResultFuncs()); + } + else if (funcsType == FuncsTypes.Forces) + { + results.AddRange(GetForcesResultFuncs()); + } + else if (funcsType == FuncsTypes.Full) + { + results.AddRange(GetStrainResultFuncs()); + results.AddRange(GetStressResultFuncs()); + results.AddRange(GetForcesResultFuncs()); + } + else + { + throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(funcsType)); + } + return results; + } + private static List GetStrainResultFuncs() + { + List resultFuncs = new (); + resultFuncs.Add(new ForceResultFunc() { Name = "Section Strain", ResultFunction = stressLogic.GetSectionStrain }); + resultFuncs.Add(new ForceResultFunc() { Name = "Total Strain", ResultFunction = stressLogic.GetTotalStrainWithPrestrain }); + resultFuncs.Add(new ForceResultFunc() { Name = "Prestrain", ResultFunction = stressLogic.GetPrestrain }); + resultFuncs.Add(new ForceResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain }); + resultFuncs.Add(new ForceResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain }); + return resultFuncs; + } + private static List GetStressResultFuncs() + { + List resultFuncs = new (); + resultFuncs.Add(new ForceResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress, UnitFactor = unitStress.Multiplyer, UnitName = unitStress.Name }); + resultFuncs.Add(new ForceResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus, UnitFactor = unitStress.Multiplyer, UnitName = unitStress.Name }); + resultFuncs.Add(new ForceResultFunc() { Name = "Modulus degradation", ResultFunction = stressLogic.GetModulusDegradation }); + return resultFuncs; + } + private static List GetForcesResultFuncs() + { + List resultFuncs = new (); + resultFuncs.Add(new ForceResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce, UnitFactor = unitForce.Multiplyer, UnitName = unitForce.Name }); + resultFuncs.Add(new ForceResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX, UnitFactor = unitMoment.Multiplyer, UnitName = unitMoment.Name }); + resultFuncs.Add(new ForceResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY, UnitFactor = unitMoment.Multiplyer, UnitName = unitMoment.Name }); + return resultFuncs; + } + } +} diff --git a/StructureHelper/Services/ResultViewers/IResultFunc.cs b/StructureHelper/Services/ResultViewers/IResultFunc.cs index f90acc1..6ab3b7a 100644 --- a/StructureHelper/Services/ResultViewers/IResultFunc.cs +++ b/StructureHelper/Services/ResultViewers/IResultFunc.cs @@ -8,10 +8,10 @@ using System.Threading.Tasks; namespace StructureHelper.Services.ResultViewers { - public interface IResultFunc + public interface IResultFunc { string Name { get; } - Func ResultFunction { get; } + T ResultFunction { get; } string UnitName { get; set; } double UnitFactor { get; } } diff --git a/StructureHelper/Services/ResultViewers/ResultFuncFactory.cs b/StructureHelper/Services/ResultViewers/ResultFuncFactory.cs deleted file mode 100644 index 3064412..0000000 --- a/StructureHelper/Services/ResultViewers/ResultFuncFactory.cs +++ /dev/null @@ -1,82 +0,0 @@ -using LoaderCalculator.Logics; -using StructureHelper.Infrastructure.UI.Converters.Units; -using StructureHelperCommon.Infrastructures.Enums; -using StructureHelperCommon.Infrastructures.Exceptions; -using StructureHelperCommon.Services.Units; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelper.Services.ResultViewers -{ - public enum FuncsTypes - { - Strain, - Stress, - Forces, - Full, - } - public static class ResultFuncFactory - { - static IUnit unitForce = CommonOperation.GetUnit(UnitTypes.Force); - static IUnit unitStress = CommonOperation.GetUnit(UnitTypes.Stress); - static IUnit unitMoment = CommonOperation.GetUnit(UnitTypes.Moment); - static IUnit unitCurvature = CommonOperation.GetUnit(UnitTypes.Curvature); - - static readonly IStressLogic stressLogic = new StressLogic(); - public static List GetResultFuncs(FuncsTypes funcsType = FuncsTypes.Full) - { - List results = new(); - if (funcsType == FuncsTypes.Strain) - { - results.AddRange(GetStrainResultFuncs()); - } - else if (funcsType == FuncsTypes.Stress) - { - results.AddRange(GetStressResultFuncs()); - } - else if (funcsType == FuncsTypes.Forces) - { - results.AddRange(GetForcesResultFuncs()); - } - else if (funcsType == FuncsTypes.Full) - { - results.AddRange(GetStrainResultFuncs()); - results.AddRange(GetStressResultFuncs()); - results.AddRange(GetForcesResultFuncs()); - } - else - { - throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(funcsType)); - } - return results; - } - private static List GetStrainResultFuncs() - { - List resultFuncs = new List(); - resultFuncs.Add(new ResultFunc() { Name = "Total Strain", ResultFunction = stressLogic.GetTotalStrain }); - resultFuncs.Add(new ResultFunc() { Name = "Total Strain with prestrain", ResultFunction = stressLogic.GetTotalStrainWithPrestrain }); - resultFuncs.Add(new ResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain }); - resultFuncs.Add(new ResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain }); - return resultFuncs; - } - private static List GetStressResultFuncs() - { - List resultFuncs = new List(); - resultFuncs.Add(new ResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress, UnitFactor = unitStress.Multiplyer, UnitName = unitStress.Name }); - resultFuncs.Add(new ResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus, UnitFactor = unitStress.Multiplyer, UnitName = unitStress.Name }); - resultFuncs.Add(new ResultFunc() { Name = "Modulus degradation", ResultFunction = stressLogic.GetModulusDegradation }); - return resultFuncs; - } - private static List GetForcesResultFuncs() - { - List resultFuncs = new List(); - resultFuncs.Add(new ResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce, UnitFactor = unitForce.Multiplyer, UnitName = unitForce.Name }); - resultFuncs.Add(new ResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX, UnitFactor = unitMoment.Multiplyer, UnitName = unitMoment.Name }); - resultFuncs.Add(new ResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY, UnitFactor = unitMoment.Multiplyer, UnitName = unitMoment.Name }); - return resultFuncs; - } - } -} diff --git a/StructureHelper/Services/ResultViewers/ShowIsoFieldResult.cs b/StructureHelper/Services/ResultViewers/ShowIsoFieldResult.cs index 035fc76..67f3170 100644 --- a/StructureHelper/Services/ResultViewers/ShowIsoFieldResult.cs +++ b/StructureHelper/Services/ResultViewers/ShowIsoFieldResult.cs @@ -4,6 +4,9 @@ using LoaderCalculator.Data.Matrix; using LoaderCalculator.Data.Ndms; using LoaderCalculator.Data.ResultData; using LoaderCalculator.Logics; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperLogics.NdmCalculations.Cracking; +using StructureHelperLogics.NdmCalculations.Triangulations; using System; using System.Collections.Generic; using System.Linq; @@ -14,13 +17,13 @@ namespace StructureHelper.Services.ResultViewers { public static class ShowIsoFieldResult { - public static void ShowResult(IStrainMatrix strainMatrix, IEnumerable ndms, IEnumerable resultFuncs) + public static void ShowResult(IStrainMatrix strainMatrix, IEnumerable ndms, IEnumerable resultFuncs) { var primitiveSets = GetPrimitiveSets(strainMatrix, ndms, resultFuncs); FieldViewerOperation.ShowViewer(primitiveSets); } - public static List GetPrimitiveSets(IStrainMatrix strainMatrix, IEnumerable ndms, IEnumerable resultFuncs) + public static List GetPrimitiveSets(IStrainMatrix strainMatrix, IEnumerable ndms, IEnumerable resultFuncs) { List primitiveSets = new List(); foreach (var valDelegate in resultFuncs) @@ -29,23 +32,81 @@ namespace StructureHelper.Services.ResultViewers List primitives = new List(); foreach (INdm ndm in ndms) { - double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm) * valDelegate.UnitFactor; - IValuePrimitive valuePrimitive; - if (ndm is IRectangleNdm) - { - var shapeNdm = ndm as IRectangleNdm; - valuePrimitive = new RectanglePrimitive() { CenterX = ndm.CenterX, CenterY = ndm.CenterY, Height = shapeNdm.Height, Width = shapeNdm.Width, Value = val }; - } - else - { - valuePrimitive = new CirclePrimitive() { CenterX = ndm.CenterX, CenterY = ndm.CenterY, Diameter = Math.Sqrt(ndm.Area / Math.PI) * 2, Value = val }; - } - primitives.Add(valuePrimitive); + primitives.Add(ProcessNdm(strainMatrix, valDelegate, ndm)); } primitiveSet.ValuePrimitives = primitives; primitiveSets.Add(primitiveSet); } return primitiveSets; } + + public static List GetPrimitiveSets(IEnumerable rebarResults, IEnumerable resultFuncs) + { + List primitiveSets = new List(); + foreach (var valDelegate in resultFuncs) + { + PrimitiveSet primitiveSet = new PrimitiveSet() { Name = valDelegate.Name }; + List primitives = new List(); + foreach (var rebarResult in rebarResults) + { + primitives.Add(ProcessNdm(valDelegate, rebarResult)); + } + primitiveSet.ValuePrimitives = primitives; + primitiveSets.Add(primitiveSet); + } + return primitiveSets; + } + + private static IValuePrimitive ProcessNdm(CrackResultFunc valDelegate, RebarCrackResult rebarResult) + { + var val = valDelegate.ResultFunction.Invoke(rebarResult) * valDelegate.UnitFactor; + IValuePrimitive valuePrimitive; + var rebarNdm = rebarResult.RebarPrimitive.GetRebarNdm(new TriangulationOptions() + { + LimiteState = LimitStates.SLS, + CalcTerm = CalcTerms.ShortTerm + } + ); + valuePrimitive = ProcessCircle(rebarNdm, val); + return valuePrimitive; + } + + private static IValuePrimitive ProcessNdm(IStrainMatrix strainMatrix, ForceResultFunc valDelegate, INdm ndm) + { + double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm) * valDelegate.UnitFactor; + IValuePrimitive valuePrimitive; + if (ndm is IRectangleNdm shapeNdm) + { + valuePrimitive = ProcessRectangle(shapeNdm, val); + } + else + { + valuePrimitive = ProcessCircle(ndm, val); + } + return valuePrimitive; + } + + private static IValuePrimitive ProcessRectangle(IRectangleNdm shapeNdm, double val) + { + return new RectanglePrimitive() + { + CenterX = shapeNdm.CenterX, + CenterY = shapeNdm.CenterY, + Height = shapeNdm.Height, + Width = shapeNdm.Width, + Value = val + }; + } + + private static IValuePrimitive ProcessCircle(INdm ndm, double val) + { + return new CirclePrimitive() + { + CenterX = ndm.CenterX, + CenterY = ndm.CenterY, + Diameter = Math.Sqrt(ndm.Area / Math.PI) * 2, + Value = val + }; + } } } diff --git a/StructureHelper/StructureHelper.csproj.user b/StructureHelper/StructureHelper.csproj.user index a12f03f..c2ddce4 100644 --- a/StructureHelper/StructureHelper.csproj.user +++ b/StructureHelper/StructureHelper.csproj.user @@ -77,6 +77,9 @@ + + Designer + Designer @@ -92,6 +95,9 @@ Designer + + Designer + Designer @@ -101,6 +107,9 @@ Designer + + Designer + Designer diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml index 1577c78..c4abe14 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/CrackResultView.xaml @@ -6,11 +6,18 @@ xmlns:local="clr-namespace:StructureHelper.Windows.CalculationWindows.CalculatorsViews" 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"> + Title="Result of calculations of crack" Height="450" Width="800" MinHeight="300" MinWidth="600" MaxHeight="800" MaxWidth="1000" WindowStartupLocation="CenterScreen"> + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs index d3d78a9..042665c 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultView.xaml.cs @@ -1,4 +1,5 @@ -using System; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -19,9 +20,16 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews /// public partial class TupleCrackResultView : Window { - public TupleCrackResultView() + TupleCrackResultViewModel viewModel; + public TupleCrackResultView(TupleCrackResultViewModel viewModel) { InitializeComponent(); + this.viewModel = viewModel; + DataContext = this.viewModel; + } + public TupleCrackResultView(TupleCrackResult crackResult) : this(new TupleCrackResultViewModel(crackResult)) + { + } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs index 8d6bef2..cbb3f51 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/Cracks/TupleCrackResultViewModel.cs @@ -1,12 +1,45 @@ -using System; +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.Ndms; +using StructureHelper.Infrastructure; +using StructureHelper.Services.Reports.CalculationReports; +using StructureHelper.Services.ResultViewers; +using StructureHelper.Windows.Errors; +using StructureHelper.Windows.ViewModels.Errors; +using StructureHelperLogics.NdmCalculations.Cracking; +using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; +using System.Windows.Input; namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews { - public class TupleCrackResultViewModel + public class TupleCrackResultViewModel : ViewModelBase { + IShowCrackIsoFieldsLogic showCrackIsoFieldsLogic => new ShowCrackIsoFieldsLogic(); + private TupleCrackResult crackResult; + private RelayCommand showIsoFieldCommand; + private IsoFieldReport isoFieldReport; + + public TupleCrackResult CrackResult => crackResult; + public List RebarResults => crackResult.RebarResults; + public RebarCrackResult SelectedResult { get; set; } + public ICommand ShowIsoFieldCommand + { + get + { + return showIsoFieldCommand ??= new RelayCommand(o => + { + showCrackIsoFieldsLogic.ShowIsoField(crackResult.RebarResults); + }); + } + } + public TupleCrackResultViewModel(TupleCrackResult crackResult) + { + this.crackResult = crackResult; + } } } diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs index 19c324a..54eccf4 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ShowCrackWidthLogic.cs @@ -24,7 +24,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu //LimitState = LimitState, //CalcTerm = CalcTerm, LongTermTuple = ForceTuple, - NdmPrimitives = ndmPrimitives + Primitives = ndmPrimitives }; var calculator = new TupleCrackCalculator() { InputData = inputData }; calculator.Run(); diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs index 950c5b5..b08bb5c 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceResultLogic/ValuePointDiagramLogic.cs @@ -22,7 +22,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu private List<(INamedAreaPoint areaPoint, INdmPrimitive ndmPrimitive)> pointCollection; private List validTuplesList; private ArrayParameter arrayOfValuesByPoint; - private IEnumerable selectedDelegates; + private IEnumerable selectedDelegates; private string exceptionMessage; public IEnumerable TupleList { get; set; } @@ -154,7 +154,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu + userPrestrain.Nz + autoPrestrain.Nz; return ndm; } - private List GetValueLabels(IEnumerable selectedDelegates) + private List GetValueLabels(IEnumerable selectedDelegates) { List strings = new(); foreach (var valuePoint in pointCollection) diff --git a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs index 1264d96..1191a0a 100644 --- a/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs +++ b/StructureHelper/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForcesResultsViewModel.cs @@ -416,7 +416,7 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu try { IStrainMatrix strainMatrix = SelectedResult.LoaderResults.ForceStrainPair.StrainMatrix; - var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ResultFuncFactory.GetResultFuncs()); + var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ForceResultFuncFactory.GetResultFuncs()); isoFieldReport = new IsoFieldReport(primitiveSets); isoFieldReport.Show(); } @@ -429,7 +429,6 @@ namespace StructureHelper.Windows.CalculationWindows.CalculatorsViews.ForceCalcu }; new ErrorMessage(vm).ShowDialog(); } - } private void GetNdms() { diff --git a/StructureHelper/Windows/Forces/ValueDelegatesLogic.cs b/StructureHelper/Windows/Forces/ValueDelegatesLogic.cs index 0307821..d85b6f0 100644 --- a/StructureHelper/Windows/Forces/ValueDelegatesLogic.cs +++ b/StructureHelper/Windows/Forces/ValueDelegatesLogic.cs @@ -11,13 +11,13 @@ namespace StructureHelper.Windows.Forces { public class ValueDelegatesLogic : ViewModelBase { - private readonly List resultFuncs; - public SelectItemsVM ResultFuncs { get; } + private readonly List resultFuncs; + public SelectItemsVM ResultFuncs { get; } public ValueDelegatesLogic() { - resultFuncs = new List(); - resultFuncs.AddRange(ResultFuncFactory.GetResultFuncs(FuncsTypes.Full)); - ResultFuncs = new SelectItemsVM(resultFuncs) + resultFuncs = new List(); + resultFuncs.AddRange(ForceResultFuncFactory.GetResultFuncs(FuncsTypes.Full)); + ResultFuncs = new SelectItemsVM(resultFuncs) { ShowButtons = true }; diff --git a/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs b/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs index 1145ff7..5bafcf7 100644 --- a/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs +++ b/StructureHelper/Windows/ViewModels/Calculations/CalculationResult/CalculationResultViewModel.cs @@ -55,7 +55,7 @@ namespace StructureHelper.Windows.ViewModels.Calculations.CalculationResult private void ShowIsoField() { IStrainMatrix strainMatrix = SelectedResult.LoaderResults.ForceStrainPair.StrainMatrix; - var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ResultFuncFactory.GetResultFuncs()); + var primitiveSets = ShowIsoFieldResult.GetPrimitiveSets(strainMatrix, ndms, ForceResultFuncFactory.GetResultFuncs()); isoFieldReport = new IsoFieldReport(primitiveSets); isoFieldReport.Show(); } diff --git a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs index cb8e637..b4c206f 100644 --- a/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs +++ b/StructureHelper/Windows/ViewModels/NdmCrossSections/AnalysisViewModelLogic.cs @@ -184,7 +184,6 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections } if (SelectedItem is LimitCurvesCalculator calculator) { - var inputData = calculator.InputData; ShowInteractionDiagramByInputData(calculator); } else @@ -193,7 +192,13 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections var result = SelectedItem.Result; if (result.IsValid == false) { - MessageBox.Show(result.Description, "Check data for analisys", MessageBoxButtons.OK, MessageBoxIcon.Warning); + var vm = new ErrorProcessor() + { + ShortText = "Errors apearred during calculations, see detailed information", + DetailText = SelectedItem.Result.Description + }; + new ErrorMessage(vm).ShowDialog(); + return; } else { diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs new file mode 100644 index 0000000..5cf6ab5 --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICheckInputDataLogic.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + public interface ICheckInputDataLogic : ICheckLogic + { + IInputData InputData { get; set; } + } +} diff --git a/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs b/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs new file mode 100644 index 0000000..dbefc5f --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Interfaces/ICheckLogic.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Interfaces +{ + public interface ICheckLogic : ILogic + { + string CheckResult { get; } + bool Check(); + } +} diff --git a/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs b/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs index fc07e65..8031064 100644 --- a/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs +++ b/StructureHelperCommon/Models/Materials/ConcreteCurveLogic.cs @@ -33,8 +33,16 @@ namespace StructureHelperCommon.Models.Materials { GetLoaderOptions(); IBuilderDirector director = GetMaterialDirector(); - var material = director.BuildMaterial(); - return material; + try + { + var material = director.BuildMaterial(); + return material; + } + catch (System.Exception) + { + + throw; + } } private IBuilderDirector GetMaterialDirector() diff --git a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs index f66f3aa..ac246ee 100644 --- a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs +++ b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs @@ -30,8 +30,17 @@ namespace StructureHelperCommon.Models.Materials { GetLoaderOptions(); IBuilderDirector director = GetMaterialDirector(); - var material = director.BuildMaterial(); - return material; + try + { + var material = director.BuildMaterial(); + return material; + } + catch (System.Exception) + { + + throw; + } + } private IBuilderDirector GetMaterialDirector() @@ -45,7 +54,7 @@ namespace StructureHelperCommon.Models.Materials { materialOptions = new ReinforcementOptions() { - DiagramType = DiagramType + DiagramType = DiagramType, }; optionLogic = new MaterialCommonOptionLogic(options); optionLogic.SetMaterialOptions(materialOptions); diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs index e160803..b463e6d 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/LimitCurve/LimitCurveLogic.cs @@ -60,14 +60,16 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces private void MultiThreadProc(IEnumerable points) { Task[] tasks = new Task[points.Count()]; - for (int i = 0; i < points.Count(); i++) + int pointCount = points.Count(); + List PointList = points.ToList(); + for (int i = 0; i < pointCount; i++) { - var point = points.ToList()[i]; + var point = PointList[i]; tasks[i] = new Task(() => FindResultPoint(point)); tasks[i].Start(); } Task.WaitAll(tasks); - for (int j = 0; j < points.Count(); j++) + for (int j = 0; j < pointCount; j++) { var taskResult = tasks[j].Result; resultList.Add(taskResult); diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs index 0a412a5..63295aa 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/Logics/ForceTupleTraceResultLogic.cs @@ -50,7 +50,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces Point2D minPoint = new(), maxPoint = new(); foreach (var item in ndmCollection) { - var strain = stressLogic.GetTotalStrain(strainMatrix, item); + var strain = stressLogic.GetSectionStrain(strainMatrix, item); if (strain < minStrain) { minStrain = strain; diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs index 8f0a361..88884c6 100644 --- a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs @@ -205,7 +205,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling var stressLogic = new StressLogic(); foreach (var item in ndmCollection) { - var strain = stressLogic.GetTotalStrain(strains, item); + var strain = stressLogic.GetSectionStrain(strains, item); if (strain > maxStrain) { maxStrain = strain; diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs new file mode 100644 index 0000000..676ed3e --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Cracking/CheckCrackCalculatorInputDataLogic.cs @@ -0,0 +1,119 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Materials; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Cracking +{ + /// + /// Logic of checking of input data for crack calcultor + /// + public class CheckCrackCalculatorInputDataLogic : ICheckInputDataLogic + { + private string checkResult; + private CrackInputData inputData; + private bool result; + + public IInputData InputData + { + get => inputData; + set + { + if (value is CrackInputData data) + { + inputData = data; + } + else + { + throw new StructureHelperException(ErrorStrings.ExpectedWas(typeof(CrackInputData), value)); + } + } + } + + public string CheckResult => checkResult; + + public IShiftTraceLogger? TraceLogger { get; set; } + public CheckCrackCalculatorInputDataLogic(CrackInputData inputData) + { + this.inputData = inputData; + } + public bool Check() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Debug); + result = true; + checkResult = string.Empty; + CheckPrimitives(); + CheckActions(); + return result; + } + + private void CheckActions() + { + if (inputData.ForceActions is null || (!inputData.ForceActions.Any())) + { + result = false; + string message = "Calculator does not contain any actions\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + }; + } + + private void CheckPrimitives() + { + if (inputData.Primitives is null || (!inputData.Primitives.Any())) + { + result = false; + string message = "Calculator does not contain any primitives\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + else + { + foreach (var primitive in inputData.Primitives) + { + if (primitive is RebarPrimitive rebar) + { + CheckRebar(rebar); + } + } + } + } + + private void CheckRebar(RebarPrimitive rebar) + { + if (rebar.HostPrimitive is null) + { + result = false; + string message = $"Primitive {rebar.Name} does not have a host\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + else + { + bool isPrimitivesContainRebarHost = inputData.Primitives.Contains(rebar.HostPrimitive); + if (isPrimitivesContainRebarHost == false) + { + result = false; + string message = $"Host {rebar.Name}({rebar.HostPrimitive.Name}) is not included in primitives\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + } + if (rebar.HostPrimitive.HeadMaterial.HelperMaterial is not ICrackedMaterial) + { + result = false; + string message = $"Material of host of {rebar.Name} does not support cracking\n"; + checkResult += message; + TraceLogger?.AddMessage(message, TraceLogStatuses.Error); + } + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs index a024b92..b1d416f 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackCalculator.cs @@ -23,6 +23,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking private CrackResult result; private IGetTupleInputDatasLogic datasLogic; private CrackCalculatorUpdateStrategy updateStrategy = new(); + private ICheckInputDataLogic checkInputDataLogic; public string Name { get; set; } public CrackInputData InputData { get; set; } @@ -44,6 +45,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking public void Run() { PrepareNewResult(); + CheckInputData(); TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); try { @@ -58,6 +60,19 @@ namespace StructureHelperLogics.NdmCalculations.Cracking } } + private void CheckInputData() + { + checkInputDataLogic = new CheckCrackCalculatorInputDataLogic(InputData) + { + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + if (checkInputDataLogic.Check() == false) + { + result.IsValid = false; + result.Description += checkInputDataLogic.CheckResult; + } + } + private void ProcessCalculations() { datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions, InputData.UserCrackInputData) diff --git a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs index 5052ce0..3e00cb6 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/CrackWidthLogicSP63.cs @@ -35,7 +35,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking TraceLogger?.AddMessage($"Rebar elongation Epsilon = {inputData.RebarStrain} - {inputData.ConcreteStrain} = {rebarElongation}(dimensionless)"); double width = rebarElongation * inputData.Length; width *= inputData.TermFactor * inputData.BondFactor * inputData.StressStateFactor * inputData.PsiSFactor; - TraceLogger?.AddMessage($"Width of crack a,crc = {width}(m)"); + TraceLogger?.AddMessage($"Width of crack a,crc = {inputData.TermFactor} * {inputData.BondFactor} * {inputData.StressStateFactor} * {inputData.PsiSFactor} * {rebarElongation} * {inputData.Length}(m) = {width}(m)"); return width; } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs index 097ad9b..82c15a2 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/GetTupleInputDatasLogic.cs @@ -52,9 +52,10 @@ namespace StructureHelperLogics.NdmCalculations.Cracking resultList.Add(new TupleCrackInputData() { IsValid = true, + TupleName = action.Name, LongTermTuple = tuple.LongTuple, ShortTermTuple = tuple.ShortTuple, - NdmPrimitives = Primitives, + Primitives = Primitives, UserCrackInputData = UserCrackInputData }); } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs index 7404778..19cdf81 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/ICrackWidthTupleResult.cs @@ -2,6 +2,9 @@ { public interface ICrackWidthTupleResult { + /// + /// Calculated crack width + /// double CrackWidth { get; set; } bool IsCrackLessThanUltimate { get; } double UltimateCrackWidth { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs index 34c5bf5..99d185f 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/LengthBetweenCracksLogicSP63.cs @@ -106,7 +106,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking private double GetAverageDiameter(IEnumerable rebars) { var tesileRebars = rebars - .Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d); + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); diameterLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); diameterLogic.Rebars = tesileRebars; var rebarDiameter = diameterLogic.GetAverageDiameter(); diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs index c3eb9bc..74a6548 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarCrackResult.cs @@ -8,12 +8,26 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { + /// + /// Result of calculation of crack for specific result + /// public class RebarCrackResult : IResult { + /// public bool IsValid { get; set; } + /// public string Description { get; set; } + /// + /// Specific rebar primitive + /// public RebarPrimitive RebarPrimitive { get; set; } + /// + /// Result of calculation of crack for long term + /// public CrackWidthRebarTupleResult LongTermResult { get; set; } + /// + /// Result of calculation of crack for short term + /// public CrackWidthRebarTupleResult ShortTermResult { get; set; } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs index 86dc758..aca6206 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressCalculator.cs @@ -62,7 +62,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking public void Run() { - GetNdms(); + GetNdmCollectionFromPrimitives(); result = new RebarStressResult() { IsValid = true, @@ -71,13 +71,13 @@ namespace StructureHelperLogics.NdmCalculations.Cracking var strainTuple = GetStrainTuple(); result.StrainTuple = strainTuple; var strainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(strainTuple); - result.RebarStrain = stressLogic.GetTotalStrain(strainMatrix, rebarNdm); + result.RebarStrain = stressLogic.GetSectionStrain(strainMatrix, rebarNdm); result.RebarStress = stressLogic.GetStress(strainMatrix, rebarNdm); result.ConcreteStrain = concreteNdm.Prestrain; } - private void GetNdms() + private void GetNdmCollectionFromPrimitives() { var options = new TriangulationOptions() { diff --git a/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs index a6aaf44..c24bac3 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/RebarStressResult.cs @@ -10,7 +10,9 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { public class RebarStressResult : IResult { + /// public bool IsValid { get; set; } + /// public string? Description { get; set; } public StrainTuple StrainTuple { get; set; } public double RebarStress { get; set; } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs index 8436f83..f5a6533 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensileConcreteAreaLogicSP63.cs @@ -29,7 +29,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); var rebarCollection = NdmCollection - .Where(x => x is RebarNdm & stressLogic.GetTotalStrain(StrainMatrix, x) > 0d); + .Where(x => x is RebarNdm & stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); var rebarArea = rebarCollection. Sum(x => x.Area * x.StressScale); TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}"); diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs index 134c75d..8303141 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaByStrainLogic.cs @@ -32,7 +32,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on areas which are proportional by maximum strain"); var rebars = Rebars - .Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d); + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); if (!rebars.Any()) { string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; @@ -40,7 +40,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking throw new StructureHelperException(errorString); } var maxStrain = rebars - .Select(x => stressLogic.GetTotalStrain(StrainMatrix, x)) + .Select(x => stressLogic.GetSectionStrain(StrainMatrix, x)) .Max(); TraceLogger?.AddMessage($"Maximum strain maxStrain = {maxStrain}"); if (TraceLogger is not null) @@ -51,7 +51,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking foreach (var rebar in rebars) { double area = rebar.Area * rebar.StressScale; - double strain = stressLogic.GetTotalStrain(StrainMatrix, rebar); + double strain = stressLogic.GetSectionStrain(StrainMatrix, rebar); TraceLogger?.AddMessage($"Rebar area = {area}(m^2)"); TraceLogger?.AddMessage($"Rebar strain = {strain}"); var reducedArea = area * strain / maxStrain; diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs index a9abe5b..d446c3a 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TensionRebarAreaSimpleSumLogic.cs @@ -11,6 +11,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + namespace StructureHelperLogics.NdmCalculations.Cracking { public class TensionRebarAreaSimpleSumLogic : ITensionRebarAreaLogic @@ -32,7 +35,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on ordinary summarizing of areas"); var rebars = Rebars - .Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d); + .Where(x => stressLogic.GetSectionStrain(StrainMatrix, x) > 0d); if (!rebars.Any()) { string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs index 81d44b3..2563d2a 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackCalculator.cs @@ -1,4 +1,5 @@ using LoaderCalculator.Data.Ndms; +using StructureHelper.Models.Materials; using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Models; @@ -26,6 +27,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking private StrainTuple shortDefaultStrainTuple; private double longLength; private double shortLength; + private object locker = new(); public string Name { get; set; } public TupleCrackInputData InputData { get; set; } @@ -68,6 +70,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { CheckInputData(); Triangulate(); + longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms); shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms); var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms); @@ -85,17 +88,28 @@ namespace StructureHelperLogics.NdmCalculations.Cracking shortLength = GetLengthBetweenCracks(shortElasticStrainTuple); } CalcCrackForce(); - foreach (var rebar in rebarPrimitives) - { - RebarCrackCalculatorInputData rebarCalculatorData = GetRebarCalculatorInputData(rebar); - var calculator = new RebarCrackCalculator + //for (int j = 0; j < 100000; j++) + //{ + result.RebarResults.Clear(); + int rebarCount = rebarPrimitives.Count; + Task[] tasks = new Task[rebarCount]; + for (int i = 0; i < rebarCount; i++) { - InputData = rebarCalculatorData, - TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) - }; - calculator.Run(); - var rebarResult = calculator.Result as RebarCrackResult; - result.RebarResults.Add(rebarResult); + var rebar = rebarPrimitives[i]; + tasks[i] = new Task(() => ProcessRebar(rebar)); + tasks[i].Start(); + } + Task.WaitAll(tasks); + for (int i = 0; i < rebarCount; i++) + { + result.RebarResults.Add(tasks[i].Result); + } + //} + + if (result.RebarResults.Any(x => x.IsValid == false)) + { + result.IsValid = false; + return; } result.LongTermResult = new() { @@ -109,25 +123,50 @@ namespace StructureHelperLogics.NdmCalculations.Cracking }; } + private RebarCrackResult ProcessRebar(RebarPrimitive rebar) + { + RebarCrackCalculatorInputData rebarCalculatorData = GetRebarCalculatorInputData(rebar); + var calculator = new RebarCrackCalculator + { + InputData = rebarCalculatorData, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + calculator.Run(); + var rebarResult = calculator.Result as RebarCrackResult; + return rebarResult; + } + private RebarCrackCalculatorInputData GetRebarCalculatorInputData(RebarPrimitive rebar) { + IEnumerable crackableNdmsLoc = null; + IEnumerable crackedNdmsLoc = null; + RebarPrimitive rebarCopy = null; + lock (locker) + { + rebarCopy = rebar.Clone() as RebarPrimitive; + rebarCopy.HeadMaterial = rebarCopy.HeadMaterial.Clone() as IHeadMaterial; + var triangulationLogicLoc = new CrackedSectionTriangulationLogic(InputData.Primitives); + crackableNdmsLoc = triangulationLogicLoc.GetNdmCollection(); + crackedNdmsLoc = triangulationLogicLoc.GetCrackedNdmCollection(); + } + var longRebarData = new RebarCrackInputData() { - CrackableNdmCollection = crackableNdms, - CrackedNdmCollection = crackedNdms, - ForceTuple = InputData.LongTermTuple as ForceTuple, + CrackableNdmCollection = crackableNdmsLoc, + CrackedNdmCollection = crackedNdmsLoc, + ForceTuple = InputData.LongTermTuple.Clone() as ForceTuple, Length = longLength }; var shortRebarData = new RebarCrackInputData() { CrackableNdmCollection = crackableNdms, CrackedNdmCollection = crackedNdms, - ForceTuple = InputData.ShortTermTuple as ForceTuple, + ForceTuple = InputData.ShortTermTuple.Clone() as ForceTuple, Length = shortLength }; var rebarCalculatorData = new RebarCrackCalculatorInputData() { - RebarPrimitive = rebar, + RebarPrimitive = rebarCopy, LongRebarData = longRebarData, ShortRebarData = shortRebarData, UserCrackInputData = InputData.UserCrackInputData @@ -153,6 +192,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking { result.IsValid = false; result.Description += forceResult.Description; + TraceLogger?.AddMessage("Bearing capacity of cross-section is not enough for action", TraceLogStatuses.Error); + return null; } var strain = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix); return strain; @@ -171,7 +212,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking private void Triangulate() { - triangulationLogic = new CrackedSectionTriangulationLogic(InputData.NdmPrimitives) + triangulationLogic = new CrackedSectionTriangulationLogic(InputData.Primitives) { //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) }; @@ -192,7 +233,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking private void CheckInputData() { - if (InputData.NdmPrimitives is null || InputData.NdmPrimitives.Count == 0) + if (InputData.Primitives is null || InputData.Primitives.Count == 0) { throw new StructureHelperException(ErrorStrings.DataIsInCorrect + ": input data doesn't have any primitives"); } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs index 9e26612..851987f 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackInputData.cs @@ -8,14 +8,32 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + namespace StructureHelperLogics.NdmCalculations.Cracking { - public class TupleCrackInputData : IInputData + /// + /// Input data for calculation of crack for specific force tuple + /// + public class TupleCrackInputData : IInputData, IHasPrimitives { + /// public bool IsValid { get; set; } + public string TupleName { get; set; } + /// + /// Force tuple for long term calculations + /// public IForceTuple? LongTermTuple { get; set; } + /// + /// Force tuple for short term calculations + /// public IForceTuple? ShortTermTuple { get; set; } - public List? NdmPrimitives {get;set;} + /// + public List? Primitives { get; set;} + /// + /// Settings ajusted by user + /// public UserCrackInputData UserCrackInputData { get; set; } } } diff --git a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs index 89e3b0b..6e3ca8b 100644 --- a/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs +++ b/StructureHelperLogics/NdmCalculations/Cracking/TupleCrackResult.cs @@ -6,21 +6,25 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +//Copyright (c) 2024 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + namespace StructureHelperLogics.NdmCalculations.Cracking { + /// + /// Result of crack calculation for specific force tuple + /// public class TupleCrackResult : IResult { + /// public bool IsValid { get; set; } + /// public string Description { get; set; } public TupleCrackInputData InputData { get; set; } public bool IsCracked { get; set; } public List RebarResults { get; private set; } public CrackWidthRebarTupleResult LongTermResult { get; set; } public CrackWidthRebarTupleResult ShortTermResult { get; set; } - //public double MaxLongTermCrackWidth => RebarResults.Select(x => x.LongTermResult.CrackWidth).Max(); - //public double MaxShortTermCrackWidth => RebarResults.Select(x => x.ShortTermResult.CrackWidth).Max(); - //public bool IsLongCrackLessThanUltimate => MaxLongTermCrackWidth <= InputData.UserCrackInputData.UltimateLongCrackWidth; - //public bool IsShortCrackLessThanUltimate => MaxShortTermCrackWidth <= InputData.UserCrackInputData.UltimateShortCrackWidth; public TupleCrackResult() { diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs index 1ecb6ed..8b41179 100644 --- a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionREbarAreaSumLogicTest.cs @@ -26,11 +26,11 @@ namespace StructureHelperTests.UnitTests.Ndms.Cracks }; // Setup the mock to return positive strains - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) .Returns(0.5); - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) .Returns(1.0); - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) .Returns(1.5); var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object) @@ -64,7 +64,7 @@ namespace StructureHelperTests.UnitTests.Ndms.Cracks }; // Setup the mock to return non-positive strain - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.IsAny())) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.IsAny())) .Returns(0.0); var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object) diff --git a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs index 736ebf8..ea12e1d 100644 --- a/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs +++ b/StructureHelperTests/UnitTests/Ndms/Cracks/TensionRebarAreaByStrainLogicTest.cs @@ -29,11 +29,11 @@ namespace StructureHelperTests.UnitTests.Ndms.Cracks }; // Setup the mock to return positive strains - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 1.0))) .Returns(0.5); - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 2.0))) .Returns(1.0); - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.Is(r => r.Area == 3.0))) .Returns(1.5); var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object) @@ -69,7 +69,7 @@ namespace StructureHelperTests.UnitTests.Ndms.Cracks }; // Setup the mock to return non-positive strain - mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny(), It.IsAny())) + mockStressLogic.Setup(s => s.GetSectionStrain(It.IsAny(), It.IsAny())) .Returns(0.0); var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object)