User data for cracks were added

This commit is contained in:
Evgeny Redikultsev
2024-05-18 15:51:59 +05:00
parent b32a7ce7df
commit 845929406e
31 changed files with 925 additions and 175 deletions

View File

@@ -60,7 +60,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
private void ProcessCalculations() private void ProcessCalculations()
{ {
datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions) datasLogic = new GetTupleInputDatasLogic(InputData.Primitives, InputData.ForceActions, InputData.UserCrackInputData)
{ {
LimitState = limitState, LimitState = limitState,
LongTerm = longTerm, LongTerm = longTerm,

View File

@@ -10,7 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public class CrackCalculatorUpdateStrategy : IUpdateStrategy<CrackCalculator> public class CrackCalculatorUpdateStrategy : IUpdateStrategy<CrackCalculator>
{ {
private CrackInputDataUpdateStrategy inputDataUpdateStrategy => new(); private CrackInputDataUpdateStrategy crackInputDataUpdateStrategy => new();
public void Update(CrackCalculator targetObject, CrackCalculator sourceObject) public void Update(CrackCalculator targetObject, CrackCalculator sourceObject)
{ {
if (ReferenceEquals(targetObject, sourceObject)) { return; } if (ReferenceEquals(targetObject, sourceObject)) { return; }
@@ -18,7 +18,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
targetObject.Name = sourceObject.Name; targetObject.Name = sourceObject.Name;
targetObject.InputData ??= new(); targetObject.InputData ??= new();
inputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData); crackInputDataUpdateStrategy.Update(targetObject.InputData, sourceObject.InputData);
} }
} }
} }

View File

@@ -16,10 +16,20 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
public List<INdmPrimitive> Primitives { get; private set; } public List<INdmPrimitive> Primitives { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
public List<IForceAction> ForceActions { get; private set; } public List<IForceAction> ForceActions { get; private set; }
public UserCrackInputData UserCrackInputData { get; private set; }
public CrackInputData() public CrackInputData()
{ {
Primitives = new(); Primitives = new();
ForceActions = new(); ForceActions = new();
UserCrackInputData = new()
{
SetSofteningFactor = true,
SofteningFactor = 1d,
SetLengthBetweenCracks = true,
LengthBetweenCracks = 0.4d,
UltimateLongCrackWidth = 0.0003d,
UltimateShortCrackWidth = 0.0004d
};
} }
} }
} }

View File

@@ -10,6 +10,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public class CrackInputDataUpdateStrategy : IUpdateStrategy<CrackInputData> public class CrackInputDataUpdateStrategy : IUpdateStrategy<CrackInputData>
{ {
private UserCrackInputDataUpdateStrategy userCrackInputDataUpdateStrategy => new();
public void Update(CrackInputData targetObject, CrackInputData sourceObject) public void Update(CrackInputData targetObject, CrackInputData sourceObject)
{ {
if (ReferenceEquals(targetObject, sourceObject)) { return; } if (ReferenceEquals(targetObject, sourceObject)) { return; }
@@ -18,6 +19,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
targetObject.ForceActions.AddRange(sourceObject.ForceActions); targetObject.ForceActions.AddRange(sourceObject.ForceActions);
targetObject.Primitives.Clear(); targetObject.Primitives.Clear();
targetObject.Primitives.AddRange(sourceObject.Primitives); targetObject.Primitives.AddRange(sourceObject.Primitives);
userCrackInputDataUpdateStrategy.Update(targetObject.UserCrackInputData, sourceObject.UserCrackInputData);
} }
} }
} }

View File

@@ -11,6 +11,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public IForceTuple? ForceTuple { get; set; } public IForceTuple? ForceTuple { get; set; }
public double CrackWidth { get; set; } public double CrackWidth { get; set; }
public double UltimateCrackWidth { get; set; }
public bool IsCrackLessThanUltimate => CrackWidth <= UltimateCrackWidth;
public double RebarStrain { get; set; } public double RebarStrain { get; set; }
public double ConcreteStrain { get; set; } public double ConcreteStrain { get; set; }
} }

