using LoaderCalculator.Data.Ndms; using LoaderCalculator.Logics; using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Exceptions; using StructureHelperCommon.Models; using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Forces; using StructureHelperCommon.Models.Loggers; using StructureHelperCommon.Services.Forces; using StructureHelperLogics.NdmCalculations.Analyses.ByForces; using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.NdmCalculations.Triangulations; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StructureHelperLogics.NdmCalculations.Cracking { public class RebarStressSofteningLogic : ICrackSofteningLogic { /// /// Rebar result immediately after cracking appearance /// private RebarStressResult crackRebarResult; /// /// Rebar resul for actual force combination /// private RebarStressResult actualRebarResult; private TriangulationOptions options; private INdm? concreteNdm; private INdm? rebarNdm; private double rebarActualStrain; private double concreteStrainActual; private double rebarActualStress; private double softeningFactor; private double minValueOfFactor = 0.2d; private IRebarPrimitive rebarPrimitive; private IRebarCrackInputData inputData; public double MinValueOfFactor { get => minValueOfFactor; set { minValueOfFactor = value; IsResultActual = false; } } public IRebarPrimitive RebarPrimitive { get => rebarPrimitive; set { rebarPrimitive = value; IsResultActual = false; } } public IRebarCrackInputData InputData { get => inputData; set { inputData = value; IsResultActual = false; } } public IShiftTraceLogger? TraceLogger { get; set; } public bool IsResultActual { get; private set; } = false; public double GetSofteningFactor() { TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Debug); if (IsResultActual == false) { GetRebarAndConcreteNdms(); softeningFactor = GetPsiSFactor(InputData.ForceTuple, InputData.CrackableNdmCollection); IsResultActual = true; } return softeningFactor; } private void GetRebarAndConcreteNdms() { options = new TriangulationOptions() { CalcTerm = CalcTerms.ShortTerm, LimiteState = LimitStates.SLS, }; concreteNdm = RebarPrimitive.GetConcreteNdm(options); concreteNdm.StressScale = 1d; rebarNdm = RebarPrimitive.GetRebarNdm(options); } private double GetPsiSFactor(ForceTuple forceTuple, IEnumerable crackableNdms) { var crackResult = calculateCrackTuples(forceTuple, crackableNdms); if (crackResult.IsValid == false) { string errorString = LoggerStrings.CalculationError + crackResult.Description; TraceLogger?.AddMessage($"Rebar name: {RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error); throw new StructureHelperException(errorString); } actualRebarResult = GetRebarStressResultByForceTuple(forceTuple); rebarActualStrain = actualRebarResult.RebarStrain; rebarActualStress = actualRebarResult.RebarStress; TraceLogger?.AddMessage($"Actual strain of rebar EpsilonS = {rebarActualStrain}(dimensionless)"); concreteStrainActual = concreteNdm .PrestrainLogic .GetAll() .Sum(x => x.PrestrainValue); TraceLogger?.AddMessage($"Actual strain of concrete on the axis of rebar EpsilonC = {concreteStrainActual}(dimensionless)"); if (crackResult.IsSectionCracked == false) { TraceLogger?.AddMessage($"Section is not cracked PsiS = {MinValueOfFactor}"); return MinValueOfFactor; } if (crackResult.FactorOfCrackAppearance == 0d) { TraceLogger?.AddMessage($"Section is cracked in start force combination, PsiS = 1.0"); return 1d; } crackRebarResult = GetRebarStressResultByForceTuple(crackResult.TupleOfCrackAppearance as ForceTuple); var stressInCracking = crackRebarResult.RebarStress; TraceLogger?.AddMessage($"Stress in rebar immediately after cracking Sigma,scrc = {stressInCracking}(Pa)"); TraceLogger?.AddMessage($"Actual stress in rebar Sigma,s = {rebarActualStress}(Pa)"); double psiS = GetExponentialSofteningFactor(stressInCracking); TraceLogger?.AddMessage($"PsiS = {psiS}"); return psiS; } private double GetExponentialSofteningFactor(double stressInCracking) { var stressRatio = stressInCracking / rebarActualStress; var logic = new ExpSofteningLogic() { ForceRatio = stressRatio, PsiSMin = MinValueOfFactor, PowerFactor = 1d, BettaFactor = 0.8d, TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) }; double psiS = logic.GetSofteningFactor(); return psiS; } private CrackForceResult calculateCrackTuples(ForceTuple forceTuple, IEnumerable ndms) { var calculator = new CrackForceBynarySearchCalculator() { Accuracy = new Accuracy() { IterationAccuracy = 0.01d, MaxIterationCount = 1000 }, //TraceLogger = TraceLogger?.GetSimilarTraceLogger(150) }; calculator.InputData.StartTuple = new ForceTuple(); calculator.InputData.EndTuple = forceTuple; calculator.InputData.CheckedNdmCollection = new List() { concreteNdm }; calculator.InputData.SectionNdmCollection = ndms; calculator.Run(); return calculator.Result as CrackForceResult; } private RebarStressResult GetRebarStressResultByForceTuple(ForceTuple forceTuple) { var calculator = new RebarStressCalculator(); calculator.InputData.ForceTuple = forceTuple; calculator.InputData.NdmCollection = InputData.CrackedNdmCollection; calculator.InputData.RebarPrimitive = RebarPrimitive; calculator.Run(); var result = calculator.Result as RebarStressResult; if (result.IsValid == false) { string errorString = LoggerStrings.CalculationError + result.Description; TraceLogger?.AddMessage($"Rebar name: {RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error); throw new StructureHelperException(errorString); } return result; } } }