From f013ddae13f8bd7dba3f42293c0a81abd19bd089 Mon Sep 17 00:00:00 2001 From: Evgeny Redikultsev Date: Sun, 29 Jan 2023 20:45:42 +0500 Subject: [PATCH] ConcreteBucklingCalculator was added --- Libraries/LoaderCalculator.dll | Bin 59904 -> 60928 bytes .../Infrastructures/Enums/Directions.cs | 15 ++ .../Infrastructures/Strings/ErrorString.cs | 3 + .../StructureHelperCommon.csproj | 1 + .../Analyses/ByForces/ForceCalculator.cs | 118 ++++++++---- .../Analyses/ByForces/ForceTupleCalculator.cs | 82 ++++++++ .../Analyses/ByForces/ForceTupleInputData.cs | 18 ++ .../Analyses/ByForces/ForcesResults.cs | 4 +- .../{ForcesResult.cs => ForcesTupleResult.cs} | 4 +- .../Analyses/ByForces/IForceCalculator.cs | 2 +- .../ByForces/IForceTupleCalculator.cs | 13 ++ .../Analyses/ByForces/IForceTupleInputData.cs | 18 ++ .../Analyses/ByForces/IForcesResults.cs | 2 +- .../Analyses/ByForces/IForcesTupleResult.cs | 11 ++ .../Buckling/ConcreteBucklingCalculator.cs | 177 ++++++++++++++++++ .../Buckling/ConcreteBucklingOptions.cs | 29 +++ .../Buckling/ConcreteBucklingResult.cs | 21 +++ .../Buckling/ConstDeltaELogic.cs | 16 ++ .../Buckling/ConstPhiLLogic.cs | 16 ++ .../Buckling/CriticalForceSP63Logic.cs | 23 +++ .../Buckling/DeltaELogicSP63.cs | 36 ++++ .../Buckling/EilerCriticalForceLogic.cs | 35 ++++ .../Buckling/IBucklingOptions.cs | 21 +++ .../Buckling/IConcreteBucklingCalculator.cs | 15 ++ .../Buckling/IConcreteBucklingOptions.cs | 15 ++ .../Buckling/IConcreteBucklingResult.cs | 24 +++ .../Buckling/IConcreteDeltaELogic.cs | 13 ++ .../Buckling/IConcretePhiLLogic.cs | 13 ++ .../Buckling/ICriticalBucklingForceLogic.cs | 14 ++ .../Buckling/IEilerCriticalForceLogic.cs | 16 ++ .../Buckling/IRCStiffnessLogic.cs | 14 ++ .../NdmCalculations/Buckling/PhiLogicSP63.cs | 41 ++++ .../Buckling/RCStiffnessLogicSP63.cs | 33 ++++ .../NdmCalculations/InterpolateService.cs | 5 +- .../ForceCalculatorTests/RCSectionsTest.cs | 26 ++- .../Ndms/RCSections/BucklingLogicTest.cs | 50 +++++ .../StructureHelperTests.csproj | 11 +- StructureHelperTests/app.config | 14 +- StructureHelperTests/packages.config | 6 +- .../ForceCalculatorView.xaml | 2 +- Windows/MainWindow/MainViewModel.cs | 6 +- .../PrimitivePropertiesView.xaml | 21 ++- .../Calculators/ForcesResultsViewModel.cs | 2 +- .../NdmCrossSections/SecondOrderViewModel.cs | 4 +- 44 files changed, 924 insertions(+), 86 deletions(-) create mode 100644 StructureHelperCommon/Infrastructures/Enums/Directions.cs create mode 100644 StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleCalculator.cs create mode 100644 StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleInputData.cs rename StructureHelperLogics/NdmCalculations/Analyses/ByForces/{ForcesResult.cs => ForcesTupleResult.cs} (89%) create mode 100644 StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleCalculator.cs create mode 100644 StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleInputData.cs create mode 100644 StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesTupleResult.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingOptions.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingResult.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ConstDeltaELogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ConstPhiLLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/CriticalForceSP63Logic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/DeltaELogicSP63.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/EilerCriticalForceLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IBucklingOptions.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingCalculator.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingOptions.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingResult.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IConcreteDeltaELogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IConcretePhiLLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/ICriticalBucklingForceLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IEilerCriticalForceLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/IRCStiffnessLogic.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/PhiLogicSP63.cs create mode 100644 StructureHelperLogics/NdmCalculations/Buckling/RCStiffnessLogicSP63.cs create mode 100644 StructureHelperTests/FunctionalTests/Ndms/RCSections/BucklingLogicTest.cs diff --git a/Libraries/LoaderCalculator.dll b/Libraries/LoaderCalculator.dll index f87555fcbb85c7341fcca03accb71824a8b45e56..c410bbe01c2ded9e9e8ff4d1e82d4040def32878 100644 GIT binary patch literal 60928 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 literal 59904 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

