Soil anchor was added

This commit is contained in:
ear
2023-12-01 20:07:26 +05:00
parent 01e6f97429
commit 8de8c00182
10 changed files with 461 additions and 3 deletions

View File

@@ -23,5 +23,6 @@
public static string ErrorOfExuting => "#0017: Error of executing";
public static string ExpectedWas(System.Type expected, System.Type was) => $"{DataIsInCorrect}: Expected {expected}, but was {was}";
public static string ExpectedWas(System.Type expected, object obj) => ExpectedWas(expected, obj.GetType());
public static string NullReference => "#0018: Null reference";
}
}

View File

@@ -12,6 +12,6 @@ namespace StructureHelperCommon.Models.Calculators
/// True if result of calculation is valid
/// </summary>
bool IsValid { get; set; }
string Description { get; set; }
string? Description { get; set; }
}
}

View File

@@ -0,0 +1,114 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Soils
{
public class AnchorCalculator : ICalculator
{
private AnchorResult result;
public string Name { get; set; }
public IAnchorSoilProperties Soil { get; set; }
public SoilAnchor Anchor { get; set; }
public IResult Result => result;
public Action<IResult> ActionToOutputResults { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public AnchorCalculator(SoilAnchor soilAnchor, IAnchorSoilProperties anchorSoilProperties)
{
Anchor = soilAnchor;
Soil = anchorSoilProperties;
}
public object Clone()
{
throw new NotImplementedException();
}
public void Run()
{
const double ratioFactor = 1.01d;
CheckParameters();
result = new() { IsValid = true };
var alpha = Math.PI / 180d * Anchor.AngleToHorizont;
var fi = Math.PI / 180d * Soil.FrictionAngle;
var sinFi = Math.Sin(fi);
double ksi0 = GetKsi();
var hk = Anchor.GroundLevel - Anchor.HeadLevel;
hk += Anchor.FreeLength * Math.Sin(alpha);
result.AnchorCenterLevel = hk;
var decrement = Math.Sqrt(Math.Pow(Math.Cos(alpha), 2) + Math.Pow(ksi0 * Math.Sin(alpha), 2));
var sigma0g = 0.5d * (Soil.VolumetricWeight * hk + Anchor.AdditionalSurfPressure) * (ksi0 + decrement);
result.AverageSidePressure = sigma0g;
var overA1 = (1 + Soil.PoissonRatio) * (sigma0g + Soil.Coheasion / Math.Tan(fi)) * sinFi;
var a1 = Soil.YoungsModulus / overA1;
double kp = GetKp(ratioFactor, sinFi, a1);
var charRak = Math.PI * Anchor.RootDiameter * Anchor.RootLength;
charRak *= 1 + sinFi;
charRak *= sigma0g * Math.Tan(fi) + Soil.Coheasion;
charRak *= kp * GetGammaC();
result.CharBearingCapacity = charRak;
result.DesignBearingCapacity = charRak / GetGammaN();
result.MortarVolumeFstStady = 0.5d * (Anchor.RootDiameter * Anchor.RootDiameter - Anchor.JetTubeDiameter * Anchor.JetTubeDiameter) * (1 + 3.1 * Anchor.WaterCementRatio) * Anchor.RootLength;
result.MortarVolumeSndStady = 0.5d * (Anchor.RootDiameter * Anchor.RootDiameter - Anchor.BoreHoleDiameter * Anchor.BoreHoleDiameter) * (1 + 3.1d * Anchor.WaterCementRatio) * Anchor.RootLength;
}
private void CheckParameters()
{
if (Anchor.RootDiameter < Anchor.BoreHoleDiameter)
{
throw new StructureHelperException(ErrorStrings.DataIsInCorrect + $": Diameter of root {Anchor.RootDiameter}m must be greater than diameter of borehole {Anchor.BoreHoleDiameter}m");
}
}
private double GetKp(double ratioFactor, double sinFi, double a1)
{
var tetta = sinFi / (1 + sinFi);
var kp = ratioFactor - Math.Pow(Anchor.BoreHoleDiameter / Anchor.RootDiameter, 2);
kp /= ratioFactor - a1 * a1 / (1 + a1 * a1);
kp = Math.Pow(kp, tetta);
return kp;
}
private double GetKsi()
{
if (Soil.SoilType == SoilType.SandAndSemiSand) { return 0.43d; }
else if (Soil.SoilType == SoilType.SemiClay) { return 0.55d; }
else if (Soil.SoilType == SoilType.Clay) { return 0.72d; }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); }
}
private double GetGammaC()
{
if (Soil.SoilType == SoilType.SandAndSemiSand) { return 0.72d; }
else if (Soil.SoilType == SoilType.SemiClay) { return 0.64d; }
else if (Soil.SoilType == SoilType.Clay) { return 0.64; }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown + $": {Soil.SoilType}"); }
}
private double GetGammaN()
{
if (Anchor.DurabilityType == DurabilityType.Temporary) { return 1.2d; }
else if (Anchor.DurabilityType == DurabilityType.Eturnal) { return 1.4d; }
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown + $": {Anchor.DurabilityType}"); }
}
}
}

