using System;
using Deltares.Standard.Logging;
namespace Deltares.Stability.Calculation2
{
///
/// Checks whether the sliding plane doesn't have sharp edges and has force points within the sliding plane
///
public class SmoothSlidingPlaneValidator : ISlidingCurveValidator
{
private double allowedMaxAngleBetweenSlices;
private double maxPercentageForcePointsInSlices = 0;
private double minMaxDifferenceAngleInDegreesBetweenSlices = double.MaxValue;
private double requiredMinPercForcePointsInSlices;
public SmoothSlidingPlaneValidator(double allowedMaxAngleBetweenSlices, double requiredMinPercForcePointsInSlices)
{
this.allowedMaxAngleBetweenSlices = allowedMaxAngleBetweenSlices;
this.requiredMinPercForcePointsInSlices = requiredMinPercForcePointsInSlices;
}
public void LogEvaluations()
{
if (minMaxDifferenceAngleInDegreesBetweenSlices > allowedMaxAngleBetweenSlices)
{
LogManager.Add(new LogMessage(
LogMessageType.Info, this,
"Spencer resultaat: " + string.Format("Maximale hoek van het glijvlak is {0:F2} graden.", minMaxDifferenceAngleInDegreesBetweenSlices)));
}
if (maxPercentageForcePointsInSlices < requiredMinPercForcePointsInSlices)
{
LogManager.Add(new LogMessage(
LogMessageType.Info, this,
"Spencer result: " + string.Format("De druklijn valt in {0:F2}% van de lamellen in het grondlichaam.", maxPercentageForcePointsInSlices)));
}
}
public bool IsValid(SlidingCurve slidingCurve)
{
if (slidingCurve is SlidingPlane)
{
SpencerEvaluationValues evaluationValues = EvaluateSpencerResults((SlidingPlane) slidingCurve);
return AreSpencerEvaluationResultsAcceptable(evaluationValues);
}
else
{
return true;
}
}
public bool SlicesMustBeFilled()
{
return true;
}
///
/// Validates the spencer results.
///
/// The result curve.
///
///
internal SpencerEvaluationValues EvaluateSpencerResults(SlidingPlane slidingPlane)
{
var result = new SpencerEvaluationValues
{
PercentageForcePointsInSlices = GetPercentageForcePointsInSlices(slidingPlane),
MaxDifferenceAngleInDegreesBetweenSlices = GetMaxDifferenceAngleInDegreesBetweenSlices(slidingPlane)
};
maxPercentageForcePointsInSlices = Math.Max(maxPercentageForcePointsInSlices, result.PercentageForcePointsInSlices);
minMaxDifferenceAngleInDegreesBetweenSlices = Math.Min(minMaxDifferenceAngleInDegreesBetweenSlices, result.MaxDifferenceAngleInDegreesBetweenSlices);
return result;
}
private bool AreSpencerEvaluationResultsAcceptable(SpencerEvaluationValues spencerEvaluationValues)
{
return spencerEvaluationValues.MaxDifferenceAngleInDegreesBetweenSlices <= allowedMaxAngleBetweenSlices &&
spencerEvaluationValues.PercentageForcePointsInSlices/100 >= requiredMinPercForcePointsInSlices;
}
private double GetMaxDifferenceAngleInDegreesBetweenSlices(SlidingPlane slidingPlane)
{
var maxAngle = 0.0;
for (int i = 1; i < slidingPlane.Slices.Count; i++)
{
var previousSlice = slidingPlane.Slices[i - 1];
var currentSlice = slidingPlane.Slices[i];
var angle = GetDifferenceInAnglesInDegrees(previousSlice.BottomAngle, currentSlice.BottomAngle);
maxAngle = Math.Max(maxAngle, angle);
}
return maxAngle;
}
private double GetDifferenceInAnglesInDegrees(double bottomAngleRadiansLeft, double bottomAngleRadiansRight)
{
var deltaLeftDegrees = ToDegrees(bottomAngleRadiansLeft);
var deltaRightDegrees = ToDegrees(bottomAngleRadiansRight);
return Math.Abs(deltaLeftDegrees - deltaRightDegrees);
}
private double GetPercentageForcePointsInSlices(SlidingPlane slidingPlane)
{
double slicesTotal = slidingPlane.Slices.Count;
var result = 100.0;
if (slicesTotal > 0)
{
var slicesOK = 0;
foreach (var slice in slidingPlane.Slices)
{
if (slice.RightForceY >= slice.BottomRight.Y && slice.RightForceY <= slice.TopRight.Y)
{
slicesOK++;
}
}
result = (slicesOK/slicesTotal)*100;
}
return result;
}
private static double ToDegrees(double radians)
{
return radians*(180/Math.PI);
}
}
///
/// Spencer circle can be evaluated by percentage of points and angle
///
public class SpencerEvaluationValues
{
///
/// The maximum difference angle in degrees between slices
///
public double MaxDifferenceAngleInDegreesBetweenSlices = double.NaN;
///
/// The percentage force points in slices
///
public double PercentageForcePointsInSlices = double.NaN;
}
}