BsW*fYN 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 T=z=%m0q;IL@u#2vcN+LVk4#}d diff --git a/StructureHelperCommon/Infrastructures/Enums/Directions.cs b/StructureHelperCommon/Infrastructures/Enums/Directions.cs new file mode 100644 index 0000000..f210380 --- /dev/null +++ b/StructureHelperCommon/Infrastructures/Enums/Directions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperCommon.Infrastructures.Enums +{ + public enum Directions + { + X, + Y, + Z + } +} diff --git a/StructureHelperCommon/Infrastructures/Strings/ErrorString.cs b/StructureHelperCommon/Infrastructures/Strings/ErrorString.cs index 1b5ba2a..227527f 100644 --- a/StructureHelperCommon/Infrastructures/Strings/ErrorString.cs +++ b/StructureHelperCommon/Infrastructures/Strings/ErrorString.cs @@ -20,5 +20,8 @@ namespace StructureHelperCommon.Infrastructures.Strings public static string FileCantBeSaved => "#0009: File can't be saved"; public static string VisualPropertyIsNotRight => "#0010: VisualPropertyIsNotRight"; public static string FactorMustBeGraterThanZero => "#0011: Partial factor must not be less than zero"; + public static string LongitudinalForceMustBeLessThanZero => "#0012: Longitudinal force must be less than zero"; + public static string LongitudinalForceMustBeLessThanCriticalForce => "#0013: Absolute value of longitudinal force must be greater than critical force"; + public static string SizeMustBeGreaterThanZero => "#0014: Size must be greater than zero"; } } diff --git a/StructureHelperCommon/StructureHelperCommon.csproj b/StructureHelperCommon/StructureHelperCommon.csproj index 5faf8c6..d5e146a 100644 --- a/StructureHelperCommon/StructureHelperCommon.csproj +++ b/StructureHelperCommon/StructureHelperCommon.csproj @@ -51,6 +51,7 @@ + diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs index 6a47239..3451fac 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceCalculator.cs @@ -10,10 +10,12 @@ using StructureHelperCommon.Models.Shapes; using StructureHelperCommon.Services.Calculations; using StructureHelperCommon.Services.Forces; using StructureHelperCommon.Services.Sections; +using StructureHelperLogics.NdmCalculations.Buckling; using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.Services.NdmPrimitives; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces @@ -27,7 +29,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public List Primitives { get; } public INdmResult Result { get; private set; } public ICompressedMember CompressedMember { get; } - public IAccuracy Accuracy { get; } + public IAccuracy Accuracy { get; set; } public void Run() { @@ -56,11 +58,42 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces if (combination.SetInGravityCenter == true) { var loaderPoint = LoaderCalculator.Logics.Geometry.GeometryOperations.GetGravityCenter(ndms); - point2D = new Point2D() { X = loaderPoint[0], Y = loaderPoint[1] }; + point2D = new Point2D() { X = loaderPoint.CenterX, Y = loaderPoint.CenterY }; } else point2D = combination.ForcePoint; var newTuple = ForceTupleService.MoveTupleIntoPoint(tuple.ForceTuple, point2D); var result = GetPrimitiveStrainMatrix(ndms, newTuple); + if (CompressedMember.Buckling == true) + { + IForceTuple longTuple; + if (calcTerm == CalcTerms.LongTerm) + { + longTuple = newTuple; + } + else + { + longTuple = GetLongTuple(combination.DesignForces, limitState); + } + var bucklingCalculator = GetBucklingCalculator(CompressedMember, limitState, calcTerm, newTuple, longTuple); + try + { + bucklingCalculator.Run(); + var bucklingResult = bucklingCalculator.Result as IConcreteBucklingResult; + if (bucklingResult.IsValid != true) + { + result.IsValid = false; + result.Desctription += $"Buckling result:\n{bucklingResult.Desctription}\n"; + } + newTuple = CalculateBuckling(newTuple, bucklingResult); + } + catch (Exception ex) + { + result.IsValid = false; + result.Desctription = $"Buckling error:\n{ex}\n"; + } + + } + result.DesignForceTuple.LimitState = limitState; result.DesignForceTuple.CalcTerm = calcTerm; result.DesignForceTuple.ForceTuple = newTuple; @@ -71,6 +104,42 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces Result = ndmResult; } + private IForceTuple GetLongTuple(List designForces, LimitStates limitState) + { + IForceTuple longTuple; + try + { + longTuple = designForces.Where(x => x.LimitState == limitState & x.CalcTerm == CalcTerms.LongTerm).First().ForceTuple; + } + catch (Exception) + { + longTuple = new ForceTuple(); + } + return longTuple; + } + + private IConcreteBucklingCalculator GetBucklingCalculator(ICompressedMember compressedMember, LimitStates limitStates, CalcTerms calcTerms, IForceTuple calcTuple, IForceTuple longTuple) + { + IConcreteBucklingOptions options = new ConcreteBucklingOptions() + { CompressedMember = compressedMember, + LimitState = limitStates, + CalcTerm = calcTerms, + CalcForceTuple = calcTuple, + LongTermTuple = longTuple, + Primitives = Primitives }; + IConcreteBucklingCalculator bucklingCalculator = new ConcreteBucklingCalculator(options, Accuracy); + return bucklingCalculator; + } + + private IForceTuple CalculateBuckling(IForceTuple calcTuple, IConcreteBucklingResult bucklingResult) + { + var newTuple = calcTuple.Clone() as IForceTuple; + newTuple.Mx *= bucklingResult.EtaFactorAlongY; + newTuple.My *= bucklingResult.EtaFactorAlongX; + return newTuple; + } + + private string CheckInputData() { string result = ""; @@ -85,51 +154,18 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { ForceCombinationLists = new List(); Primitives = new List(); - CompressedMember = new CompressedMember(); + CompressedMember = new CompressedMember() { Buckling = false }; Accuracy = new Accuracy() { IterationAccuracy = 0.001d, MaxIterationCount = 1000 }; LimitStatesList = new List() { LimitStates.ULS, LimitStates.SLS }; CalcTermsList = new List() { CalcTerms.ShortTerm, CalcTerms.LongTerm }; } - private ForcesResult GetPrimitiveStrainMatrix(IEnumerable ndmCollection, IForceTuple tuple) + private IForcesTupleResult GetPrimitiveStrainMatrix(IEnumerable ndmCollection, IForceTuple tuple) { - var mx = tuple.Mx; - var my = tuple.My; - var nz = tuple.Nz; - - try - { - var loaderData = new LoaderOptions - { - Preconditions = new Preconditions - { - ConditionRate = Accuracy.IterationAccuracy, - MaxIterationCount = Accuracy.MaxIterationCount, - StartForceMatrix = new ForceMatrix { Mx = mx, My = my, Nz = nz } - }, - NdmCollection = ndmCollection - }; - var calculator = new Calculator(); - calculator.Run(loaderData, new CancellationToken()); - var calcResult = calculator.Result; - if (calcResult.AccuracyRate <= Accuracy.IterationAccuracy) - { - return new ForcesResult() { IsValid = true, Desctription = "Analysis is done succsefully", LoaderResults = calcResult }; - } - else - { - return new ForcesResult() { IsValid = false, Desctription = "Required accuracy rate has not achived", LoaderResults = calcResult }; - } - - } - catch (Exception ex) - { - var result = new ForcesResult() { IsValid = false }; - if (ex.Message == "Calculation result is not valid: stiffness matrix is equal to zero") { result.Desctription = "Stiffness matrix is equal to zero \nProbably section was collapsed"; } - else { result.Desctription = $"Error is appeared due to analysis. Error: {ex}"; } - return result; - } - + IForceTupleInputData inputData = new ForceTupleInputData() { NdmCollection = ndmCollection, Tuple = tuple, Accuracy = Accuracy }; + IForceTupleCalculator calculator = new ForceTupleCalculator(inputData); + calculator.Run(); + return calculator.Result as IForcesTupleResult; } public object Clone() diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleCalculator.cs new file mode 100644 index 0000000..47988e8 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleCalculator.cs @@ -0,0 +1,82 @@ +using LoaderCalculator.Data.Matrix; +using LoaderCalculator.Data.SourceData; +using LoaderCalculator; +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public class ForceTupleCalculator : IForceTupleCalculator + { + public string Name { get; set; } + public INdmResult Result { get; private set; } + + private IForceTupleInputData inputData; + + public ForceTupleCalculator(IForceTupleInputData inputData) + { + this.inputData = inputData; + } + + public void Run() + { + Result = CalculateResult(); + } + + private IForcesTupleResult CalculateResult() + { + var ndmCollection = inputData.NdmCollection; + var tuple = inputData.Tuple; + var accuracy = inputData.Accuracy; + + + var mx = tuple.Mx; + var my = tuple.My; + var nz = tuple.Nz; + + try + { + var loaderData = new LoaderOptions + { + Preconditions = new Preconditions + { + ConditionRate = accuracy.IterationAccuracy, + MaxIterationCount = accuracy.MaxIterationCount, + StartForceMatrix = new ForceMatrix { Mx = mx, My = my, Nz = nz } + }, + NdmCollection = ndmCollection + }; + var calculator = new Calculator(); + calculator.Run(loaderData, new CancellationToken()); + var calcResult = calculator.Result; + if (calcResult.AccuracyRate <= accuracy.IterationAccuracy) + { + return new ForcesTupleResult() { IsValid = true, Desctription = "Analysis is done succsefully", LoaderResults = calcResult }; + } + else + { + return new ForcesTupleResult() { IsValid = false, Desctription = "Required accuracy rate has not achived", LoaderResults = calcResult }; + } + + } + catch (Exception ex) + { + var result = new ForcesTupleResult() { IsValid = false }; + if (ex.Message == "Calculation result is not valid: stiffness matrix is equal to zero") { result.Desctription = "Stiffness matrix is equal to zero \nProbably section was collapsed"; } + else { result.Desctription = $"Error is appeared due to analysis. Error: {ex}"; } + return result; + } + } + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleInputData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleInputData.cs new file mode 100644 index 0000000..241e76d --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForceTupleInputData.cs @@ -0,0 +1,18 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public class ForceTupleInputData : IForceTupleInputData + { + public IEnumerable NdmCollection { get; set; } + public IForceTuple Tuple { get; set; } + public IAccuracy Accuracy { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResults.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResults.cs index e2ce7d3..75fd467 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResults.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResults.cs @@ -9,12 +9,12 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public class ForcesResults : IForcesResults { public bool IsValid { get; set; } - public List ForcesResultList { get; } + public List ForcesResultList { get; } public string Desctription { get; set; } public ForcesResults() { - ForcesResultList = new List(); + ForcesResultList = new List(); } } } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResult.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesTupleResult.cs similarity index 89% rename from StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResult.cs rename to StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesTupleResult.cs index 10bb070..7de59dc 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesResult.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/ForcesTupleResult.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { - public class ForcesResult : INdmResult + public class ForcesTupleResult : IForcesTupleResult { public bool IsValid { get; set; } public IDesignForceTuple DesignForceTuple { get; set; } @@ -22,7 +22,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces /// public ILoaderResults LoaderResults { get; set; } - public ForcesResult() + public ForcesTupleResult() { DesignForceTuple = new DesignForceTuple(); } diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs index ebf5d12..25d9723 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceCalculator.cs @@ -14,6 +14,6 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces List CalcTermsList { get; } List LimitStatesList { get; } ICompressedMember CompressedMember { get; } - IAccuracy Accuracy { get; } + IAccuracy Accuracy { get; set; } } } \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleCalculator.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleCalculator.cs new file mode 100644 index 0000000..07a411a --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleCalculator.cs @@ -0,0 +1,13 @@ +using StructureHelperCommon.Models.Calculators; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface IForceTupleCalculator : INdmCalculator + { + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleInputData.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleInputData.cs new file mode 100644 index 0000000..c151d6f --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForceTupleInputData.cs @@ -0,0 +1,18 @@ +using LoaderCalculator.Data.Ndms; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface IForceTupleInputData + { + IEnumerable NdmCollection { get; set; } + IForceTuple Tuple { get; set; } + IAccuracy Accuracy { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesResults.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesResults.cs index 9c8fd39..e0f5ddd 100644 --- a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesResults.cs +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesResults.cs @@ -5,7 +5,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces public interface IForcesResults : INdmResult { string Desctription { get; set; } - List ForcesResultList { get; } + List ForcesResultList { get; } bool IsValid { get; set; } } } \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesTupleResult.cs b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesTupleResult.cs new file mode 100644 index 0000000..4a108fc --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Analyses/ByForces/IForcesTupleResult.cs @@ -0,0 +1,11 @@ +using LoaderCalculator.Data.ResultData; +using StructureHelperCommon.Models.Forces; + +namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces +{ + public interface IForcesTupleResult : INdmResult + { + IDesignForceTuple DesignForceTuple { get; set; } + ILoaderResults LoaderResults { get; set; } + } +} \ No newline at end of file diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs new file mode 100644 index 0000000..0738077 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingCalculator.cs @@ -0,0 +1,177 @@ +using LoaderCalculator.Data.Materials.MaterialBuilders; +using LoaderCalculator.Data.Ndms; +using LoaderCalculator.Logics; +using LoaderCalculator.Logics.Geometry; +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Shapes; +using StructureHelperCommon.Services.Forces; +using StructureHelperLogics.Models.Materials; +using StructureHelperLogics.NdmCalculations.Analyses; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Primitives; +using StructureHelperLogics.Services.NdmPrimitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ConcreteBucklingCalculator : IConcreteBucklingCalculator + { + private IConcreteBucklingOptions options; + private IEilerCriticalForceLogic criticalForceLogic; + private IRCStiffnessLogic stiffnessLogicX, stiffnessLogicY; + private List ndmCollection; + private List concreteNdms; + private List otherNdms; + IForcesTupleResult forcesResults; + + public string Name { get; set; } + + public INdmResult Result { get; private set; } + + public IAccuracy Accuracy { get; set; } + + private (double EtaAlongX, double EtaAlongY) GetBucklingCoefficients() + { + var stiffness = GetStiffness(); + criticalForceLogic.LongForce = options.CalcForceTuple.Nz; + criticalForceLogic.StiffnessEI = stiffness.DX; + criticalForceLogic.DesignLength = options.CompressedMember.GeometryLength * options.CompressedMember.LengthFactorY; + var etaAlongY = criticalForceLogic.GetEtaFactor(); + criticalForceLogic.StiffnessEI = stiffness.DY; + criticalForceLogic.DesignLength = options.CompressedMember.GeometryLength * options.CompressedMember.LengthFactorX; + var etaAlongX = criticalForceLogic.GetEtaFactor(); + return (etaAlongX, etaAlongY); + } + + public ConcreteBucklingCalculator(IConcreteBucklingOptions options, IAccuracy accuracy) + { + this.options = options; + Accuracy = accuracy; + + var allPrimitives = options.Primitives; + var concretePrimitives = GetConcretePrimitives(); + var otherPrimitives = allPrimitives.Except(concretePrimitives); + ndmCollection = NdmPrimitivesService.GetNdms(allPrimitives, options.LimitState, options.CalcTerm); + concreteNdms = NdmPrimitivesService.GetNdms(concretePrimitives, options.LimitState, options.CalcTerm); + otherNdms = NdmPrimitivesService.GetNdms(otherPrimitives, options.LimitState, options.CalcTerm); + } + + private (IConcreteDeltaELogic DeltaLogicX, IConcreteDeltaELogic DeltaLogicY) GetDeltaLogics() + { + IForceTuple forceTuple = options.CalcForceTuple; + if (forceTuple.Nz >= 0) { return (new ConstDeltaELogic(), new ConstDeltaELogic()); } + var eccentricityAlongX = options.CalcForceTuple.My / forceTuple.Nz; + var eccentricityAlongY = options.CalcForceTuple.Mx / forceTuple.Nz; + 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); + var DeltaElogicAboutY = new DeltaELogicSP63(eccentricityAlongX, sizeAlongX); + return (DeltaElogicAboutX, DeltaElogicAboutY); + } + + private IEnumerable GetConcretePrimitives() + { + var primitives = options.Primitives.Where(x => x.HeadMaterial.HelperMaterial is IConcreteLibMaterial); + return primitives; + } + + private (double DX, double DY) GetStiffness() + { + var gravityCenter = GeometryOperations.GetGravityCenter(ndmCollection); + + var concreteInertia = GeometryOperations.GetMomentsOfInertiaMod(concreteNdms, gravityCenter); + var otherInertia = GeometryOperations.GetMomentsOfInertiaMod(otherNdms, gravityCenter); + + var stiffnessX = stiffnessLogicX.GetStiffnessCoeffitients(); + var dX = stiffnessX.Kc * concreteInertia.MomentX + stiffnessX.Ks * otherInertia.MomentX; + + var stiffnessY = stiffnessLogicY.GetStiffnessCoeffitients(); + var dY = stiffnessY.Kc * concreteInertia.MomentY + stiffnessY.Ks * otherInertia.MomentY; + + return (dX, dY); + } + + private IConcretePhiLLogic GetPhiLogic() + { + IPoint2D point = GetMostTensionedPoint(); + var phiLogic = new PhiLogicSP63(options.CalcForceTuple, options.LongTermTuple, point); + return phiLogic; + } + + private IPoint2D GetMostTensionedPoint() + { + var strains = forcesResults.LoaderResults.StrainMatrix; + double maxStrain = double.NegativeInfinity; + IPoint2D point = new Point2D(); + var stressLogic = new StressLogic(); + foreach (var item in ndmCollection) + { + var strain = stressLogic.GetTotalStrain(strains, item); + if (strain > maxStrain) + { + maxStrain = strain; + point = new Point2D() { X = item.CenterX, Y = item.CenterY }; + } + } + return point; + } + + private IForceTupleCalculator GetForceCalculator() + { + var tuple = options.CalcForceTuple; + IForceTupleInputData inputData = new ForceTupleInputData() { NdmCollection = ndmCollection, Tuple = tuple, Accuracy = Accuracy }; + IForceTupleCalculator calculator = new ForceTupleCalculator(inputData); + return calculator; + } + + public void Run() + { + var checkResult = CheckInputData(); + if (checkResult != "") + { + Result = new ConcreteBucklingResult() { IsValid = false, Desctription = checkResult }; + return; + } + else + { + IConcretePhiLLogic phiLLogic = GetPhiLogic(); + var (DeltaLogicAboutX, DeltaLogicAboutY) = GetDeltaLogics(); + stiffnessLogicX = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutX); + stiffnessLogicY = new RCStiffnessLogicSP63(phiLLogic, DeltaLogicAboutY); + criticalForceLogic = new EilerCriticalForceLogic(); + + var (EtaFactorX, EtaFactorY) = GetBucklingCoefficients(); + Result = new ConcreteBucklingResult() + { + IsValid = true, + EtaFactorAlongX = EtaFactorX, + EtaFactorAlongY = EtaFactorY + }; + } + } + + private string CheckInputData() + { + string result = ""; + IForceTupleCalculator calculator = GetForceCalculator(); + calculator.Run(); + forcesResults = calculator.Result as IForcesTupleResult; + if (forcesResults.IsValid != true) + { + result += "Bearind capacity of crosssection is not enough for initial forces\n"; + } + return result; + } + + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingOptions.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingOptions.cs new file mode 100644 index 0000000..820b7f2 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingOptions.cs @@ -0,0 +1,29 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + /// + internal class ConcreteBucklingOptions : IConcreteBucklingOptions + { + /// + public IForceTuple LongTermTuple { get; set; } + /// + public ICompressedMember CompressedMember { get; set; } + /// + public LimitStates LimitState { get; set; } + /// + public CalcTerms CalcTerm { get; set; } + /// + public IEnumerable Primitives { get; set; } + /// + public IForceTuple CalcForceTuple { get; set; } +} +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingResult.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingResult.cs new file mode 100644 index 0000000..1d3e233 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConcreteBucklingResult.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + /// + public class ConcreteBucklingResult : IConcreteBucklingResult + { + /// + public bool IsValid { get; set; } + /// + public string Desctription { get; set; } + /// + public double EtaFactorAlongX { get; set; } + /// + public double EtaFactorAlongY { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConstDeltaELogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConstDeltaELogic.cs new file mode 100644 index 0000000..ed60dd4 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConstDeltaELogic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class ConstDeltaELogic : IConcreteDeltaELogic + { + public double GetDeltaE() + { + return 1.5d; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ConstPhiLLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/ConstPhiLLogic.cs new file mode 100644 index 0000000..a9cdc03 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ConstPhiLLogic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal class ConstPhiLLogic : IConcretePhiLLogic + { + public double GetPhil() + { + return 2.0d; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/CriticalForceSP63Logic.cs b/StructureHelperLogics/NdmCalculations/Buckling/CriticalForceSP63Logic.cs new file mode 100644 index 0000000..6d14887 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/CriticalForceSP63Logic.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal class CriticalForceSP63Logic : ICriticalBucklingForceLogic + { + double concreteFactor, reinforcementFactor; + + public double GetCriticalForce() + { + throw new NotImplementedException(); + } + + public double GetEtaFactor() + { + throw new NotImplementedException(); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/DeltaELogicSP63.cs b/StructureHelperLogics/NdmCalculations/Buckling/DeltaELogicSP63.cs new file mode 100644 index 0000000..631aab6 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/DeltaELogicSP63.cs @@ -0,0 +1,36 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Strings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class DeltaELogicSP63 : IConcreteDeltaELogic + { + const double deltaEMin = 0.15d; + const double deltaEMax = 1.5d; + + readonly double eccentricity; + readonly double size; + public DeltaELogicSP63(double eccentricity, double size) + { + if (size <= 0 ) + { + throw new StructureHelperException(ErrorStrings.SizeMustBeGreaterThanZero + $", actual size: {size}"); + } + this.eccentricity = eccentricity; + this.size = size; + } + + public double GetDeltaE() + { + var deltaE = Math.Abs(eccentricity) / size; + deltaE = Math.Max(deltaE, deltaEMin); + deltaE = Math.Min(deltaE, deltaEMax); + return deltaE; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/EilerCriticalForceLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/EilerCriticalForceLogic.cs new file mode 100644 index 0000000..9a76b38 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/EilerCriticalForceLogic.cs @@ -0,0 +1,35 @@ +using StructureHelperCommon.Infrastructures.Exceptions; +using StructureHelperCommon.Infrastructures.Strings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal class EilerCriticalForceLogic : IEilerCriticalForceLogic + { + public double LongForce { get; set; } + public double StiffnessEI { get; set; } + public double DesignLength { get; set; } + + public double GetCriticalForce() + { + double Ncr = - Math.Pow(Math.PI, 2) * StiffnessEI / (Math.Pow(DesignLength, 2)); + return Ncr; + } + + public double GetEtaFactor() + { + if (LongForce >= 0d) return 1d; + var Ncr = GetCriticalForce(); + if (LongForce <= Ncr) + { + throw new StructureHelperException(ErrorStrings.LongitudinalForceMustBeLessThanCriticalForce); + } + double eta = 1 / (1 - LongForce / Ncr); + return eta; + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IBucklingOptions.cs b/StructureHelperLogics/NdmCalculations/Buckling/IBucklingOptions.cs new file mode 100644 index 0000000..ecfc7c3 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IBucklingOptions.cs @@ -0,0 +1,21 @@ +using StructureHelperCommon.Infrastructures.Enums; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Sections; +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IBucklingOptions + { + ICompressedMember CompressedMember { get; } + LimitStates LimitState { get; } + CalcTerms CalcTerm { get; } + IEnumerable Primitives { get; } + IForceTuple CalcForceTuple { get; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingCalculator.cs b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingCalculator.cs new file mode 100644 index 0000000..6555062 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingCalculator.cs @@ -0,0 +1,15 @@ +using StructureHelperCommon.Models.Calculators; +using StructureHelperLogics.NdmCalculations.Analyses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal interface IConcreteBucklingCalculator : INdmCalculator + { + IAccuracy Accuracy { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingOptions.cs b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingOptions.cs new file mode 100644 index 0000000..5ee4b4b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingOptions.cs @@ -0,0 +1,15 @@ +using StructureHelperCommon.Models.Calculators; +using StructureHelperCommon.Models.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IConcreteBucklingOptions : IBucklingOptions + { + IForceTuple LongTermTuple { get; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingResult.cs b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingResult.cs new file mode 100644 index 0000000..635aa2b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteBucklingResult.cs @@ -0,0 +1,24 @@ +using StructureHelperLogics.NdmCalculations.Analyses; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + ///

