using LoaderCalculator.Data.Ndms; using StructureHelperCommon.Infrastructures.Enums; 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 StructureHelperLogics.Models.Materials; using StructureHelperLogics.NdmCalculations.Buckling; using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.Services.NdmPrimitives; namespace StructureHelperLogics.NdmCalculations.Analyses.ByForces { /// public class ForceCalculatorLogic : IForceCalculatorLogic { private ForceCalculatorResult result; private IProcessorLogic eccentricityLogic; private ForceTupleBucklingLogic bucklingLogic; private ITriangulatePrimitiveLogic triangulateLogic; private List combinationLists; public IForceCalculatorInputData InputData { get; set; } public IShiftTraceLogger? TraceLogger { get; set; } public Action ActionToOutputResults { get; set; } public ForceCalculatorResult GetForcesResults() { TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service); TraceInputData(); GetCombinations(); CalculateResult(); TraceResult(); return result; } private void TraceResult() { TraceForcesResultLogic traceLogic = new() { Collection = result.ForcesResultList }; List traceEntries = traceLogic.GetTraceEntries(); foreach (var item in traceEntries) { TraceLogger?.AddEntry(item); } } private void TraceInputData() { ITraceEntityLogic tracelogic = new TracePrimitiveFactory() { Collection = InputData.Primitives }; tracelogic.AddEntriesToTraceLogger(TraceLogger); tracelogic = new TraceMaterialsFactory() { Collection = InputData.Primitives.Select(x => x.NdmElement.HeadMaterial).Distinct() }; tracelogic.AddEntriesToTraceLogger(TraceLogger); } private void CalculateResult() { result = new ForceCalculatorResult() { IsValid = true }; foreach (var combination in combinationLists) { foreach (var tuple in combination.DesignForces) { var limitState = tuple.LimitState; var calcTerm = tuple.CalcTerm; if (InputData.LimitStatesList.Contains(limitState) & InputData.CalcTermsList.Contains(calcTerm)) { ExtendedForceTupleCalculatorResult extendedResult = new(); extendedResult.StateCalcTermPair.LimitState = limitState; extendedResult.StateCalcTermPair.CalcTerm = calcTerm; try { IForceTupleCalculatorResult tupleResult = ProcessNdmResult(combination, tuple); extendedResult.IsValid = tupleResult.IsValid; extendedResult.ForcesTupleResult = tupleResult; } catch (Exception ex) { extendedResult.IsValid = false; extendedResult.Description += ex.Message; } result.ForcesResultList.Add(extendedResult); ActionToOutputResults?.Invoke(result); } } } } private IForceTupleCalculatorResult ProcessNdmResult(IForceCombinationList combination, IDesignForceTuple tuple) { IForceTupleCalculatorResult tupleResult; LimitStates limitState = tuple.LimitState; CalcTerms calcTerm = tuple.CalcTerm; triangulateLogic = new TriangulatePrimitiveLogic() { Primitives = InputData.Primitives, LimitState = limitState, CalcTerm = calcTerm, TraceLogger = TraceLogger }; var ndms = triangulateLogic.GetNdms(); 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 }; forcelogic = new ForceTupleMoveToPointDecorator(forcelogic) { Point2D = point2D }; } var newTuple = forcelogic.GetValue(); TraceLogger?.AddMessage("Input force combination"); TraceLogger?.AddEntry(new TraceTablesFactory().GetByForceTuple(newTuple)); if (InputData.CompressedMember.Buckling == true) { if (newTuple.Nz >= 0d) { TraceLogger?.AddMessage(string.Format("Second order effect is not considered as Nz={0} >= 0", newTuple.Nz)); tupleResult = GetForceResult(ndms, newTuple); } else { tupleResult = ProcessCompressedMember(combination, tuple, ndms, newTuple); } } else { if (newTuple.Nz < 0d) { string message = string.Format("Second order effect is not considered, despite force Nz={0}", newTuple.Nz); TraceLogger?.AddMessage(message, TraceLogStatuses.Warning); } tupleResult = GetForceResult(ndms, newTuple); } return tupleResult; } private IForceTupleCalculatorResult ProcessCompressedMember(IForceCombinationList combination, IDesignForceTuple tuple, List ndms, IForceTuple newTuple) { IForceTupleCalculatorResult tupleResult; LimitStates limitState = tuple.LimitState; CalcTerms calcTerm = tuple.CalcTerm; TraceLogger?.AddMessage("Get eccentricity for full load"); eccentricityLogic = new ProcessEccentricity(InputData.CompressedMember, ndms, newTuple) { TraceLogger = TraceLogger ?? null }; newTuple = eccentricityLogic.GetValue(); var buclingInputData = new BucklingInputData() { Combination = combination, LimitState = limitState, CalcTerm = calcTerm, Ndms = ndms, ForceTuple = newTuple }; bucklingLogic = new ForceTupleBucklingLogic(buclingInputData) { CompressedMember = InputData.CompressedMember, Accuracy = InputData.Accuracy, Primitives = InputData.Primitives, TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) }; var buckResult = bucklingLogic.GetForceTupleByBuckling(); if (buckResult.IsValid == true) { newTuple = buckResult.Value; } else { return new ForceTupleCalculatorResult() { IsValid = false, ForceTuple = tuple.ForceTuple, Description = buckResult.Description, }; } string message = string.Intern("Result of second order was obtained successfully, new force combination was obtained"); TraceLogger?.AddMessage(message); tupleResult = GetForceResult(ndms, newTuple); return tupleResult; } private IForceTupleCalculatorResult GetForceResult(List ndms, IForceTuple newTuple) { TraceLogger?.AddMessage("Calculation of cross-section is started"); var tupleResult = GetPrimitiveStrainMatrix(ndms, newTuple, InputData.Accuracy); return tupleResult; } private void GetCombinations() { combinationLists = new List(); foreach (var item in InputData.ForceActions) { combinationLists.AddRange(item.GetCombinations()); } } private IForceTupleCalculatorResult GetPrimitiveStrainMatrix(IEnumerable ndmCollection, IForceTuple tuple, IAccuracy accuracy) { var inputData = new ForceTupleInputData() { NdmCollection = ndmCollection, ForceTuple = tuple, Accuracy = accuracy, CheckStrainLimit = InputData.CheckStrainLimit, }; var calculator = new ForceTupleCalculator(); calculator.InputData = inputData; if (TraceLogger is not null) { calculator.TraceLogger = TraceLogger.GetSimilarTraceLogger(); } calculator.Run(); return calculator.Result as IForceTupleCalculatorResult; } } }