View File

@@ -0,0 +1,40 @@
using StructureHelperCommon.Models.Calculators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Soils
{
public class AnchorResult : IResult
{
/// <inheritdoc/>
public bool IsValid { get; set; }
/// <inheritdoc/>
public string? Description { get; set; }
/// <summary>
/// Characteristic Bearing Capacity, N
/// </summary>
public double CharBearingCapacity { get; set; }
/// <summary>
/// Design Bearing Capacity, N
/// </summary>
public double DesignBearingCapacity { get; set; }
/// <summary>
/// Average side pressure, Pa
/// </summary>
public double AverageSidePressure { get;set; }
/// <summary>
/// Volume of mortar of first stady, m^3
/// </summary>
public double MortarVolumeFstStady { get; set; }
/// <summary>
/// Volume of mortar of second stady, m^3
/// </summary>
public double MortarVolumeSndStady { get; set; }
public double AnchorCenterLevel { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Soils
{
public class AnchorSoilProperties : IAnchorSoilProperties
{
public Guid Id { get;}
/// <inheritdoc/>
public double YoungsModulus { get; set; }
/// <inheritdoc/>
public double PoissonRatio { get; set; }
/// <inheritdoc/>
public double VolumetricWeight { get; set; }
/// <inheritdoc/>
public double FrictionAngle { get; set; }
/// <inheritdoc/>
public double Coheasion { get; set; }
/// <inheritdoc/>
public SoilType SoilType { get; set; }
public AnchorSoilProperties(Guid id)
{
Id = id;
YoungsModulus = 20e6d; //20MPa
PoissonRatio = 0.3d;
VolumetricWeight = 20e3d; //20kN/m^3
FrictionAngle = 25d;
Coheasion = 30e3d; //30kPa
SoilType = SoilType.SandAndSemiSand;
}
public AnchorSoilProperties() : this(Guid.NewGuid()) { }
}
}

View File

@@ -0,0 +1,46 @@
using StructureHelperCommon.Infrastructures.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Soils
{
public enum SoilType
{
SandAndSemiSand,
SemiClay,
Clay
}
/// <summary>
/// Properties of soil for calculating of soil anchor
/// </summary>
public interface IAnchorSoilProperties : ISaveable
{
/// <summary>
/// Young's modulus, Pa
/// </summary>
double YoungsModulus { get; set; }
/// <summary>
/// Poison ratio
/// </summary>
double PoissonRatio { get; set; }
/// <summary>
/// Volumetric weight, N/m^3
/// </summary>
double VolumetricWeight { get; set; }
/// <summary>
/// Angle of internal friction, degree
/// </summary>
double FrictionAngle { get; set; }
/// <summary>
/// Coheasion, Pa
/// </summary>
double Coheasion { get; set; }
/// <summary>
/// Type of Soil
/// </summary>
SoilType SoilType { get; set; }
}
}

View File

@@ -0,0 +1,148 @@
using StructureHelperCommon.Infrastructures.Exceptions;
using StructureHelperCommon.Infrastructures.Interfaces;
using StructureHelperCommon.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperCommon.Models.Soils
{
public enum DurabilityType
{
Temporary,
Eturnal
}
public class SoilAnchor : ISaveable
{
private double rootLength;
private double rootDiameter;
private double freeLength;
private double jetTubeDiameter;
private double waterCementRatio;
private double boreHoleDiameter;
private double angleToHorizont;
private double additionalSurfPressure;
private double headLevel;
/// <inheritdoc/>
public Guid Id {get; private set;}
/// <summary>
/// Length of root, m
/// </summary>
public double RootLength
{
get => rootLength; set
{
CheckObject.CheckMinMax(value, 0d, 10d);
rootLength = value;
}
}
/// <summary>
/// Diameter of root, m
/// </summary>
public double RootDiameter
{
get => rootDiameter; set
{
CheckObject.CheckMinMax(value, 0d, 1d);
rootDiameter = value;
}
}
/// <summary>
///
/// </summary>
public double GroundLevel { get; set; }
/// <summary>
/// Absolute level of head of anchor, m
/// </summary>
public double HeadLevel { get => headLevel; set => headLevel = value; }
/// <summary>
/// Free Length, m
/// </summary>
public double FreeLength
{
get => freeLength; set
{
CheckObject.CheckMinMax(value, 0d, 20d);
freeLength = value;
}
}
/// <summary>
/// Diameter of boregole, m
/// </summary>
public double BoreHoleDiameter
{
get => boreHoleDiameter; set
{
CheckObject.CheckMinMax(value, 0d, 1d);
boreHoleDiameter = value;
}
}
/// <summary>
/// Diameter of tube for jetting of mortar
/// </summary>
public double JetTubeDiameter
{
get => jetTubeDiameter; set
{
CheckObject.CheckMinMax(value, 0d, 0.1d);
jetTubeDiameter = value;
}
}
/// <summary>
/// Water-Cement ratio of jetting mortar
/// </summary>
public double WaterCementRatio
{
get => waterCementRatio; set
{
CheckObject.CheckMinMax(value, 0d, 3d);
waterCementRatio = value;
}
}
/// <summary>
/// Angle between horizontal plane and axis of anchor, degree
/// </summary>
public double AngleToHorizont
{
get => angleToHorizont; set
{
CheckObject.CheckMinMax(value, 0d, 60d);
angleToHorizont = value;
}
}
/// <summary>
/// Additional pressure on the surface of ground, Pa
/// </summary>
public double AdditionalSurfPressure
{
get => additionalSurfPressure; set
{
CheckObject.CheckMinMax(value, 0d, 2e4d); //20kPa
additionalSurfPressure = value;
}
}
public DurabilityType DurabilityType {get;set;}
public SoilAnchor(Guid id)
{
Id = id;
RootLength = 6;
HeadLevel = -4d;
FreeLength = 7d;
BoreHoleDiameter = 0.145d;
RootDiameter = boreHoleDiameter / 0.9d;
JetTubeDiameter = 0.025d;
WaterCementRatio = 0.45d;
AngleToHorizont = 15;
DurabilityType = DurabilityType.Temporary;
}
public SoilAnchor() : this(Guid.NewGuid()) { }
}
}

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace StructureHelperCommon.Services
{
@@ -43,5 +44,12 @@ namespace StructureHelperCommon.Services
throw new StructureHelperException($"{ErrorStrings.ExpectedWas(targetType, sourceObject.GetType())}");
}
}
public static void CheckMinMax (double value, double minValue, double maxValue)
{
if (value == null || minValue == null || maxValue == null) { throw new StructureHelperException(ErrorStrings.NullReference); }
if (value < minValue) { throw new StructureHelperException($"{ErrorStrings.IncorrectValue}: Value must be greater than {minValue}"); }
if (value > maxValue) { throw new StructureHelperException($"{ErrorStrings.IncorrectValue}: Value must be less than {maxValue}"); }
}
}
}

