diff --git a/StructureHelper/Libraries/LoaderCalculator.dll b/StructureHelper/Libraries/LoaderCalculator.dll index 7a3289f..cdc1bd5 100644 Binary files a/StructureHelper/Libraries/LoaderCalculator.dll and b/StructureHelper/Libraries/LoaderCalculator.dll differ 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++)