using System; using System.Collections.Generic; using Deltares.Mathematics; // ======================================================================================================================= // Class name: // // Description: // // Copyright (c) 2008-2010 Deltares // // Date ID Modification // 2008-08-13 Best Created // 2010-04-20 Sel Implementation general StabilityCalculation class // 2010-05-19 Sel Made preparations in the slip plane for GA // 2010-05-20 Sel Implemented Ga in Spencer and Finetuned use of GA in general // ======================================================================================================================= namespace Deltares.Stability.Calculation.Inner { public class TSpencerCalculation : TStabilityCalculation, IExtremeCalculation { // Private fields private bool AddToZoneArr = false; private TPoints[] BackuplipPoints; private GeneticAlgorithm FGeneticAlgorithm; private TPoints[] FMinSlipPoints; private TPoints[] FMinSlipPointsZone1; private TPoints[] FMinSlipPointsZone2; private TPoints[][] FPointsArray; // private List zoneResultsList = new List(); // private int LocalZonenr = 0; private int MinZonenr; private double[] mingenome; // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= //Constructor Create() public TSpencerCalculation() : base() { // TODO: Add any constructor code here } public double[] MinGenome { get { return mingenome; } set { mingenome = value; } } public TSpencerResult CreateSpencerResultPlane(TSpencerPlane ASpencerPlane, int AZonenr, double AStability) // ======================================================================================================================= { TSpencerResult LResultSpencer; int i; int LNSlices; LNSlices = ASpencerPlane.NSlices; LResultSpencer = new TSpencerResult(); LResultSpencer.SetSliceDimension(LNSlices); for (i = 0; i < LNSlices; i++) { LResultSpencer.Slices[i] = new Tslice(ASpencerPlane.GetSlice(i)); } LResultSpencer.ZoneNr = AZonenr; LResultSpencer.CalcMethod = FInterfaceData.ModelData.CalcType; LResultSpencer.StabilityFactor = AStability; return LResultSpencer; } public void DumpSpencerResult(TPoints[] slipPoints, int aZone) { TSpencerPlane LSpencerplane; int LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; LSpencerplane = new TSpencerPlane(); LSpencerplane.XLeftSurface = Math.Min(slipPoints[0].XCoor, slipPoints[LSlipPointCount - 1].XCoor); LSpencerplane.XRightSurface = Math.Max(slipPoints[0].XCoor, slipPoints[LSlipPointCount - 1].XCoor); LSpencerplane.InterfaceData = FInterfaceData; //@ Unsupported function or procedure: 'Copy' LSpencerplane.SlipPlanePoints = (TPoints[]) slipPoints.Clone(); LSpencerplane.DoDumpData = true; FSafety = LSpencerplane.SafetyFactor; FDumpData.CalcMethod = FInterfaceData.ModelData.CalcType; TSpencerResult LResultSpencer = CreateSpencerResultPlane(LSpencerplane, aZone, FSafety); FDumpData.AddMinimumSpencerplane(LResultSpencer); } public void CalculationSpencerGA(GeneticAlgorithm AGeneticAlgorithm) { int LGenIndex; TBounds LBounds; // Set options AGeneticAlgorithm.InitializePopulationMethod = InitializePopulationMethod.Parabolic; AGeneticAlgorithm.CrossOverRandomFrequency = RandomFrequency.Never; AGeneticAlgorithm.MutationRandomFrequency = RandomFrequency.Never; // Set the bounds for the genetic algorithm LBounds.Min = SpencerCalculation.CBoundsMin; LBounds.Inc = SpencerCalculation.CBoundsInc; AGeneticAlgorithm.GenomeCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; for (LGenIndex = 0; LGenIndex < AGeneticAlgorithm.GenomeCount; LGenIndex++) { AGeneticAlgorithm.SetBounds(LGenIndex, LBounds); } // Communicate the address of the calculation AGeneticAlgorithm.GeneticCalculation = this; // Determine safety factor AGeneticAlgorithm.Calculation(); ComputeExtremeResult(AGeneticAlgorithm.Fittest); } public override void CalculationGrid() { FSafety = Constants.CFMinStart; // Write interface data for controle FInterfaceData.Writeinterfacedata(); // Create all the slide planes CreateSlipPoints(null); // Do the calculation for al planes CalculateSpencerPlanes(); } public override void CalculationGA(GeneticAlgorithm AGeneticAlgorithm) { FGeneticAlgorithm = AGeneticAlgorithm; double BackupSafety; CalculationSpencerGA(FGeneticAlgorithm); if ((FInterfaceData.ModelData.HasZonePlot)) { // Sla minimale circel in ieder geval op als zone 0 AddToZoneArr = true; // LocalZonenr = 0; BackuplipPoints = (TPoints[]) FMinSlipPoints.Clone(); BackupSafety = FSafety; // ProcessFinalSafety(); if (!(MinZonenr == 1)) { // start a search for zone 1 // add a zone penalty for not zon 1 // calculations FSafety = FSafetyZone1; zonePenalty = 10; CalculationSpencerGA(FGeneticAlgorithm); if (FSafety > BackupSafety) { FSafety = BackupSafety; FMinSlipPoints = (TPoints[]) BackuplipPoints.Clone(); } AddToZoneArr = false; zonePenalty = 0; } ProcessFZoneSafety(); // for (int i = 0; i < zoneResultsList.Count; i++) // { // FDumpData.AddMinimumSpencerplane(zoneResultsList[i]); // } } else { ProcessFinalSafety(); } } public override void CalculationLM(LevenbergMarquardtExtreme ALevenbergMarquardt) { TBounds LBounds; //{ Communicate the address of the calculation and set options } ALevenbergMarquardt.LevenbergMarquardtCalculation = this; ALevenbergMarquardt.IterationCount = 100; ALevenbergMarquardt.Shift = 0.01; ALevenbergMarquardt.DriftGrant = 0.01; ALevenbergMarquardt.ParameterCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; ALevenbergMarquardt.VariableCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; ALevenbergMarquardt.LambdaLower = 1; ALevenbergMarquardt.LambdaUpper = 4096; ALevenbergMarquardt.LambdaBoost = 4; for (int LGenIndex = 0; LGenIndex < ALevenbergMarquardt.ParameterCount; LGenIndex++) { LBounds.Min = 0; LBounds.Inc = 1; ALevenbergMarquardt.SetBounds(LGenIndex, LBounds); } ALevenbergMarquardt.LevenbergMarquardtCalculation = this; // {add result from GA } for (int i = 0; i < ALevenbergMarquardt.ParameterCount; i++) { ALevenbergMarquardt.Parameters[i] = FGeneticAlgorithm.Fittest[i]; } // do the calculatiom ALevenbergMarquardt.Calculation(); // get the result slide plane FGeneticAlgorithm.Fittest = ALevenbergMarquardt.Parameters; // TODO Must be implemented, see issue MSTAB-646. Is used in class StartCalculation: the critical point found by the GA must be used as inital point for LM. } public double ComputeExtremeResult(double[] AGenome) { double result; int LSlipPointIndex; int LSlipPointCount; TPoints[] LSlipPoints; var LSlipPointList = new List(); // Create slip plane accorging to genome CreateSlipPoints(AGenome); // Put data in slip plane LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; LSlipPoints = new TPoints[LSlipPointCount]; for (LSlipPointIndex = 0; LSlipPointIndex < LSlipPointCount; LSlipPointIndex++) { LSlipPoints[LSlipPointIndex].XCoor = FPointsArray[LSlipPointIndex][1].XCoor; LSlipPoints[LSlipPointIndex].ZCoor = FPointsArray[LSlipPointIndex][1].ZCoor; } // Do the calculation for the plane result = DetermineSafety(LSlipPoints); if ((FInterfaceData.ModelData.HasZonePlot) && (result > 0) && (result < Constants.CFMinStart)) { for (LSlipPointIndex = 0; LSlipPointIndex < LSlipPointCount; LSlipPointIndex++) { LSlipPointList.Add(LSlipPoints[LSlipPointIndex]); } int LZoneNr = FZone.GetSpencerZoneNr(LSlipPointList); if (!(LZoneNr == 1)) { result = result + zonePenalty; } } return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private TPoints[] SurfacePoints(TPoints AMinPoint, TPoints AMaxPoint, int AIntervalCount, double AIntervalRatio) { TPoints[] result; int i; double LDistance; double LDeltaDistance; var LOldPoint = new TPoints(); var LNewPoint = new TPoints(); LDistance = MStabDatafunctions.GetSignedDistanceOnBoundary(AMinPoint, AMaxPoint, FInterfaceData.SurfaceLine); LDeltaDistance = LDistance*AIntervalRatio; LOldPoint = AMinPoint; result = new TPoints[AIntervalCount + 1]; result[0].XCoor = LOldPoint.XCoor; result[0].ZCoor = LOldPoint.ZCoor; result[AIntervalCount].XCoor = AMaxPoint.XCoor; result[AIntervalCount].ZCoor = AMaxPoint.ZCoor; for (i = 1; i < AIntervalCount; i++) { MStabDatafunctions.GetPointOnBoundaryAtDistance(ref LNewPoint, LOldPoint, LDeltaDistance, FInterfaceData.SurfaceLine); result[i].XCoor = LNewPoint.XCoor; result[i].ZCoor = LNewPoint.ZCoor; LOldPoint.XCoor = LNewPoint.XCoor; LOldPoint.ZCoor = LNewPoint.ZCoor; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private TPoints[] SoilPoints(TPoints AMaxPoint, TPoints AMinPoint, int AIntervalCount, double AIntervalRatio) { TPoints[] result; int LIntervalIndex; double LStartX; double LStartZ; double LEndX; double LEndZ; double LDeltaX; double LDeltaZ; LStartX = AMaxPoint.XCoor; LEndX = AMinPoint.XCoor; LStartZ = AMaxPoint.ZCoor; LEndZ = AMinPoint.ZCoor; LDeltaX = (LEndX - LStartX)*AIntervalRatio; LDeltaZ = (LEndZ - LStartZ)*AIntervalRatio; // Note, that the end points are specified separately. When GA ia applied these end point do not match the end ratio result = new TPoints[AIntervalCount + 1]; result[AIntervalCount].XCoor = LEndX; result[AIntervalCount].ZCoor = LEndZ; for (LIntervalIndex = 0; LIntervalIndex < AIntervalCount; LIntervalIndex++) { result[LIntervalIndex].XCoor = LStartX + LIntervalIndex*LDeltaX; result[LIntervalIndex].ZCoor = LStartZ + LIntervalIndex*LDeltaZ; } return result; } // Private methods // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private void CreateSlipPoints(double[] AGenome) { int LSlipPointIndex; int LSlipPointCount; int LIntervalCount; double[] LIntervalRatio; TPoints[] LTopLine; TPoints[] LBottomLine; LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; FPointsArray = new TPoints[LSlipPointCount][]; if ((FInterfaceData.SpencerPlaneData.Topline == null)) { for (LSlipPointIndex = 0; LSlipPointIndex < LSlipPointCount; LSlipPointIndex++) { FPointsArray[LSlipPointIndex] = new TPoints[1]; FPointsArray[LSlipPointIndex][0].XCoor = FInterfaceData.SpencerPlaneData.BottomLine[LSlipPointIndex].XCoor; FPointsArray[LSlipPointIndex][0].ZCoor = FInterfaceData.SpencerPlaneData.BottomLine[LSlipPointIndex].ZCoor; } } else { // Shortcut to top and bottom coordinates LTopLine = FInterfaceData.SpencerPlaneData.Topline; LBottomLine = FInterfaceData.SpencerPlaneData.BottomLine; // For the grid method linear increments are used, for genetic algorithm the genome value if (((AGenome != null))) { LIntervalCount = 2; LIntervalRatio = AGenome; } else { LIntervalCount = FInterfaceData.SpencerPlaneData.NumberofIntervals; LIntervalRatio = new double[LSlipPointCount]; for (LSlipPointIndex = 0; LSlipPointIndex < LSlipPointCount; LSlipPointIndex++) { LIntervalRatio[LSlipPointIndex] = Convert.ToDouble(1)/Convert.ToDouble(LIntervalCount); } } // Entrance surface FPointsArray[0] = SurfacePoints(LBottomLine[0], LTopLine[0], LIntervalCount, LIntervalRatio[0]); // Enclosed area for (LSlipPointIndex = 1; LSlipPointIndex <= LSlipPointCount - 2; LSlipPointIndex++) { FPointsArray[LSlipPointIndex] = SoilPoints(LBottomLine[LSlipPointIndex], LTopLine[LSlipPointIndex], LIntervalCount, LIntervalRatio[LSlipPointIndex]); } // Exit surface FPointsArray[LSlipPointCount - 1] = SurfacePoints(LTopLine[LSlipPointCount - 1], LBottomLine[LSlipPointCount - 1], LIntervalCount, (1 - LIntervalRatio[LSlipPointCount - 1])); // The positions of the free slipcircle must be ascending. Correct in case of genetic algorithm if (((AGenome != null))) { ForceAscendingPositions(AGenome); } } } // ======================================================================================================================= // Date ID Modification // 2010-02-15 Sel Created // ======================================================================================================================= private void ForceAscendingPositions(double[] AGenome) { int LPointsIndex; int LPointsCount; int LLowerIndex; int LUpperIndex; double LLowerPosition; double LUpperPosition; double LLowerValue; double LUpperValue; // Mirror positions in case of reverse geometry LPointsCount = FPointsArray.Length; if (((FInterfaceData.ZoneData.StabilitySide == TStabilitySideSet.LeftSide))) { for (LPointsIndex = 1; LPointsIndex <= LPointsCount; LPointsIndex++) { FPointsArray[LPointsIndex][1].XCoor = -FPointsArray[LPointsIndex][1].XCoor; } } LUpperIndex = 0; do { // Proceed along the slipcircle until a descending position is met or all points, EXCEPT the LAST, are passed LPointsIndex = LUpperIndex + 1; while ((FPointsArray[LPointsIndex - 1][1].XCoor < FPointsArray[LPointsIndex][1].XCoor) && (LPointsIndex < LPointsCount - 1)) { LPointsIndex++; } // Proceed along the slipcircle until an ascending position is met or all points, EXCEPT the LAST are passed LLowerIndex = LPointsIndex - 1; LLowerPosition = FPointsArray[LLowerIndex][1].XCoor; while ((LLowerPosition >= FPointsArray[LPointsIndex][1].XCoor) && (LPointsIndex < LPointsCount - 1)) { LPointsIndex++; } LUpperIndex = LPointsIndex; // In case the right bound is hit, the position must be moved somewhere beyond the lower position if ((LLowerPosition >= FPointsArray[LUpperIndex][1].XCoor)) { LLowerValue = FPointsArray[LUpperIndex][0].XCoor; LUpperValue = FPointsArray[LUpperIndex][2].XCoor; FPointsArray[LUpperIndex][1].XCoor = (LLowerPosition + LLowerValue)/2; // Adapt gen value to the changed position AGenome[LUpperIndex] = (FPointsArray[LUpperIndex][1].XCoor - LLowerValue)/ (LUpperValue - LLowerValue); AGenome[LUpperIndex] = Math.Min(Math.Max(SpencerCalculation.CBoundsMin, AGenome[LUpperIndex]), SpencerCalculation.CBoundsMin + SpencerCalculation.CBoundsInc); // Adapt position and level to the changed gen value FPointsArray[LUpperIndex][1].XCoor = LLowerValue + AGenome[LUpperIndex]*(LUpperValue - LLowerValue); LLowerValue = FPointsArray[LUpperIndex][0].ZCoor; LUpperValue = FPointsArray[LUpperIndex][2].ZCoor; FPointsArray[LUpperIndex][1].ZCoor = LLowerValue + AGenome[LUpperIndex]*(LUpperValue - LLowerValue); } // Adapt range of descending points into ascending points LUpperPosition = FPointsArray[LUpperIndex][1].XCoor; for (LPointsIndex = LLowerIndex + 1; LPointsIndex < LUpperIndex; LPointsIndex++) { LLowerValue = FPointsArray[LPointsIndex][0].XCoor; LUpperValue = FPointsArray[LPointsIndex][2].XCoor; FPointsArray[LPointsIndex][1].XCoor = LLowerPosition + (LUpperPosition - LLowerPosition)*(LPointsIndex - LLowerIndex)/ (LUpperIndex - LLowerIndex); // Adapt gen value to the changed position AGenome[LPointsIndex] = (FPointsArray[LPointsIndex][1].XCoor - LLowerValue)/ (LUpperValue - LLowerValue); AGenome[LPointsIndex] = Math.Min(Math.Max(SpencerCalculation.CBoundsMin, AGenome[LPointsIndex]), SpencerCalculation.CBoundsMin + SpencerCalculation.CBoundsInc); // Adapt position and level to the changed gen value FPointsArray[LPointsIndex][1].XCoor = LLowerValue + AGenome[LPointsIndex]*(LUpperValue - LLowerValue); LLowerValue = FPointsArray[LPointsIndex][0].ZCoor; LUpperValue = FPointsArray[LPointsIndex][2].ZCoor; FPointsArray[LPointsIndex][1].ZCoor = LLowerValue + AGenome[LPointsIndex]*(LUpperValue - LLowerValue); } } while (!((LUpperIndex == LPointsCount - 1))); // Dispose mirrored positions in case of reverse geometry if (((FInterfaceData.ZoneData.StabilitySide == TStabilitySideSet.LeftSide))) { for (LPointsIndex = 1; LPointsIndex <= LPointsCount; LPointsIndex++) { FPointsArray[LPointsIndex][1].XCoor = -FPointsArray[LPointsIndex][1].XCoor; } } } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private void InitialiseHelpArrays(ref int[] AMax, ref int[] ANew, int ANSlipPoints) { int i; AMax = new int[ANSlipPoints]; ANew = new int[ANSlipPoints]; // Initialise for (i = 0; i < ANSlipPoints; i++) { //@ Unsupported function: 'High' AMax[i] = FPointsArray[i].Length - 1; ANew[i] = 0; } } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private bool UpdateSlipPlane(ref TPoints[] ASlipPlanePoints, ref int[] ANew, int[] AMax) { bool result; int i; int LNSlipPoints; LNSlipPoints = ANew.Length; // put data in slip plane ASlipPlanePoints = new TPoints[LNSlipPoints]; for (i = 0; i < LNSlipPoints; i++) { ASlipPlanePoints[i].XCoor = FPointsArray[i][ANew[i]].XCoor; ASlipPlanePoints[i].ZCoor = FPointsArray[i][ANew[i]].ZCoor; } // Increment new ANew[0]++; for (i = 0; i <= LNSlipPoints - 2; i++) { if ((ANew[i] > AMax[i])) { ANew[i + 1]++; ANew[i] = 0; } } result = (ANew[LNSlipPoints - 1] == AMax[LNSlipPoints - 1] + 1); return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private string CheckOnForbiddenLines(TPoints[] ASlipPlanePoints) { string result; int i; int j; double LXStart; double LZStart; double LXEnd; double LZEnd; int LNSlipPoints; LNSlipPoints = ASlipPlanePoints.Length; result = ""; for (j = 1; j < LNSlipPoints; j++) { LXStart = ASlipPlanePoints[j - 1].XCoor; LZStart = ASlipPlanePoints[j - 1].ZCoor; LXEnd = ASlipPlanePoints[j].XCoor; LZEnd = ASlipPlanePoints[j].ZCoor; for (i = FInterfaceData.ForbiddenLines.GetLowerBound(0); i <= FInterfaceData.ForbiddenLines.GetUpperBound(0); i++) { if ( (FInterfaceData.ForbiddenLines[i].LineIntersectsForbiddenLine(LXStart, LZStart, LXEnd, LZEnd))) { result = " SlipPlane cuts forbidden line."; } } } return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private bool CheckOnIncreasingCoordinates(TPoints[] ASlipPlanePoints) { bool result; int j; int LNSlipPoints; LNSlipPoints = ASlipPlanePoints.Length; result = true; if ((ASlipPlanePoints[0].XCoor < ASlipPlanePoints[1].XCoor)) { for (j = 1; j < LNSlipPoints; j++) { result = result && (ASlipPlanePoints[j - 1].XCoor <= ASlipPlanePoints[j].XCoor); } } else { for (j = 1; j < LNSlipPoints; j++) { result = result && (ASlipPlanePoints[j - 1].XCoor >= ASlipPlanePoints[j].XCoor); } } return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private bool IsSlipPlaneOk(TPoints[] ASlipPlanePoints) { bool result; result = CheckOnIncreasingCoordinates(ASlipPlanePoints); if (result) { result = (CheckOnForbiddenLines(ASlipPlanePoints) == ""); } return result; } // ======================================================================================================================= // Date ID Modification // 2009-05-27 Created // ======================================================================================================================= private void AddMinimumSpencerPlane(TSpencerPlane ASpencerPlane, int AZonenr, double AStability) { TSpencerResult LResultSpencer = CreateSpencerResultPlane(ASpencerPlane, AZonenr, AStability); if (AddToZoneArr) { // zoneResultsList[LocalZonenr] = LResultSpencer; } else { FDumpData.AddMinimumSpencerplane(LResultSpencer); } } // ======================================================================================================================= // Description In FPointsarray are all the points to be connected for creating the slip planes // This is done by creating a point index help array new. // first are all new set to 0. // the first one is incemented. // If the maximum of the first one is reached (in LMax) the second one is incremented // and the first one is set to zero // And so on // // Date ID Modification // 2008-08-14 Best Created // ======================================================================================================================= private void CalculateSpencerPlanes() { int[] LNew = null; int[] LMax = null; int LSlipPointCount; var LSlipPlanePoints = new TPoints[0]; bool LFinish; // Create dynamic zone arrays LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; InitialiseHelpArrays(ref LMax, ref LNew, LSlipPointCount); int maxRuns = 1; for (int i = 0; i < FPointsArray.Length; i++) { maxRuns *= FPointsArray[i].Length; } int count = 0; if ((LSlipPointCount > 1)) { do { LFinish = UpdateSlipPlane(ref LSlipPlanePoints, ref LNew, LMax); DetermineSafety(LSlipPlanePoints); count++; if (DoProgress != null) { DoProgress(Convert.ToDouble(count)/Convert.ToDouble(maxRuns)); } } while (!LFinish); ProcessFinalSafety(); } } // ======================================================================================================================= // Date ID Modification // 2010-05-19 Sel Created // ======================================================================================================================= private double DetermineSafety(TPoints[] ASlipPoints) { TSpencerPlane LSpencerplane; int LSlipPointCount; double LSafetyFactor = Constants.CFMinStart; double[] LMinStabilityResults; int LZoneNr = 3; LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; if ((IsSlipPlaneOk(ASlipPoints))) { LSpencerplane = new TSpencerPlane(); LSpencerplane.XLeftSurface = Math.Min(ASlipPoints[0].XCoor, ASlipPoints[LSlipPointCount - 1].XCoor); LSpencerplane.XRightSurface = Math.Max(ASlipPoints[0].XCoor, ASlipPoints[LSlipPointCount - 1].XCoor); LSpencerplane.InterfaceData = FInterfaceData; LSpencerplane.SlipPlanePoints = (TPoints[]) ASlipPoints.Clone(); LSafetyFactor = LSpencerplane.SafetyFactor; var SlipPoints = new List(); for (int i = 0; i < LSlipPointCount; i++) { SlipPoints.Add(LSpencerplane.SlipPlanePoints[i]); } if (FInterfaceData.ModelData.HasZonePlot) { LZoneNr = FZone.GetSpencerZoneNr(SlipPoints); if (LZoneNr == 1) { if ((LSafetyFactor < FSafetyZone1)) { FSafetyZone1 = LSafetyFactor; FMinSlipPointsZone1 = (TPoints[]) ASlipPoints.Clone(); } } else { if ((LSafetyFactor < FSafetyZone2)) { FSafetyZone2 = LSafetyFactor; FMinSlipPointsZone2 = (TPoints[]) ASlipPoints.Clone(); } } } if ((LSafetyFactor < FSafety)) { // keep track of minimum slide planes for all zones FSafety = LSafetyFactor; MinZonenr = LZoneNr; //@ Unsupported function or procedure: 'Copy' FMinSlipPoints = (TPoints[]) ASlipPoints.Clone(); double[] sliceArray = LSpencerplane.GetSliceArray(); LMinStabilityResults = new double[sliceArray.Length + 1]; sliceArray.CopyTo(LMinStabilityResults, 0); LMinStabilityResults[LMinStabilityResults.Length - 1] = LSafetyFactor; if ((DoSetValues != null)) { DoSetValues("Spencer", LMinStabilityResults); } } } return LSafetyFactor; } // ======================================================================================================================= // Date ID Modification // 2010-05-20 Sel Created // ======================================================================================================================= private void ProcessFinalSafety() { int LZone = 0; int LSlipPointCount; // Final calculation with minimal slide plane for dump LSlipPointCount = FInterfaceData.SpencerPlaneData.BottomLine.Length; if (FInterfaceData.ModelData.HasZonePlot) { if ((FSafety < Constants.CFMinStart - 1)) { var SlipList = new List(); for (int i = 0; i < LSlipPointCount; i++) { SlipList.Add(FMinSlipPoints[i]); } LZone = FZone.GetSpencerZoneNr(SlipList); } } if ((FSafety < Constants.CFMinStart - 1)) { DumpSpencerResult(FMinSlipPoints, LZone); } } /// /// The slipplanes of the different zones are present /// recalculate and write them to dump /// private void ProcessFZoneSafety() { int LZone = 0; if ((FSafety < Constants.CFMinStart - 1)) { DumpSpencerResult(FMinSlipPoints, LZone); } LZone = 1; if ((FSafetyZone1 < Constants.CFMinStart - 1)) { DumpSpencerResult(FMinSlipPointsZone1, LZone); } LZone = 3; if ((FSafetyZone2 < Constants.CFMinStart - 1)) { DumpSpencerResult(FMinSlipPointsZone2, LZone); } } // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= } // end TSpencerCalculation } namespace Deltares.Stability.Calculation.Inner { public class SpencerCalculation { public const int CBoundsMin = 0; public const int CBoundsInc = 1; } // end SpencerCalculation }