View File

@@ -29,7 +29,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
} }
public bool IsSectionCracked(double factor) public bool IsSectionCracked(double factor)
{ {
sectionCrackedLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); sectionCrackedLogic.TraceLogger ??= TraceLogger?.GetSimilarTraceLogger(50);
var actualTuple = ForceTupleService.InterpolateTuples(EndTuple, StartTuple, factor); var actualTuple = ForceTupleService.InterpolateTuples(EndTuple, StartTuple, factor);
sectionCrackedLogic.Tuple = actualTuple; sectionCrackedLogic.Tuple = actualTuple;

View File

@@ -22,143 +22,41 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
internal class CrackWidthLogicInputDataFactory : ILogic 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; public double RebarStrain { get; set; }
private INdm concreteNdm; public double ConcreteStrain { get; set;}
private INdm rebarNdm;
private StrainTuple strainTupleActual;
private double rebarStrainActual;
private double concreteStrainActual;
private double rebarStressActual;
public CalcTerms CalcTerm { get; set; } public CalcTerms CalcTerm { get; set; }
public RebarPrimitive RebarPrimitive { get; set; }
public RebarCrackInputData InputData { get; set; } public RebarCrackInputData InputData { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; } public IShiftTraceLogger? TraceLogger { get; set; }
public CrackWidthLogicInputDataFactory(ICrackSofteningLogic softeningLogic)
{
this.softeningLogic = softeningLogic;
}
public ICrackWidthLogicInputData GetCrackWidthLogicInputData() public ICrackWidthLogicInputData GetCrackWidthLogicInputData()
{ {
GetNdms();
CrackWidthLogicInputDataSP63 data = new(); CrackWidthLogicInputDataSP63 data = new();
if (CalcTerm == CalcTerms.LongTerm) if (CalcTerm == CalcTerms.LongTerm)
{ {
data.TermFactor = 1.4d; data.TermFactor = longTermFactor;
} }
else else
{ {
data.TermFactor = 1d; data.TermFactor = shortTermFactor;
} }
data.PsiSFactor = GetPsiSFactor(InputData.ForceTuple, InputData.NdmCollection); data.PsiSFactor = softeningLogic.GetSofteningFactor();
data.StressStateFactor = 1.0d; data.StressStateFactor = 1.0d;
data.BondFactor = 0.5d; data.BondFactor = 0.5d;
data.Length = InputData.Length; data.Length = InputData.Length;
data.ConcreteStrain = concreteStrainActual; data.ConcreteStrain = ConcreteStrain;
data.RebarStrain = rebarStrainActual; data.RebarStrain = RebarStrain;
return data; 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;
}
} }
} }

View File

@@ -22,11 +22,13 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
public LimitStates LimitState { get; set; } public LimitStates LimitState { get; set; }
public CalcTerms LongTerm { get; set; } public CalcTerms LongTerm { get; set; }
public CalcTerms ShortTerm { 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; Primitives = primitives;
ForceActions = forceActions; ForceActions = forceActions;
UserCrackInputData = userCrackInputData;
} }
public List<TupleCrackInputData> GetTupleInputDatas() public List<TupleCrackInputData> GetTupleInputDatas()
@@ -52,7 +54,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
IsValid = true, IsValid = true,
LongTermTuple = tuple.LongTuple, LongTermTuple = tuple.LongTuple,
ShortTermTuple = tuple.ShortTuple, ShortTermTuple = tuple.ShortTuple,
NdmPrimitives = Primitives NdmPrimitives = Primitives,
UserCrackInputData = UserCrackInputData
}); });
} }
} }
@@ -64,7 +67,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
if (ForceActions is null) 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"); throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": {nameof(ForceActions)} is null");
} }
} }

View File

@@ -11,5 +11,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
CalcTerms LongTerm { get; set; } CalcTerms LongTerm { get; set; }
CalcTerms ShortTerm { get; set; } CalcTerms ShortTerm { get; set; }
List<TupleCrackInputData> GetTupleInputDatas(); List<TupleCrackInputData> GetTupleInputDatas();
UserCrackInputData UserCrackInputData { get; set; }
} }
} }

