Logic fo TupleCrackCalculator was changed

This commit is contained in:
RedikultsevEvg
2024-07-28 22:34:47 +05:00
parent 732af8bc09
commit 35b4000f64
12 changed files with 474 additions and 92 deletions

View File

@@ -89,7 +89,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{
result = false;
string message = $"Host {rebar.Name} ({rebar.HostPrimitive.Name}) is not included in primitives\n";
checkResult += message;
CheckResult += message;
TraceLogger?.AddMessage(message, TraceLogStatuses.Error);
}
}
@@ -97,7 +97,7 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
{
result = false;
string message = $"Material of host of {rebar.Name} ({rebar.HostPrimitive.HeadMaterial.Name}) does not support cracking\n";
checkResult += message;
CheckResult += message;
TraceLogger?.AddMessage(message, TraceLogStatuses.Error);
}
}

View File

@@ -0,0 +1,15 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public interface IRebarCalulatorsFactory : ILogic
{
TupleCrackInputData InputData { get; set; }
double LongLength { get; set; }
IEnumerable<RebarPrimitive> Rebars { get; set; }
double ShortLength { get; set; }
List<IRebarCrackCalculator> GetCalculators();
}
}

View File

@@ -0,0 +1,12 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public interface IRebarCrackCalculator : ICalculator
{
Action<IResult> ActionToOutputResults { get; set; }
RebarCrackCalculatorInputData InputData { get; set; }
IShiftTraceLogger? TraceLogger { get; set; }
}
}

View File

@@ -0,0 +1,14 @@
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public interface IRebarCrackInputDataFactory
{
RebarPrimitive Rebar { get; set; }
TupleCrackInputData InputData { get; set; }
double LongLength { get; set; }
double ShortLength { get; set; }
RebarCrackCalculatorInputData GetInputData();
}
}

View File

@@ -0,0 +1,18 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public interface ITupleRebarsCrackSolver : ILogic
{
string Description { get; }
TupleCrackInputData InputData { get; set; }
bool IsResultValid { get; }
double LongLength { get; set; }
IEnumerable<RebarPrimitive> Rebars { get; set; }
List<RebarCrackResult> Result { get; }
double ShortLength { get; set; }
void Run();
}
}

View File

@@ -0,0 +1,47 @@
using StructureHelperCommon.Models;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public class RebarCalulatorsFactory : IRebarCalulatorsFactory
{
private IRebarCrackInputDataFactory inputFactory;
public IEnumerable<RebarPrimitive> Rebars { get; set; }
public TupleCrackInputData InputData { get; set; }
public double LongLength { get; set; }
public double ShortLength { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; }
public RebarCalulatorsFactory(IRebarCrackInputDataFactory inputFactory)
{
this.inputFactory = inputFactory;
}
public RebarCalulatorsFactory() : this(new RebarCrackInputDataFactory()) { }
public List<IRebarCrackCalculator> GetCalculators()
{
List<IRebarCrackCalculator> calculators = new List<IRebarCrackCalculator>();
foreach (var rebar in Rebars)
{
inputFactory.Rebar = rebar;
inputFactory.InputData = InputData;
inputFactory.LongLength = LongLength;
inputFactory.ShortLength = ShortLength;
var calculator = new RebarCrackCalculator
{
InputData = inputFactory.GetInputData()
};
calculators.Add(calculator);
}
return calculators;
}
}
}

View File

