User data for cracks were added
This commit is contained in:
@@ -60,7 +60,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
|
||||
private void ProcessCalculations()
|
||||
{
|
||||
datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions)
|
||||
datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions, InputData.UserCrackInputData)
|
||||
{
|
||||
LimitState = limitState,
|
||||
LongTerm = longTerm,
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class CrackCalculatorUpdateStrategy : IUpdateStrategy<CrackCalculator>
|
||||
{
|
||||
private CrackInputDataUpdateStrategy inputDataUpdateStrategy => new();
|
||||
private CrackInputDataUpdateStrategy crackInputDataUpdateStrategy => new();
|
||||
public void Update(CrackCalculator targetObject, CrackCalculator sourceObject)
|
||||
{
|
||||
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||
@@ -18,7 +18,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
|
||||
targetObject.Name = sourceObject.Name;
|
||||
targetObject.InputData ??= new();
|
||||
inputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData);
|
||||
crackInputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,20 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
public List<INdmPrimitive> Primitives { get; private set; }
|
||||
/// <inheritdoc/>
|
||||
public List<IForceAction> ForceActions { get; private set; }
|
||||
public UserCrackInputData UserCrackInputData { get; private set; }
|
||||
public CrackInputData()
|
||||
{
|
||||
Primitives = new();
|
||||
ForceActions = new();
|
||||
UserCrackInputData = new()
|
||||
{
|
||||
SetSofteningFactor = true,
|
||||
SofteningFactor = 1d,
|
||||
SetLengthBetweenCracks = true,
|
||||
LengthBetweenCracks = 0.4d,
|
||||
UltimateLongCrackWidth = 0.0003d,
|
||||
UltimateShortCrackWidth = 0.0004d
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class CrackInputDataUpdateStrategy : IUpdateStrategy<CrackInputData>
|
||||
{
|
||||
private UserCrackInputDataUpdateStrategy userCrackInputDataUpdateStrategy => new();
|
||||
public void Update(CrackInputData targetObject, CrackInputData sourceObject)
|
||||
{
|
||||
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||
@@ -18,6 +19,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
targetObject.ForceActions.AddRange(sourceObject.ForceActions);
|
||||
targetObject.Primitives.Clear();
|
||||
targetObject.Primitives.AddRange(sourceObject.Primitives);
|
||||
|
||||
userCrackInputDataUpdateStrategy.Update(targetObject.UserCrackInputData, sourceObject.UserCrackInputData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public IForceTuple? ForceTuple { get; set; }
|
||||
public double CrackWidth { get; set; }
|
||||
public double UltimateCrackWidth { get; set; }
|
||||
public bool IsCrackLessThanUltimate => CrackWidth <= UltimateCrackWidth;
|
||||
public double RebarStrain { get; set; }
|
||||
public double ConcreteStrain { get; set; }
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
}
|
||||
public bool IsSectionCracked(double factor)
|
||||
{
|
||||
sectionCrackedLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
sectionCrackedLogic.TraceLogger ??= TraceLogger?.GetSimilarTraceLogger(50);
|
||||
|
||||
var actualTuple = ForceTupleService.InterpolateTuples(EndTuple, StartTuple, factor);
|
||||
sectionCrackedLogic.Tuple = actualTuple;
|
||||
|
||||
@@ -22,143 +22,41 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
internal class CrackWidthLogicInputDataFactory : ILogic
|
||||
{
|
||||
private IStressLogic stressLogic => new StressLogic();
|
||||
private const double longTermFactor = 1.4d;
|
||||
private const double shortTermFactor = 1d;
|
||||
private ICrackSofteningLogic softeningLogic;
|
||||
|
||||
private const double minimumPsiSFactor = 0.2d;
|
||||
private INdm concreteNdm;
|
||||
private INdm rebarNdm;
|
||||
private StrainTuple strainTupleActual;
|
||||
private double rebarStrainActual;
|
||||
private double concreteStrainActual;
|
||||
private double rebarStressActual;
|
||||
public double RebarStrain { get; set; }
|
||||
public double ConcreteStrain { get; set;}
|
||||
|
||||
public CalcTerms CalcTerm { get; set; }
|
||||
public RebarPrimitive RebarPrimitive { get; set; }
|
||||
public RebarCrackInputData InputData { get; set; }
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
|
||||
public CrackWidthLogicInputDataFactory(ICrackSofteningLogic softeningLogic)
|
||||
{
|
||||
this.softeningLogic = softeningLogic;
|
||||
}
|
||||
|
||||
public ICrackWidthLogicInputData GetCrackWidthLogicInputData()
|
||||
{
|
||||
GetNdms();
|
||||
|
||||
CrackWidthLogicInputDataSP63 data = new();
|
||||
if (CalcTerm == CalcTerms.LongTerm)
|
||||
{
|
||||
data.TermFactor = 1.4d;
|
||||
data.TermFactor = longTermFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.TermFactor = 1d;
|
||||
data.TermFactor = shortTermFactor;
|
||||
}
|
||||
data.PsiSFactor = GetPsiSFactor(InputData.ForceTuple, InputData.NdmCollection);
|
||||
data.PsiSFactor = softeningLogic.GetSofteningFactor();
|
||||
data.StressStateFactor = 1.0d;
|
||||
data.BondFactor = 0.5d;
|
||||
data.Length = InputData.Length;
|
||||
data.ConcreteStrain = concreteStrainActual;
|
||||
data.RebarStrain = rebarStrainActual;
|
||||
data.ConcreteStrain = ConcreteStrain;
|
||||
data.RebarStrain = RebarStrain;
|
||||
return data;
|
||||
}
|
||||
|
||||
private void GetNdms()
|
||||
{
|
||||
var 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<INdm> ndms)
|
||||
{
|
||||
var crackResult = calculateCrackTuples(forceTuple, ndms);
|
||||
strainTupleActual = CalcStrainMatrix(forceTuple, ndms);
|
||||
rebarStrainActual = stressLogic.GetTotalStrain(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleActual), rebarNdm);
|
||||
TraceLogger?.AddMessage($"Actual strain of rebar EpsilonS = {rebarStrainActual}(dimensionless)");
|
||||
concreteStrainActual = concreteNdm.Prestrain;
|
||||
//concreteStrainActual = stressLogic.GetTotalStrain(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleActual), concreteNdm);
|
||||
TraceLogger?.AddMessage($"Actual strain of concrete on the axis of rebar EpsilonC = {concreteStrainActual}(dimensionless");
|
||||
if (crackResult.IsValid == false)
|
||||
{
|
||||
string errorString = LoggerStrings.CalculationError + crackResult.Description;
|
||||
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(errorString);
|
||||
}
|
||||
if (crackResult.IsSectionCracked == false)
|
||||
{
|
||||
TraceLogger?.AddMessage($"Section is not cracked PsiS = {minimumPsiSFactor}");
|
||||
return minimumPsiSFactor;
|
||||
}
|
||||
if (crackResult.FactorOfCrackAppearance == 0d)
|
||||
{
|
||||
TraceLogger?.AddMessage($"Section is cracked in start force combination, PsiS = 1.0");
|
||||
return 1d;
|
||||
}
|
||||
var strainTupleInCacking = CalcStrainMatrix(crackResult.TupleOfCrackAppearance as ForceTuple, ndms);
|
||||
var stressInCracking = stressLogic.GetStress(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleInCacking), rebarNdm);
|
||||
TraceLogger?.AddMessage($"Stress in rebar immediately after cracing Sigma,scrc = {stressInCracking}(Pa)");
|
||||
rebarStressActual = stressLogic.GetStress(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleActual), rebarNdm);
|
||||
TraceLogger?.AddMessage($"Actual stress in rebar Sigma,s = {rebarStressActual}(Pa)");
|
||||
var stressRatio = stressInCracking / rebarStressActual;
|
||||
var logic = new ExpSofteningLogic()
|
||||
{
|
||||
ForceRatio = stressRatio,
|
||||
PsiSMin = minimumPsiSFactor,
|
||||
PowerFactor = 1d,
|
||||
BettaFactor = 0.8d,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
double psiS = logic.GetSofteningFactor();
|
||||
TraceLogger?.AddMessage($"PsiS = {psiS}");
|
||||
return psiS;
|
||||
}
|
||||
|
||||
private CrackForceResult calculateCrackTuples(ForceTuple forceTuple, IEnumerable<INdm> ndms)
|
||||
{
|
||||
var sectionCrackedLogic = new SectionCrackedLogic()
|
||||
{
|
||||
NdmCollection = ndms,
|
||||
CheckedNdmCollection = new List<INdm>() { concreteNdm },
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(100)
|
||||
};
|
||||
var crackedLogis = new CrackedLogic(sectionCrackedLogic)
|
||||
{
|
||||
StartTuple = new ForceTuple(),
|
||||
EndTuple = forceTuple,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(100)
|
||||
};
|
||||
var calculator = new CrackForceCalculator(crackedLogis)
|
||||
{
|
||||
NdmCollection = ndms,
|
||||
EndTuple = forceTuple,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(150)
|
||||
};
|
||||
calculator.Run();
|
||||
return calculator.Result as CrackForceResult;
|
||||
}
|
||||
|
||||
private StrainTuple CalcStrainMatrix(ForceTuple forceTuple, IEnumerable<INdm> ndms)
|
||||
{
|
||||
IForceTupleInputData inputData = new ForceTupleInputData()
|
||||
{
|
||||
NdmCollection = ndms,
|
||||
Tuple = forceTuple
|
||||
};
|
||||
IForceTupleCalculator calculator = new ForceTupleCalculator()
|
||||
{
|
||||
InputData = inputData,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
calculator.Run();
|
||||
var forceResult = calculator.Result as IForcesTupleResult;
|
||||
if (forceResult.IsValid == false)
|
||||
{
|
||||
TraceLogger?.AddMessage(LoggerStrings.CalculationError + $": {forceResult.Description}", TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(ErrorStrings.CalculationError);
|
||||
}
|
||||
var strain = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix);
|
||||
return strain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,13 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
public LimitStates LimitState { get; set; }
|
||||
public CalcTerms LongTerm { get; set; }
|
||||
public CalcTerms ShortTerm { get; set; }
|
||||
public UserCrackInputData UserCrackInputData { get; set; }
|
||||
|
||||
public GetTupleInputDatasLogic(List<INdmPrimitive> primitives, List<IForceAction> forceActions)
|
||||
public GetTupleInputDatasLogic(List<INdmPrimitive> primitives, List<IForceAction> forceActions, UserCrackInputData userCrackInputData)
|
||||
{
|
||||
Primitives = primitives;
|
||||
ForceActions = forceActions;
|
||||
UserCrackInputData = userCrackInputData;
|
||||
}
|
||||
|
||||
public List<TupleCrackInputData> GetTupleInputDatas()
|
||||
@@ -52,7 +54,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
IsValid = true,
|
||||
LongTermTuple = tuple.LongTuple,
|
||||
ShortTermTuple = tuple.ShortTuple,
|
||||
NdmPrimitives = Primitives
|
||||
NdmPrimitives = Primitives,
|
||||
UserCrackInputData = UserCrackInputData
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -64,7 +67,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
if (ForceActions is null)
|
||||
{
|
||||
TraceLogger?.AddMessage("Force action is null", TraceLogStatuses.Error);
|
||||
TraceLogger?.AddMessage("Force action list is null", TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": {nameof(ForceActions)} is null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
CalcTerms LongTerm { get; set; }
|
||||
CalcTerms ShortTerm { get; set; }
|
||||
List<TupleCrackInputData> GetTupleInputDatas();
|
||||
UserCrackInputData UserCrackInputData { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,23 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface of logic of obtaining of length between cracks
|
||||
/// </summary>
|
||||
public interface ILengthBetweenCracksLogic : ILogic
|
||||
{
|
||||
/// <summary>
|
||||
/// Full collection of ndm parts of cross-section
|
||||
/// </summary>
|
||||
IEnumerable<INdm> NdmCollection { get; set; }
|
||||
/// <summary>
|
||||
/// Strain matrix in cracked state
|
||||
/// </summary>
|
||||
IStrainMatrix StrainMatrix { get; set; }
|
||||
/// <summary>
|
||||
/// Returns length between cracks
|
||||
/// </summary>
|
||||
/// <returns>Length betwenn cracks</returns>
|
||||
double GetLength();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
/// <summary>
|
||||
/// Logic fo calculating of tensile area of RC crosssection
|
||||
/// </summary>
|
||||
public interface ITensileAreaLogic : ILogic
|
||||
public interface ITensileConcreteAreaLogic : ILogic
|
||||
{
|
||||
IEnumerable<INdm> NdmCollection { get; set; }
|
||||
IStrainMatrix StrainMatrix { get; set; }
|
||||
@@ -0,0 +1,28 @@
|
||||
using LoaderCalculator.Data.Matrix;
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||
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 StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic for obtaining of summary area in tension zone of cracked cross-section
|
||||
/// </summary>
|
||||
public interface ITensionRebarAreaLogic : ILogic
|
||||
{
|
||||
|
||||
IStrainMatrix StrainMatrix { get; set; }
|
||||
IEnumerable<RebarNdm> Rebars { get; set; }
|
||||
double GetTensionRebarArea();
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic for obtaining of length between cracks according to SP63.13330.2018
|
||||
/// </summary>
|
||||
public class LengthBetweenCracksLogicSP63 : ILengthBetweenCracksLogic
|
||||
{
|
||||
const double minDiameterFactor = 10d;
|
||||
@@ -21,28 +24,44 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
const double maxLength = 0.4d;
|
||||
private const double areaFactor = 0.5d;
|
||||
readonly IAverageDiameterLogic diameterLogic;
|
||||
readonly ITensileAreaLogic tensileAreaLogic;
|
||||
IStressLogic stressLogic;
|
||||
readonly ITensileConcreteAreaLogic concreteAreaLogic;
|
||||
ITensionRebarAreaLogic rebarAreaLogic;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<INdm> NdmCollection { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public IStrainMatrix StrainMatrix { get; set; }
|
||||
/// <inheritdoc/>
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
|
||||
public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileAreaLogic tensileAreaLogic)
|
||||
public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileConcreteAreaLogic concreteAreaLogic, ITensionRebarAreaLogic rebarAreaLogic)
|
||||
{
|
||||
this.diameterLogic = diameterLogic;
|
||||
this.tensileAreaLogic = tensileAreaLogic;
|
||||
stressLogic = new StressLogic();
|
||||
this.concreteAreaLogic = concreteAreaLogic;
|
||||
this.rebarAreaLogic = rebarAreaLogic;
|
||||
}
|
||||
public LengthBetweenCracksLogicSP63() :
|
||||
this
|
||||
( new EquivalentDiameterLogic(),
|
||||
new TensileAreaLogicSP63())
|
||||
new TensileConcreteAreaLogicSP63(),
|
||||
new TensionRebarAreaSimpleSumLogic())
|
||||
{ }
|
||||
/// <inheritdoc/>
|
||||
public double GetLength()
|
||||
{
|
||||
TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service);
|
||||
IEnumerable<RebarNdm?> rebars = GetRebars();
|
||||
double rebarArea = GetRebarArea(rebars);
|
||||
double rebarDiameter = GetAverageDiameter(rebars);
|
||||
double concreteArea = GetConcreteArea();
|
||||
double length = GetLengthBetweenCracks(rebarArea, rebarDiameter, concreteArea);
|
||||
return length;
|
||||
}
|
||||
|
||||
private IEnumerable<RebarNdm?> GetRebars()
|
||||
{
|
||||
var rebars = NdmCollection
|
||||
.Where(x => x is RebarNdm & stressLogic.GetTotalStrain(StrainMatrix, x) > 0d)
|
||||
.Where(x => x is RebarNdm)
|
||||
.Select(x => x as RebarNdm);
|
||||
if (!rebars.Any())
|
||||
{
|
||||
@@ -50,21 +69,12 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(errorString);
|
||||
}
|
||||
if (TraceLogger is not null)
|
||||
{
|
||||
TraceService.TraceNdmCollection(TraceLogger, rebars);
|
||||
|
||||
return rebars;
|
||||
}
|
||||
var rebarArea = rebars.Sum(x => x.Area * x.StressScale);
|
||||
TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}");
|
||||
diameterLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
diameterLogic.Rebars = rebars;
|
||||
var rebarDiameter = diameterLogic.GetAverageDiameter();
|
||||
TraceLogger?.AddMessage($"Average rebar diameter ds = {rebarDiameter}");
|
||||
tensileAreaLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
tensileAreaLogic.NdmCollection = NdmCollection;
|
||||
tensileAreaLogic.StrainMatrix = StrainMatrix;
|
||||
var concreteArea = tensileAreaLogic.GetTensileArea();
|
||||
TraceLogger?.AddMessage($"Concrete effective area Ac,eff = {concreteArea}(m^2)");
|
||||
|
||||
private double GetLengthBetweenCracks(double rebarArea, double rebarDiameter, double concreteArea)
|
||||
{
|
||||
var length = areaFactor * concreteArea / rebarArea * rebarDiameter;
|
||||
TraceLogger?.AddMessage($"Base length between cracks Lcrc = {areaFactor} * {concreteArea} / {rebarArea} * {rebarDiameter} = {length}(m)");
|
||||
double minLengthByDiameter = minDiameterFactor * rebarDiameter;
|
||||
@@ -81,5 +91,34 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
TraceLogger?.AddMessage($"Finally Lcrc = {length}(m)");
|
||||
return length;
|
||||
}
|
||||
|
||||
private double GetConcreteArea()
|
||||
{
|
||||
concreteAreaLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
concreteAreaLogic.NdmCollection = NdmCollection;
|
||||
concreteAreaLogic.StrainMatrix = StrainMatrix;
|
||||
var concreteArea = concreteAreaLogic.GetTensileArea();
|
||||
TraceLogger?.AddMessage($"Concrete effective area Ac,eff = {concreteArea}(m^2)");
|
||||
return concreteArea;
|
||||
}
|
||||
|
||||
private double GetAverageDiameter(IEnumerable<RebarNdm?> rebars)
|
||||
{
|
||||
diameterLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
diameterLogic.Rebars = rebars;
|
||||
var rebarDiameter = diameterLogic.GetAverageDiameter();
|
||||
TraceLogger?.AddMessage($"Average rebar diameter ds = {rebarDiameter}");
|
||||
return rebarDiameter;
|
||||
}
|
||||
|
||||
private double GetRebarArea(IEnumerable<RebarNdm?> rebars)
|
||||
{
|
||||
rebarAreaLogic.StrainMatrix = StrainMatrix;
|
||||
rebarAreaLogic.Rebars = rebars;
|
||||
rebarAreaLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
var rebarArea = rebarAreaLogic.GetTensionRebarArea();
|
||||
TraceLogger?.AddMessage($"Summary rebar area As = {rebarArea}(m^2)");
|
||||
return rebarArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using StructureHelperCommon.Infrastructures.Enums;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperCommon.Models.Calculators;
|
||||
using StructureHelperCommon.Models.Forces;
|
||||
using StructureHelperCommon.Models.Loggers;
|
||||
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||
|
||||
@@ -8,8 +10,11 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class RebarCrackCalculator : ICalculator
|
||||
{
|
||||
ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63();
|
||||
RebarCrackResult result;
|
||||
private ICrackSofteningLogic crackSofteningLogic;
|
||||
private ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63();
|
||||
private RebarCrackResult result;
|
||||
private RebarStressResult rebarStressResult;
|
||||
|
||||
public string Name { get; set; }
|
||||
public RebarCrackCalculatorInputData InputData { get; set; }
|
||||
public IResult Result => result;
|
||||
@@ -32,16 +37,36 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
crackWidthLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
|
||||
try
|
||||
{
|
||||
GetSofteningLogic(InputData.LongRebarData);
|
||||
rebarStressResult = GetRebarStressResult(InputData.LongRebarData);
|
||||
var dataAcrc1 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.LongTerm);
|
||||
var dataAcrc2 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.ShortTerm);
|
||||
var dataAcrc3 = GetCrackWidthInputData(InputData.ShortRebarData, CalcTerms.ShortTerm);
|
||||
|
||||
crackWidthLogic.InputData = dataAcrc1;
|
||||
var acrc1 = crackWidthLogic.GetCrackWidth();
|
||||
|
||||
var longRebarResult = new CrackWidthTupleResult()
|
||||
{
|
||||
CrackWidth = acrc1,
|
||||
UltimateCrackWidth = InputData.UserCrackInputData.UltimateLongCrackWidth,
|
||||
RebarStrain = rebarStressResult.RebarStrain,
|
||||
ConcreteStrain = rebarStressResult.ConcreteStrain
|
||||
};
|
||||
|
||||
GetSofteningLogic(InputData.ShortRebarData);
|
||||
rebarStressResult = GetRebarStressResult(InputData.ShortRebarData);
|
||||
var dataAcrc3 = GetCrackWidthInputData(InputData.ShortRebarData, CalcTerms.ShortTerm);
|
||||
|
||||
crackWidthLogic.InputData = dataAcrc2;
|
||||
var acrc2 = crackWidthLogic.GetCrackWidth();
|
||||
crackWidthLogic.InputData = dataAcrc3;
|
||||
var acrc3 = crackWidthLogic.GetCrackWidth();
|
||||
|
||||
double acrcShort = acrc1 - acrc2 + acrc3;
|
||||
TraceLogger?.AddMessage($"Long crack width acrc = acrc,1 = {acrc1}(m)");
|
||||
TraceLogger?.AddMessage($"Short crack width acrc = acrc,1 - acrc,2 + acrc,3 = {acrc1} - {acrc2} + {acrc3} = {acrcShort}(m)");
|
||||
var shortRebarResult = new CrackWidthTupleResult()
|
||||
{
|
||||
CrackWidth = acrcShort,
|
||||
UltimateCrackWidth = InputData.UserCrackInputData.UltimateShortCrackWidth
|
||||
};
|
||||
result.LongTermResult = longRebarResult;
|
||||
}
|
||||
@@ -53,13 +78,35 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
result.RebarPrimitive = InputData.RebarPrimitive;
|
||||
}
|
||||
|
||||
private void GetSofteningLogic(RebarCrackInputData rebarData)
|
||||
{
|
||||
if (InputData.UserCrackInputData.SetSofteningFactor == true)
|
||||
{
|
||||
crackSofteningLogic = new StabSoftetingLogic(InputData.UserCrackInputData.SofteningFactor)
|
||||
{
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
crackSofteningLogic = new RebarStressSofteningLogic()
|
||||
{
|
||||
RebarPrimitive = InputData.RebarPrimitive,
|
||||
InputData = rebarData,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private ICrackWidthLogicInputData GetCrackWidthInputData(RebarCrackInputData inputData, CalcTerms calcTerm)
|
||||
{
|
||||
var factoryInputData = new CrackWidthLogicInputDataFactory()
|
||||
|
||||
var factoryInputData = new CrackWidthLogicInputDataFactory(crackSofteningLogic)
|
||||
{
|
||||
CalcTerm = calcTerm,
|
||||
InputData = inputData,
|
||||
RebarPrimitive = InputData.RebarPrimitive,
|
||||
RebarStrain = rebarStressResult.RebarStrain,
|
||||
ConcreteStrain = rebarStressResult.ConcreteStrain,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
var crackWidthInputData = factoryInputData.GetCrackWidthLogicInputData();
|
||||
@@ -70,5 +117,24 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private RebarStressResult GetRebarStressResult(RebarCrackInputData inputData)
|
||||
{
|
||||
var calculator = new RebarStressCalculator()
|
||||
{
|
||||
ForceTuple = inputData.ForceTuple,
|
||||
NdmCollection = inputData.CrackedNdmCollection,
|
||||
RebarPrimitive = InputData.RebarPrimitive
|
||||
};
|
||||
calculator.Run();
|
||||
var result = calculator.Result as RebarStressResult;
|
||||
if (result.IsValid == false)
|
||||
{
|
||||
string errorString = LoggerStrings.CalculationError + result.Description;
|
||||
TraceLogger?.AddMessage($"Rebar name: {InputData.RebarPrimitive.Name}\n" + errorString, TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(errorString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,5 +23,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
/// </summary>
|
||||
public RebarCrackInputData? ShortRebarData { get; set; }
|
||||
public RebarPrimitive RebarPrimitive { get; set; }
|
||||
public UserCrackInputData UserCrackInputData { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class RebarCrackInputData : IInputData
|
||||
{
|
||||
public IEnumerable<INdm> NdmCollection { get; set; }
|
||||
public IEnumerable<INdm> CrackableNdmCollection { get; set; }
|
||||
public IEnumerable<INdm> CrackedNdmCollection { get; set; }
|
||||
public ForceTuple ForceTuple { get; set; }
|
||||
public double Length { get; set; }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models.Forces;
|
||||
using StructureHelperCommon.Models.Loggers;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperCommon.Services.Forces;
|
||||
using StructureHelperLogics.NdmCalculations.Analyses.ByForces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LoaderCalculator.Logics;
|
||||
using StructureHelperLogics.NdmCalculations.Primitives;
|
||||
using StructureHelperCommon.Infrastructures.Enums;
|
||||
using StructureHelperLogics.NdmCalculations.Triangulations;
|
||||
using StructureHelperCommon.Models.Calculators;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class RebarStressCalculator : ICalculator
|
||||
{
|
||||
private IStressLogic stressLogic;
|
||||
private Ndm concreteNdm;
|
||||
private RebarNdm rebarNdm;
|
||||
private RebarStressResult result;
|
||||
|
||||
public ForceTuple ForceTuple { get; set; }
|
||||
public IEnumerable<INdm> NdmCollection { get; set; }
|
||||
public RebarPrimitive RebarPrimitive { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public IResult Result => result;
|
||||
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
|
||||
public StrainTuple GetStrainTuple()
|
||||
{
|
||||
IForceTupleInputData inputData = new ForceTupleInputData()
|
||||
{
|
||||
NdmCollection = NdmCollection,
|
||||
Tuple = ForceTuple
|
||||
};
|
||||
IForceTupleCalculator calculator = new ForceTupleCalculator()
|
||||
{
|
||||
InputData = inputData,
|
||||
//TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
calculator.Run();
|
||||
var forceResult = calculator.Result as IForcesTupleResult;
|
||||
if (forceResult.IsValid == false)
|
||||
{
|
||||
//TraceLogger?.AddMessage(LoggerStrings.CalculationError + $": {forceResult.Description}", TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(ErrorStrings.CalculationError);
|
||||
}
|
||||
var strain = TupleConverter.ConvertToStrainTuple(forceResult.LoaderResults.StrainMatrix);
|
||||
return strain;
|
||||
}
|
||||
public RebarStressCalculator(IStressLogic stressLogic)
|
||||
{
|
||||
this.stressLogic = stressLogic;
|
||||
}
|
||||
public RebarStressCalculator() : this(new StressLogic())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Run()
|
||||
{
|
||||
GetNdms();
|
||||
result = new RebarStressResult()
|
||||
{
|
||||
IsValid = true,
|
||||
Description = string.Empty
|
||||
};
|
||||
var strainTuple = GetStrainTuple();
|
||||
result.StrainTuple = strainTuple;
|
||||
var strainMatrix = TupleConverter.ConvertToLoaderStrainMatrix(strainTuple);
|
||||
result.RebarStrain = stressLogic.GetTotalStrain(strainMatrix, rebarNdm);
|
||||
result.RebarStress = stressLogic.GetStress(strainMatrix, rebarNdm);
|
||||
result.ConcreteStrain = concreteNdm.Prestrain;
|
||||
}
|
||||
|
||||
|
||||
private void GetNdms()
|
||||
{
|
||||
var options = new TriangulationOptions()
|
||||
{
|
||||
CalcTerm = CalcTerms.ShortTerm,
|
||||
LimiteState = LimitStates.SLS,
|
||||
};
|
||||
concreteNdm = RebarPrimitive.GetConcreteNdm(options);
|
||||
concreteNdm.StressScale = 1d;
|
||||
rebarNdm = RebarPrimitive.GetRebarNdm(options);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
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.Cracking
|
||||
{
|
||||
public class RebarStressResult : IResult
|
||||
{
|
||||
public bool IsValid { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public StrainTuple StrainTuple { get; set; }
|
||||
public double RebarStress { get; set; }
|
||||
public double RebarStrain { get; set; }
|
||||
public double ConcreteStrain { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic of calculating of factor of softening by power expression
|
||||
/// </summary>
|
||||
public class ExpSofteningLogic : ICrackSofteningLogic
|
||||
{
|
||||
private double forceRatio;
|
||||
@@ -7,8 +7,15 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic of calculating of factor of softening in crack of RC structures
|
||||
/// </summary>
|
||||
public interface ICrackSofteningLogic : ILogic
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns softening factor
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
double GetSofteningFactor();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
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
|
||||
{
|
||||
private IStressLogic stressLogic;
|
||||
private RebarStressResult afterCrackingRebarResult;
|
||||
private RebarStressResult actualRebarResult;
|
||||
|
||||
|
||||
private INdm concreteNdm;
|
||||
private INdm rebarNdm;
|
||||
|
||||
private double rebarStrainActual;
|
||||
private double concreteStrainActual;
|
||||
private double rebarStressActual;
|
||||
|
||||
public double MinValueOfFactor { get; set; } = 0.2d;
|
||||
public RebarPrimitive RebarPrimitive { get; set; }
|
||||
public RebarCrackInputData InputData { get; set; }
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
|
||||
public double GetSofteningFactor()
|
||||
{
|
||||
GetNdms();
|
||||
return GetPsiSFactor(InputData.ForceTuple, InputData.CrackableNdmCollection, InputData.CrackedNdmCollection);
|
||||
}
|
||||
|
||||
private void GetNdms()
|
||||
{
|
||||
var 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<INdm> crackableNndms, IEnumerable<INdm> crackedNndms)
|
||||
{
|
||||
|
||||
var crackResult = calculateCrackTuples(forceTuple, crackableNndms);
|
||||
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 = GetRebarStressResult(forceTuple);
|
||||
rebarStrainActual = actualRebarResult.RebarStrain;
|
||||
rebarStressActual = actualRebarResult.RebarStress;
|
||||
TraceLogger?.AddMessage($"Actual strain of rebar EpsilonS = {rebarStrainActual}(dimensionless)");
|
||||
concreteStrainActual = concreteNdm.Prestrain;
|
||||
//concreteStrainActual = stressLogic.GetTotalStrain(TupleConverter.ConvertToLoaderStrainMatrix(strainTupleActual), concreteNdm);
|
||||
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;
|
||||
}
|
||||
afterCrackingRebarResult = GetRebarStressResult(crackResult.TupleOfCrackAppearance as ForceTuple);
|
||||
|
||||
var stressInCracking = afterCrackingRebarResult.RebarStress;
|
||||
TraceLogger?.AddMessage($"Stress in rebar immediately after cracking Sigma,scrc = {stressInCracking}(Pa)");
|
||||
TraceLogger?.AddMessage($"Actual stress in rebar Sigma,s = {rebarStressActual}(Pa)");
|
||||
double psiS = GetExponentialSofteningFactor(stressInCracking);
|
||||
TraceLogger?.AddMessage($"PsiS = {psiS}");
|
||||
//return 0.94d;
|
||||
return psiS;
|
||||
}
|
||||
|
||||
private double GetExponentialSofteningFactor(double stressInCracking)
|
||||
{
|
||||
var stressRatio = stressInCracking / rebarStressActual;
|
||||
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<INdm> ndms)
|
||||
{
|
||||
var sectionCrackedLogic = new SectionCrackedLogic()
|
||||
{
|
||||
NdmCollection = ndms,
|
||||
CheckedNdmCollection = new List<INdm>() { concreteNdm },
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(100)
|
||||
};
|
||||
var crackedLogis = new CrackedLogic(sectionCrackedLogic)
|
||||
{
|
||||
StartTuple = new ForceTuple(),
|
||||
EndTuple = forceTuple,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(100)
|
||||
};
|
||||
var calculator = new CrackForceCalculator(crackedLogis)
|
||||
{
|
||||
NdmCollection = ndms,
|
||||
EndTuple = forceTuple,
|
||||
Accuracy = new Accuracy()
|
||||
{
|
||||
IterationAccuracy = 0.01d,
|
||||
MaxIterationCount = 1000
|
||||
},
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(150)
|
||||
};
|
||||
calculator.Run();
|
||||
return calculator.Result as CrackForceResult;
|
||||
}
|
||||
|
||||
private RebarStressResult GetRebarStressResult(ForceTuple forceTuple)
|
||||
{
|
||||
var calculator = new RebarStressCalculator()
|
||||
{
|
||||
ForceTuple = forceTuple,
|
||||
NdmCollection = InputData.CrackedNdmCollection,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using StructureHelperCommon.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class StabSoftetingLogic : ICrackSofteningLogic
|
||||
{
|
||||
private double stabSofteningValue;
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
public StabSoftetingLogic(double stabSofteningValue)
|
||||
{
|
||||
this.stabSofteningValue = stabSofteningValue;
|
||||
}
|
||||
public double GetSofteningFactor()
|
||||
{
|
||||
TraceLogger?.AddMessage($"Constant value of softening factor PsiS = {stabSofteningValue}");
|
||||
return stabSofteningValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class TensileAreaLogicSP63 : ITensileAreaLogic
|
||||
public class TensileConcreteAreaLogicSP63 : ITensileConcreteAreaLogic
|
||||
{
|
||||
const double maxConcreteFactor = 0.5d;
|
||||
const double minConcreteFactor = 0.1d;
|
||||
@@ -0,0 +1,64 @@
|
||||
using LoaderCalculator.Data.Matrix;
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using LoaderCalculator.Logics;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models.Loggers;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperLogics.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class TensionRebarAreaByStrainLogic : ITensionRebarAreaLogic
|
||||
{
|
||||
IStressLogic stressLogic;
|
||||
public IStrainMatrix StrainMatrix { get; set; }
|
||||
public IEnumerable<RebarNdm> Rebars { get; set; }
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
public TensionRebarAreaByStrainLogic(IStressLogic stressLogic)
|
||||
{
|
||||
this.stressLogic = stressLogic;
|
||||
}
|
||||
public TensionRebarAreaByStrainLogic() : this(new StressLogic())
|
||||
{
|
||||
|
||||
}
|
||||
public double GetTensionRebarArea()
|
||||
{
|
||||
TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service);
|
||||
TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on areas which are proportional by maximum strain");
|
||||
var rebars = Rebars
|
||||
.Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d);
|
||||
if (!rebars.Any())
|
||||
{
|
||||
string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars";
|
||||
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(errorString);
|
||||
}
|
||||
var maxStrain = rebars
|
||||
.Select(x => stressLogic.GetTotalStrain(StrainMatrix, x))
|
||||
.Max();
|
||||
TraceLogger?.AddMessage($"Maximum strain maxStrain = {maxStrain}");
|
||||
if (TraceLogger is not null)
|
||||
{
|
||||
TraceService.TraceNdmCollection(TraceLogger, rebars);
|
||||
}
|
||||
double sumArea = 0d;
|
||||
foreach (var rebar in rebars)
|
||||
{
|
||||
double area = rebar.Area * rebar.StressScale;
|
||||
double strain = stressLogic.GetTotalStrain(StrainMatrix, rebar);
|
||||
TraceLogger?.AddMessage($"Rebar area = {area}(m^2)");
|
||||
TraceLogger?.AddMessage($"Rebar strain = {strain}");
|
||||
var reducedArea = area * strain / maxStrain;
|
||||
TraceLogger?.AddMessage($"Reduced rebar area = area * strain / maxStrain = {area} * {strain} / {maxStrain} = {reducedArea}(m^2)");
|
||||
sumArea += reducedArea;
|
||||
}
|
||||
return sumArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using LoaderCalculator.Data.Matrix;
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using LoaderCalculator.Logics;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperCommon.Models.Loggers;
|
||||
using StructureHelperLogics.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
public class TensionRebarAreaSimpleSumLogic : ITensionRebarAreaLogic
|
||||
{
|
||||
IStressLogic stressLogic;
|
||||
public IStrainMatrix StrainMatrix { get; set; }
|
||||
public IEnumerable<RebarNdm> Rebars { get; set; }
|
||||
public IShiftTraceLogger? TraceLogger { get; set; }
|
||||
public TensionRebarAreaSimpleSumLogic(IStressLogic stressLogic)
|
||||
{
|
||||
this.stressLogic = stressLogic;
|
||||
}
|
||||
public TensionRebarAreaSimpleSumLogic() : this(new StressLogic())
|
||||
{
|
||||
|
||||
}
|
||||
public double GetTensionRebarArea()
|
||||
{
|
||||
TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service);
|
||||
TraceLogger?.AddMessage("Method of obtaining of summary area of rebars in tension based on ordinary summarizing of areas");
|
||||
var rebars = Rebars
|
||||
.Where(x => stressLogic.GetTotalStrain(StrainMatrix, x) > 0d);
|
||||
if (!rebars.Any())
|
||||
{
|
||||
string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars";
|
||||
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
|
||||
throw new StructureHelperException(errorString);
|
||||
}
|
||||
if (TraceLogger is not null)
|
||||
{
|
||||
TraceService.TraceNdmCollection(TraceLogger, rebars);
|
||||
}
|
||||
var rebarArea = rebars.Sum(x => x.Area * x.StressScale);
|
||||
return rebarArea;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,14 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
private static readonly ILengthBetweenCracksLogic lengthLogic = new LengthBetweenCracksLogicSP63();
|
||||
private TupleCrackResult result;
|
||||
private IEnumerable<INdmPrimitive> ndmPrimitives;
|
||||
private ICrackedSectionTriangulationLogic triangulationLogic;
|
||||
private List<RebarPrimitive>? rebarPrimitives;
|
||||
private IEnumerable<INdm> defaultNdms;
|
||||
private IEnumerable<INdm> fulyCrackedNdms;
|
||||
private IEnumerable<INdm> crackableNdms;
|
||||
private IEnumerable<INdm> crackedNdms;
|
||||
private IEnumerable<INdm> elasticNdms;
|
||||
private CrackForceResult crackForceResult;
|
||||
private StrainTuple longDefaultStrainTuple;
|
||||
private StrainTuple shortDefaultStrainTuple;
|
||||
private ITriangulatePrimitiveLogic triangulateLogic;
|
||||
private double longLength;
|
||||
private double shortLength;
|
||||
|
||||
@@ -69,13 +67,22 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
CheckInputData();
|
||||
Triangulate();
|
||||
longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, defaultNdms);
|
||||
shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, defaultNdms);
|
||||
longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
|
||||
shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
|
||||
var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms);
|
||||
var shortElasticStrainTuple = CalcStrainMatrix(InputData.ShortTermTuple as ForceTuple, elasticNdms);
|
||||
if (result.IsValid == false) { return; }
|
||||
if (InputData.UserCrackInputData.SetLengthBetweenCracks == true)
|
||||
{
|
||||
longLength = InputData.UserCrackInputData.LengthBetweenCracks;
|
||||
shortLength = InputData.UserCrackInputData.LengthBetweenCracks;
|
||||
TraceLogger?.AddMessage($"User value of length between cracks Lcrc = {longLength}");
|
||||
}
|
||||
else
|
||||
{
|
||||
longLength = GetLengthBetweenCracks(longElasticStrainTuple);
|
||||
shortLength = GetLengthBetweenCracks(shortElasticStrainTuple);
|
||||
}
|
||||
CalcCrackForce();
|
||||
foreach (var rebar in rebarPrimitives)
|
||||
{
|
||||
@@ -95,13 +102,15 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
var longRebarData = new RebarCrackInputData()
|
||||
{
|
||||
NdmCollection = fulyCrackedNdms,
|
||||
CrackableNdmCollection = crackableNdms,
|
||||
CrackedNdmCollection = crackedNdms,
|
||||
ForceTuple = InputData.LongTermTuple as ForceTuple,
|
||||
Length = longLength
|
||||
};
|
||||
var shortRebarData = new RebarCrackInputData()
|
||||
{
|
||||
NdmCollection = fulyCrackedNdms,
|
||||
CrackableNdmCollection = crackableNdms,
|
||||
CrackedNdmCollection = crackedNdms,
|
||||
ForceTuple = InputData.ShortTermTuple as ForceTuple,
|
||||
Length = shortLength
|
||||
};
|
||||
@@ -109,7 +118,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
RebarPrimitive = rebar,
|
||||
LongRebarData = longRebarData,
|
||||
ShortRebarData = shortRebarData
|
||||
ShortRebarData = shortRebarData,
|
||||
UserCrackInputData = InputData.UserCrackInputData
|
||||
};
|
||||
return rebarCalculatorData;
|
||||
}
|
||||
@@ -124,7 +134,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
IForceTupleCalculator calculator = new ForceTupleCalculator()
|
||||
{
|
||||
InputData = inputData,
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
//TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
calculator.Run();
|
||||
var forceResult = calculator.Result as IForcesTupleResult;
|
||||
@@ -152,11 +162,11 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
triangulationLogic = new CrackedSectionTriangulationLogic(InputData.NdmPrimitives)
|
||||
{
|
||||
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
//TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
|
||||
};
|
||||
rebarPrimitives = triangulationLogic.GetRebarPrimitives();
|
||||
defaultNdms = triangulationLogic.GetNdmCollection();
|
||||
fulyCrackedNdms = triangulationLogic.GetCrackedNdmCollection();
|
||||
crackableNdms = triangulationLogic.GetNdmCollection();
|
||||
crackedNdms = triangulationLogic.GetCrackedNdmCollection();
|
||||
elasticNdms = triangulationLogic.GetElasticNdmCollection();
|
||||
}
|
||||
|
||||
@@ -164,7 +174,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
var calculator = new CrackForceCalculator();
|
||||
calculator.EndTuple = InputData.LongTermTuple;
|
||||
calculator.NdmCollection = defaultNdms;
|
||||
calculator.NdmCollection = crackableNdms;
|
||||
calculator.Run();
|
||||
crackForceResult = calculator.Result as CrackForceResult;
|
||||
}
|
||||
|
||||
@@ -16,5 +16,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
public IForceTuple? LongTermTuple { get; set; }
|
||||
public IForceTuple? ShortTermTuple { get; set; }
|
||||
public List<INdmPrimitive>? NdmPrimitives {get;set;}
|
||||
public UserCrackInputData UserCrackInputData { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using StructureHelperCommon.Models.Calculators;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings for crack calculations assigned by user
|
||||
/// </summary>
|
||||
public class UserCrackInputData : IInputData
|
||||
{
|
||||
/// <summary>
|
||||
/// Flag of assigning of user value of softening factor
|
||||
/// </summary>
|
||||
public bool SetSofteningFactor {get;set;}
|
||||
/// <summary>
|
||||
/// User value of softening factor, dimensionless
|
||||
/// </summary>
|
||||
public double SofteningFactor {get;set;}
|
||||
/// <summary>
|
||||
/// Flag of assigning of user value of length between cracks
|
||||
/// </summary>
|
||||
public bool SetLengthBetweenCracks {get;set;}
|
||||
/// <summary>
|
||||
/// Length between cracks, m
|
||||
/// </summary>
|
||||
public double LengthBetweenCracks {get;set;}
|
||||
/// <summary>
|
||||
/// Ultimate long-term crack width, m
|
||||
/// </summary>
|
||||
public double UltimateLongCrackWidth { get; set; }
|
||||
/// <summary>
|
||||
/// Ultimate short-term crack width, m
|
||||
/// </summary>
|
||||
public double UltimateShortCrackWidth { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using StructureHelperCommon.Infrastructures.Interfaces;
|
||||
using StructureHelperCommon.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StructureHelperLogics.NdmCalculations.Cracking
|
||||
{
|
||||
internal class UserCrackInputDataUpdateStrategy : IUpdateStrategy<UserCrackInputData>
|
||||
{
|
||||
public void Update(UserCrackInputData targetObject, UserCrackInputData sourceObject)
|
||||
{
|
||||
if (ReferenceEquals(targetObject, sourceObject)) { return; }
|
||||
CheckObject.CompareTypes(targetObject, sourceObject);
|
||||
|
||||
targetObject.SetSofteningFactor = sourceObject.SetSofteningFactor;
|
||||
targetObject.SofteningFactor = sourceObject.SofteningFactor;
|
||||
targetObject.SetLengthBetweenCracks = sourceObject.SetLengthBetweenCracks;
|
||||
targetObject.LengthBetweenCracks = sourceObject.LengthBetweenCracks;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
using LoaderCalculator.Data.Matrix;
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using LoaderCalculator.Logics;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||
namespace StructureHelperTests.UnitTests.Ndms.Cracks
|
||||
{
|
||||
public class TensionRebarAreaSimpleSumLogicTests
|
||||
{
|
||||
[Test]
|
||||
public void GetTensionRebarArea_ShouldReturnCorrectSumArea_WhenRebarsInTension()
|
||||
{
|
||||
// Arrange
|
||||
var mockStressLogic = new Mock<IStressLogic>();
|
||||
var mockStrainMatrix = new Mock<IStrainMatrix>();
|
||||
var mockTraceLogger = new Mock<IShiftTraceLogger>();
|
||||
|
||||
var rebars = new List<RebarNdm>
|
||||
{
|
||||
new RebarNdm { Area = 1.0, StressScale = 1.0 },
|
||||
new RebarNdm { Area = 2.0, StressScale = 1.0 },
|
||||
new RebarNdm { Area = 3.0, StressScale = 1.0 }
|
||||
};
|
||||
|
||||
// Setup the mock to return positive strains
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 1.0)))
|
||||
.Returns(0.5);
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 2.0)))
|
||||
.Returns(1.0);
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 3.0)))
|
||||
.Returns(1.5);
|
||||
|
||||
var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object)
|
||||
{
|
||||
StrainMatrix = mockStrainMatrix.Object,
|
||||
Rebars = rebars,
|
||||
TraceLogger = mockTraceLogger.Object
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = logic.GetTensionRebarArea();
|
||||
|
||||
// Assert
|
||||
// Expected result calculation:
|
||||
// rebarArea = 1.0 * 1.0 + 2.0 * 1.0 + 3.0 * 1.0 = 6.0
|
||||
Assert.AreEqual(6.0, result);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetTensionRebarArea_ShouldThrowException_WhenNoRebarsInTension()
|
||||
{
|
||||
// Arrange
|
||||
var mockStressLogic = new Mock<IStressLogic>();
|
||||
var mockStrainMatrix = new Mock<IStrainMatrix>();
|
||||
var mockTraceLogger = new Mock<IShiftTraceLogger>();
|
||||
|
||||
var rebars = new List<RebarNdm>
|
||||
{
|
||||
new RebarNdm { Area = 1.0, StressScale = 1.0 }
|
||||
};
|
||||
|
||||
// Setup the mock to return non-positive strain
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.IsAny<RebarNdm>()))
|
||||
.Returns(0.0);
|
||||
|
||||
var logic = new TensionRebarAreaSimpleSumLogic(mockStressLogic.Object)
|
||||
{
|
||||
StrainMatrix = mockStrainMatrix.Object,
|
||||
Rebars = rebars,
|
||||
TraceLogger = mockTraceLogger.Object
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<StructureHelperException>(() => logic.GetTensionRebarArea());
|
||||
StringAssert.Contains("Collection of rebars does not contain any tensile rebars", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
using LoaderCalculator.Data.Matrix;
|
||||
using LoaderCalculator.Data.Ndms;
|
||||
using LoaderCalculator.Logics;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using StructureHelperCommon.Infrastructures.Exceptions;
|
||||
using StructureHelperCommon.Models;
|
||||
using StructureHelperLogics.NdmCalculations.Cracking;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace StructureHelperTests.UnitTests.Ndms.Cracks
|
||||
{
|
||||
public class TensionRebarAreaByStrainLogicTests
|
||||
{
|
||||
[Test]
|
||||
public void GetTensionRebarArea_ShouldReturnCorrectSumArea_WhenRebarsInTension()
|
||||
{
|
||||
// Arrange
|
||||
var mockStressLogic = new Mock<IStressLogic>();
|
||||
var mockStrainMatrix = new Mock<IStrainMatrix>();
|
||||
var mockTraceLogger = new Mock<IShiftTraceLogger>();
|
||||
|
||||
var rebars = new List<RebarNdm>
|
||||
{
|
||||
new RebarNdm { Area = 1.0, StressScale = 1.0 },
|
||||
new RebarNdm { Area = 2.0, StressScale = 1.0 },
|
||||
new RebarNdm { Area = 3.0, StressScale = 1.0 }
|
||||
};
|
||||
|
||||
// Setup the mock to return positive strains
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 1.0)))
|
||||
.Returns(0.5);
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 2.0)))
|
||||
.Returns(1.0);
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.Is<RebarNdm>(r => r.Area == 3.0)))
|
||||
.Returns(1.5);
|
||||
|
||||
var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object)
|
||||
{
|
||||
StrainMatrix = mockStrainMatrix.Object,
|
||||
Rebars = rebars,
|
||||
TraceLogger = mockTraceLogger.Object
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = logic.GetTensionRebarArea();
|
||||
|
||||
// Assert
|
||||
// Expected result calculation:
|
||||
// maxStrain = 1.5
|
||||
// reducedArea for rebar 1 = 1.0 * 0.5 / 1.5 = 0.333...
|
||||
// reducedArea for rebar 2 = 2.0 * 1.0 / 1.5 = 1.333...
|
||||
// reducedArea for rebar 3 = 3.0 * 1.5 / 1.5 = 3.0
|
||||
// sumArea = 0.333... + 1.333... + 3.0 = 4.666...
|
||||
Assert.AreEqual(4.666666666666667, result, 9);
|
||||
}
|
||||
[Test]
|
||||
public void GetTensionRebarArea_ShouldThrowException_WhenNoRebarsInTension()
|
||||
{
|
||||
// Arrange
|
||||
var mockStressLogic = new Mock<IStressLogic>();
|
||||
var mockStrainMatrix = new Mock<IStrainMatrix>();
|
||||
var mockTraceLogger = new Mock<IShiftTraceLogger>();
|
||||
|
||||
var rebars = new List<RebarNdm>
|
||||
{
|
||||
new RebarNdm { Area = 1.0, StressScale = 1.0 }
|
||||
};
|
||||
|
||||
// Setup the mock to return non-positive strain
|
||||
mockStressLogic.Setup(s => s.GetTotalStrain(It.IsAny<IStrainMatrix>(), It.IsAny<RebarNdm>()))
|
||||
.Returns(0.0);
|
||||
|
||||
var logic = new TensionRebarAreaByStrainLogic(mockStressLogic.Object)
|
||||
{
|
||||
StrainMatrix = mockStrainMatrix.Object,
|
||||
Rebars = rebars,
|
||||
TraceLogger = mockTraceLogger.Object
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<StructureHelperException>(() => logic.GetTensionRebarArea());
|
||||
StringAssert.Contains("Collection of rebars does not contain any tensile rebars", ex.Message);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user