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; } }