+ /// Results of calculation of buckling of reinforced concrete section + /// + public interface IConcreteBucklingResult : INdmResult + { + /// + /// Factor of increasing of bending moment (p-delta effect) in the plain XOZ + /// + double EtaFactorAlongX { get; set; } + /// + /// Factor of increasing of bending moment (p-delta effect) in the plain YOZ + /// + double EtaFactorAlongY { get; set; } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IConcreteDeltaELogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteDeltaELogic.cs new file mode 100644 index 0000000..5654179 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IConcreteDeltaELogic.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal interface IConcreteDeltaELogic + { + double GetDeltaE(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IConcretePhiLLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IConcretePhiLLogic.cs new file mode 100644 index 0000000..504e935 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IConcretePhiLLogic.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IConcretePhiLLogic + { + double GetPhil(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/ICriticalBucklingForceLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/ICriticalBucklingForceLogic.cs new file mode 100644 index 0000000..1d14189 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/ICriticalBucklingForceLogic.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal interface ICriticalBucklingForceLogic + { + double GetCriticalForce(); + double GetEtaFactor(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IEilerCriticalForceLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IEilerCriticalForceLogic.cs new file mode 100644 index 0000000..c778b72 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IEilerCriticalForceLogic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal interface IEilerCriticalForceLogic : ICriticalBucklingForceLogic + { + double LongForce { get; set; } + double StiffnessEI { get; set; } + double DesignLength { get; set; } + + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/IRCStiffnessLogic.cs b/StructureHelperLogics/NdmCalculations/Buckling/IRCStiffnessLogic.cs new file mode 100644 index 0000000..39cee43 --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/IRCStiffnessLogic.cs @@ -0,0 +1,14 @@ +using StructureHelperLogics.NdmCalculations.Primitives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public interface IRCStiffnessLogic + { + (double Kc, double Ks) GetStiffnessCoeffitients(); + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/PhiLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Buckling/PhiLogicSP63.cs new file mode 100644 index 0000000..cb02ffd --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/PhiLogicSP63.cs @@ -0,0 +1,41 @@ +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Shapes; +using StructureHelperCommon.Services.Forces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + public class PhiLogicSP63 : IConcretePhiLLogic + { + readonly IForceTuple fullForceTuple; + readonly IForceTuple longForceTuple; + readonly IPoint2D point; + public PhiLogicSP63(IForceTuple fullForceTuple, IForceTuple longForceTuple, IPoint2D point) + { + this.fullForceTuple = fullForceTuple; + this.longForceTuple = longForceTuple; + this.point = point; + } + + public double GetPhil() + { + var distance = Math.Sqrt(point.X * point.X + point.Y * point.Y); + var fullMoment = GetMoment(fullForceTuple, distance); + var longMoment = GetMoment(longForceTuple, distance); + if (fullMoment == 0d) { return 2d; } + var phi = 1 + longMoment / fullMoment; + phi = Math.Max(1, phi); + phi = Math.Min(2, phi); + return phi; + } + + private double GetMoment(IForceTuple forceTuple, double distance) + { + return Math.Abs(forceTuple.Nz) * distance + Math.Abs(forceTuple.Mx) + Math.Abs(forceTuple.My); + } + } +} diff --git a/StructureHelperLogics/NdmCalculations/Buckling/RCStiffnessLogicSP63.cs b/StructureHelperLogics/NdmCalculations/Buckling/RCStiffnessLogicSP63.cs new file mode 100644 index 0000000..357a14b --- /dev/null +++ b/StructureHelperLogics/NdmCalculations/Buckling/RCStiffnessLogicSP63.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StructureHelperLogics.NdmCalculations.Buckling +{ + internal class RCStiffnessLogicSP63 : IRCStiffnessLogic + { + IConcretePhiLLogic phiLLogic { get; } + IConcreteDeltaELogic deltaELogic { get; } + + public RCStiffnessLogicSP63() : this(new ConstPhiLLogic(), new ConstDeltaELogic()) { } + + public RCStiffnessLogicSP63(IConcretePhiLLogic phiLLogic, IConcreteDeltaELogic deltaELogic) + { + this.phiLLogic = phiLLogic; + this.deltaELogic = deltaELogic; + } + + public (double Kc, double Ks) GetStiffnessCoeffitients() + { + const double initialKs = 0.7d; + const double initialKc = 0.15d; + const double deltaEAddition = 0.3d; + double phiL = phiLLogic.GetPhil(); + double deltaE = deltaELogic.GetDeltaE(); + double kc = initialKc / (phiL * (deltaEAddition + deltaE)); + return (kc, initialKs); + } + } +} diff --git a/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs b/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs index 11ced04..5d1cd4b 100644 --- a/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs +++ b/StructureHelperLogics/Services/NdmCalculations/InterpolateService.cs @@ -1,5 +1,6 @@ using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Services.Forces; +using StructureHelperCommon.Services.Sections; using StructureHelperLogics.Models.Primitives; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using System; @@ -19,8 +20,8 @@ namespace StructureHelperLogics.Services.NdmCalculations calculator.LimitStatesList.Add(finishDesignForce.LimitState); calculator.CalcTermsList.Clear(); calculator.CalcTermsList.Add(finishDesignForce.CalcTerm); - calculator.Accuracy.IterationAccuracy = source.Accuracy.IterationAccuracy; - calculator.Accuracy.MaxIterationCount = source.Accuracy.MaxIterationCount; + CompressedMemberServices.CopyProperties(source.CompressedMember, calculator.CompressedMember); + calculator.Accuracy = source.Accuracy; calculator.Primitives.AddRange(source.Primitives); calculator.ForceCombinationLists.Clear(); var combination = new ForceCombinationList() diff --git a/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs b/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs index 07c92a1..26c8f1d 100644 --- a/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs +++ b/StructureHelperTests/FunctionalTests/Ndms/Calculators/ForceCalculatorTests/RCSectionsTest.cs @@ -1,4 +1,5 @@ using LoaderCalculator.Tests.Infrastructures.Logics; +using Moq; using NUnit.Framework; using StructureHelperLogics.Models.Templates.CrossSections.RCs; using StructureHelperLogics.Models.Templates.RCs; @@ -8,15 +9,19 @@ namespace StructureHelperTests.FunctionalTests.Ndms.Calculators.ForceCalculatorT { public class RCSectionsTest { - [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 2, 2, -0.00062544561815463693d, -0.0029292919541166911d, 0.00035383082501577246d)] - [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 3, 2, -0.00046762265275279838d, -0.0025101896869558888d, 0.00027185795017719519d)] - [TestCase(0.5d, 0.5d, 0.025d, 0.025d, 3, 3, -0.00080914991212906239d, -0.00080914991212906184d, 0.00011900072665826425d)] - public void Run_SouldPass(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount, double expectedKx, double expectedKy, double expectedEpsZ) + [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 2, 2, false, -0.00062544561815463693d, -0.0029292919541166911d, 0.00035383082501577246d)] + [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 3, 2, false, -0.00046762265275279838d, -0.0025101896869558888d, 0.00027185795017719519d)] + [TestCase(0.5d, 0.5d, 0.025d, 0.025d, 3, 3, false, -0.00080914991212906239d, -0.00080914991212906184d, 0.00011900072665826425d)] + [TestCase(0.5d, 0.5d, 0.025d, 0.025d, 3, 3, true, -0.0008126213321004612d, -0.00081262133210046055d, 0.00011963568117586145d)] + [TestCase(0.5d, 0.6d, 0.025d, 0.025d, 3, 3, true, -0.00047720148631058529d, -0.00077269031816753532d, 0.00010610472872420363d)] + [TestCase(0.6d, 0.5d, 0.025d, 0.025d, 3, 3, true, -0.00077269031816753478d, -0.00047720148631058437d, 0.00010610472872420363d)] + public void Run_ShouldPass(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount, bool isBuckling, double expectedKx, double expectedKy, double expectedEpsZ) { //Arrange var template = new RectangleBeamTemplate(width, height) { TopDiameter = topDiametr, BottomDiameter = bottomDiametr, WidthCount = widthCount, HeightCount = heightCount}; var newSection = new SectionTemplate(new RectGeometryLogic(template)).GetCrossSection(); - var calculator = newSection.SectionRepository.CalculatorsList[0]; + var calculator = newSection.SectionRepository.CalculatorsList[0] as IForceCalculator; + calculator.CompressedMember.Buckling = isBuckling; //Act calculator.Run(); var result = calculator.Result as IForcesResults; @@ -32,15 +37,16 @@ namespace StructureHelperTests.FunctionalTests.Ndms.Calculators.ForceCalculatorT Assert.AreEqual(expectedEpsZ, epsz, ExpectedProcessor.GetAccuracyForExpectedValue(expectedEpsZ)); } - [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 2, 2, true, true)] - [TestCase(1d, 0.2d, 0.012d, 0.012d, 5, 2, true, false)] - [TestCase(1d, 0.2d, 0.012d, 0.025d, 5, 2, true, true)] - public void Run_SouldPass_Result_IsNotValid(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount, bool calcResult, bool firstForceResult) + [TestCase(0.4d, 0.6d, 0.012d, 0.025d, 2, 2, false, true, true)] + [TestCase(1d, 0.2d, 0.012d, 0.012d, 5, 2, false, true, false)] + [TestCase(1d, 0.2d, 0.012d, 0.025d, 5, 2, false, true, true)] + public void Run_ShouldPass_Result_IsNotValid(double width, double height, double topDiametr, double bottomDiametr, int widthCount, int heightCount,bool isBuckling, bool calcResult, bool firstForceResult) { //Arrange var template = new RectangleBeamTemplate(width, height) { TopDiameter = topDiametr, BottomDiameter = bottomDiametr, WidthCount = widthCount, HeightCount = heightCount }; var newSection = new SectionTemplate(new RectGeometryLogic(template)).GetCrossSection(); - var calculator = newSection.SectionRepository.CalculatorsList[0]; + var calculator = newSection.SectionRepository.CalculatorsList[0] as IForceCalculator; + calculator.CompressedMember.Buckling = isBuckling; //Act calculator.Run(); var result = calculator.Result as IForcesResults; diff --git a/StructureHelperTests/FunctionalTests/Ndms/RCSections/BucklingLogicTest.cs b/StructureHelperTests/FunctionalTests/Ndms/RCSections/BucklingLogicTest.cs new file mode 100644 index 0000000..56abd72 --- /dev/null +++ b/StructureHelperTests/FunctionalTests/Ndms/RCSections/BucklingLogicTest.cs @@ -0,0 +1,50 @@ +using LoaderCalculator.Tests.Infrastructures.Logics; +using Moq; +using NUnit.Framework; +using StructureHelperCommon.Models.Forces; +using StructureHelperCommon.Models.Shapes; +using StructureHelperLogics.Models.Templates.CrossSections.RCs; +using StructureHelperLogics.Models.Templates.RCs; +using StructureHelperLogics.NdmCalculations.Analyses.ByForces; +using StructureHelperLogics.NdmCalculations.Buckling; + +namespace StructureHelperTests.FunctionalTests.Ndms.RCSections +{ + public class BucklingLogicTest + { + [TestCase(0d, 0d, 0d, 0d, 0d, -100d, -0.15d, 0.15d, 1d)] + [TestCase(0d, 0d, -50d, 0d, 0d, -100d, -0.15d, 0.15d, 1.5d)] + [TestCase(0d, 0d, -100d, 0d, 0d, -100d, -0.15d, 0.15d, 2d)] + [TestCase(0d, 0d, 0d, -10d, 0d, -100d, -0.15d, 0.15d, 1d)] + [TestCase(-5d, 0d, -50d, -10d, 0d, -100d, -0.15d, 0.15d, 1.5d)] + [TestCase(-10d, 0d, -100d, -10d, 0d, -100d, -0.15d, 0.15d, 2d)] + [TestCase(0d, 0d, 0d, -10d, 10d, -100d, -0.15d, 0.15d, 1d)] + [TestCase(-5d, 5d, -50d, -10d, 10d, -100d, -0.15d, 0.15d, 1.5d)] + [TestCase(-10d, 10d, -100d, -10d, 10d, -100d, -0.15d, 0.15d, 2d)] + public void Run_ShoulPass_PhiLogicSP63(double longMx, double longMy, double longNz, double shortMx, double shortMy, double shortNz, double pointX, double pointY, double expectedPhi) + { + //Arrange + var fullTuple = new ForceTuple() { Mx = shortMx, My = shortMy, Nz = shortNz }; + var longTuple = new ForceTuple() { Mx = longMx, My = longMy, Nz = longNz }; + var point = new Point2D() { X = pointX, Y = pointY }; + //Act + var phiLogic = new PhiLogicSP63(fullTuple, longTuple, point); + var phiL = phiLogic.GetPhil(); + //Assert + Assert.AreEqual(expectedPhi, phiL, 0.01d); + } + + [TestCase(0d, 0.5d, 0.15d)] + [TestCase(0.1d, 0.5d, 0.2d)] + [TestCase(1d, 0.5d, 1.5d)] + public void Run_ShoulPass_DeltaELogicSP63(double eccentricity, double size, double expectedDeltaE) + { + //Arrange + //Act + var deltaELogic = new DeltaELogicSP63(eccentricity, size); + var deltaE = deltaELogic.GetDeltaE(); + //Assert + Assert.AreEqual(expectedDeltaE, deltaE, 0.01d); + } + } +} diff --git a/StructureHelperTests/StructureHelperTests.csproj b/StructureHelperTests/StructureHelperTests.csproj index 3c234b3..7b76be3 100644 --- a/StructureHelperTests/StructureHelperTests.csproj +++ b/StructureHelperTests/StructureHelperTests.csproj @@ -1,7 +1,7 @@  - + Debug AnyCPU @@ -44,6 +44,7 @@ + @@ -58,16 +59,14 @@ - ..\packages\Castle.Core.5.1.0\lib\net462\Castle.Core.dll - True + ..\packages\Castle.Core.5.1.1\lib\net462\Castle.Core.dll ..\Libraries\LoaderCalculator.dll True - ..\packages\Moq.4.18.2\lib\net462\Moq.dll - True + ..\packages\Moq.4.18.4\lib\net462\Moq.dll ..\packages\NUnit.3.13.3\lib\net45\nunit.framework.dll @@ -112,7 +111,7 @@ + - \ No newline at end of file diff --git a/StructureHelperTests/app.config b/StructureHelperTests/app.config index 0075fb7..5bd96bc 100644 --- a/StructureHelperTests/app.config +++ b/StructureHelperTests/app.config @@ -8,7 +8,19 @@ - + + + + + + + + + + + + + diff --git a/StructureHelperTests/packages.config b/StructureHelperTests/packages.config index 7c07542..a3a8821 100644 --- a/StructureHelperTests/packages.config +++ b/StructureHelperTests/packages.config @@ -1,9 +1,9 @@  - - + + - + \ No newline at end of file diff --git a/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceCalculatorView.xaml b/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceCalculatorView.xaml index 2363cdf..411ecb2 100644 --- a/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceCalculatorView.xaml +++ b/Windows/CalculationWindows/CalculatorsViews/ForceCalculatorViews/ForceCalculatorView.xaml @@ -49,7 +49,7 @@ - + diff --git a/Windows/MainWindow/MainViewModel.cs b/Windows/MainWindow/MainViewModel.cs index 7feb8af..e7df72c 100644 --- a/Windows/MainWindow/MainViewModel.cs +++ b/Windows/MainWindow/MainViewModel.cs @@ -287,11 +287,11 @@ namespace StructureHelper.Windows.MainWindow { if (CheckMaterials() == false) { return;} var ndms = NdmPrimitivesService.GetNdms(repository.Primitives, LimitStates.SLS, CalcTerms.ShortTerm); - double[] center = GeometryOperations.GetGravityCenter(ndms); + var center = GeometryOperations.GetGravityCenter(ndms); foreach (var item in PrimitiveLogic.Items) { - item.CenterX -= center[0]; - item.CenterY -= center[1]; + item.CenterX -= center.CenterX; + item.CenterY -= center.CenterY; } }, o => repository.Primitives.Count() > 0 diff --git a/Windows/PrimitivePropertiesWindow/PrimitivePropertiesView.xaml b/Windows/PrimitivePropertiesWindow/PrimitivePropertiesView.xaml index b59edfe..173a83f 100644 --- a/Windows/PrimitivePropertiesWindow/PrimitivePropertiesView.xaml +++ b/Windows/PrimitivePropertiesWindow/PrimitivePropertiesView.xaml @@ -112,23 +112,24 @@ + + + - - - + - - + + - - - - - + + + + + diff --git a/Windows/ViewModels/Calculations/Calculators/ForcesResultsViewModel.cs b/Windows/ViewModels/Calculations/Calculators/ForcesResultsViewModel.cs index bbba5ac..de01491 100644 --- a/Windows/ViewModels/Calculations/Calculators/ForcesResultsViewModel.cs +++ b/Windows/ViewModels/Calculations/Calculators/ForcesResultsViewModel.cs @@ -41,7 +41,7 @@ namespace StructureHelper.Windows.ViewModels.Calculations.Calculators private IEnumerable ndms; private IReport isoFieldReport; - public ForcesResult SelectedResult { get; set; } + public ForcesTupleResult SelectedResult { get; set; } private RelayCommand showIsoFieldCommand; private RelayCommand exportToCSVCommand; private RelayCommand interpolateCommand; diff --git a/Windows/ViewModels/NdmCrossSections/SecondOrderViewModel.cs b/Windows/ViewModels/NdmCrossSections/SecondOrderViewModel.cs index fe267b0..3294617 100644 --- a/Windows/ViewModels/NdmCrossSections/SecondOrderViewModel.cs +++ b/Windows/ViewModels/NdmCrossSections/SecondOrderViewModel.cs @@ -37,7 +37,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections get => member.LengthFactorX; set { - member.GeometryLength = value; + member.LengthFactorX = value; OnPropertyChanged(nameof(LengthFactorX)); } } @@ -47,7 +47,7 @@ namespace StructureHelper.Windows.ViewModels.NdmCrossSections get => member.LengthFactorY; set { - member.GeometryLength = value; + member.LengthFactorY= value; OnPropertyChanged(nameof(LengthFactorY)); } }