From b81b7a09292c8554067e3e013bcc27985ce64615 Mon Sep 17 00:00:00 2001 From: Evgeny Redikultsev Date: Sun, 10 Mar 2024 19:20:01 +0500 Subject: [PATCH] Logics of accidental eccentricity were separated and tested --- .../Libraries/LoaderCalculator.dll | Bin 86016 -> 86016 bytes .../PublishProfiles/FolderProfile.pubxml.user | 2 +- .../Models/Calculators/GenericResult.cs | 15 ++ .../Materials/ConcreteMaterialOptionLogic.cs | 6 +- .../Libraries/Factories/LibMaterialFactory.cs | 2 +- .../Materials/MaterialCommonOptionLogic.cs | 75 ++++++-- .../Materials/ReinforcementByBuilderLogic.cs | 5 +- .../Logics/AccidentalEccentricityLogic.cs | 90 ---------- .../Sections/Logics/ForceTupleCopier.cs | 23 +++ .../Logics/ForceTupleMoveToPointDecorator.cs | 32 ++++ .../Logics/IAccidentalEccentricityLogic.cs | 38 ---- .../Models/Sections/Logics/IHasInputForce.cs | 17 ++ .../Sections/Logics/IProcessorDecorator.cs | 14 ++ .../Models/Sections/Logics/IProcessorLogic.cs | 22 +++ .../Logics/IRcAccEccentricityLogic.cs | 12 ++ .../Logics/IRcEccentricityAxisLogic.cs | 8 + .../Sections/Logics/RcAccEccentricityLogic.cs | 54 ++++++ .../Logics/RcEccentricityAxisLogic.cs | 57 ++++++ .../Sections/Logics/RcEccentricityLogic.cs | 100 +++++++++++ .../Services/Forces/ForceTupleService.cs | 7 - .../Analyses/ByForces/ForceCalculator.cs | 164 +++++------------- .../Buckling/ConcreteBucklingCalculator.cs | 121 +++++++------ .../Buckling/ForceTupleBucklingLogic.cs | 136 +++++++++++++++ .../Buckling/IForceTupleBucklingLogic.cs | 13 ++ .../Buckling/ProcessEccentricity.cs | 57 ++++++ .../RcAccEccentricityAxisTest.cs | 39 +++++ .../Eccentricitis/RcAccEccentricityTest.cs | 43 +++++ .../Eccentricitis/RcEccentricityLogicTest.cs | 58 +++++++ .../MaterialTests/MaterialStrengthTest.cs | 4 +- .../ViewModelTests/GraphViewModelTest.cs | 2 +- 30 files changed, 885 insertions(+), 331 deletions(-) create mode 100644 StructureHelperCommon/Models/Calculators/GenericResult.cs delete mode 100644 StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs delete mode 100644 StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs create mode 100644 StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs create mode 100644 StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs create mode 100644 StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs create mode 100644 StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs diff --git a/StructureHelper/Libraries/LoaderCalculator.dll b/StructureHelper/Libraries/LoaderCalculator.dll index 7a3289fa0f054162f36e6b065bb2fb231ec10756..cdc1bd5ecae456967ae8d73def90b97860779a03 100644 GIT binary patch delta 29276 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 delta 29333 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 diff --git a/StructureHelper/Properties/PublishProfiles/FolderProfile.pubxml.user b/StructureHelper/Properties/PublishProfiles/FolderProfile.pubxml.user index 7cc792e..3948670 100644 --- a/StructureHelper/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/StructureHelper/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - True|2024-02-02T07:22:50.1454015Z;True|2023-02-25T13:37:39.2738786+05:00;False|2023-02-25T13:37:24.0284261+05:00;True|2023-02-25T13:34:01.6858860+05:00;True|2023-02-25T13:31:18.8295711+05:00;False|2023-02-25T13:25:21.5807199+05:00;False|2023-02-25T13:24:41.7164398+05:00; + True|2024-03-10T14:11:27.6834663Z;True|2024-02-02T12:22:50.1454015+05:00;True|2023-02-25T13:37:39.2738786+05:00;False|2023-02-25T13:37:24.0284261+05:00;True|2023-02-25T13:34:01.6858860+05:00;True|2023-02-25T13:31:18.8295711+05:00;False|2023-02-25T13:25:21.5807199+05:00;False|2023-02-25T13:24:41.7164398+05:00; \ No newline at end of file diff --git a/StructureHelperCommon/Models/Calculators/GenericResult.cs b/StructureHelperCommon/Models/Calculators/GenericResult.cs new file mode 100644 index 0000000..c03c6d6 --- /dev/null +++ b/StructureHelperCommon/Models/Calculators/GenericResult.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Calculators +{ + public class GenericResult : IResult + { + public bool IsValid { get; set; } + public string? Description { get; set; } + public T? Value { get; set; } + } +} diff --git a/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs b/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs index 69016d0..d1786ea 100644 --- a/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs +++ b/StructureHelperCommon/Models/Materials/ConcreteMaterialOptionLogic.cs @@ -16,7 +16,7 @@ namespace StructureHelperCommon.Models.Materials { private ConcreteLogicOptions options; private MaterialCommonOptionLogic optionLogic; - private FactorLogic factorLogic; + public ConcreteMaterialOptionLogic(ConcreteLogicOptions options) { @@ -32,10 +32,6 @@ namespace StructureHelperCommon.Models.Materials var concreteOptions = materialOptions as ConcreteOptions; optionLogic = new MaterialCommonOptionLogic(options); optionLogic.SetMaterialOptions(concreteOptions); - factorLogic = new FactorLogic(options.SafetyFactors); - var strength = factorLogic.GetTotalFactor(options.LimitState, options.CalcTerm); - concreteOptions.ExternalFactor.Compressive = strength.Compressive; - concreteOptions.ExternalFactor.Tensile = strength.Tensile; concreteOptions.WorkInTension = options.WorkInTension; concreteOptions.RelativeHumidity = options.RelativeHumidity; concreteOptions.Age = options.Age; diff --git a/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs b/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs index c85cb09..1f31608 100644 --- a/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs +++ b/StructureHelperCommon/Models/Materials/Libraries/Factories/LibMaterialFactory.cs @@ -240,7 +240,7 @@ namespace StructureHelperCommon.Models.Materials.Libraries Code = code, Name = "A400", InitModulus = 2e11d, - MainStrength = 400e6d + MainStrength = 390e6d }, new ReinforcementMaterialEntity(new Guid("045b54b1-0bbf-41fd-a27d-aeb20f600bb4")) { diff --git a/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs b/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs index 80097e1..f5b1f7d 100644 --- a/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs +++ b/StructureHelperCommon/Models/Materials/MaterialCommonOptionLogic.cs @@ -1,12 +1,16 @@ -using StructureHelperCommon.Infrastructures.Enums; +using LoaderCalculator.Data.Materials.MaterialBuilders; +using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Materials.Libraries; using LCMB = LoaderCalculator.Data.Materials.MaterialBuilders; +using SHEnums = StructureHelperCommon.Infrastructures.Enums; namespace StructureHelperCommon.Models.Materials { public class MaterialCommonOptionLogic : IMaterialOptionLogic { private IMaterialLogicOptions options; + private FactorLogic factorLogic; public MaterialCommonOptionLogic(IMaterialLogicOptions options) { @@ -17,6 +21,58 @@ namespace StructureHelperCommon.Models.Materials { materialOptions.InitModulus = options.MaterialEntity.InitModulus; materialOptions.Strength = options.MaterialEntity.MainStrength; + ProcessCodeType(materialOptions); + ProcessLimitState(materialOptions); + ProcessCalcTerm(materialOptions); + ProcessExternalFactors(materialOptions); + } + + private void ProcessExternalFactors(IMaterialOptions materialOptions) + { + factorLogic = new FactorLogic(options.SafetyFactors); + var strength = factorLogic.GetTotalFactor(options.LimitState, options.CalcTerm); + materialOptions.ExternalFactor.Compressive = strength.Compressive; + materialOptions.ExternalFactor.Tensile = strength.Tensile; + } + + private void ProcessCalcTerm(IMaterialOptions materialOptions) + { + if (options.CalcTerm == CalcTerms.ShortTerm) + { + materialOptions.IsShortTerm = true; + } + else if (options.CalcTerm == CalcTerms.LongTerm) + { + materialOptions.IsShortTerm = false; + } + else + { + throw new StructureHelperException(ErrorStrings.LoadTermIsNotValid); + } + } + + private void ProcessLimitState(IMaterialOptions materialOptions) + { + if (options.LimitState == SHEnums.LimitStates.ULS) + { + materialOptions.LimitState = LCMB.LimitStates.Collapse; + } + else if (options.LimitState == SHEnums.LimitStates.SLS) + { + materialOptions.LimitState = LCMB.LimitStates.ServiceAbility; + } + else if (options.LimitState == SHEnums.LimitStates.Special) + { + materialOptions.LimitState = LCMB.LimitStates.Special; + } + else + { + throw new StructureHelperException(ErrorStrings.LimitStatesIsNotValid); + } + } + + private void ProcessCodeType(IMaterialOptions materialOptions) + { if (options.MaterialEntity.CodeType == CodeTypes.EuroCode_2_1990) { materialOptions.CodesType = LCMB.CodesType.EC2_1990; @@ -25,23 +81,10 @@ namespace StructureHelperCommon.Models.Materials { materialOptions.CodesType = LCMB.CodesType.SP63_2018; } - else { throw new StructureHelperException($"{ErrorStrings.ObjectTypeIsUnknown} : {materialOptions.CodesType}"); } - if (options.LimitState == LimitStates.ULS) + else { - materialOptions.LimitState = LCMB.LimitStates.Collapse; + throw new StructureHelperException($"{ErrorStrings.ObjectTypeIsUnknown} : {materialOptions.CodesType}"); } - else if (options.LimitState == LimitStates.SLS) - { - materialOptions.LimitState = LCMB.LimitStates.ServiceAbility; - } - else if (options.LimitState == LimitStates.Special) - { - materialOptions.LimitState = LCMB.LimitStates.Special; - } - else { throw new StructureHelperException(ErrorStrings.LimitStatesIsNotValid); } - if (options.CalcTerm == CalcTerms.ShortTerm) { materialOptions.IsShortTerm = true; } - else if (options.CalcTerm == CalcTerms.LongTerm) { materialOptions.IsShortTerm = false; } - else { throw new StructureHelperException(ErrorStrings.LoadTermIsNotValid); } } } } diff --git a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs index 6104cdd..f66f3aa 100644 --- a/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs +++ b/StructureHelperCommon/Models/Materials/ReinforcementByBuilderLogic.cs @@ -43,7 +43,10 @@ namespace StructureHelperCommon.Models.Materials private void GetLoaderOptions() { - materialOptions = new ReinforcementOptions() { DiagramType = DiagramType}; + materialOptions = new ReinforcementOptions() + { + DiagramType = DiagramType + }; optionLogic = new MaterialCommonOptionLogic(options); optionLogic.SetMaterialOptions(materialOptions); } diff --git a/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs deleted file mode 100644 index f90df30..0000000 --- a/StructureHelperCommon/Models/Sections/Logics/AccidentalEccentricityLogic.cs +++ /dev/null @@ -1,90 +0,0 @@ -using StructureHelperCommon.Models.Forces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia -//All rights reserved. - -namespace StructureHelperCommon.Models.Sections -{ - public class AccidentalEccentricityLogic : IAccidentalEccentricityLogic - { - private double lengthFactor; - private double sizeFactor; - private double minEccentricity; - - public double Length { get; set; } - public double SizeX { get; set; } - public double SizeY { get; set; } - public IForceTuple InitialForceTuple { get; set; } - public IShiftTraceLogger? TraceLogger { get; set; } - public AccidentalEccentricityLogic() - { - lengthFactor = 600d; - sizeFactor = 30d; - minEccentricity = 0.01d; - } - public ForceTuple GetForceTuple() - { - var lengthEccetricity = Length / lengthFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by length ea = {0} / {1} = {2}", Length, lengthFactor, lengthEccetricity)); - var sizeXEccetricity = SizeX / sizeFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by SizeX ea ={0} / {1} = {2}", SizeX, sizeFactor, sizeXEccetricity)); - var sizeYEccetricity = SizeY / sizeFactor; - TraceLogger?.AddMessage(string.Format("Accidental eccentricity by SizeY ea ={0} / {1} = {2}", SizeY, sizeFactor, sizeYEccetricity)); - TraceLogger?.AddMessage(string.Format("Minimum accidental eccentricity ea = {0}", minEccentricity)); - var xEccentricity = Math.Abs(InitialForceTuple.My / InitialForceTuple.Nz); - TraceLogger?.AddMessage(string.Format("Actual eccentricity e0,x = {0}", xEccentricity)); - var yEccentricity = Math.Abs(InitialForceTuple.Mx / InitialForceTuple.Nz); - TraceLogger?.AddMessage(string.Format("Actual eccentricity e0,y = {0}", yEccentricity)); - - var xFullEccentricity = new List() - { - lengthEccetricity, - sizeXEccetricity, - minEccentricity, - xEccentricity - } - .Max(); - string mesEx = string.Format("Eccentricity e,x = max({0}; {1}; {2}; {3}) = {4}", - lengthEccetricity, sizeXEccetricity, - minEccentricity, xEccentricity, - xFullEccentricity); - TraceLogger?.AddMessage(mesEx); - var yFullEccentricity = new List() - { - lengthEccetricity, - sizeYEccetricity, - minEccentricity, - yEccentricity - } - .Max(); - string mesEy = string.Format("Eccentricity e,y = max({0}; {1}; {2}; {3}) = {4}", - lengthEccetricity, sizeYEccetricity, - minEccentricity, yEccentricity, - yFullEccentricity); - TraceLogger?.AddMessage(mesEy); - var xSign = InitialForceTuple.Mx == 0d ? -1d : Math.Sign(InitialForceTuple.Mx); - var ySign = InitialForceTuple.My == 0d ? -1d : Math.Sign(InitialForceTuple.My); - var mx = (-1d) * InitialForceTuple.Nz * yFullEccentricity * xSign; - var my = (-1d) * InitialForceTuple.Nz * xFullEccentricity * ySign; - TraceLogger?.AddMessage(string.Format("Bending moment arbitrary X-axis Mx = {0} * {1} = {2}", InitialForceTuple.Nz, yFullEccentricity, mx), TraceLogStatuses.Debug); - TraceLogger?.AddMessage(string.Format("Bending moment arbitrary Y-axis My = {0} * {1} = {2}", InitialForceTuple.Nz, xFullEccentricity, my), TraceLogStatuses.Debug); - - var newTuple = new ForceTuple() - { - Mx = mx, - My = my, - Nz = InitialForceTuple.Nz, - Qx = InitialForceTuple.Qx, - Qy = InitialForceTuple.Qy, - Mz = InitialForceTuple.Mz, - }; - TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); - return newTuple; - } - } -} diff --git a/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs b/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs new file mode 100644 index 0000000..d57fbdf --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/ForceTupleCopier.cs @@ -0,0 +1,23 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class ForceTupleCopier : IProcessorLogic + { + public IForceTuple InputForceTuple { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public ForceTupleCopier(IForceTuple forceTuple) + { + InputForceTuple = forceTuple; + } + public IForceTuple GetValue() + { + return InputForceTuple.Clone() as IForceTuple; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs b/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs new file mode 100644 index 0000000..eaf8c73 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/ForceTupleMoveToPointDecorator.cs @@ -0,0 +1,32 @@ +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Shapes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class ForceTupleMoveToPointDecorator : IProcessorDecorator + { + public IPoint2D Point2D { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + /// + /// Internal source of ForceTuple + /// + public IProcessorLogic ForceTupleLogics { get; } + public ForceTupleMoveToPointDecorator(IProcessorLogic procLogic) + { + ForceTupleLogics = procLogic; + } + public IForceTuple GetValue() + { + ForceTupleLogics.TraceLogger = TraceLogger; + var newTuple = ForceTupleLogics.GetValue(); + newTuple.Mx += newTuple.Nz * Point2D.Y; + newTuple.My -= newTuple.Nz * Point2D.X; + return newTuple; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs deleted file mode 100644 index 27c9d2c..0000000 --- a/StructureHelperCommon/Models/Sections/Logics/IAccidentalEccentricityLogic.cs +++ /dev/null @@ -1,38 +0,0 @@ -using StructureHelperCommon.Infrastructures.Interfaces; -using StructureHelperCommon.Models.Forces; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StructureHelperCommon.Models.Sections -{ - /// - /// Logic for calculating of value of accidental eccentricity - /// - public interface IAccidentalEccentricityLogic : ILogic - { - /// - /// Properties of compressed member - /// - double Length { get;set;} - /// - /// Size of cross-section along X-axis, m - /// - double SizeX { get; set; } - /// - /// Size of cross-section along Y-axis, m - /// - double SizeY { get; set; } - /// - /// Initial tuple of force - /// - IForceTuple InitialForceTuple { get; set; } - /// - /// Returns new force tuple with accidental eccentricity - /// - /// - ForceTuple GetForceTuple(); - } -} diff --git a/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs b/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs new file mode 100644 index 0000000..03fc403 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IHasInputForce.cs @@ -0,0 +1,17 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IHasInputForce + { + /// + /// Initial tuple of force + /// + IForceTuple InputForceTuple { get; set; } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs b/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs new file mode 100644 index 0000000..517aa22 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IProcessorDecorator.cs @@ -0,0 +1,14 @@ +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IProcessorDecorator : IProcessorLogic + { + IProcessorLogic ForceTupleLogics { get; } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs new file mode 100644 index 0000000..cf90cc0 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IProcessorLogic.cs @@ -0,0 +1,22 @@ +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections +{ + /// + /// Logic for calculating of some value + /// + public interface IProcessorLogic : ILogic + { + /// + /// Returns new value + /// + /// + T GetValue(); + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs new file mode 100644 index 0000000..4f929af --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IRcAccEccentricityLogic.cs @@ -0,0 +1,12 @@ +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IRcAccEccentricityLogic : IProcessorLogic<(double ex, double ey)> + { + double Length { get; set; } + double SizeX { get; set; } + double SizeY { get; set; } + IShiftTraceLogger? TraceLogger { get; set; } + + (double ex, double ey) GetValue(); + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs b/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs new file mode 100644 index 0000000..9c8695d --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/IRcEccentricityAxisLogic.cs @@ -0,0 +1,8 @@ +namespace StructureHelperCommon.Models.Sections.Logics +{ + public interface IRcEccentricityAxisLogic : IProcessorLogic + { + double Length { get; set; } + double Size { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs new file mode 100644 index 0000000..5db7f39 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcAccEccentricityLogic.cs @@ -0,0 +1,54 @@ +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class RcAccEccentricityLogic : IRcAccEccentricityLogic + { + private const string accEccMessage = "Accidental eccentricity along {0}-axis"; + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double SizeX { get; set; } + /// + /// Size of cross-section along Y-axis, m + /// + public double SizeY { get; set; } + /// + public IShiftTraceLogger? TraceLogger { get; set; } + private IRcEccentricityAxisLogic eccentricityLogic; + public RcAccEccentricityLogic(IRcEccentricityAxisLogic eccentricityLogic) + { + this.eccentricityLogic = eccentricityLogic; + } + public RcAccEccentricityLogic() : this(new RcEccentricityAxisLogic()) + { + + } + public (double ex, double ey) GetValue() + { + eccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(string.Format(accEccMessage, "x")); + eccentricityLogic.Length = Length; + eccentricityLogic.Size = SizeX; + var xFullEccentricity = eccentricityLogic.GetValue(); + TraceLogger?.AddMessage(string.Format(accEccMessage, "y")); + eccentricityLogic.Size = SizeY; + var yFullEccentricity = eccentricityLogic.GetValue(); + return (xFullEccentricity, yFullEccentricity); + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs new file mode 100644 index 0000000..30e581e --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityAxisLogic.cs @@ -0,0 +1,57 @@ +using StructureHelperCommon.Models.Loggers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Models.Sections.Logics +{ + public class RcEccentricityAxisLogic : IRcEccentricityAxisLogic + { + private readonly double lengthFactor; + private readonly double sizeFactor; + private readonly double minEccentricity; + + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double Size { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public RcEccentricityAxisLogic() + { + lengthFactor = 600d; + sizeFactor = 30d; + minEccentricity = 0.01d; + } + public double GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + var lengthEccetricity = Length / lengthFactor; + TraceLogger?.AddMessage(string.Format("Length of member = {0}(m)", Length)); + TraceLogger?.AddMessage(string.Format("Accidental eccentricity by length e,a = {0}(m) / {1} = {2}(m)", Length, lengthFactor, lengthEccetricity)); + TraceLogger?.AddMessage(string.Format("Size of cross-section of member = {0}(m)", Size)); + var sizeXEccetricity = Size / sizeFactor; + TraceLogger?.AddMessage(string.Format("Accidental eccentricity by size e,a ={0}(m) / {1} = {2}(m)", Size, sizeFactor, sizeXEccetricity)); ; + TraceLogger?.AddMessage(string.Format("In any case, minimum accidental eccentricity e,a = {0}(m)", minEccentricity)); + + var fullEccentricity = new List() + { + lengthEccetricity, + sizeXEccetricity, + minEccentricity, + } + .Max(); + string mesEcc = string.Format("Maximum accidental eccentricity e,a = max({0}(m); {1}(m); {2}(m)) = {3}(m)", + lengthEccetricity, sizeXEccetricity, + minEccentricity, + fullEccentricity); + TraceLogger?.AddMessage(mesEcc); + return fullEccentricity; + } + } +} diff --git a/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs new file mode 100644 index 0000000..1743674 --- /dev/null +++ b/StructureHelperCommon/Models/Sections/Logics/RcEccentricityLogic.cs @@ -0,0 +1,100 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; +using StructureHelperCommon.Models.Sections.Logics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +//Copyright (c) 2023 Redikultsev Evgeny, Ekaterinburg, Russia +//All rights reserved. + +namespace StructureHelperCommon.Models.Sections +{ + public class RcEccentricityLogic : IProcessorLogic, IHasInputForce + { + private const string fstAxisName = "x"; + private const string sndAxisName = "y"; + private const string actualEccMessage = "Actual eccentricity e0,{0} = {1}(m)"; + private const string maxEccentricityMessage = "Eccentricity e,{0} = max({1}(m); {2}(m)) = {3}(m)"; + private const string OutPutBendingMomentMessage = "Bending moment arbitrary {0}-axis M{0} = Nz * e,{0} = {1}(N) * {2}(m) = {3}(N*m)"; + + /// + /// Properties of compressed member + /// + public double Length { get; set; } + /// + /// Size of cross-section along X-axis, m + /// + public double SizeX { get; set; } + /// + /// Size of cross-section along Y-axis, m + /// + public double SizeY { get; set; } + /// + public IForceTuple? InputForceTuple { get; set; } + /// + public IShiftTraceLogger? TraceLogger { get; set; } + public IRcAccEccentricityLogic EccentricityLogic { get; private set; } + + public RcEccentricityLogic(IRcAccEccentricityLogic eccentricityLogic) + { + EccentricityLogic = eccentricityLogic; + } + + public RcEccentricityLogic() : this(new RcAccEccentricityLogic()) + { + + } + + public IForceTuple GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + if (InputForceTuple is null) + { + string errorString = ErrorStrings.NullReference + $": {nameof(InputForceTuple)}"; + TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); + throw new StructureHelperException(errorString); + } + + EccentricityLogic.Length = Length; + EccentricityLogic.SizeX = SizeX; + EccentricityLogic.SizeY = SizeY; + EccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + + var (ex, ey) = EccentricityLogic.GetValue(); + + var xEccentricity = Math.Abs(InputForceTuple.My / InputForceTuple.Nz); + TraceLogger?.AddMessage(string.Format(actualEccMessage, fstAxisName, xEccentricity)); + var yEccentricity = Math.Abs(InputForceTuple.Mx / InputForceTuple.Nz); + TraceLogger?.AddMessage(string.Format(actualEccMessage, sndAxisName, yEccentricity)); + + var xFullEccentricity = Math.Max(ex, xEccentricity); + var yFullEccentricity = Math.Max(ey, yEccentricity); + string mesEx = string.Format(maxEccentricityMessage, fstAxisName, ex, xEccentricity, xFullEccentricity); + TraceLogger?.AddMessage(mesEx); + string mesEy = string.Format(maxEccentricityMessage, sndAxisName, ey, yEccentricity, yFullEccentricity); + TraceLogger?.AddMessage(mesEy); + var xSign = InputForceTuple.Mx == 0d ? -1d : Math.Sign(InputForceTuple.Mx); + var ySign = InputForceTuple.My == 0d ? -1d : Math.Sign(InputForceTuple.My); + var mx = (-1d) * InputForceTuple.Nz * yFullEccentricity * xSign; + var my = (-1d) * InputForceTuple.Nz * xFullEccentricity * ySign; + TraceLogger?.AddMessage(string.Format(OutPutBendingMomentMessage, fstAxisName, InputForceTuple.Nz, yFullEccentricity, mx), TraceLogStatuses.Debug); + TraceLogger?.AddMessage(string.Format(OutPutBendingMomentMessage, sndAxisName, InputForceTuple.Nz, xFullEccentricity, my), TraceLogStatuses.Debug); + + var newTuple = new ForceTuple() + { + Mx = mx, + My = my, + Nz = InputForceTuple.Nz, + Qx = InputForceTuple.Qx, + Qy = InputForceTuple.Qy, + Mz = InputForceTuple.Mz, + }; + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); + return newTuple; + } + } +} diff --git a/StructureHelperCommon/Services/Forces/ForceTupleService.cs b/StructureHelperCommon/Services/Forces/ForceTupleService.cs index ab74200..2e51453 100644 --- a/StructureHelperCommon/Services/Forces/ForceTupleService.cs +++ b/StructureHelperCommon/Services/Forces/ForceTupleService.cs @@ -20,13 +20,6 @@ namespace StructureHelperCommon.Services.Forces target.Clear(); SumTupleToTarget(source, target, factor); } - public static IForceTuple MoveTupleIntoPoint(IForceTuple forceTuple, IPoint2D point2D) - { - var newTuple = forceTuple.Clone() as IForceTuple; - newTuple.Mx += newTuple.Nz * point2D.Y; - newTuple.My -= newTuple.Nz * point2D.X; - return newTuple; - } public static IForceTuple SumTuples(IForceTuple first, IForceTuple second, double factor = 1d) { CheckTuples(first, second); diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs index 93e7fc2..55d40ac 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs @@ -4,13 +4,16 @@ using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Loggers; using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models.Sections.Logics; using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Services.Forces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces.Logics; using StructureHelperLogics.NdmCalculations.Buckling; using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.Services.NdmPrimitives; +using System; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { @@ -19,6 +22,8 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces static readonly ForceCalculatorUpdateStrategy updateStrategy = new(); private readonly IForceTupleCalculator forceTupleCalculator; private ForcesResults result; + private IProcessorLogic eccentricityLogic; + private ForceTupleBucklingLogic bucklingLogic; public string Name { get; set; } public List LimitStatesList { get; private set; } @@ -34,6 +39,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public void Run() { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); var checkResult = CheckInputData(); if (checkResult != "") { @@ -95,13 +101,14 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces CalcTerms calcTerm = tuple.CalcTerm; var ndms = NdmPrimitivesService.GetNdms(Primitives, limitState, calcTerm); IPoint2D point2D; + IProcessorLogic forcelogic = new ForceTupleCopier(tuple.ForceTuple); if (combination.SetInGravityCenter == true) { var (Cx, Cy) = LoaderCalculator.Logics.Geometry.GeometryOperations.GetGravityCenter(ndms); - point2D = new Point2D(){ X = Cx, Y = Cy }; + point2D = new Point2D() { X = Cx, Y = Cy }; + forcelogic = new ForceTupleMoveToPointDecorator(forcelogic) { Point2D = point2D}; } - else point2D = combination.ForcePoint; - var newTuple = ForceTupleService.MoveTupleIntoPoint(tuple.ForceTuple, point2D); + var newTuple = forcelogic.GetValue(); TraceLogger?.AddMessage($"Input force combination"); TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); if (CompressedMember.Buckling == true) @@ -109,27 +116,12 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces if (newTuple.Nz >= 0d) { TraceLogger?.AddMessage(string.Format("Second order effect is not considered as Nz={0} >= 0", newTuple.Nz)); + tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); } else { - TraceLogger?.AddMessage("Get eccentricity for full load"); - newTuple = ProcessAccEccentricity(ndms, newTuple); - var buckResult = GetForceTupleByBuckling(combination, limitState, calcTerm, ndms, newTuple); - if (buckResult.isValid == true) - { - newTuple = buckResult.tuple; - } - else - { - return new ForcesTupleResult() - { - IsValid = false, - DesignForceTuple = tuple, - Description = buckResult.description, - }; - } - } - tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); + tupleResult = ProcessCompressedMember(combination, tuple, ndms, newTuple); + } } else { @@ -143,10 +135,19 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces return tupleResult; } - private (bool isValid, IForceTuple tuple, string description) GetForceTupleByBuckling(IForceCombinationList combination, LimitStates limitState, CalcTerms calcTerm, List ndms, IForceTuple newTuple) + private IForcesTupleResult ProcessCompressedMember(IForceCombinationList combination, IDesignForceTuple tuple, List ndms, IForceTuple newTuple) { - var tuple = newTuple.Clone() as IForceTuple; - var inputData = new BucklingInputData() + IForcesTupleResult tupleResult; + LimitStates limitState = tuple.LimitState; + CalcTerms calcTerm = tuple.CalcTerm; + + TraceLogger?.AddMessage("Get eccentricity for full load"); + eccentricityLogic = new ProcessEccentricity(CompressedMember, ndms, newTuple) + { + TraceLogger = TraceLogger ?? null + }; + newTuple = eccentricityLogic.GetValue(); + var buclingInputData = new BucklingInputData() { Combination = combination, LimitState = limitState, @@ -154,117 +155,42 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces Ndms = ndms, ForceTuple = newTuple }; - var bucklingResult = ProcessBuckling(inputData); - - if (bucklingResult.IsValid != true) + bucklingLogic = new ForceTupleBucklingLogic(buclingInputData) { - TraceLogger?.AddMessage(bucklingResult.Description, TraceLogStatuses.Error); - return (false, tuple, $"Buckling result:\n{bucklingResult.Description}"); + CompressedMember = CompressedMember, + Accuracy = Accuracy, + Primitives = Primitives, + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + var buckResult = bucklingLogic.GetForceTupleByBuckling(); + if (buckResult.IsValid == true) + { + newTuple = buckResult.Value; } else { - tuple = CalculateBuckling(tuple, bucklingResult); - TraceLogger?.AddMessage(string.Intern("Force combination with considering of second order effects")); - TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(tuple)); + return new ForcesTupleResult() + { + IsValid = false, + DesignForceTuple = tuple, + Description = buckResult.Description, + }; } - - return (true, tuple, string.Empty); + TraceLogger?.AddMessage(string.Intern("Result of second order was obtained succesfully, new force combination was obtained")); + tupleResult = GetForceResult(limitState, calcTerm, ndms, newTuple); + return tupleResult; } private IForcesTupleResult GetForceResult(LimitStates limitState, CalcTerms calcTerm, List ndms, IForceTuple newTuple) { + TraceLogger?.AddMessage("Calculation of cross-section is started"); var tupleResult = GetPrimitiveStrainMatrix(ndms, newTuple, Accuracy); tupleResult.DesignForceTuple.LimitState = limitState; tupleResult.DesignForceTuple.CalcTerm = calcTerm; tupleResult.DesignForceTuple.ForceTuple = newTuple; return tupleResult; - } - private IForceTuple ProcessAccEccentricity(List ndms, IForceTuple tuple) - { - var newTuple = tuple.Clone() as IForceTuple; - var accLogic = new AccidentalEccentricityLogic() - { - Length = CompressedMember.GeometryLength, - SizeX = ndms.Max(x => x.CenterX) - ndms.Min(x => x.CenterX), - SizeY = ndms.Max(x => x.CenterY) - ndms.Min(x => x.CenterY), - InitialForceTuple = newTuple, - }; - if (TraceLogger is not null) - { - accLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - newTuple = accLogic.GetForceTuple(); - return newTuple; - } - - private IConcreteBucklingResult ProcessBuckling(BucklingInputData inputData) - { - IForceTuple resultTuple; - IForceTuple longTuple; - if (inputData.CalcTerm == CalcTerms.LongTerm) - { - longTuple = inputData.ForceTuple; - } - else - { - longTuple = GetLongTuple(inputData.Combination.DesignForces, inputData.LimitState); - } - TraceLogger?.AddMessage("Get eccentricity for long term load"); - longTuple = ProcessAccEccentricity(inputData.Ndms, longTuple); - var bucklingCalculator = GetBucklingCalculator(CompressedMember, inputData.LimitState, inputData.CalcTerm, inputData.ForceTuple, longTuple); - if (TraceLogger is not null) - { - bucklingCalculator.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - bucklingCalculator.Run(); - var bucklingResult = bucklingCalculator.Result as IConcreteBucklingResult; - - return bucklingResult; - } - - private IForceTuple GetLongTuple(List designForces, LimitStates limitState) - { - IForceTuple longTuple; - try - { - longTuple = designForces - .Where(x => x.LimitState == limitState & x.CalcTerm == CalcTerms.LongTerm) - .Single() - .ForceTuple; - } - catch (Exception) - { - longTuple = new ForceTuple(); - } - return longTuple; - } - - private IConcreteBucklingCalculator GetBucklingCalculator(ICompressedMember compressedMember, LimitStates limitStates, CalcTerms calcTerms, IForceTuple calcTuple, IForceTuple longTuple) - { - var options = new ConcreteBucklingOptions() - { - CompressedMember = compressedMember, - LimitState = limitStates, - CalcTerm = calcTerms, - CalcForceTuple = calcTuple, - LongTermTuple = longTuple, - Primitives = Primitives - }; - var bucklingCalculator = new ConcreteBucklingCalculator(options, Accuracy); - return bucklingCalculator; - } - - private ForceTuple CalculateBuckling(IForceTuple calcTuple, IConcreteBucklingResult bucklingResult) - { - var newTuple = calcTuple.Clone() as ForceTuple; - newTuple.Mx *= bucklingResult.EtaFactorAlongY; - newTuple.My *= bucklingResult.EtaFactorAlongX; - return newTuple; - } - - private string CheckInputData() { string result = ""; diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs index a0b557a..e9e1cc5 100644 --- a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs @@ -57,6 +57,66 @@ namespace StructureHelperLogics.NdmCalculations.Buckling otherNdms = ndmCollection.Except(concreteNdms).ToList(); } + public void Run() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage(LoggerStrings.MethodBasedOn + "SP63.13330.2018"); + var checkResult = CheckInputData(); + if (checkResult != "") + { + ProcessFalseResult(checkResult); + return; + } + else + { + ProcessValidResult(); + } + TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); + } + + private void ProcessValidResult() + { + var phiLLogic = GetPhiLogic(); + var (DeltaLogicAboutX, DeltaLogicAboutY) = GetDeltaLogics(); + stiffnessLogicX = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutX); + stiffnessLogicY = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutY); + if (TraceLogger is not null) + { + stiffnessLogicX.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + stiffnessLogicY.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + criticalForceLogic = new EilerCriticalForceLogic(); + if (TraceLogger is not null) + { + criticalForceLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + + var (EtaFactorX, EtaFactorY) = GetBucklingCoefficients(); + var messageString = "Eta factor orbitrary {0} axis, Eta{0} = {1} (dimensionless)"; + var messageStringX = string.Format(messageString, "X", EtaFactorX); + var messageStringY = string.Format(messageString, "Y", EtaFactorY); + TraceLogger?.AddMessage(messageStringX); + TraceLogger?.AddMessage(messageStringY); + Result = new ConcreteBucklingResult() + { + IsValid = true, + EtaFactorAlongX = EtaFactorX, + EtaFactorAlongY = EtaFactorY + }; + } + + private void ProcessFalseResult(string checkResult) + { + TraceLogger?.AddMessage(checkResult, TraceLogStatuses.Error); + Result = new ConcreteBucklingResult() + { + IsValid = false, + Description = checkResult, + EtaFactorAlongX = double.PositiveInfinity, + EtaFactorAlongY = double.PositiveInfinity + }; + } + private (IConcreteDeltaELogic DeltaLogicX, IConcreteDeltaELogic DeltaLogicY) GetDeltaLogics() { IForceTuple forceTuple = options.CalcForceTuple; @@ -66,6 +126,15 @@ namespace StructureHelperLogics.NdmCalculations.Buckling } var eccentricityAlongX = options.CalcForceTuple.My / forceTuple.Nz; var eccentricityAlongY = options.CalcForceTuple.Mx / forceTuple.Nz; + const string eccMesssage = "Eccentricity along {0}-axis e{0} = {1}(N * m) / {2}(N) = {3}(m)"; + TraceLogger?.AddMessage(string.Format(eccMesssage, + "x", + options.CalcForceTuple.My, forceTuple.Nz, + eccentricityAlongX)); + TraceLogger?.AddMessage(string.Format(eccMesssage, + "y", + options.CalcForceTuple.Mx, forceTuple.Nz, + eccentricityAlongY)); var sizeAlongX = ndmCollection.Max(x => x.CenterX) - ndmCollection.Min(x => x.CenterX); var sizeAlongY = ndmCollection.Max(x => x.CenterY) - ndmCollection.Min(x => x.CenterY); var DeltaElogicAboutX = new DeltaELogicSP63(eccentricityAlongY, sizeAlongY); @@ -82,7 +151,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling { const string sumStif = "Summary stiffness"; var gravityCenter = GeometryOperations.GetGravityCenter(ndmCollection); - string message = string.Format("Gravity center, x = {0}, y = {1}", gravityCenter.Cx, gravityCenter.Cy); + string message = string.Format("Gravity center, x = {0}(m), y = {1}(m)", gravityCenter.Cx, gravityCenter.Cy); TraceLogger?.AddMessage(message); if (TraceLogger is not null) { @@ -152,55 +221,7 @@ namespace StructureHelperLogics.NdmCalculations.Buckling return calculator; } - public void Run() - { - TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); - TraceLogger?.AddMessage(LoggerStrings.MethodBasedOn + "SP63.13330.2018"); - var checkResult = CheckInputData(); - if (checkResult != "") - { - TraceLogger?.AddMessage(checkResult, TraceLogStatuses.Error); - Result = new ConcreteBucklingResult() - { - IsValid = false, - Description = checkResult, - EtaFactorAlongX = double.PositiveInfinity, - EtaFactorAlongY = double.PositiveInfinity - }; - return; - } - else - { - var phiLLogic = GetPhiLogic(); - var (DeltaLogicAboutX, DeltaLogicAboutY) = GetDeltaLogics(); - stiffnessLogicX = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutX); - stiffnessLogicY = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutY); - if (TraceLogger is not null) - { - stiffnessLogicX.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - stiffnessLogicY.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - criticalForceLogic = new EilerCriticalForceLogic(); - if (TraceLogger is not null) - { - criticalForceLogic.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); - } - - var (EtaFactorX, EtaFactorY) = GetBucklingCoefficients(); - var messageString = "Eta factor orbitrary {0} axis, Eta{0} = {1} (dimensionless)"; - var messageStringX = string.Format(messageString, "X", EtaFactorX); - var messageStringY = string.Format(messageString, "Y", EtaFactorY); - TraceLogger?.AddMessage(messageStringX); - TraceLogger?.AddMessage(messageStringY); - Result = new ConcreteBucklingResult() - { - IsValid = true, - EtaFactorAlongX = EtaFactorX, - EtaFactorAlongY = EtaFactorY - }; - } - TraceLogger?.AddMessage(LoggerStrings.CalculationHasDone); - } + private string CheckInputData() { diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs new file mode 100644 index 0000000..e3e0d09 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ForceTupleBucklingLogic.cs @@ -0,0 +1,136 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelperCommon.Models.Sections; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperCommon.Models.Loggers; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ForceTupleBucklingLogic : IForceTupleBucklingLogic + { + private IProcessorLogic eccentricityLogic; + private BucklingInputData bucklingInputData; + + public ICompressedMember CompressedMember { get; set; } + public IAccuracy Accuracy { get; set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public IEnumerable Primitives { get; set; } + + public ForceTupleBucklingLogic(BucklingInputData inputData) + { + bucklingInputData = inputData; + } + + public GenericResult GetForceTupleByBuckling() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + + var tuple = bucklingInputData.ForceTuple.Clone() as IForceTuple; + + var bucklingResult = ProcessBuckling(bucklingInputData); + + if (bucklingResult.IsValid != true) + { + TraceLogger?.AddMessage(bucklingResult.Description, TraceLogStatuses.Error); + var tupleResult = new GenericResult() + { + IsValid = false, + Description = $"Buckling result:\n{bucklingResult.Description}", + Value = tuple + }; + return tupleResult; + } + else + { + tuple = CalculateBuckling(tuple, bucklingResult); + TraceLogger?.AddMessage(string.Intern("Force combination with considering of second order effects")); + TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(tuple)); + } + var trueTupleResult = new GenericResult() + { + IsValid = true, + Description = string.Empty, + Value = tuple + }; + return trueTupleResult; + } + + private IConcreteBucklingResult ProcessBuckling(BucklingInputData inputData) + { + IForceTuple resultTuple; + IForceTuple longTuple; + if (inputData.CalcTerm == CalcTerms.LongTerm) + { + longTuple = inputData.ForceTuple; + } + else + { + longTuple = GetLongTuple(inputData.Combination.DesignForces, inputData.LimitState); + } + TraceLogger?.AddMessage("Get eccentricity for long term load"); + eccentricityLogic = new ProcessEccentricity(CompressedMember, inputData.Ndms, longTuple) + { + TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) + }; + longTuple = eccentricityLogic.GetValue(); + var bucklingCalculator = GetBucklingCalculator(inputData.LimitState, inputData.CalcTerm, inputData.ForceTuple, longTuple); + if (TraceLogger is not null) + { + bucklingCalculator.TraceLogger = TraceLogger.GetSimilarTraceLogger(50); + } + bucklingCalculator.Run(); + var bucklingResult = bucklingCalculator.Result as IConcreteBucklingResult; + + return bucklingResult; + } + + private IForceTuple GetLongTuple(List designForces, LimitStates limitState) + { + IForceTuple longTuple; + try + { + longTuple = designForces + .Where(x => x.LimitState == limitState & x.CalcTerm == CalcTerms.LongTerm) + .Single() + .ForceTuple; + } + catch (Exception) + { + longTuple = new ForceTuple(); + } + return longTuple; + } + + private IConcreteBucklingCalculator GetBucklingCalculator(LimitStates limitStates, CalcTerms calcTerms, IForceTuple calcTuple, IForceTuple longTuple) + { + var options = new ConcreteBucklingOptions() + { + CompressedMember = CompressedMember, + LimitState = limitStates, + CalcTerm = calcTerms, + CalcForceTuple = calcTuple, + LongTermTuple = longTuple, + Primitives = Primitives + }; + var bucklingCalculator = new ConcreteBucklingCalculator(options, Accuracy); + return bucklingCalculator; + } + + private ForceTuple CalculateBuckling(IForceTuple calcTuple, IConcreteBucklingResult bucklingResult) + { + var newTuple = calcTuple.Clone() as ForceTuple; + newTuple.Mx *= bucklingResult.EtaFactorAlongY; + newTuple.My *= bucklingResult.EtaFactorAlongX; + return newTuple; + } + + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs new file mode 100644 index 0000000..2fcd9f8 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IForceTupleBucklingLogic.cs @@ -0,0 +1,13 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Infrastructures.Interfaces; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IForceTupleBucklingLogic : ILogic + { + GenericResult GetForceTupleByBuckling(); + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs b/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs new file mode 100644 index 0000000..8932242 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ProcessEccentricity.cs @@ -0,0 +1,57 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using StructureHelperCommon.Models.Loggers; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ProcessEccentricity : IProcessorLogic + { + private IProcessorLogic eccentricityLogic; + + public ICompressedMember CompressedMember { get; private set; } + public IEnumerable Ndms { get; private set; } + public IShiftTraceLogger? TraceLogger { get; set; } + public IForceTuple InputForceTuple { get; set; } + + private double sizeX; + private double sizeY; + + public ProcessEccentricity(IProcessorLogic eccentricityLogic) + { + this.eccentricityLogic = eccentricityLogic; + } + public ProcessEccentricity(ICompressedMember compressedMember, IEnumerable ndms, IForceTuple initialForceTuple) + { + CompressedMember = compressedMember; + Ndms = ndms; + InputForceTuple = initialForceTuple; + sizeX = ndms.Max(x => x.CenterX) - ndms.Min(x => x.CenterX); + sizeY = ndms.Max(x => x.CenterY) - ndms.Min(x => x.CenterY); + eccentricityLogic = new RcEccentricityLogic() + { + InputForceTuple = InputForceTuple, + Length = CompressedMember.GeometryLength, + SizeX = sizeX, + SizeY = sizeY, + }; + } + + public IForceTuple GetValue() + { + TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); + TraceLogger?.AddMessage("Get eccentricity taking into account accidental eccentricity"); + TraceLogger?.AddMessage(string.Format("Cross-section size along x-axis dx = {0}, along y-axis dy = {1}", sizeX, sizeY)); + + eccentricityLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); + var newTuple = eccentricityLogic.GetValue(); + return newTuple; + } + } +} diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs new file mode 100644 index 0000000..1691ca2 --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityAxisTest.cs @@ -0,0 +1,39 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcEccentricityAxisLogicTests + { + [TestCase(12d, 0.2d, 0.02d)] + [TestCase(3d, 0.9d, 0.03d)] + [TestCase(2, 0.2d, 0.01d)] + public void GetValue_ShouldCalculateCorrectly(double length, double size, double expectedEccentricity) + { + // Arrange + var loggerMock = new Mock(); + + var rcEccentricityAxisLogic = new RcEccentricityAxisLogic + { + Length = length, + Size = size, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcEccentricityAxisLogic.GetValue(); + + // Assert + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(7)); // Adjust based on your actual calls + Assert.AreEqual(expectedEccentricity, result, 0.0001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs new file mode 100644 index 0000000..673a002 --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcAccEccentricityTest.cs @@ -0,0 +1,43 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcAccEccentricityLogicTests + { + [Test] + public void GetValue_ShouldCalculateCorrectly() + { + // Arrange + var eccentricityAxisLogicMock = new Mock(); + eccentricityAxisLogicMock.Setup(el => el.GetValue()).Returns(3.0); // Adjust based on your expected result + + var loggerMock = new Mock(); + + var rcAccEccentricityLogic = new RcAccEccentricityLogic(eccentricityAxisLogicMock.Object) + { + Length = 100.0, + SizeX = 5.0, + SizeY = 10.0, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcAccEccentricityLogic.GetValue(); + + // Assert + eccentricityAxisLogicMock.Verify(el => el.GetValue(), Times.Exactly(2)); + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(3)); // Adjust based on your actual calls + Assert.AreEqual(3.0, result.ex, 0.001); // Adjust based on your expected result + Assert.AreEqual(3.0, result.ey, 0.001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs new file mode 100644 index 0000000..bef8dcd --- /dev/null +++ b/StructureHelperTests/FunctionalTests/RCs/Eccentricitis/RcEccentricityLogicTest.cs @@ -0,0 +1,58 @@ +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections.Logics; +using StructureHelperCommon.Models.Sections; +using StructureHelperCommon.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperTests.FunctionalTests.RCs.Eccentricitis +{ + public class RcEccentricityLogicTests + { + [TestCase(30, 1.0, 2.0, -60, -30)] + [TestCase(30, 2.0, 1.0, -30, -60)] + public void GetValue_ShouldCalculateCorrectly(double nz, double ex, double ey, double expectedMx, double expectedMy) + { + // Arrange + var inputForceTuple = new ForceTuple + { + Mx = 10, + My = 20, + Nz = nz, + Qx = 40.0, + Qy = 50.0, + Mz = 60.0, + }; + + var eccentricityLogicMock = new Mock(); + eccentricityLogicMock.Setup(el => el.GetValue()).Returns((ex, ey)); + + var loggerMock = new Mock(); + + var rcEccentricityLogic = new RcEccentricityLogic(eccentricityLogicMock.Object) + { + Length = 100.0, + SizeX = 5.0, + SizeY = 10.0, + InputForceTuple = inputForceTuple, + TraceLogger = loggerMock.Object, + }; + + // Act + var result = rcEccentricityLogic.GetValue(); + + // Assert + eccentricityLogicMock.Verify(el => el.GetValue(), Times.Once); + //loggerMock.Verify(logger => logger.AddMessage(It.IsAny(), It.IsAny()), Times.Exactly(6)); // Adjust based on your actual calls + //loggerMock.Verify(logger => logger.AddEntry(It.IsAny()), Times.Once); // Adjust based on your actual calls + Assert.AreEqual(expectedMx, result.Mx, 0.001); // Adjust based on your expected result + Assert.AreEqual(expectedMy, result.My, 0.001); // Adjust based on your expected result + // Add more assertions based on your expected behavior + } + } +} diff --git a/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs b/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs index 9f5078d..86b8db4 100644 --- a/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs +++ b/StructureHelperTests/UnitTests/MaterialTests/MaterialStrengthTest.cs @@ -7,8 +7,8 @@ namespace StructureHelperTests.UnitTests.MaterialTests { public class MaterialStrengthTest { - [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 347826086.95652175d, 347826086.95652175d)] - [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 400000000d, 400000000d)] + [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 339130434.78260875d, 339130434.78260875d)] + [TestCase(HeadmaterialType.Reinforcement400, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 390000000d, 390000000d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.ShortTerm, 400000000.0d, 434782608.69565225d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.ULS, CalcTerms.LongTerm, 434782608.69565225d, 434782608.69565225d)] [TestCase(HeadmaterialType.Reinforecement500, CodeTypes.SP63_2018, LimitStates.SLS, CalcTerms.ShortTerm, 5e8d, 5e8d)] diff --git a/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs b/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs index c64a078..858a9c0 100644 --- a/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs +++ b/StructureHelperTests/ViewModelTests/GraphViewModelTest.cs @@ -15,7 +15,7 @@ namespace StructureHelperTests.ViewModelTests var labels = new List(); for (int i = 0; i < columnCount; i++) { - labels[i] = $"Column{i}"; + labels.Add($"Column{i}"); } var array = new ArrayParameter(rowCount, columnCount, labels); for (int i = 0; i < columnCount; i++)