diff --git a/StructureHelperCommon/Models/Forces/IFactoredForceTuple.cs b/StructureHelperCommon/Models/Forces/IFactoredForceTuple.cs
new file mode 100644
index 0000000..15c5b9c
--- /dev/null
+++ b/StructureHelperCommon/Models/Forces/IFactoredForceTuple.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperCommon.Models.Forces
+{
+ public interface IFactoredForceTuple
+ {
+ IForceTuple ForceTuple { get; set; }
+ IFactoredCombinationProperty CombinationProperty { get; set; }
+ }
+}
diff --git a/StructureHelperCommon/Models/Forces/Logics/GetFactorByFactoredCombinationProperty.cs b/StructureHelperCommon/Models/Forces/Logics/GetFactorByFactoredCombinationProperty.cs
new file mode 100644
index 0000000..06d4e61
--- /dev/null
+++ b/StructureHelperCommon/Models/Forces/Logics/GetFactorByFactoredCombinationProperty.cs
@@ -0,0 +1,29 @@
+using StructureHelperCommon.Infrastructures.Enums;
+
+//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
+//All rights reserved.
+
+namespace StructureHelperCommon.Models.Forces.Logics
+{
+ public class GetFactorByFactoredCombinationProperty : IGetLoadFactor
+ {
+ private const double defaultSLSfactor = 1d;
+ private const double defaultShortTermFactor = 1d;
+
+ public IFactoredCombinationProperty CombinationProperty { get; set; }
+ public LimitStates LimitState { get; set; }
+ public CalcTerms CalcTerm { get; set; }
+
+ public double GetFactor()
+ {
+ double stateFactor = CombinationProperty.LimitState is LimitStates.SLS ? defaultSLSfactor : (1d / CombinationProperty.ULSFactor);
+ double termFactor = CombinationProperty.CalcTerm is CalcTerms.ShortTerm ? defaultShortTermFactor : (1d / CombinationProperty.LongTermFactor);
+ double shortSlsFactor = stateFactor * termFactor;
+ stateFactor = LimitState is LimitStates.SLS ? 1d : CombinationProperty.ULSFactor;
+ termFactor = CalcTerm is CalcTerms.ShortTerm ? 1d : CombinationProperty.LongTermFactor;
+ double factor = shortSlsFactor * stateFactor * termFactor;
+ return factor;
+ }
+
+ }
+}
diff --git a/StructureHelperCommon/Models/Forces/Logics/IGetLoadFactor.cs b/StructureHelperCommon/Models/Forces/Logics/IGetLoadFactor.cs
new file mode 100644
index 0000000..3b776b3
--- /dev/null
+++ b/StructureHelperCommon/Models/Forces/Logics/IGetLoadFactor.cs
@@ -0,0 +1,13 @@
+using StructureHelperCommon.Infrastructures.Enums;
+using StructureHelperCommon.Infrastructures.Interfaces;
+
+namespace StructureHelperCommon.Models.Forces
+{
+ ///
+ /// Implements logic for calculating factor of load
+ ///
+ public interface IGetLoadFactor
+ {
+ double GetFactor();
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/CoordinateByLevelLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/CoordinateByLevelLogic.cs
new file mode 100644
index 0000000..d5f97bb
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/CoordinateByLevelLogic.cs
@@ -0,0 +1,44 @@
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public class CoordinateByLevelLogic : ICoordinateByLevelLogic
+ {
+ public IShiftTraceLogger? TraceLogger { get; set; }
+
+ public CoordinateByLevelLogic(IShiftTraceLogger? traceLogger)
+ {
+ TraceLogger = traceLogger;
+ }
+
+ public double GetCoordinate(double startCoord, double endCoord, double relativeLevel)
+ {
+ CheckRelativeLevel(relativeLevel);
+ double delta = endCoord - startCoord;
+ double coordinate = startCoord + delta * (relativeLevel + 0.5d);
+ return coordinate;
+ }
+
+ private void CheckRelativeLevel(double relativeLevel)
+ {
+ if (relativeLevel > 0.5d)
+ {
+ string errorString = ErrorStrings.IncorrectValue + ": relative level must not be greater than 0.5";
+ TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
+ throw new StructureHelperException(errorString);
+ }
+ if (relativeLevel < -0.5d)
+ {
+ string errorString = ErrorStrings.IncorrectValue + ": relative level must not be less than -0.5";
+ TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
+ throw new StructureHelperException(errorString);
+ }
+ }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetDirectShearForceLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetDirectShearForceLogic.cs
new file mode 100644
index 0000000..901fb5d
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/GetDirectShearForceLogic.cs
@@ -0,0 +1,64 @@
+using StructureHelperCommon.Models;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models.Loggers;
+
+//Copyright (c) 2025 Redikultsev Evgeny, Ekaterinburg, Russia
+//All rights reserved.
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ ///
+ public class GetDirectShearForceLogic : IGetDirectShearForceLogic
+ {
+ ISumForceByShearLoadLogic summaryForceLogic;
+
+ ///
+ public IShiftTraceLogger? TraceLogger { get; set; }
+ public IBeamShearAxisAction AxisAction { get; private set; }
+ public IInclinedSection InclinedSection { get; private set; }
+
+ public GetDirectShearForceLogic(
+ IBeamShearAxisAction axisAction,
+ IInclinedSection inclinedSection,
+ IShiftTraceLogger? traceLogger)
+ {
+ AxisAction = axisAction;
+ InclinedSection = inclinedSection;
+ TraceLogger = traceLogger;
+ }
+
+ public GetDirectShearForceLogic(
+ IBeamShearAxisAction axisAction,
+ IInclinedSection inclinedSection,
+ IShiftTraceLogger? traceLogger,
+ ISumForceByShearLoadLogic summaryForceLogic)
+ {
+ this.summaryForceLogic = summaryForceLogic;
+ AxisAction = axisAction;
+ InclinedSection = inclinedSection;
+ TraceLogger = traceLogger;
+ }
+
+ ///
+ public double CalculateShearForce()
+ {
+ TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
+ InitializeStrategies();
+ double supportShearForce = AxisAction.SupportShearForce;
+ TraceLogger?.AddMessage($"Shear force at support Qmax = {supportShearForce}(N)");
+ TraceLogger?.AddMessage($"Start of inclined section a,start = {InclinedSection.StartCoord}(m)");
+ TraceLogger?.AddMessage($"End of inclined section a,end = {InclinedSection.EndCoord}(m)");
+ double summarySpanShearForce = AxisAction.ShearLoads
+ .Sum(load => summaryForceLogic.GetSumShearForce(load, InclinedSection.StartCoord, InclinedSection.EndCoord));
+ TraceLogger?.AddMessage($"Summary span force deltaQ = {summarySpanShearForce}(N)");
+ double shearForce = supportShearForce + summarySpanShearForce;
+ TraceLogger?.AddMessage($"Summary shear force at the end of inclined section Q = {shearForce}(N)");
+ return shearForce;
+ }
+
+ private void InitializeStrategies()
+ {
+ summaryForceLogic ??= new SumForceByShearLoadLogic(TraceLogger);
+ }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/GetSumForceByShearActionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/GetSumForceByShearActionLogic.cs
deleted file mode 100644
index 7ccb246..0000000
--- a/StructureHelperLogics/Models/BeamShears/Logics/GetSumForceByShearActionLogic.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using StructureHelperCommon.Infrastructures.Exceptions;
-using StructureHelperCommon.Models;
-using StructureHelperCommon.Models.Forces;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace StructureHelperLogics.Models.BeamShears
-{
- public class GetSumForceByShearActionLogic : IGetSumForceByShearActionLogic
- {
- public IShiftTraceLogger? TraceLogger { get; set; }
-
- public GetSumForceByShearActionLogic(IShiftTraceLogger? traceLogger)
- {
- TraceLogger = traceLogger;
- }
-
- public double GetSumShearForce(IBeamShearLoad beamShearAction, double startCoord, double endCoord)
- {
- if (beamShearAction is IDistributedLoad distributedLoad)
- {
- return GetDistributedLoadSum(distributedLoad, startCoord, endCoord);
- }
- else if (beamShearAction is IConcentratedForce concenratedForce)
- {
- return GetConcentratedForceSum(concenratedForce, startCoord, endCoord);
- }
- else
- {
- throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(beamShearAction));
- }
- }
-
- private double GetConcentratedForceSum(IConcentratedForce concentratedForce, double startCoord, double endCoord)
- {
- TraceLogger?.AddMessage($"Concentrated force Name = {concentratedForce.Name}, Value = {concentratedForce.ForceValue}(N/m) ");
- if (concentratedForce.ForceCoordinate > endCoord)
- {
- TraceLogger?.AddMessage($"Force coordinate {concentratedForce.ForceCoordinate}(m) is bigger than section end {endCoord}(m), so total load is zero");
- return 0;
- }
- double totalLoad;
- double limitCoordinate = startCoord;
- if (concentratedForce.ForceCoordinate >= startCoord)
- {
- limitCoordinate = GetCoordinateByLevel(startCoord, endCoord, concentratedForce.RelativeLoadLevel);
- }
- if (concentratedForce.ForceCoordinate < limitCoordinate)
- {
- totalLoad = concentratedForce.ForceValue * concentratedForce.LoadRatio;
- TraceLogger?.AddMessage($"Total load Q,tot = {concentratedForce.ForceValue}(N) * {concentratedForce.LoadRatio} = {totalLoad}(N)");
- }
- else
- {
- TraceLogger?.AddMessage($"Force coordinate {concentratedForce.ForceCoordinate}(m) is bigger than limit coordinate {limitCoordinate}(m), so total load is zero");
- totalLoad = 0d;
- }
- return totalLoad;
- }
-
- private double GetDistributedLoadSum(IDistributedLoad distributedLoad, double startCoord, double endCoord)
- {
- TraceLogger?.AddMessage($"Uniformly distributed load Name = {distributedLoad.Name}, Value = {distributedLoad.LoadValue}(N/m) ");
- double loadStartCoord = Math.Max(distributedLoad.StartCoordinate, 0d);
- if (loadStartCoord > endCoord)
- {
- TraceLogger?.AddMessage($"Load start coordinate {loadStartCoord}(m) is bigger than section end {endCoord}(m), so total load is zero");
- return 0d;
- }
- double endCoordByLevel = GetCoordinateByLevel(startCoord, endCoord, distributedLoad.RelativeLoadLevel);
- double loadEndCoord = Math.Min(distributedLoad.EndCoordinate, endCoordByLevel);
- double loadLength = loadEndCoord - loadStartCoord;
- TraceLogger?.AddMessage($"Total length L,tot = {loadEndCoord}(m) - {loadStartCoord}(m) = {loadLength}(m)");
- double totalLoad = distributedLoad.LoadValue * distributedLoad.LoadRatio * loadLength;
- TraceLogger?.AddMessage($"Total load Q,tot = {distributedLoad.LoadValue}(N/m) * {distributedLoad.LoadRatio} * {loadLength}(m) = {totalLoad}(N)");
- return totalLoad;
- }
-
- private double GetCoordinateByLevel(double startCoord, double endCoord, double relativeLevel)
- {
- CheckRelativeLevel(relativeLevel);
- double delta = endCoord - startCoord;
- double coordinate = startCoord + delta * (relativeLevel + 0.5d);
- return coordinate;
- }
-
- private void CheckRelativeLevel(double relativeLevel)
- {
- if (relativeLevel > 0.5d)
- {
- string errorString = ErrorStrings.IncorrectValue + ": relative level must not be greater than 0.5";
- TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
- throw new StructureHelperException(errorString);
- }
- if (relativeLevel < -0.5d)
- {
- string errorString = ErrorStrings.IncorrectValue + ": relative level must not be less than -0.5";
- TraceLogger?.AddMessage(errorString, TraceLogStatuses.Error);
- throw new StructureHelperException(errorString);
- }
- }
- }
-}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/ICoordinateByLevelLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/ICoordinateByLevelLogic.cs
new file mode 100644
index 0000000..14479d9
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/ICoordinateByLevelLogic.cs
@@ -0,0 +1,14 @@
+using StructureHelperCommon.Infrastructures.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public interface ICoordinateByLevelLogic : ILogic
+ {
+ double GetCoordinate(double startCoord, double endCoord, double relativeLevel);
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetDirectShearForceLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IGetDirectShearForceLogic.cs
new file mode 100644
index 0000000..aa12f03
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/IGetDirectShearForceLogic.cs
@@ -0,0 +1,17 @@
+using StructureHelperCommon.Infrastructures.Interfaces;
+using StructureHelperCommon.Models.Forces;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ ///
+ /// Implements logic of calculating shear force without considering term and limit state
+ ///
+ public interface IGetDirectShearForceLogic : ILogic
+ {
+ ///
+ /// Returns value of shear force at the end of inclined section
+ ///
+ /// Value of shear force at the end of inclined section
+ double CalculateShearForce();
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogic.cs
new file mode 100644
index 0000000..77003d0
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogic.cs
@@ -0,0 +1,15 @@
+using StructureHelperCommon.Infrastructures.Interfaces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ internal interface IShearForceLogic : ILogic
+ {
+ double GetShearForce();
+
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogicInputData.cs b/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogicInputData.cs
new file mode 100644
index 0000000..17452d8
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/IShearForceLogicInputData.cs
@@ -0,0 +1,18 @@
+using StructureHelperCommon.Infrastructures.Enums;
+using StructureHelperCommon.Models.Forces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public interface IShearForceLogicInputData
+ {
+ IBeamShearAxisAction AxisAction {get;set;}
+ IInclinedSection InclinedSection { get; set; }
+ LimitStates LimitState { get; set; }
+ CalcTerms CalcTerm { get; set; }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/IGetSumForceByShearActionLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/ISumForceByShearLoadLogic.cs
similarity index 75%
rename from StructureHelperLogics/Models/BeamShears/Logics/IGetSumForceByShearActionLogic.cs
rename to StructureHelperLogics/Models/BeamShears/Logics/ISumForceByShearLoadLogic.cs
index 26ea453..f961cef 100644
--- a/StructureHelperLogics/Models/BeamShears/Logics/IGetSumForceByShearActionLogic.cs
+++ b/StructureHelperLogics/Models/BeamShears/Logics/ISumForceByShearLoadLogic.cs
@@ -11,15 +11,15 @@ namespace StructureHelperLogics.Models.BeamShears
///
/// Implement logic for obtaining of summary force of action from start to end
///
- public interface IGetSumForceByShearActionLogic : ILogic
+ public interface ISumForceByShearLoadLogic : ILogic
{
///
/// Returns summary force of action from start to end
///
- /// Source action
+ /// Source action
/// Coordinate of start point, m
/// Coordinate of end point, m
/// Summary force, N
- double GetSumShearForce(IBeamShearLoad beamShearAction, double startCoord, double endCoord);
+ double GetSumShearForce(IBeamShearLoad beamShearLoad, double startCoord, double endCoord);
}
}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogic.cs
new file mode 100644
index 0000000..63669dc
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogic.cs
@@ -0,0 +1,55 @@
+using StructureHelperCommon.Models;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models.Forces.Logics;
+using StructureHelperCommon.Models.Loggers;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public class ShearForceLogic : IShearForceLogic
+ {
+ private IGetLoadFactor getFactorLogic;
+ private IGetDirectShearForceLogic getDirectShearForceLogic;
+
+ public IShearForceLogicInputData InputData { get;}
+ public IShiftTraceLogger? TraceLogger { get; set; }
+
+ public ShearForceLogic(IShearForceLogicInputData inputData, IShiftTraceLogger? traceLogger)
+ {
+ InputData = inputData;
+ TraceLogger = traceLogger;
+ }
+
+ public ShearForceLogic(
+ IShearForceLogicInputData inputData,
+ IShiftTraceLogger? traceLogger,
+ IGetLoadFactor getFactorLogic,
+ IGetDirectShearForceLogic getDirectShearForceLogic)
+ {
+ InputData = inputData;
+ TraceLogger = traceLogger;
+ this.getFactorLogic = getFactorLogic;
+ this.getDirectShearForceLogic = getDirectShearForceLogic;
+ }
+
+ public double GetShearForce()
+ {
+ TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
+ InitializeStrategies();
+ double factor = getFactorLogic.GetFactor();
+ double directShearForce = getDirectShearForceLogic.CalculateShearForce();
+ double shearForce = directShearForce * factor;
+ return shearForce;
+ }
+
+ private void InitializeStrategies()
+ {
+ getFactorLogic ??= new GetFactorByFactoredCombinationProperty()
+ {
+ CombinationProperty = InputData.AxisAction.FactoredCombinationProperty,
+ LimitState = InputData.LimitState,
+ CalcTerm = InputData.CalcTerm
+ };
+ getDirectShearForceLogic ??= new GetDirectShearForceLogic(InputData.AxisAction, InputData.InclinedSection, TraceLogger);
+ }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogicInputData.cs b/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogicInputData.cs
new file mode 100644
index 0000000..3544f62
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/ShearForceLogicInputData.cs
@@ -0,0 +1,18 @@
+using StructureHelperCommon.Infrastructures.Enums;
+using StructureHelperCommon.Models.Forces;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace StructureHelperLogics.Models.BeamShears.Logics
+{
+ public class ShearForceLogicInputData : IShearForceLogicInputData
+ {
+ public IBeamShearAxisAction AxisAction { get; set; }
+ public IInclinedSection InclinedSection { get; set; }
+ public LimitStates LimitState { get; set; }
+ public CalcTerms CalcTerm { get; set; }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/SumConcentratedForceLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/SumConcentratedForceLogic.cs
new file mode 100644
index 0000000..60ec768
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/SumConcentratedForceLogic.cs
@@ -0,0 +1,77 @@
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models.Loggers;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public class SumConcentratedForceLogic : ISumForceByShearLoadLogic
+ {
+ private ICoordinateByLevelLogic coordinateByLevelLogic;
+ public IShiftTraceLogger? TraceLogger { get; set; }
+
+ public SumConcentratedForceLogic(ICoordinateByLevelLogic coordinateByLevelLogic, IShiftTraceLogger? traceLogger)
+ {
+ this.coordinateByLevelLogic = coordinateByLevelLogic;
+ TraceLogger = traceLogger;
+ }
+
+ public SumConcentratedForceLogic(IShiftTraceLogger? traceLogger)
+
+ {
+ TraceLogger = traceLogger;
+ }
+
+ public double GetSumShearForce(IBeamShearLoad beamShearLoad, double startCoord, double endCoord)
+ {
+ TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
+ if (beamShearLoad is IConcentratedForce concentratedForce)
+ {
+ InitializeStrategies();
+ double sumForce = GetConcentratedForceSum(concentratedForce, startCoord, endCoord);
+ return sumForce;
+ }
+ else
+ {
+ throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(beamShearLoad) + ": beam shear load is not concentrated force");
+ }
+ }
+
+ private void InitializeStrategies()
+ {
+ coordinateByLevelLogic ??= new CoordinateByLevelLogic(TraceLogger);
+ }
+
+ private double GetConcentratedForceSum(IConcentratedForce concentratedForce, double startCoord, double endCoord)
+ {
+ TraceLogger?.AddMessage($"Concentrated force Name = {concentratedForce.Name}, Value = {concentratedForce.ForceValue}(N/m) ");
+ if (concentratedForce.ForceCoordinate > endCoord)
+ {
+ TraceLogger?.AddMessage($"Force coordinate {concentratedForce.ForceCoordinate}(m) is bigger than section end {endCoord}(m), so total load is zero");
+ return 0;
+ }
+ return GetConcentratedForce(concentratedForce, startCoord, endCoord);
+ }
+
+ private double GetConcentratedForce(IConcentratedForce concentratedForce, double startCoord, double endCoord)
+ {
+ double totalLoad;
+ double limitCoordinate = startCoord;
+ if (concentratedForce.ForceCoordinate >= startCoord)
+ {
+ limitCoordinate = coordinateByLevelLogic.GetCoordinate(startCoord, endCoord, concentratedForce.RelativeLoadLevel);
+ }
+ if (concentratedForce.ForceCoordinate < limitCoordinate)
+ {
+ totalLoad = concentratedForce.ForceValue * concentratedForce.LoadRatio;
+ TraceLogger?.AddMessage($"Total load Q,tot = {concentratedForce.ForceValue}(N) * {concentratedForce.LoadRatio} = {totalLoad}(N)");
+ }
+ else
+ {
+ TraceLogger?.AddMessage($"Force coordinate {concentratedForce.ForceCoordinate}(m) is bigger than limit coordinate {limitCoordinate}(m), so total load is zero");
+ totalLoad = 0d;
+ }
+ return totalLoad;
+ }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/SumDistributedLoadLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/SumDistributedLoadLogic.cs
new file mode 100644
index 0000000..d20309e
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/SumDistributedLoadLogic.cs
@@ -0,0 +1,62 @@
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models.Loggers;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public class SumDistributedLoadLogic : ISumForceByShearLoadLogic
+ {
+ private ICoordinateByLevelLogic coordinateByLevelLogic;
+ public IShiftTraceLogger? TraceLogger { get; set; }
+
+ public SumDistributedLoadLogic(IShiftTraceLogger? traceLogger)
+ {
+ TraceLogger = traceLogger;
+ }
+
+ public SumDistributedLoadLogic(ICoordinateByLevelLogic coordinateByLevelLogic, IShiftTraceLogger? traceLogger)
+ {
+ this.coordinateByLevelLogic = coordinateByLevelLogic;
+ TraceLogger = traceLogger;
+ }
+
+ public double GetSumShearForce(IBeamShearLoad beamShearLoad, double startCoord, double endCoord)
+ {
+ TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
+ if (beamShearLoad is IDistributedLoad distributedLoad)
+ {
+ InitializeStrategies();
+ double sumForce = GetDistributedLoadSum(distributedLoad, startCoord, endCoord);
+ return sumForce;
+ }
+ else
+ {
+ throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(beamShearLoad) + ": beam shear load is not distributed load");
+ }
+ }
+
+ private void InitializeStrategies()
+ {
+ coordinateByLevelLogic ??= new CoordinateByLevelLogic(TraceLogger);
+ }
+
+ private double GetDistributedLoadSum(IDistributedLoad distributedLoad, double startCoord, double endCoord)
+ {
+ TraceLogger?.AddMessage($"Uniformly distributed load Name = {distributedLoad.Name}, Value = {distributedLoad.LoadValue}(N/m) ");
+ double loadStartCoord = Math.Max(distributedLoad.StartCoordinate, 0d);
+ if (loadStartCoord > endCoord)
+ {
+ TraceLogger?.AddMessage($"Load start coordinate {loadStartCoord}(m) is bigger than section end {endCoord}(m), so total load is zero");
+ return 0d;
+ }
+ double endCoordByLevel = coordinateByLevelLogic.GetCoordinate(startCoord, endCoord, distributedLoad.RelativeLoadLevel);
+ double loadEndCoord = Math.Min(distributedLoad.EndCoordinate, endCoordByLevel);
+ double loadLength = loadEndCoord - loadStartCoord;
+ TraceLogger?.AddMessage($"Total length L,tot = {loadEndCoord}(m) - {loadStartCoord}(m) = {loadLength}(m)");
+ double totalLoad = distributedLoad.LoadValue * distributedLoad.LoadRatio * loadLength;
+ TraceLogger?.AddMessage($"Total load Q,tot = {distributedLoad.LoadValue}(N/m) * {distributedLoad.LoadRatio} * {loadLength}(m) = {totalLoad}(N)");
+ return totalLoad;
+ }
+ }
+}
diff --git a/StructureHelperLogics/Models/BeamShears/Logics/SumForceByShearLoadLogic.cs b/StructureHelperLogics/Models/BeamShears/Logics/SumForceByShearLoadLogic.cs
new file mode 100644
index 0000000..b56733b
--- /dev/null
+++ b/StructureHelperLogics/Models/BeamShears/Logics/SumForceByShearLoadLogic.cs
@@ -0,0 +1,67 @@
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models.Loggers;
+using StructureHelperLogics.Models.BeamShears.Logics;
+
+namespace StructureHelperLogics.Models.BeamShears
+{
+ public class SumForceByShearLoadLogic : ISumForceByShearLoadLogic
+ {
+ private ISumForceByShearLoadLogic sumDistributedLoadLogic;
+ private ISumForceByShearLoadLogic sumConcentratedForceLogic;
+ public IShiftTraceLogger? TraceLogger { get; set; }
+
+ public SumForceByShearLoadLogic(IShiftTraceLogger? traceLogger)
+ {
+ TraceLogger = traceLogger;
+ }
+
+ public SumForceByShearLoadLogic(
+ ISumForceByShearLoadLogic sumDistributedLoadLogic,
+ ISumForceByShearLoadLogic sumConcentratedForceLogic,
+ IShiftTraceLogger? traceLogger)
+ {
+ this.sumDistributedLoadLogic = sumDistributedLoadLogic;
+ this.sumConcentratedForceLogic = sumConcentratedForceLogic;
+ TraceLogger = traceLogger;
+ }
+
+ public double GetSumShearForce(IBeamShearLoad beamShearLoad, double startCoord, double endCoord)
+ {
+ TraceLogger?.AddMessage(LoggerStrings.LogicType(this), TraceLogStatuses.Service);
+ if (beamShearLoad is IDistributedLoad distributedLoad)
+ {
+ TraceLogger?.AddMessage($"Load is uniformly distributed load");
+ double sumDistributed = GetDistributedLoadSum(distributedLoad, startCoord, endCoord);
+ return sumDistributed;
+ }
+ else if (beamShearLoad is IConcentratedForce concenratedForce)
+ {
+ TraceLogger?.AddMessage($"Load is concentrated force");
+ return GetConcentratedForceSum(concenratedForce, startCoord, endCoord);
+ }
+ else
+ {
+ throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknownObj(beamShearLoad));
+ }
+ }
+
+ private double GetConcentratedForceSum(IConcentratedForce concenratedForce, double startCoord, double endCoord)
+ {
+ sumConcentratedForceLogic ??= new SumConcentratedForceLogic(TraceLogger);
+ double sumForce = sumConcentratedForceLogic.GetSumShearForce(concenratedForce, startCoord, endCoord);
+ TraceLogger?.AddMessage($"Sum of uniformly distributed load Qud = {sumForce}(N)");
+ return sumForce;
+ }
+
+ private double GetDistributedLoadSum(IDistributedLoad distributedLoad, double startCoord, double endCoord)
+ {
+ sumDistributedLoadLogic ??= new SumDistributedLoadLogic(TraceLogger);
+ double sumForce = sumDistributedLoadLogic.GetSumShearForce(distributedLoad, startCoord, endCoord);
+ TraceLogger?.AddMessage($"Sum of concentrated force Qcf = {sumForce}(N)");
+ return sumForce;
+ }
+
+ }
+}
diff --git a/StructureHelperTests/UnitTests/BeamShearTests/GetDirectShearForceLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/GetDirectShearForceLogicTests.cs
new file mode 100644
index 0000000..485295e
--- /dev/null
+++ b/StructureHelperTests/UnitTests/BeamShearTests/GetDirectShearForceLogicTests.cs
@@ -0,0 +1,55 @@
+using Moq;
+using NUnit.Framework;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models;
+using StructureHelperLogics.Models.BeamShears.Logics;
+using StructureHelperLogics.Models.BeamShears;
+
+namespace StructureHelperTests.UnitTests.BeamShearTests
+{
+
+
+ namespace YourNamespace.Tests
+ {
+ [TestFixture]
+ public class GetDirectShearForceLogicTests
+ {
+ private Mock _mockLogger;
+ private Mock _mockSummaryForceLogic;
+ private GetDirectShearForceLogic _logic;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mockLogger = new Mock();
+ _mockSummaryForceLogic = new Mock();
+ var mockAxisAction = new Mock();
+ var mockInclinedSection = new Mock();
+ var mockShearLoad = new Mock();
+
+ mockAxisAction.Setup(a => a.SupportShearForce).Returns(100.0);
+ mockAxisAction.Setup(a => a.ShearLoads).Returns(new List { mockShearLoad.Object });
+
+ mockInclinedSection.Setup(i => i.StartCoord).Returns(2.0);
+ mockInclinedSection.Setup(i => i.EndCoord).Returns(5.0);
+
+ _mockSummaryForceLogic.Setup(s => s.GetSumShearForce(mockShearLoad.Object, 2.0, 5.0)).Returns(50.0);
+ _logic = new GetDirectShearForceLogic(mockAxisAction.Object, mockInclinedSection.Object, _mockLogger.Object, _mockSummaryForceLogic.Object);
+ }
+
+ [Test]
+ public void GetShearForce_ShouldReturnCorrectShearForce()
+ {
+ // Arrange
+
+ // Act
+ double result = _logic.CalculateShearForce();
+
+ // Assert
+ Assert.That(result, Is.EqualTo(150.0));
+ _mockLogger.Verify(l => l.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce);
+ }
+ }
+ }
+
+}
diff --git a/StructureHelperTests/UnitTests/BeamShearTests/GetShearForceLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/GetShearForceLogicTests.cs
new file mode 100644
index 0000000..941b901
--- /dev/null
+++ b/StructureHelperTests/UnitTests/BeamShearTests/GetShearForceLogicTests.cs
@@ -0,0 +1,48 @@
+using Moq;
+using NUnit.Framework;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models;
+using StructureHelperLogics.Models.BeamShears;
+namespace StructureHelperTests.UnitTests.BeamShearTests
+{
+ [TestFixture]
+ public class GetShearForceLogicTests
+ {
+ private Mock _mockLogger;
+ private Mock _mockGetFactorLogic;
+ private Mock _mockGetDirectShearForceLogic;
+ private Mock _mockInputData;
+ private ShearForceLogic _logic;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mockLogger = new Mock();
+ _mockGetFactorLogic = new Mock();
+ _mockGetDirectShearForceLogic = new Mock();
+ _mockInputData = new Mock();
+
+ _logic = new ShearForceLogic(
+ _mockInputData.Object,
+ _mockLogger.Object,
+ _mockGetFactorLogic.Object,
+ _mockGetDirectShearForceLogic.Object
+ );
+ }
+
+ [Test]
+ public void GetShearForce_ShouldReturnCorrectShearForce()
+ {
+ // Arrange
+ _mockGetFactorLogic.Setup(f => f.GetFactor()).Returns(1.5);
+ _mockGetDirectShearForceLogic.Setup(d => d.CalculateShearForce()).Returns(100.0);
+
+ // Act
+ double result = _logic.GetShearForce();
+
+ // Assert
+ Assert.That(result, Is.EqualTo(150.0));
+ _mockLogger.Verify(l => l.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce);
+ }
+ }
+}
diff --git a/StructureHelperTests/UnitTests/BeamShearTests/SumConcentratedForceLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/SumConcentratedForceLogicTests.cs
new file mode 100644
index 0000000..c85a480
--- /dev/null
+++ b/StructureHelperTests/UnitTests/BeamShearTests/SumConcentratedForceLogicTests.cs
@@ -0,0 +1,69 @@
+using Moq;
+using NUnit.Framework;
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models;
+using StructureHelperLogics.Models.BeamShears;
+
+namespace StructureHelperTests.UnitTests.BeamShearTests
+{
+ [TestFixture]
+ public class SumConcentratedForceLogicTests
+ {
+ private Mock _mockLogger;
+ private Mock _mockCoordinateByLevelLogic;
+ private SumConcentratedForceLogic _logic;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mockLogger = new Mock();
+ _mockCoordinateByLevelLogic = new Mock();
+ _logic = new SumConcentratedForceLogic(_mockCoordinateByLevelLogic.Object, _mockLogger.Object);
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldReturnCorrectForce_ForValidConcentratedForce()
+ {
+ // Arrange
+ var mockConcentratedForce = new Mock();
+ mockConcentratedForce.Setup(f => f.ForceCoordinate).Returns(3.0);
+ mockConcentratedForce.Setup(f => f.ForceValue).Returns(100.0);
+ mockConcentratedForce.Setup(f => f.LoadRatio).Returns(0.8);
+ mockConcentratedForce.Setup(f => f.RelativeLoadLevel).Returns(0.5);
+
+ _mockCoordinateByLevelLogic.Setup(c => c.GetCoordinate(2.0, 5.0, 0.5)).Returns(3.5);
+
+ // Act
+ double result = _logic.GetSumShearForce(mockConcentratedForce.Object, 2.0, 5.0);
+
+ // Assert
+ Assert.That(result, Is.EqualTo(80.0));
+ _mockLogger.Verify(l => l.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce);
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldReturnZero_WhenForceCoordinateExceedsEndCoord()
+ {
+ // Arrange
+ var mockConcentratedForce = new Mock();
+ mockConcentratedForce.Setup(f => f.ForceCoordinate).Returns(6.0);
+
+ // Act
+ double result = _logic.GetSumShearForce(mockConcentratedForce.Object, 2.0, 5.0);
+
+ // Assert
+ Assert.That(result, Is.EqualTo(0.0));
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldThrowException_ForInvalidShearLoad()
+ {
+ // Arrange
+ var mockInvalidShearLoad = new Mock();
+
+ // Act & Assert
+ Assert.Throws(() => _logic.GetSumShearForce(mockInvalidShearLoad.Object, 2.0, 5.0));
+ }
+ }
+ }
diff --git a/StructureHelperTests/UnitTests/BeamShearTests/SumDistributedLoadLogicTests.cs b/StructureHelperTests/UnitTests/BeamShearTests/SumDistributedLoadLogicTests.cs
new file mode 100644
index 0000000..c147ccc
--- /dev/null
+++ b/StructureHelperTests/UnitTests/BeamShearTests/SumDistributedLoadLogicTests.cs
@@ -0,0 +1,71 @@
+using Moq;
+using NUnit.Framework;
+using StructureHelperCommon.Infrastructures.Exceptions;
+using StructureHelperCommon.Models.Forces;
+using StructureHelperCommon.Models;
+using StructureHelperLogics.Models.BeamShears;
+
+namespace StructureHelperTests.UnitTests.BeamShearTests
+{
+ [TestFixture]
+ public class SumDistributedLoadLogicTests
+ {
+ private Mock _mockLogger;
+ private Mock _mockCoordinateByLevelLogic;
+ private SumDistributedLoadLogic _logic;
+
+ [SetUp]
+ public void Setup()
+ {
+ _mockLogger = new Mock();
+ _mockCoordinateByLevelLogic = new Mock();
+ _logic = new SumDistributedLoadLogic(_mockCoordinateByLevelLogic.Object, _mockLogger.Object);
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldReturnCorrectForce_ForValidDistributedLoad()
+ {
+ // Arrange
+ var mockDistributedLoad = new Mock();
+ mockDistributedLoad.Setup(d => d.StartCoordinate).Returns(1.0);
+ mockDistributedLoad.Setup(d => d.EndCoordinate).Returns(4.0);
+ mockDistributedLoad.Setup(d => d.LoadValue).Returns(50.0);
+ mockDistributedLoad.Setup(d => d.LoadRatio).Returns(0.9);
+ mockDistributedLoad.Setup(d => d.RelativeLoadLevel).Returns(0.5);
+
+ _mockCoordinateByLevelLogic.Setup(c => c.GetCoordinate(2.0, 5.0, 0.5)).Returns(4.5);
+
+ // Act
+ double result = _logic.GetSumShearForce(mockDistributedLoad.Object, 2.0, 5.0);
+
+ // Assert
+ Assert.That(result, Is.EqualTo(135.0));
+ _mockLogger.Verify(l => l.AddMessage(It.IsAny(), It.IsAny()), Times.AtLeastOnce);
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldReturnZero_WhenStartCoordExceedsEndCoord()
+ {
+ // Arrange
+ var mockDistributedLoad = new Mock();
+ mockDistributedLoad.Setup(d => d.StartCoordinate).Returns(6.0);
+
+ // Act
+ double result = _logic.GetSumShearForce(mockDistributedLoad.Object, 2.0, 5.0);
+
+ // Assert
+ Assert.That(result, Is.EqualTo(0.0));
+ }
+
+ [Test]
+ public void GetSumShearForce_ShouldThrowException_ForInvalidShearLoad()
+ {
+ // Arrange
+ var mockInvalidShearLoad = new Mock();
+
+ // Act & Assert
+ Assert.Throws(() => _logic.GetSumShearForce(mockInvalidShearLoad.Object, 2.0, 5.0));
+ }
+ }
+
+}