View File

@@ -9,10 +9,23 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
/// <summary>
/// Interface of logic of obtaining of length between cracks
/// </summary>
public interface ILengthBetweenCracksLogic : ILogic public interface ILengthBetweenCracksLogic : ILogic
{ {
/// <summary>
/// Full collection of ndm parts of cross-section
/// </summary>
IEnumerable<INdm> NdmCollection { get; set; } IEnumerable<INdm> NdmCollection { get; set; }
/// <summary>
/// Strain matrix in cracked state
/// </summary>
IStrainMatrix StrainMatrix { get; set; } IStrainMatrix StrainMatrix { get; set; }
/// <summary>
/// Returns length between cracks
/// </summary>
/// <returns>Length betwenn cracks</returns>
double GetLength(); double GetLength();
} }
} }

View File

@@ -13,7 +13,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
/// <summary> /// <summary>
/// Logic fo calculating of tensile area of RC crosssection /// Logic fo calculating of tensile area of RC crosssection
/// </summary> /// </summary>
public interface ITensileAreaLogic : ILogic public interface ITensileConcreteAreaLogic : ILogic
{ {
IEnumerable<INdm> NdmCollection { get; set; } IEnumerable<INdm> NdmCollection { get; set; }
IStrainMatrix StrainMatrix { get; set; } IStrainMatrix StrainMatrix { get; set; }

View File

@@ -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();
}
}

View File

@@ -13,6 +13,9 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
/// <summary>
/// Logic for obtaining of length between cracks according to SP63.13330.2018
/// </summary>
public class LengthBetweenCracksLogicSP63 : ILengthBetweenCracksLogic public class LengthBetweenCracksLogicSP63 : ILengthBetweenCracksLogic
{ {
const double minDiameterFactor = 10d; const double minDiameterFactor = 10d;
@@ -21,50 +24,57 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
const double maxLength = 0.4d; const double maxLength = 0.4d;
private const double areaFactor = 0.5d; private const double areaFactor = 0.5d;
readonly IAverageDiameterLogic diameterLogic; readonly IAverageDiameterLogic diameterLogic;
readonly ITensileAreaLogic tensileAreaLogic; readonly ITensileConcreteAreaLogic concreteAreaLogic;
IStressLogic stressLogic; ITensionRebarAreaLogic rebarAreaLogic;
/// <inheritdoc/>
public IEnumerable<INdm> NdmCollection { get; set; } public IEnumerable<INdm> NdmCollection { get; set; }
/// <inheritdoc/>
public IStrainMatrix StrainMatrix { get; set; } public IStrainMatrix StrainMatrix { get; set; }
/// <inheritdoc/>
public IShiftTraceLogger? TraceLogger { get; set; } public IShiftTraceLogger? TraceLogger { get; set; }
public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileAreaLogic tensileAreaLogic) public LengthBetweenCracksLogicSP63(IAverageDiameterLogic diameterLogic, ITensileConcreteAreaLogic concreteAreaLogic, ITensionRebarAreaLogic rebarAreaLogic)
{ {
this.diameterLogic = diameterLogic; this.diameterLogic = diameterLogic;
this.tensileAreaLogic = tensileAreaLogic; this.concreteAreaLogic = concreteAreaLogic;
stressLogic = new StressLogic(); this.rebarAreaLogic = rebarAreaLogic;
} }
public LengthBetweenCracksLogicSP63() : public LengthBetweenCracksLogicSP63() :
this this
( new EquivalentDiameterLogic(), ( new EquivalentDiameterLogic(),
new TensileAreaLogicSP63()) new TensileConcreteAreaLogicSP63(),
new TensionRebarAreaSimpleSumLogic())
{ } { }
/// <inheritdoc/>
public double GetLength() public double GetLength()
{ {
TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service); 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 var rebars = NdmCollection
.Where(x => x is RebarNdm & stressLogic.GetTotalStrain(StrainMatrix, x) > 0d) .Where(x => x is RebarNdm)
.Select(x => x as RebarNdm); .Select(x => x as RebarNdm);
if (! rebars.Any()) if (!rebars.Any())
{ {
string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars"; string errorString = ErrorStrings.DataIsInCorrect + ": Collection of rebars does not contain any tensile rebars";
TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error); TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
throw new StructureHelperException(errorString); throw new StructureHelperException(errorString);
} }
if (TraceLogger is not null)
{ return rebars;
TraceService.TraceNdmCollection(TraceLogger, rebars); }
}
var rebarArea = rebars.Sum(x => x.Area * x.StressScale); private double GetLengthBetweenCracks(double rebarArea, double rebarDiameter, double concreteArea)
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)");
var length = areaFactor * concreteArea / rebarArea * rebarDiameter; var length = areaFactor * concreteArea / rebarArea * rebarDiameter;
TraceLogger?.AddMessage($"Base length between cracks Lcrc = {areaFactor} * {concreteArea} / {rebarArea} * {rebarDiameter} = {length}(m)"); TraceLogger?.AddMessage($"Base length between cracks Lcrc = {areaFactor} * {concreteArea} / {rebarArea} * {rebarDiameter} = {length}(m)");
double minLengthByDiameter = minDiameterFactor * rebarDiameter; double minLengthByDiameter = minDiameterFactor * rebarDiameter;
@@ -81,5 +91,34 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
TraceLogger?.AddMessage($"Finally Lcrc = {length}(m)"); TraceLogger?.AddMessage($"Finally Lcrc = {length}(m)");
return length; 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;
}
} }
} }

