Change curvature calculator

This commit is contained in:
Evgeny Redikultsev
2025-11-29 21:43:00 +05:00
parent 5daa32a954
commit f381229a63
73 changed files with 1361 additions and 406 deletions

View File

@@ -24,8 +24,8 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
TraceLogger = traceLogger;
CheckRebarPrimitiveLogic checkRebarPrimitiveLogic = new()
{
CheckRebarHostMaterial = false,
CheckRebarPlacement = false
CheckRebarHostMaterial = true,
CheckRebarPlacement = true
};
primitivesCheckLogic = new HasPrimitivesCheckLogic(TraceLogger, checkRebarPrimitiveLogic);
}
@@ -39,12 +39,12 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
TraceMessage(errorString);
throw new StructureHelperException(errorString);
}
if (Entity.Primitives is null || !Entity.Primitives.Any())
if (Entity.Primitives is null || Entity.Primitives.Count == 0)
{
TraceMessage("Calculator does not contain any primitives");
result = false;
}
if (Entity.ForceActions is null || !Entity.ForceActions.Any())
if (Entity.ForceActions is null || Entity.ForceActions.Count == 0)
{
TraceMessage("Calculator does not contain any forces");
result = false;

View File

@@ -3,36 +3,88 @@ using StructureHelperCommon.Services;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
public class CurvatureCalculatorInputDataUpdateStrategy : IParentUpdateStrategy<ICurvatureCalculatorInputData>
/// <summary>
/// Provides an update strategy for <see cref="ICurvatureCalculatorInputData"/>,
/// allowing transfer of child collections and nested objects from a source
/// instance to a target instance.
/// </summary>
public class CurvatureCalculatorInputDataUpdateStrategy
: IParentUpdateStrategy<ICurvatureCalculatorInputData>
{
private IUpdateStrategy<IDeflectionFactor> deflectionUpdateStrategy;
private IUpdateStrategy<IDeflectionFactor> DeflectionUpdateStrategy => deflectionUpdateStrategy ??= new DeflectionFactorUpdateStrategy();
private IUpdateStrategy<IDeflectionFactor>? _deflectionUpdateStrategy;
/// <summary>
/// Gets the strategy used to update the <see cref="IDeflectionFactor"/> object.
/// Lazily initialized to <see cref="DeflectionFactorUpdateStrategy"/> if none supplied.
/// </summary>
private IUpdateStrategy<IDeflectionFactor> DeflectionUpdateStrategy =>
_deflectionUpdateStrategy ??= new DeflectionFactorUpdateStrategy();
/// <summary>
/// When true, the children's data (collections and nested objects)
/// will be updated from the source. Defaults to true.
/// </summary>
public bool UpdateChildren { get; set; } = true;
public void Update(ICurvatureCalculatorInputData targetObject, ICurvatureCalculatorInputData sourceObject)
/// <summary>
/// Creates a new instance of the update strategy.
/// </summary>
/// <param name="deflectionUpdateStrategy">
/// Optional custom update strategy for <see cref="IDeflectionFactor"/>.
/// </param>
public CurvatureCalculatorInputDataUpdateStrategy(
IUpdateStrategy<IDeflectionFactor>? deflectionUpdateStrategy = null)
{
CheckObject.ThrowIfNull(sourceObject, nameof(sourceObject));
CheckObject.ThrowIfNull(targetObject, nameof(targetObject));
if (ReferenceEquals(targetObject, sourceObject))
_deflectionUpdateStrategy = deflectionUpdateStrategy;
}
/// <inheritdoc />
public void Update(ICurvatureCalculatorInputData target, ICurvatureCalculatorInputData source)
{
CheckObject.ThrowIfNull(source, nameof(source));
CheckObject.ThrowIfNull(target, nameof(target));
if (ReferenceEquals(target, source))
return;
if (UpdateChildren == true)
if (UpdateChildren)
{
CheckProperties(targetObject, sourceObject);
targetObject.Primitives.Clear();
targetObject.Primitives.AddRange(sourceObject.Primitives);
targetObject.ForceActions.Clear();
targetObject.ForceActions.AddRange(sourceObject.ForceActions);
ValidateChildProperties(target, source);
UpdateCollections(target, source);
DeflectionUpdateStrategy.Update(target.DeflectionFactor, source.DeflectionFactor);
}
}
private static void CheckProperties(ICurvatureCalculatorInputData targetObject, ICurvatureCalculatorInputData sourceObject)
/// <summary>
/// Validates that all required child properties are not null.
/// </summary>
private static void ValidateChildProperties(
ICurvatureCalculatorInputData target,
ICurvatureCalculatorInputData source)
{
CheckObject.ThrowIfNull(sourceObject.Primitives);
CheckObject.ThrowIfNull(targetObject.Primitives);
CheckObject.ThrowIfNull(sourceObject.ForceActions);
CheckObject.ThrowIfNull(targetObject.ForceActions);
CheckObject.ThrowIfNull(source.Primitives, nameof(source.Primitives));
CheckObject.ThrowIfNull(target.Primitives, nameof(target.Primitives));
CheckObject.ThrowIfNull(source.ForceActions, nameof(source.ForceActions));
CheckObject.ThrowIfNull(target.ForceActions, nameof(target.ForceActions));
CheckObject.ThrowIfNull(source.DeflectionFactor, nameof(source.DeflectionFactor));
CheckObject.ThrowIfNull(target.DeflectionFactor, nameof(target.DeflectionFactor));
}
/// <summary>
/// Replaces the target collections with copies of the source collections.
/// </summary>
private static void UpdateCollections(
ICurvatureCalculatorInputData target,
ICurvatureCalculatorInputData source)
{
target.Primitives.Clear();
target.Primitives.AddRange(source.Primitives);
target.ForceActions.Clear();
target.ForceActions.AddRange(source.ForceActions);
}
}
}