@@ -8,7 +8,7 @@ using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public class RebarCrackCalculator : ICalculator
public class RebarCrackCalculator : IRebarCrackCalculator
{
private ICrackSofteningLogic crackSofteningLogic;
private ICrackWidthLogic crackWidthLogic = new CrackWidthLogicSP63();

View File

@@ -0,0 +1,76 @@
using LoaderCalculator.Data.Ndms;
using StructureHelper.Models.Materials;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public class RebarCrackInputDataFactory : IRebarCrackInputDataFactory
{
private ICrackedSectionTriangulationLogic triangulationLogicLoc;
public RebarCrackInputDataFactory(ICrackedSectionTriangulationLogic triangulationLogicLoc)
{
this.triangulationLogicLoc = triangulationLogicLoc;
}
public RebarCrackInputDataFactory(TupleCrackInputData inputData) : this (new CrackedSectionTriangulationLogic(inputData.Primitives))
{
}
public RebarCrackInputDataFactory()
{
}
public RebarPrimitive Rebar { get; set; }
public TupleCrackInputData InputData { get; set; }
public double LongLength { get; set; }
public double ShortLength { get; set; }
public RebarCrackCalculatorInputData GetInputData()
{
IEnumerable<INdm> crackableNdmsLoc = null;
IEnumerable<INdm> crackedNdmsLoc = null;
INdm concreteNdmUnderRebar;
RebarPrimitive rebarCopy = null;
rebarCopy = Rebar.Clone() as RebarPrimitive;
rebarCopy.HeadMaterial = rebarCopy.HeadMaterial.Clone() as IHeadMaterial;
triangulationLogicLoc = new CrackedSectionTriangulationLogic(InputData.Primitives);
crackableNdmsLoc = triangulationLogicLoc.GetNdmCollection();
crackedNdmsLoc = triangulationLogicLoc.GetCrackedNdmCollection();
var longRebarData = new RebarCrackInputData()
{
CrackableNdmCollection = crackableNdmsLoc,
CrackedNdmCollection = crackedNdmsLoc,
ForceTuple = InputData.LongTermTuple.Clone() as ForceTuple,
Length = LongLength
};
var shortRebarData = new RebarCrackInputData()
{
CrackableNdmCollection = crackableNdmsLoc,
CrackedNdmCollection = crackedNdmsLoc,
ForceTuple = InputData.ShortTermTuple.Clone() as ForceTuple,
Length = ShortLength
};
var rebarCalculatorData = new RebarCrackCalculatorInputData()
{
RebarPrimitive = rebarCopy,
LongRebarData = longRebarData,
ShortRebarData = shortRebarData,
UserCrackInputData = InputData.UserCrackInputData
};
return rebarCalculatorData;
}
}
}

View File