View File

@@ -1,6 +1,8 @@
using StructureHelperCommon.Infrastructures.Enums; using StructureHelperCommon.Infrastructures.Enums;
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models; using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators; using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Loggers; using StructureHelperCommon.Models.Loggers;
using StructureHelperLogics.NdmCalculations.Primitives; using StructureHelperLogics.NdmCalculations.Primitives;
@@ -8,8 +10,11 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public class RebarCrackCalculator : ICalculator public class RebarCrackCalculator : ICalculator
{ {
ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63(); private ICrackSofteningLogic crackSofteningLogic;
RebarCrackResult result; private ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63();
private RebarCrackResult result;
private RebarStressResult rebarStressResult;
public string Name { get; set; } public string Name { get; set; }
public RebarCrackCalculatorInputData InputData { get; set; } public RebarCrackCalculatorInputData InputData { get; set; }
public IResult Result => result; public IResult Result => result;
@@ -32,16 +37,36 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
crackWidthLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50); crackWidthLogic.TraceLogger = TraceLogger?.GetSimilarTraceLogger(50);
try try
{ {
GetSofteningLogic(InputData.LongRebarData);
rebarStressResult = GetRebarStressResult(InputData.LongRebarData);
var dataAcrc1 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.LongTerm); var dataAcrc1 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.LongTerm);
var dataAcrc2 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.ShortTerm); var dataAcrc2 = GetCrackWidthInputData(InputData.LongRebarData, CalcTerms.ShortTerm);
var dataAcrc3 = GetCrackWidthInputData(InputData.ShortRebarData, CalcTerms.ShortTerm); crackWidthLogic.InputData = dataAcrc1;
crackWidthLogic.InputData = dataAcrc1;
var acrc1 = crackWidthLogic.GetCrackWidth(); var acrc1 = crackWidthLogic.GetCrackWidth();
var longRebarResult = new CrackWidthTupleResult() var longRebarResult = new CrackWidthTupleResult()
{ {
CrackWidth = acrc1, 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; result.LongTermResult = longRebarResult;
} }
@@ -53,13 +78,35 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
result.RebarPrimitive = InputData.RebarPrimitive; 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) private ICrackWidthLogicInputData GetCrackWidthInputData(RebarCrackInputData inputData, CalcTerms calcTerm)
{ {
var factoryInputData = new CrackWidthLogicInputDataFactory()
var factoryInputData = new CrackWidthLogicInputDataFactory(crackSofteningLogic)
{ {
CalcTerm = calcTerm, CalcTerm = calcTerm,
InputData = inputData, InputData = inputData,
RebarPrimitive = InputData.RebarPrimitive, RebarStrain = rebarStressResult.RebarStrain,
ConcreteStrain = rebarStressResult.ConcreteStrain,
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
}; };
var crackWidthInputData = factoryInputData.GetCrackWidthLogicInputData(); var crackWidthInputData = factoryInputData.GetCrackWidthLogicInputData();
@@ -70,5 +117,24 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
throw new NotImplementedException(); 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;
}
} }
} }