View File

@@ -6,6 +6,7 @@ using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Models.Sections;
using StructureHelperCommon.Models.Sections.Logics;
using StructureHelperCommon.Models.Shapes;
using StructureHelperCommon.Services.Forces;
using StructureHelperLogics.Services.NdmPrimitives;
using System;
@@ -16,7 +17,7 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
private const LimitStates limitState = LimitStates.SLS;
private CurvatureCalculatorResult result;
private ICurvatureForceCalculator forceCalculator;
private ICurvatureForceCalculator ForceCalculator => forceCalculator ??= new CurvatureForceCalculator();
private ICurvatureForceCalculator ForceCalculator => forceCalculator ??= new CurvatureForceCalculator(TraceLogger);
private IPoint2D gravityCenter;
public ICurvatureCalculatorInputData InputData { get; set; }
@@ -27,6 +28,9 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
public void Run()
{
TraceLogger?.AddMessage($"Calculator type: {GetType()}", TraceLogStatuses.Service);
TraceLogger?.AddMessage($"Bending deflection is calculated by expression delta = S * k * L ^ 2");
TraceLogger?.AddMessage($"Longitudinal deflection is calculated by expression delta = S * k * L");
PrepareNewResult();
SetGravityCenter();
try
@@ -44,30 +48,37 @@ namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
foreach (var action in InputData.ForceActions)
{
TraceLogger?.AddMessage($"Calculation for action {action.Name} has been started");
var combinationList = action.GetCombinations();
foreach (var combination in combinationList)
{
var longTuple = combination.DesignForces.Single(x => x.LimitState == limitState && x.CalcTerm == CalcTerms.LongTerm).ForceTuple;
var shortTuple = combination.DesignForces.Single(x => x.LimitState == limitState && x.CalcTerm == CalcTerms.ShortTerm).ForceTuple;
if (action.SetInGravityCenter == true)
TraceLogger?.AddMessage($"Totally {combination.DesignForces.Count} combinations has been extracted successfully");
var pairList = ForceActionService.ConvertCombinationToPairs(combination).Where(x => x.LimitState == limitState).ToList();
foreach (var pair in pairList)
{
IProcessorLogic<IForceTuple> forceLogic = new ForceTupleCopier(longTuple);
forceLogic = new ForceTupleMoveToPointDecorator(forceLogic) { Point2D = gravityCenter };
longTuple = forceLogic.GetValue();
forceLogic = new ForceTupleCopier(shortTuple);
forceLogic = new ForceTupleMoveToPointDecorator(forceLogic) { Point2D = gravityCenter };
shortTuple = forceLogic.GetValue();
pair.Name = action.Name;
TraceLogger?.AddMessage($"Calculation for combination of force {pair.Name} has been started");
if (action.SetInGravityCenter == true)
{
IProcessorLogic<IForceTuple> forceLogic = new ForceTupleCopier(pair.LongForceTuple);
forceLogic = new ForceTupleMoveToPointDecorator(forceLogic) { Point2D = gravityCenter };
pair.LongForceTuple = forceLogic.GetValue();
forceLogic = new ForceTupleCopier(pair.FullForceTuple);
forceLogic = new ForceTupleMoveToPointDecorator(forceLogic) { Point2D = gravityCenter };
pair.FullForceTuple = forceLogic.GetValue();
}
CurvatureForceCalculatorInputData forceInputData = new()
{
ForcePair = pair,
Primitives = InputData.Primitives,
DeflectionFactor = InputData.DeflectionFactor
};
ForceCalculator.InputData = forceInputData;
ForceCalculator.Run();
ICurvatureForceCalculatorResult forceResult = (ICurvatureForceCalculatorResult)ForceCalculator.Result;
result.ForceCalculatorResults.Add(forceResult);
}
CurvatureForceCalculatorInputData forceInputData = new()
{
LongTermTuple = longTuple,
ShortTermTuple = shortTuple,
Primitives = InputData.Primitives,
DeflectionFactor = InputData.DeflectionFactor
};
ForceCalculator.InputData = forceInputData;
ForceCalculator.Run();
result.ForceCalculatorResults.Add((ICurvatureForceCalculatorResult)ForceCalculator.Result);
}
}
}