@@ -33,7 +33,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
private StrainTuple shortDefaultStrainTuple;
private double longLength;
private double shortLength;
private object locker = new();
public string Name { get; set; }
public TupleCrackInputData InputData { get; set; }
@@ -43,8 +42,8 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
public void Run()
{
PrepareNewResult();
TraceLogger?.AddMessage(LoggerStrings.CalculatorType(this), TraceLogStatuses.Service);
PrepareNewResult();
try
{
@@ -79,6 +78,13 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
longDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
shortDefaultStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, crackableNdms);
GetLengthBeetwenCracks();
SolveRebarResult();
GetMinMaxCrackWidth();
}
private void GetLengthBeetwenCracks()
{
var longElasticStrainTuple = CalcStrainMatrix(InputData.LongTermTuple as ForceTuple, elasticNdms);
var shortElasticStrainTuple = CalcStrainMatrix(InputData.ShortTermTuple as ForceTuple, elasticNdms);
if (result.IsValid == false) { return; }
@@ -93,30 +99,11 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
longLength = GetLengthBetweenCracks(longElasticStrainTuple);
shortLength = GetLengthBetweenCracks(shortElasticStrainTuple);
}
//CalcCrackForce();
//for (int j = 0; j < 100000; j++)
//{
result.RebarResults.Clear();
int rebarCount = rebarPrimitives.Count;
Task<RebarCrackResult>[] tasks = new Task<RebarCrackResult>[rebarCount];
for (int i = 0; i < rebarCount; i++)
{
var rebar = rebarPrimitives[i];
tasks[i] = new Task<RebarCrackResult>(() => ProcessRebar(rebar));
tasks[i].Start();
}
Task.WaitAll(tasks);
for (int i = 0; i < rebarCount; i++)
{
result.RebarResults.Add(tasks[i].Result);
}
//}
}
if (result.RebarResults.Any(x => x.IsValid == false))
{
result.IsValid = false;
return;
}
private void GetMinMaxCrackWidth()
{
if (result.IsValid == false || result.RebarResults.Count == 0) { return; }
result.LongTermResult = new()
{
CrackWidth = result.RebarResults.Max(x => x.LongTermResult.CrackWidth),
@@ -129,61 +116,23 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
};
}
private RebarCrackResult ProcessRebar(RebarPrimitive rebar)
private void SolveRebarResult()
{
RebarCrackCalculatorInputData rebarCalculatorData = GetRebarCalculatorInputData(rebar);
var calculator = new RebarCrackCalculator
result.RebarResults.Clear();
ITupleRebarsCrackSolver solver = new TupleRebarsCrackSolver();
solver.Rebars = rebarPrimitives;
solver.InputData = InputData;
solver.LongLength = longLength;
solver.ShortLength = shortLength;
solver.TraceLogger = TraceLogger?.GetSimilarTraceLogger(0);
solver.Run();
if (solver.IsResultValid == false)
{
InputData = rebarCalculatorData,
TraceLogger = TraceLogger?.GetSimilarTraceLogger(50)
};
calculator.Run();
var rebarResult = calculator.Result as RebarCrackResult;
return rebarResult;
}
private RebarCrackCalculatorInputData GetRebarCalculatorInputData(RebarPrimitive rebar)
{
IEnumerable<INdm> crackableNdmsLoc = null;
IEnumerable<INdm> crackedNdmsLoc = null;
INdm concreteNdmUnderRebar;
RebarPrimitive rebarCopy = null;
lock (locker)
{
rebarCopy = rebar.Clone() as RebarPrimitive;
rebarCopy.HeadMaterial = rebarCopy.HeadMaterial.Clone() as IHeadMaterial;
var triangulationLogicLoc = new CrackedSectionTriangulationLogic(InputData.Primitives);
crackableNdmsLoc = triangulationLogicLoc.GetNdmCollection();
crackedNdmsLoc = triangulationLogicLoc.GetCrackedNdmCollection();
//concreteNdmUnderRebar = rebarCopy.GetConcreteNdm(new TriangulationOptions()
//{ CalcTerm = crackingTerm,
// LimiteState = crackingLimitState });
//concreteNdmUnderRebar.StressScale = 1d;
//crackableNdmsLoc = new List<INdm>() { concreteNdmUnderRebar};
result.IsValid = false;
result.Description += solver.Description;
return;
}
var longRebarData = new RebarCrackInputData()
{
CrackableNdmCollection = crackableNdmsLoc,
CrackedNdmCollection = crackedNdmsLoc,
ForceTuple = InputData.LongTermTuple.Clone() as ForceTuple,
Length = longLength
};
var shortRebarData = new RebarCrackInputData()
{
CrackableNdmCollection = crackableNdmsLoc,
CrackedNdmCollection = crackedNdms,
ForceTuple = InputData.ShortTermTuple.Clone() as ForceTuple,
Length = shortLength
};
var rebarCalculatorData = new RebarCrackCalculatorInputData()
{
RebarPrimitive = rebarCopy,
LongRebarData = longRebarData,
ShortRebarData = shortRebarData,
UserCrackInputData = InputData.UserCrackInputData
};
return rebarCalculatorData;
result.RebarResults.AddRange(solver.Result);
}
private StrainTuple CalcStrainMatrix(ForceTuple forceTuple, IEnumerable<INdm> ndms)
@@ -234,15 +183,6 @@ namespace StructureHelperLogics.NdmCalculations.Cracking
elasticNdms = triangulationLogic.GetElasticNdmCollection();
}
private void CalcCrackForce()
{
var calculator = new CrackForceCalculator();
calculator.EndTuple = InputData.LongTermTuple;
calculator.NdmCollection = crackableNdms;
calculator.Run();
crackForceResult = calculator.Result as CrackForceResult;
}
private void CheckInputData()
{
if (InputData.Primitives is null || InputData.Primitives.Count == 0)

View File

@@ -0,0 +1,96 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
using StructureHelperLogics.NdmCalculations.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperLogics.NdmCalculations.Cracking
{
public class TupleRebarsCrackSolver : ITupleRebarsCrackSolver
{
private IRebarCalulatorsFactory calculatorsFactory;
public IEnumerable<RebarPrimitive> Rebars { get; set; }
public TupleCrackInputData InputData { get; set; }
public double LongLength { get; set; }
public double ShortLength { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; }
public List<RebarCrackResult> Result { get; private set; }
public bool IsResultValid { get; private set; }
public string Description { get; private set; }
public TupleRebarsCrackSolver(IRebarCalulatorsFactory calulatorsFactory)
{
this.calculatorsFactory = calulatorsFactory;
}
public TupleRebarsCrackSolver() : this(new RebarCalulatorsFactory()) { }
public void Run()
{
Result = new List<RebarCrackResult>();
Description = string.Empty;
var rebarCalculators = GetRebarCalculators();
List<Task<RebarCrackResult>> tasks = new();
foreach (var calculator in rebarCalculators)
{
if (TraceLogger != null)
{
calculator.TraceLogger = new ShiftTraceLogger();
}
tasks.Add(new Task<RebarCrackResult>(() => ProcessCalculator(calculator)));
}
var taskArray = tasks.ToArray();
foreach (var task in taskArray)
{
task.Start();
}
Task.WaitAll(taskArray);
if (TraceLogger != null)
{
for (int i = 0; i < rebarCalculators.Count(); i++)
{
TraceLogger.TraceLoggerEntries.AddRange(rebarCalculators[i].TraceLogger.TraceLoggerEntries);
}
}
for (int i = 0; i < taskArray.Length; i++)
{
Result.Add(taskArray[i].Result);
}
if (Result.Any(x => x.IsValid == false))
{
IsResultValid = false;
Description += "\n There not valid results for rebar";
return;
}
IsResultValid = true;
}
private RebarCrackResult ProcessCalculator(IRebarCrackCalculator calculator)
{
calculator.Run();
var rebarResult = calculator.Result as RebarCrackResult;
return rebarResult;
}
private List<IRebarCrackCalculator> GetRebarCalculators()
{
calculatorsFactory.Rebars = Rebars;
calculatorsFactory.InputData = InputData;
calculatorsFactory.LongLength = LongLength;
calculatorsFactory.ShortLength = ShortLength;
calculatorsFactory.TraceLogger = TraceLogger?.GetSimilarTraceLogger(0);
return calculatorsFactory.GetCalculators();
}
}
}

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using Moq;
using NUnit.Framework;
using StructureHelperCommon.Models;
using StructureHelperLogics.NdmCalculations.Cracking;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperTests.UnitTests.Ndms.Cracks
{
public class RebarCalulatorsFactoryTests
{
[Test]
public void GetCalculators_ShouldReturnListOfCalculators()
{
// Arrange
var mockInputFactory = new Mock<IRebarCrackInputDataFactory>();
var rebar = new RebarPrimitive();
var inputData = new TupleCrackInputData();
var rebarCrackInputData = new RebarCrackCalculatorInputData();
mockInputFactory.SetupProperty(f => f.Rebar, rebar);
mockInputFactory.SetupProperty(f => f.InputData, inputData);
mockInputFactory.SetupProperty(f => f.LongLength, 10.0);
mockInputFactory.SetupProperty(f => f.ShortLength, 5.0);
mockInputFactory.Setup(f => f.GetInputData()).Returns(rebarCrackInputData);
var factory = new RebarCalulatorsFactory(mockInputFactory.Object)
{
Rebars = new List<RebarPrimitive> { rebar },
InputData = inputData,
LongLength = 10.0,
ShortLength = 5.0,
TraceLogger = null
};
// Act
var calculators = factory.GetCalculators();
// Assert
var calculator = calculators[0];
Assert.NotNull(calculator);
Assert.AreEqual(rebarCrackInputData, calculator.InputData);
Assert.Null(calculator.TraceLogger);
}
[Test]
public void GetCalculators_ShouldInitializeCalculatorsWithCorrectData()
{
// Arrange
var mockInputFactory = new Mock<IRebarCrackInputDataFactory>();
var rebar1 = new RebarPrimitive();
var rebar2 = new RebarPrimitive();
var inputData = new TupleCrackInputData();
var rebarInputData1 = new RebarCrackCalculatorInputData();
var rebarInputData2 = new RebarCrackCalculatorInputData();
var mockLogger = new Mock<IShiftTraceLogger>();
mockInputFactory.SetupSequence(f => f.GetInputData())
.Returns(rebarInputData1)
.Returns(rebarInputData2);
mockInputFactory.Setup(f => f.GetInputData()).Returns(rebarInputData1);
mockLogger.Setup(l => l.GetSimilarTraceLogger(50)).Returns(mockLogger.Object);
var factory = new RebarCalulatorsFactory(mockInputFactory.Object)
{
Rebars = new List<RebarPrimitive> { rebar1, rebar2 },
InputData = inputData,
LongLength = 20.0,
ShortLength = 10.0,
TraceLogger = mockLogger.Object
};
// Act
var calculators = factory.GetCalculators();
// Assert
Assert.AreEqual(2, calculators.Count);
Assert.AreEqual(rebarInputData1, calculators[0].InputData);
//Assert.AreEqual(rebarInputData2, calculators[1].InputData);
Assert.AreEqual(mockLogger.Object, calculators[0].TraceLogger);
Assert.AreEqual(mockLogger.Object, calculators[1].TraceLogger);
}
}
}

View File

@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using StructureHelperLogics.NdmCalculations.Cracking;
using StructureHelperLogics.NdmCalculations.Primitives;
namespace StructureHelperTests.UnitTests.Ndms.Cracks
{
public class TupleRebarsCrackSolverTest
{
[Test]
public void Run_ShouldProcessAllCalculatorsAndSetValidResults()
{
// Arrange
var mockCalculatorFactory = new Mock<IRebarCalulatorsFactory>();
var mockCalculator = new Mock<IRebarCrackCalculator>();
mockCalculator.Setup(c => c.Run());
mockCalculator.Setup(c => c.Result).Returns(new RebarCrackResult { IsValid = true });
var calculators = new List<IRebarCrackCalculator> { mockCalculator.Object };
mockCalculatorFactory.Setup(f => f.GetCalculators()).Returns(calculators);
var solver = new TupleRebarsCrackSolver(mockCalculatorFactory.Object)
{
Rebars = new List<RebarPrimitive>(),
InputData = new TupleCrackInputData(),
LongLength = 10.0,
ShortLength = 5.0,
TraceLogger = null
};
// Act
solver.Run();
// Assert
mockCalculator.Verify(c => c.Run(), Times.Once);
Assert.True(solver.IsResultValid);
Assert.NotNull(solver.Result);
Assert.True(solver.Result.All(r => r.IsValid));
}
[Test]
public void Run_ShouldSetInvalidResultWhenAnyCalculatorResultIsInvalid()
{
// Arrange
var mockCalculatorFactory = new Mock<IRebarCalulatorsFactory>();
var mockCalculator1 = new Mock<IRebarCrackCalculator>();
mockCalculator1.Setup(c => c.Run());
mockCalculator1.Setup(c => c.Result).Returns(new RebarCrackResult { IsValid = true });
var mockCalculator2 = new Mock<IRebarCrackCalculator>();
mockCalculator2.Setup(c => c.Run());
mockCalculator2.Setup(c => c.Result).Returns(new RebarCrackResult { IsValid = false });
var calculators = new List<IRebarCrackCalculator> { mockCalculator1.Object, mockCalculator2.Object };
mockCalculatorFactory.Setup(f => f.GetCalculators()).Returns(calculators);
var solver = new TupleRebarsCrackSolver(mockCalculatorFactory.Object)
{
Rebars = new List<RebarPrimitive>(),
InputData = new TupleCrackInputData(),
LongLength = 10.0,
ShortLength = 5.0,
TraceLogger = null
};
// Act
solver.Run();
// Assert
mockCalculator1.Verify(c => c.Run(), Times.Once);
mockCalculator2.Verify(c => c.Run(), Times.Once);
Assert.False(solver.IsResultValid);
}
}
}