View File

@@ -23,5 +23,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
/// </summary> /// </summary>
public RebarCrackInputData? ShortRebarData { get; set; } public RebarCrackInputData? ShortRebarData { get; set; }
public RebarPrimitive RebarPrimitive { get; set; } public RebarPrimitive RebarPrimitive { get; set; }
public UserCrackInputData UserCrackInputData { get; set; }
} }
} }

View File

@@ -13,7 +13,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public class RebarCrackInputData : IInputData 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 ForceTuple ForceTuple { get; set; }
public double Length { get; set; } public double Length { get; set; }
} }

View File

@@ -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();
}
}
}

View File

@@ -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; }
}
}

View File

@@ -11,6 +11,9 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
/// <summary>
/// Logic of calculating of factor of softening by power expression
/// </summary>
public class ExpSofteningLogic : ICrackSofteningLogic public class ExpSofteningLogic : ICrackSofteningLogic
{ {
private double forceRatio; private double forceRatio;

View File

@@ -7,8 +7,15 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
/// <summary>
/// Logic of calculating of factor of softening in crack of RC structures
/// </summary>
public interface ICrackSofteningLogic : ILogic public interface ICrackSofteningLogic : ILogic
{ {
/// <summary>
/// Returns softening factor
/// </summary>
/// <returns></returns>
double GetSofteningFactor(); double GetSofteningFactor();
} }
} }

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -14,7 +14,7 @@ using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
public class TensileAreaLogicSP63 : ITensileAreaLogic public class TensileConcreteAreaLogicSP63 : ITensileConcreteAreaLogic
{ {
const double maxConcreteFactor = 0.5d; const double maxConcreteFactor = 0.5d;
const double minConcreteFactor = 0.1d; const double minConcreteFactor = 0.1d;

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -16,16 +16,14 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
private static readonly ILengthBetweenCracksLogic lengthLogic = new LengthBetweenCracksLogicSP63(); private static readonly ILengthBetweenCracksLogic lengthLogic = new LengthBetweenCracksLogicSP63();
private TupleCrackResult result; private TupleCrackResult result;
private IEnumerable<INdmPrimitive> ndmPrimitives;
private ICrackedSectionTriangulationLogic triangulationLogic; private ICrackedSectionTriangulationLogic triangulationLogic;
private List<RebarPrimitive>? rebarPrimitives; private List<RebarPrimitive>? rebarPrimitives;
private IEnumerable<INdm> defaultNdms; private IEnumerable<INdm> crackableNdms;
private IEnumerable<INdm> fulyCrackedNdms; private IEnumerable<INdm> crackedNdms;
private IEnumerable<INdm> elasticNdms; private IEnumerable<INdm> elasticNdms;
private CrackForceResult crackForceResult; private CrackForceResult crackForceResult;
private StrainTuple longDefaultStrainTuple; private StrainTuple longDefaultStrainTuple;
private StrainTuple shortDefaultStrainTuple; private StrainTuple shortDefaultStrainTuple;
private ITriangulatePrimitiveLogic triangulateLogic;
private double longLength; private double longLength;
private double shortLength; private double shortLength;
@@ -69,13 +67,22 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
CheckInputData(); CheckInputData();
Triangulate(); Triangulate();
longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, defaultNdms); longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, defaultNdms); shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms); var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms);
var shortElasticStrainTuple = CalcStrainMatrix(InputData.ShortTermTuple as ForceTuple, elasticNdms); var shortElasticStrainTuple = CalcStrainMatrix(InputData.ShortTermTuple as ForceTuple, elasticNdms);
if (result.IsValid == false) { return; } if (result.IsValid == false) { return; }
longLength = GetLengthBetweenCracks(longElasticStrainTuple); if (InputData.UserCrackInputData.SetLengthBetweenCracks == true)
shortLength = GetLengthBetweenCracks(shortElasticStrainTuple); {
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(); CalcCrackForce();
foreach (var rebar in rebarPrimitives) foreach (var rebar in rebarPrimitives)
{ {
@@ -95,13 +102,15 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
var longRebarData = new RebarCrackInputData() var longRebarData = new RebarCrackInputData()
{ {
NdmCollection = fulyCrackedNdms, CrackableNdmCollection = crackableNdms,
CrackedNdmCollection = crackedNdms,
ForceTuple = InputData.LongTermTuple as ForceTuple, ForceTuple = InputData.LongTermTuple as ForceTuple,
Length = longLength Length = longLength
}; };
var shortRebarData = new RebarCrackInputData() var shortRebarData = new RebarCrackInputData()
{ {
NdmCollection = fulyCrackedNdms, CrackableNdmCollection = crackableNdms,
CrackedNdmCollection = crackedNdms,
ForceTuple = InputData.ShortTermTuple as ForceTuple, ForceTuple = InputData.ShortTermTuple as ForceTuple,
Length = shortLength Length = shortLength
}; };
@@ -109,7 +118,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
RebarPrimitive = rebar, RebarPrimitive = rebar,
LongRebarData = longRebarData, LongRebarData = longRebarData,
ShortRebarData = shortRebarData ShortRebarData = shortRebarData,
UserCrackInputData = InputData.UserCrackInputData
}; };
return rebarCalculatorData; return rebarCalculatorData;
} }
@@ -124,7 +134,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
IForceTupleCalculator calculator = new ForceTupleCalculator() IForceTupleCalculator calculator = new ForceTupleCalculator()
{ {
InputData = inputData, InputData = inputData,
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
}; };
calculator.Run(); calculator.Run();
var forceResult = calculator.Result as IForcesTupleResult; var forceResult = calculator.Result as IForcesTupleResult;
@@ -152,11 +162,11 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
triangulationLogic = new CrackedSectionTriangulationLogic(InputData.NdmPrimitives) triangulationLogic = new CrackedSectionTriangulationLogic(InputData.NdmPrimitives)
{ {
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50) //TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
}; };
rebarPrimitives = triangulationLogic.GetRebarPrimitives(); rebarPrimitives = triangulationLogic.GetRebarPrimitives();
defaultNdms = triangulationLogic.GetNdmCollection(); crackableNdms = triangulationLogic.GetNdmCollection();
fulyCrackedNdms = triangulationLogic.GetCrackedNdmCollection(); crackedNdms = triangulationLogic.GetCrackedNdmCollection();
elasticNdms = triangulationLogic.GetElasticNdmCollection(); elasticNdms = triangulationLogic.GetElasticNdmCollection();
} }
@@ -164,7 +174,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{ {
var calculator = new CrackForceCalculator(); var calculator = new CrackForceCalculator();
calculator.EndTuple = InputData.LongTermTuple; calculator.EndTuple = InputData.LongTermTuple;
calculator.NdmCollection = defaultNdms; calculator.NdmCollection = crackableNdms;
calculator.Run(); calculator.Run();
crackForceResult = calculator.Result as CrackForceResult; crackForceResult = calculator.Result as CrackForceResult;
} }

View File

@@ -16,5 +16,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
public IForceTuple? LongTermTuple { get; set; } public IForceTuple? LongTermTuple { get; set; }
public IForceTuple? ShortTermTuple { get; set; } public IForceTuple? ShortTermTuple { get; set; }
public List<INdmPrimitive>? NdmPrimitives {get;set;} public List<INdmPrimitive>? NdmPrimitives {get;set;}
public UserCrackInputData UserCrackInputData { get; set; }
} }
} }

View File

@@ -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; }
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}