View File

@@ -1,9 +1,6 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Services;
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{

View File

@@ -0,0 +1,81 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Calculators;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
public class GetDeflectionByCurvatureLogic : IGetDeflectionByCurvatureLogic
{
public GetDeflectionByCurvatureLogic(IShiftTraceLogger traceLogger)
{
TraceLogger = traceLogger;
}
public IShiftTraceLogger? TraceLogger { get; set; }
public ICurvatureTermResult GetDeflection(IForceTuple curvature, IDeflectionFactor factor)
{
double L = factor.SpanLength;
TraceLogger?.AddMessage($"Span length L = {L}(m)");
var result = new CurvatureTermResult();
result.DeflectionMx = ComputeDeflection(
axisName: "X",
curvature: curvature.Mx,
k: factor.DeflectionFactors.Mx,
ultimate: factor.MaxDeflections.Mx,
spanLength: L,
isQuadratic: true);
result.DeflectionMy = ComputeDeflection(
axisName: "Y",
curvature: curvature.My,
k: factor.DeflectionFactors.My,
ultimate: factor.MaxDeflections.My,
spanLength: L,
isQuadratic: true);
result.DeflectionNz = ComputeDeflection(
axisName: "Z",
curvature: curvature.Nz,
k: factor.DeflectionFactors.Nz,
ultimate: factor.MaxDeflections.Nz,
spanLength: L,
isQuadratic: false);
return result;
}
private DeflectionResult ComputeDeflection(
string axisName,
double curvature,
double k,
double ultimate,
double spanLength,
bool isQuadratic)
{
double deflection = isQuadratic
? k * curvature * spanLength * spanLength
: k * curvature * spanLength;
string formula = isQuadratic
? $"{k} * {curvature} * ({spanLength})^2"
: $"{k} * {curvature} * {spanLength}";
TraceLogger?.AddMessage(
$"Deflection along {axisName} axis = {formula} = {deflection}(m)");
return new DeflectionResult
{
Curvature = curvature,
UltimateDeflection = ultimate,
Deflection = deflection
};
}
}
}