View File

@@ -15,8 +15,6 @@ namespace StructureHelperTests.UnitTests.Calcuators
//Arrange
var calculator = new LimitCurveCalculator(new StabLimitCurveLogic())
{
XMax = xmax,
Ymax = ymax
};
//Act
calculator.Run();

View File

@@ -0,0 +1,65 @@
using NUnit.Framework;
using StructureHelperCommon.Models.Soils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StructureHelperTests.UnitTests.Calcuators
{
[TestFixture]
public class SoilAnchorCalculatorTest
{
[TestCase(6d, 0.483d, 7d, 0d, -2.188d, 25d, 30e3d, 2005767.1007324921d, 1671472.5839437435d)]
[TestCase(6d, 0.483d, 7d, 0d, -2.188d, 30d, 0d, 1437198.1109237692d, 1197665.0924364743d)]
public void Run_ShouldPass(double rootLength, double rootDiameter, double freeLength, double graundLevel, double headLevel, double fi, double c, double expectedCharBearingCapacity, double expectedDesignBearingCapacity)
{
//Arrange
var anchor = new SoilAnchor()
{
RootLength = rootLength,
RootDiameter = rootDiameter,
FreeLength = freeLength,
GroundLevel = graundLevel,
HeadLevel = headLevel,
};
var soil = new AnchorSoilProperties()
{
FrictionAngle = fi,
Coheasion = c
};
//Act
var calculator = new AnchorCalculator(anchor, soil);
calculator.Run();
var result = calculator.Result as AnchorResult;
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedCharBearingCapacity, result.CharBearingCapacity, expectedCharBearingCapacity * 1e-6d);
Assert.AreEqual(expectedDesignBearingCapacity, result.DesignBearingCapacity, expectedDesignBearingCapacity * 1e-6d);
}
[TestCase(6d, 0.2d, 7d, 0.145d, 0.28290937500000002d, 0.13633537500000006d)]
[TestCase(6d, 0.483, 7d, 0.145d, 1.6716908400000001d, 1.5251168399999999d)]
public void Run_ShouldPass_Volume(double rootLength, double rootDiameter, double freeLength, double boreHoleDiameter, double expectedVolume1, double expectedVolume2)
{
//Arrange
var anchor = new SoilAnchor()
{
RootLength = rootLength,
RootDiameter = rootDiameter,
FreeLength = freeLength,
BoreHoleDiameter = boreHoleDiameter,
};
var soil = new AnchorSoilProperties();
//Act
var calculator = new AnchorCalculator(anchor, soil);
calculator.Run();
var result = calculator.Result as AnchorResult;
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(expectedVolume1, result.MortarVolumeFstStady, expectedVolume1 * 1e-6d);
Assert.AreEqual(expectedVolume2, result.MortarVolumeSndStady, expectedVolume2 * 1e-6d);
}
}
}