View File

@@ -0,0 +1,59 @@
using StructureHelperCommon.Models;
using StructureHelperCommon.Models.Forces;
using StructureHelperCommon.Services.Forces;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
/// <summary>
/// Provides logic for calculating long-term and short-term deflection terms
/// based on curvature values and deflection factors. Uses an underlying
/// <see cref="IGetDeflectionByCurvatureLogic"/> to compute the deflection
/// for a given curvature state.
/// </summary>
public class GetTermDeflectionLogic : IGetTermDeflectionLogic
{
private IGetDeflectionByCurvatureLogic deflectionLogic;
private IGetDeflectionByCurvatureLogic DeflectionLogic => deflectionLogic ??= new GetDeflectionByCurvatureLogic(TraceLogger);
private IForceTupleServiceLogic forceTupleServiceLogic;
private IForceTupleServiceLogic ForceTupleServiceLogic => forceTupleServiceLogic ??= new ForceTupleServiceLogic();
public IForceTuple LongCurvature { get; set; }
public IForceTuple ShortLongCurvature { get; set; }
public IForceTuple ShortFullCurvature { get; set; }
public IDeflectionFactor DeflectionFactor { get; set; }
public IShiftTraceLogger? TraceLogger { get; set; }
public GetTermDeflectionLogic(IShiftTraceLogger traceLogger)
{
TraceLogger = traceLogger;
}
public GetTermDeflectionLogic(IGetDeflectionByCurvatureLogic deflectionLogic, IForceTupleServiceLogic forceTupleServiceLogic, IShiftTraceLogger? traceLogger)
{
this.deflectionLogic = deflectionLogic;
this.forceTupleServiceLogic = forceTupleServiceLogic;
TraceLogger = traceLogger;
}
public ICurvatureTermResult GetLongResult()
{
TraceCurvature(LongCurvature);
ICurvatureTermResult longTermDeflection = DeflectionLogic.GetDeflection(LongCurvature, DeflectionFactor);
return longTermDeflection;
}
private void TraceCurvature(IForceTuple curvature)
{
TraceLogger?.AddMessage($"Curvature kx = {curvature.Mx}(1/m), ky = {curvature.My}(1/m), epsz = {curvature.Nz}(dimensionless)");
}
public ICurvatureTermResult GetShortResult()
{
var deltaShortCurvature = ForceTupleServiceLogic.SumTuples(ShortFullCurvature, ShortLongCurvature, -1);
var shortCurvature = ForceTupleServiceLogic.SumTuples(LongCurvature, deltaShortCurvature);
TraceCurvature(shortCurvature);
ICurvatureTermResult shortTermDeflection = DeflectionLogic.GetDeflection(shortCurvature, DeflectionFactor);
return shortTermDeflection;
}
}
}

View File

@@ -0,0 +1,13 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
public interface IGetDeflectionByCurvatureLogic : ILogic
{
ICurvatureTermResult GetDeflection(IForceTuple curvature, IDeflectionFactor DeflectionFactor);
}
}

View File

@@ -0,0 +1,27 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Models.Forces;
using System;
using System.Collections.Generic;
using System.Text;
namespace StructureHelperLogics.NdmCalculations.Analyses.Curvatures
{
public interface IGetTermDeflectionLogic : ILogic
{
IDeflectionFactor DeflectionFactor { get; set; }
/// <summary>
/// Curvature of cross-section form long term load with long term properties of material
/// </summary>
IForceTuple LongCurvature { get; set; }
/// <summary>
/// Curvature of cross-section form long term load with short term properties of material
/// </summary>
IForceTuple ShortLongCurvature { get; set; }
/// <summary>
/// Curvature of cross-section form short term load with short term properties of material
/// </summary>
IForceTuple ShortFullCurvature { get; set; }
ICurvatureTermResult GetLongResult();
ICurvatureTermResult GetShortResult();
}
}