using System; using System.Collections.Generic; // ======================================================================================================================= // Class name: // // Description: // // Copyright (c) 2007-2010 Deltares // // Date ID Modification // 2008-04-07 Best Created // ======================================================================================================================= namespace Deltares.Stability.Calculation.Inner { public class TSliceDivision { private TCalculationTypeSet FCalculationType; private TPoints[] FFreaticLine; private TPoints[] FGeometryPoints; private TLayerRecord[] FLayers; private bool FLeftSideIsActive = false; private double FLowestZ = 0; private int FNSlices = 0; private List FPLLinePoints = new List(); private TPoints[][] FPLLines; private double FRadius = 0; private List FSlices = new List(); private TPoints[] FSlipPoints; private int FStriveSlice = 0; private TPoints[] FSurfaceLine; private TWaterLineRecord[] FWaterLines; private double FXMidActive = 0; private double FXMidpassive = 0; private double FXRightSurface = 0; private double FZMidActive = 0; private double FZMidpassive = 0; // used in uplift calculation private double FZtangent = 0; private double FxLeftSurface = 0; public TSliceDivision() : base() { FNSlices = 0; } public int NSlices { get { return FNSlices; } set { FNSlices = value; } } // Number of slices public List Slices { get { return FSlices; } } // Actual slices public int StriveSlice { get { return FStriveSlice; } set { FStriveSlice = value; } } // Requested number 0f slices public TPoints[] SurfaceLine { get { return FSurfaceLine; } set { FSurfaceLine = value; } } public TPoints[] FreaticLine { get { return FFreaticLine; } set { FFreaticLine = value; } } public TPoints[] GeometryPoints { get { return FGeometryPoints; } set { FGeometryPoints = value; } } public List PLLinePoints { get { return FPLLinePoints; } } public TWaterLineRecord[] WaterLines { get { return FWaterLines; } set { FWaterLines = value; } } public TPoints[][] PLLines { get { return FPLLines; } set { FPLLines = value; } } public TLayerRecord[] Layers { get { return FLayers; } set { FLayers = value; } } public TCalculationTypeSet CalculationType { get { return FCalculationType; } set { FCalculationType = value; } } public bool LeftSideIsActive { get { return FLeftSideIsActive; } set { FLeftSideIsActive = value; } } // for all slip surfaces public double XLeftSurface { get { return FxLeftSurface; } set { FxLeftSurface = value; } } public double XRightSurface { get { return FXRightSurface; } set { FXRightSurface = value; } } // For circulair surfaces public double XMidActive { get { return FXMidActive; } set { FXMidActive = value; } } public double ZMidActive { get { return FZMidActive; } set { FZMidActive = value; } } public double Radius { get { return FRadius; } set { FRadius = value; } } // additonal center points Uplift public double XMidpassive { get { return FXMidpassive; } set { FXMidpassive = value; } } public double ZMidpassive { get { return FZMidpassive; } set { FZMidpassive = value; } } public double ZTangent { get { return FZtangent; } set { FZtangent = value; } } // in case of a spencer calculation public TPoints[] SlipPoints { get { return FSlipPoints; } set { FSlipPoints = value; } } public void DivideFailureSurfaceInSlices() { FLowestZ = DetermineLowestSlidePlaneZ(); switch (FCalculationType) { case TCalculationTypeSet.csBishop: case TCalculationTypeSet.csFellenius: case TCalculationTypeSet.csBishopProb: SliceDivisionCircle(); break; case TCalculationTypeSet.csLift: case TCalculationTypeSet.csLiftSpencer: SliceDivisionLift(); break; case TCalculationTypeSet.csSpencer: SliceDivisionSpencer(); break; case TCalculationTypeSet.csHorizontalBalance: SliceDevisionHorizontalBalanceCalculation(); break; } } // Private Declarations // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private void AddLastSpencerSlice(int ANSlipPoints) { double LZTop; double LZBottom; Tslice LSlice; double LZs = 0; double LXs = 0; // The last slice is a dummy slice only used for division // The left side of this slice is the Rightsurface LSlice = new Tslice(); LSlice.xLeft = FXRightSurface; LZTop = MStabDatafunctions.ZTopAtSurface(FXRightSurface, FSurfaceLine); LSlice.ZTopLeft = LZTop; LZBottom = MStabDatafunctions.ZBottomAtSurface(FXRightSurface, FSurfaceLine); if ((Math.Abs(LZTop - LZBottom) < Constants.CGeoAccu)) { LSlice.ZBottomLeft = LZBottom; } else { // Obviously a vertical Find the intersection point if (MStabDatafunctions.IntersectLines(FXRightSurface, LZTop, FXRightSurface, LZBottom, SlipPoints[ANSlipPoints - 2].XCoor, SlipPoints[ANSlipPoints - 2].ZCoor, SlipPoints[ANSlipPoints - 1].XCoor, SlipPoints[ANSlipPoints - 1].ZCoor, ref LXs, ref LZs)) { LSlice.ZBottomLeft = LZs; } else { LSlice.ZBottomLeft = LZBottom; } } AddSlices(LSlice); } // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private void AddFirstSpencerSlice() { double LZBottom = 0; double LZTop = 0; Tslice LSlice; double LZs = 0; double LXs = 0; LSlice = new Tslice(); LSlice.xLeft = FxLeftSurface; LZTop = MStabDatafunctions.ZTopAtSurface(FxLeftSurface, FSurfaceLine); LSlice.ZTopLeft = LZTop; LZBottom = MStabDatafunctions.ZBottomAtSurface(FxLeftSurface, FSurfaceLine); if ((Math.Abs(LZTop - LZBottom) < Constants.CGeoAccu)) { LSlice.ZBottomLeft = LZBottom; } else { // Obviously a vertical Find the intersection point if (MStabDatafunctions.IntersectLines(FxLeftSurface, LZTop, FxLeftSurface, LZBottom, SlipPoints[0].XCoor, SlipPoints[0].ZCoor, SlipPoints[1].XCoor, SlipPoints[1].ZCoor, ref LXs, ref LZs)) { LSlice.ZBottomLeft = LZs; } else { LSlice.ZBottomLeft = LZBottom; } } AddSlices(LSlice); } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private void AddSlices(Tslice aSlice) { FSlices.Add(aSlice); aSlice.CreateGeometryItems(); FNSlices = FSlices.Count; } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private void swapslices(ref Tslice first, ref Tslice second) { double xL; double ZtopL; double ZbotL; double xR; double ZtopR; double ZbotR; xL = first.xLeft; ZtopL = first.ZTopLeft; ZbotL = first.ZBottomLeft; xR = first.xRight; ZtopR = first.ZTopRight; ZbotR = first.ZBottomRight; first.xLeft = second.xLeft; first.ZTopLeft = second.ZTopLeft; first.ZBottomLeft = second.ZBottomLeft; first.xRight = second.xRight; first.ZTopRight = second.ZTopRight; first.ZBottomRight = second.ZBottomRight; second.xLeft = xL; second.ZTopLeft = ZtopL; second.ZBottomLeft = ZbotL; second.xRight = xR; second.ZTopRight = ZtopR; second.ZBottomRight = ZbotR; } // ======================================================================================================================= // Date ID Modification // 2007-04-25 Best Created // ======================================================================================================================= private void RemoveASlice(int ANumber) { FSlices.RemoveAt(ANumber); FNSlices --; } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private void NextSlice(double AXCoor) { const double CMinSliceWidth = 0.001; bool Found; int i; Tslice Lslice; // First check if x is in slipplane area. if ((AXCoor > FxLeftSurface + CMinSliceWidth) && (AXCoor < FXRightSurface - CMinSliceWidth)) { // Kijk of het een nieuwe X-koordinaat betreft i = 0; do { i++; Found = (Math.Abs(AXCoor - Slices[i].xLeft) < CMinSliceWidth); } while (!(Found || (i == FNSlices - 1))); // Add X if not yet present if (!Found) { Lslice = new Tslice(); try { Lslice.xLeft = AXCoor; Lslice.ZTopLeft = MStabDatafunctions.ZTopAtSurface(AXCoor, FSurfaceLine); Lslice.ZBottomLeft = DetermineZBottom(AXCoor); AddSlices(Lslice); } finally { //@ Unsupported property or method(C): 'Free' Lslice = null; } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private void DivideLargeSlicesInSmaller() { int i; int j; int NumberOfSlices; int Numbers; double StriveWidth; double dx; double size; int LStriveSlice; LStriveSlice = FStriveSlice; StriveWidth = (FXRightSurface - FxLeftSurface)/LStriveSlice; NumberOfSlices = FNSlices; for (i = 0; i <= NumberOfSlices - 2; i++) { dx = Slices[i + 1].xLeft - Slices[i].xLeft; if (dx > 1.2*StriveWidth) { Numbers = Convert.ToInt32(Math.Floor(dx/StriveWidth)); size = dx/(Numbers + 1); for (j = 1; j <= Numbers; j++) { NextSlice(Slices[i].xLeft + j*size); } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-09 Best Created // ======================================================================================================================= private void FillRightSide() { int i; for (i = 0; i <= FNSlices - 2; i++) { Slices[i].xRight = Slices[i + 1].xLeft; Slices[i].ZTopRight = Slices[i + 1].ZTopLeft; Slices[i].ZBottomRight = Slices[i + 1].ZBottomLeft; Slices[i].CreateGeometryItems(); } } // ... Circular slipplane ... // ======================================================================================================================= // Date ID Modification // 2008-08-06 Best Created // ======================================================================================================================= private void DetermineCircleData(ref double AXMid, ref double AZMid, ref double ARad, bool AIsLeftRequested) { switch (FCalculationType) { case TCalculationTypeSet.csBishop: case TCalculationTypeSet.csFellenius: case TCalculationTypeSet.csBishopProb: AXMid = FXMidActive; AZMid = FZMidActive; ARad = FRadius; break; case TCalculationTypeSet.csLift: case TCalculationTypeSet.csLiftSpencer: if (AIsLeftRequested) { if ((FXMidActive < FXMidpassive)) { AXMid = FXMidActive; AZMid = FZMidActive; ARad = FZMidActive - FZtangent; } else { AXMid = FXMidpassive; AZMid = FZMidpassive; ARad = FZMidpassive - FZtangent; } } else { if ((FXMidActive > FXMidpassive)) { AXMid = FXMidActive; AZMid = FZMidActive; ARad = FZMidActive - FZtangent; } else { AXMid = FXMidpassive; AZMid = FZMidpassive; ARad = FZMidpassive - FZtangent; } } break; } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void AddLastSlice() { Tslice LSlice; double LXs1 = 0; double LZs2 = 0; double LZBot = 0; double LZs1 = 0; int N = 0; double Lxs2 = 0; double LXMid = 0; double LZMid = 0; double LRad = 0; bool LIsLeftRequested = false; LIsLeftRequested = false; DetermineCircleData(ref LXMid, ref LZMid, ref LRad, LIsLeftRequested); // De laatste slice is een dummy slice alleen voor de indeling // De left side van deze slice is de Fxrightsurface LSlice = new Tslice(); LSlice.xLeft = FXRightSurface; LSlice.ZTopLeft = MStabDatafunctions.ZTopAtSurface(FXRightSurface, FSurfaceLine); // If a vertical boundary is present have another look LZBot = MStabDatafunctions.ZBottomAtSurface(FXRightSurface, FSurfaceLine); if (Math.Abs(LZBot - LSlice.ZTopLeft) < Constants.CGeoAccu) { LSlice.ZBottomLeft = LSlice.ZTopLeft; } else { // find intersection point on vertical MStabDatafunctions.Intersect_Circle_line(LXMid, LZMid, LRad, FXRightSurface, FXRightSurface, LSlice.ZTopLeft + 0.1*Constants.CGeoAccu, LZBot - 0.1*Constants.CGeoAccu, ref N, ref LXs1, ref LZs1, ref Lxs2, ref LZs2); if ((N > 0)) { LSlice.ZBottomLeft = LZs1; } else { LSlice.ZBottomLeft = LSlice.ZTopLeft; } } AddSlices(LSlice); } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void AddFirstSlice() { double LZBot = 0; double Lxs2 = 0; double LZs1 = 0; double LXs1 = 0; double LZs2 = 0; Tslice LSlice; int N = 0; double LXMid = 0; double LZMid = 0; double LRad = 0; bool LIsLeftRequested = true; DetermineCircleData(ref LXMid, ref LZMid, ref LRad, LIsLeftRequested); LSlice = new Tslice(); // entree point from circle LSlice.xLeft = FxLeftSurface; LSlice.ZTopLeft = MStabDatafunctions.ZTopAtSurface(FxLeftSurface, FSurfaceLine); LZBot = MStabDatafunctions.ZBottomAtSurface(FxLeftSurface, FSurfaceLine); if (Math.Abs(LZBot - LSlice.ZTopLeft) < Constants.CGeoAccu) { // if no vertical part top and bottom of first point are the same LSlice.ZBottomLeft = LSlice.ZTopLeft; } else { // if vertical part is present then find intersection point on vertical part MStabDatafunctions.Intersect_Circle_line(LXMid, LZMid, LRad, FxLeftSurface, FxLeftSurface, LSlice.ZTopLeft + 0.1*Constants.CGeoAccu, LZBot - 0.1*Constants.CGeoAccu, ref N, ref LXs1, ref LZs1, ref Lxs2, ref LZs2); if ((N > 0)) {} else { LSlice.ZBottomLeft = LSlice.ZTopLeft; } } AddSlices(LSlice); } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private double DetermineUpliftBottompoint(double Ax) { double result; double LXMidLeft; double LZMidLeft; double lXMidRight; double LZMidRight; double LZSurface; double LRadius; // find x on left and right side if ((FXMidActive > FXMidpassive)) { lXMidRight = FXMidActive; LZMidRight = FZMidActive; LXMidLeft = FXMidpassive; LZMidLeft = FZMidpassive; } else { lXMidRight = FXMidpassive; LZMidRight = FZMidpassive; LXMidLeft = FXMidActive; LZMidLeft = FZMidActive; } if ((!(FCalculationType == TCalculationTypeSet.csLiftSpencer))) { if ((Ax < LXMidLeft)) { LRadius = LZMidLeft - FZtangent; result = MStabDatafunctions.ZAtXOnCircle(Ax, LXMidLeft, LZMidLeft, LRadius); } else { if ((Ax > lXMidRight)) { LRadius = LZMidRight - FZtangent; result = MStabDatafunctions.ZAtXOnCircle(Ax, lXMidRight, LZMidRight, LRadius); } else { result = FZtangent; } } } else { // Lift spencer has a wig at passive side if ((Ax < LXMidLeft)) { if (FLeftSideIsActive) { LRadius = LZMidLeft - FZtangent; result = MStabDatafunctions.ZAtXOnCircle(Ax, LXMidLeft, LZMidLeft, LRadius); } else { LZSurface = MStabDatafunctions.ZTopAtSurface(FxLeftSurface, FSurfaceLine); result = MStabDatafunctions.LinInpolY(FxLeftSurface, LZSurface, LXMidLeft, FZtangent, Ax); } } else { if ((Ax > lXMidRight)) { if (FLeftSideIsActive) { LZSurface = MStabDatafunctions.ZTopAtSurface(FXRightSurface, FSurfaceLine); result = MStabDatafunctions.LinInpolY(FXRightSurface, LZSurface, lXMidRight, FZtangent, Ax); } else { LRadius = LZMidRight - FZtangent; result = MStabDatafunctions.ZAtXOnCircle(Ax, lXMidRight, LZMidRight, LRadius); } } else { result = FZtangent; } } } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-09 Best Created // ======================================================================================================================= private double DetermineSpencerBottomPoint(double AXCoor) { double result; bool Ready; int i; i = 0; result = -999.99; do { i++; Ready = ((AXCoor >= SlipPoints[i - 1].XCoor) && (AXCoor <= SlipPoints[i].XCoor)); if (Ready) { result = MStabDatafunctions.LinInpolY(SlipPoints[i - 1].XCoor, SlipPoints[i - 1].ZCoor, SlipPoints[i].XCoor, SlipPoints[i].ZCoor, AXCoor); } } while (!(Ready || (i == FSlipPoints.GetUpperBound(0)))); return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-08 Best Created // ======================================================================================================================= private double DetermineZBottom(double AXCoor) { double result; result = 0; switch (FCalculationType) { case TCalculationTypeSet.csBishop: case TCalculationTypeSet.csFellenius: case TCalculationTypeSet.csBishopProb: result = MStabDatafunctions.ZAtXOnCircle(AXCoor, FXMidActive, FZMidActive, (FZMidActive - FZtangent)); break; case TCalculationTypeSet.csLift: case TCalculationTypeSet.csLiftSpencer: result = DetermineUpliftBottompoint(AXCoor); break; case TCalculationTypeSet.csSpencer: result = DetermineSpencerBottomPoint(AXCoor); break; case TCalculationTypeSet.csHorizontalBalance: result = FZtangent; break; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineCircleIntersectionPointsWithLayers() { int i = 0; int j = 0; bool LFinish = false; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; int LNs = 0; double Lxs1 = 0; double LZs1 = 0; double LXs2 = 0; double LZs2 = 0; for (i = 0; i < FLayers.Length; i++) { // see if the area can possibly be in the reach of a circel LFinish = Layers[i].MinX > FXMidActive + FRadius; if (!LFinish) { LFinish = Layers[i].MaxX < FXMidActive - FRadius; } if (!LFinish) { LFinish = Layers[i].MaxZ < FZMidActive - FRadius; } if (!LFinish) { // Intersection is possible for (j = 1; j < Layers[i].NumberOfLayerPoints; j++) { Lx1 = Layers[i].Layerpoints[j - 1].XCoor; LZ1 = Layers[i].Layerpoints[j - 1].ZCoor; LX2 = Layers[i].Layerpoints[j].XCoor; LZ2 = Layers[i].Layerpoints[j].ZCoor; MStabDatafunctions.Intersect_Circle_line(FXMidActive, FZMidActive, FRadius, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { NextSlice(Lxs1); } if ((LNs > 1)) { NextSlice(LXs2); } } } } } // ======================================================================================================================= // Date ID Modification // 2008-12-02 Best Created // ======================================================================================================================= private void DetermineCircleIntersectionpointsWithWaterLines() { int i = 0; int j = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; int LNs = 0; double Lxs1 = 0; double LZs1 = 0; double LXs2 = 0; double LZs2 = 0; TWaterLineRecord LWaterline; for (i = 0; i < FWaterLines.Length; i++) { LWaterline = WaterLines[i]; for (j = 0; j < LWaterline.Waterline.Length; j++) { NextSlice(LWaterline.Waterline[j].XCoor); } // Intersection is possible for (j = 1; j < LWaterline.Waterline.Length; j++) { Lx1 = LWaterline.Waterline[j - 1].XCoor; LZ1 = LWaterline.Waterline[j - 1].ZCoor; LX2 = LWaterline.Waterline[j].XCoor; LZ2 = LWaterline.Waterline[j].ZCoor; MStabDatafunctions.Intersect_Circle_line(FXMidActive, FZMidActive, FRadius, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { NextSlice(Lxs1); } if ((LNs > 1)) { NextSlice(LXs2); } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineCircleIntersectionpointsWithFreaticLine() { int j = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; int LNs = 0; double Lxs1 = 0; double LZs1 = 0; double LXs2 = 0; double LZs2 = 0; if (FFreaticLine != null) { for (j = 0; j < FFreaticLine.Length; j++) { NextSlice(FreaticLine[j].XCoor); } // Intersection is possible for (j = 1; j < FFreaticLine.Length; j++) { Lx1 = FreaticLine[j - 1].XCoor; LZ1 = FreaticLine[j - 1].ZCoor; LX2 = FreaticLine[j].XCoor; LZ2 = FreaticLine[j].ZCoor; MStabDatafunctions.Intersect_Circle_line(FXMidActive, FZMidActive, FRadius, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { NextSlice(Lxs1); } if ((LNs > 1)) { NextSlice(LXs2); } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineUpliftIntersectionPointsWithLayers() { int i = 0; int j = 0; bool LFinish = false; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; int LNs = 0; double Lxs1 = 0; double LZs1 = 0; double LXs2 = 0; double LZs2 = 0; double LXMidLeft = 0; double LXMidRight = 0; double LZMidLeft = 0; double LZMidRight = 0; double LRadLeft = 0; double LRadRight = 0; bool LIsLeftRequested = false; double LXS = 0; double LZS = 0; LIsLeftRequested = true; DetermineCircleData(ref LXMidLeft, ref LZMidLeft, ref LRadLeft, LIsLeftRequested); LIsLeftRequested = false; DetermineCircleData(ref LXMidRight, ref LZMidRight, ref LRadRight, LIsLeftRequested); for (i = 0; i < FLayers.Length; i++) { // see if the area can possibly be in the reach of a slide plane LFinish = Layers[i].MinX > LXMidRight + LRadRight; if (!LFinish) { LFinish = Layers[i].MaxX < LXMidLeft - LRadLeft; } if (!LFinish) { LFinish = Layers[i].MaxZ < FZtangent; } if (!LFinish) { // Intersection is possible for (j = 1; j < Layers[i].NumberOfLayerPoints; j++) { Lx1 = Layers[i].Layerpoints[j - 1].XCoor; LZ1 = Layers[i].Layerpoints[j - 1].ZCoor; LX2 = Layers[i].Layerpoints[j].XCoor; LZ2 = Layers[i].Layerpoints[j].ZCoor; // See if there is intersection with left circel MStabDatafunctions.Intersect_Circle_line(LXMidLeft, LZMidLeft, LRadLeft, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { if ((Lxs1 < LXMidLeft)) { NextSlice(Lxs1); } } if ((LNs > 1)) { if ((LXs2 < LXMidLeft)) { NextSlice(LXs2); } } // see if there is an intersection with the straight line if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, LXMidLeft, FZtangent, LXMidRight, FZtangent, ref LXS, ref LZS)) { NextSlice(LXS); } // See if there is intersection with the right circel MStabDatafunctions.Intersect_Circle_line(LXMidRight, LZMidRight, LRadRight, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { if ((Lxs1 > LXMidRight)) { NextSlice(Lxs1); } } if ((LNs > 1)) { if ((LXs2 > LXMidRight)) { NextSlice(LXs2); } } } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineUpliftIntersectionPointsWithPiezolines() { int i = 0; int j = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; int LNs = 0; double Lxs1 = 0; double LZs1 = 0; double LXs2 = 0; double LZs2 = 0; double LXMidLeft = 0; double LXMidRight = 0; double LZMidLeft = 0; double LZMidRight = 0; double LRadLeft = 0; double LRadRight = 0; bool LIsLeftRequested = false; double LXS = 0; double LZS = 0; TPoints[] LPlLine; LIsLeftRequested = true; DetermineCircleData(ref LXMidLeft, ref LZMidLeft, ref LRadLeft, LIsLeftRequested); LIsLeftRequested = false; DetermineCircleData(ref LXMidRight, ref LZMidRight, ref LRadRight, LIsLeftRequested); for (i = PLLines.GetLowerBound(0); i <= PLLines.GetUpperBound(0); i++) { LPlLine = PLLines[i]; // Intersection is possible for (j = 1; j < LPlLine.Length; j++) { Lx1 = LPlLine[j - 1].XCoor; LZ1 = LPlLine[j - 1].ZCoor; LX2 = LPlLine[j].XCoor; LZ2 = LPlLine[j].ZCoor; if ((Lx1 < LXMidLeft) && (LX2 > LXMidLeft - LRadLeft)) { // See if there is intersection with left circel MStabDatafunctions.Intersect_Circle_line(LXMidLeft, LZMidLeft, LRadLeft, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { if ((Lxs1 < LXMidLeft)) { NextSlice(Lxs1); } } if ((LNs > 1)) { if ((LXs2 < LXMidLeft)) { NextSlice(LXs2); } } } if ((Lx1 < LXMidRight) && (LX2 > LXMidLeft)) { // see if there is an intersection with the straight line if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, LXMidLeft, FZtangent, LXMidRight, FZtangent, ref LXS, ref LZS)) { NextSlice(LXS); } } // See if there is intersection with the right circel if ((Lx1 < LXMidRight + LRadRight) && (LX2 > LXMidRight)) { MStabDatafunctions.Intersect_Circle_line(LXMidRight, LZMidRight, LRadRight, Lx1, LX2, LZ1, LZ2, ref LNs, ref Lxs1, ref LZs1, ref LXs2, ref LZs2); if ((LNs > 0)) { if ((Lxs1 > LXMidRight)) { NextSlice(Lxs1); } } if ((LNs > 1)) { if ((LXs2 > LXMidRight)) { NextSlice(LXs2); } } } } } } // (* // {======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // =======================================================================================================================} // procedure TSliceDivision.DetermineUpliftIntersectionpointsWithWaterLines; // var // i, j: Integer; // Lx1: Double; // LX2: Double; // LZ1: Double; // LZ2: Double; // LNs: Integer; // Lxs1: Double; // LZs1: Double; // LXs2: Double; // LZs2: Double; // LWaterline: TWaterlineRecord; // begin // for i := 0 to length(FWaterlines) - 1 do // begin // LWaterline := FWaterlines[i]; // // for j := 0 to length(LWaterline.Waterline) - 1 do // begin // NextSlice(LWaterline.Waterline[j].XCoor); // end; // // for j := 1 to length(LWaterline.Waterline) - 1 do // begin // LX1 := LWaterline.Waterline[j - 1].XCoor; // LZ1 := LWaterline.Waterline[j - 1].ZCoor; // LX2 := LWaterline.Waterline[j].XCoor; // LZ2 := LWaterline.Waterline[j].ZCoor; // Intersect_Circle_line(FXMidActive, FZMidActive, FRadius, LX1, LX2, LZ1, LZ2, // LNs, Lxs1, LZs1, Lxs2, LZs2); // if (LnS > 0) then // begin // NextSlice(Lxs1); // end; // if (LnS > 1) then // begin // NextSlice(Lxs2); // end; // end; // end; // end; // *) // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineSpencerIntersectionPointsWithLayers() { int i = 0; int j = 0; int k = 0; bool LFinish = false; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; double Lx3 = 0; double LX4 = 0; double LZ3 = 0; double LZ4 = 0; double LXS = 0; double LZS = 0; int LNSlipPoints = 0; LNSlipPoints = FSlipPoints.Length; for (i = 0; i < FLayers.Length; i++) { // see if the area can possibly be in the reach of a slide plane LFinish = Layers[i].MinX > FXRightSurface; if (!LFinish) { LFinish = Layers[i].MaxX < FxLeftSurface; } if (!LFinish) { LFinish = Layers[i].MaxZ < FLowestZ; } if (!LFinish) { // Intersection is possible for (j = 1; j < Layers[i].NumberOfLayerPoints; j++) { Lx1 = Layers[i].Layerpoints[j - 1].XCoor; LZ1 = Layers[i].Layerpoints[j - 1].ZCoor; LX2 = Layers[i].Layerpoints[j].XCoor; LZ2 = Layers[i].Layerpoints[j].ZCoor; for (k = 1; k < LNSlipPoints; k++) { Lx3 = SlipPoints[k - 1].XCoor; LZ3 = SlipPoints[k - 1].ZCoor; LX4 = SlipPoints[k].XCoor; LZ4 = SlipPoints[k].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref LXS, ref LZS)) { NextSlice(LXS); } } } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineHorizontalBalanceIntersectionPointsWithLayers() { int i = 0; int j = 0; bool LFinish = false; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; double Lx3 = 0; double LX4 = 0; double LZ3 = 0; double LZ4 = 0; double LXS = 0; double LZS = 0; for (i = 0; i < FLayers.Length; i++) { // see if the area can possibly be in the reach of a slide plane LFinish = Layers[i].MinX > FXRightSurface; if (!LFinish) { LFinish = Layers[i].MaxX < FxLeftSurface; } if (!LFinish) { LFinish = Layers[i].MaxZ < FLowestZ; } if (!LFinish) { Lx3 = FxLeftSurface; LZ3 = FZtangent; LX4 = FXRightSurface; LZ4 = FZtangent; // Intersection is possible for (j = 1; j < Layers[i].NumberOfLayerPoints; j++) { Lx1 = Layers[i].Layerpoints[j - 1].XCoor; LZ1 = Layers[i].Layerpoints[j - 1].ZCoor; LX2 = Layers[i].Layerpoints[j].XCoor; LZ2 = Layers[i].Layerpoints[j].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref LXS, ref LZS)) { NextSlice(LXS); } } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-21 Best Created // ======================================================================================================================= private void DetermineSpencerIntersectionpointsWithFreaticLine() { int j = 0; int K = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; double Lxs = 0; double LZs = 0; double Lx3 = 0; double LX4 = 0; double LZ3 = 0; double LZ4 = 0; TPoints[] LWaterline; int LNSlipPoints = 0; LNSlipPoints = FSlipPoints.Length; if (FFreaticLine != null) { LWaterline = FFreaticLine; for (j = 0; j < LWaterline.Length; j++) { NextSlice(LWaterline[j].XCoor); } // Intersection is possible for (j = 1; j < LWaterline.Length; j++) { Lx1 = LWaterline[j - 1].XCoor; LZ1 = LWaterline[j - 1].ZCoor; LX2 = LWaterline[j].XCoor; LZ2 = LWaterline[j].ZCoor; for (K = 1; K < LNSlipPoints; K++) { Lx3 = SlipPoints[K - 1].XCoor; LZ3 = SlipPoints[K - 1].ZCoor; LX4 = SlipPoints[K].XCoor; LZ4 = SlipPoints[K].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref Lxs, ref LZs)) { NextSlice(Lxs); } } } } } // ======================================================================================================================= // Date ID Modification // 2009-06-04 Created // ======================================================================================================================= private void DetermineSpencerIntersectionpointsWithWaterLines() { int i = 0; int j = 0; int K = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; double Lxs = 0; double LZs = 0; double Lx3 = 0; double LX4 = 0; double LZ3 = 0; double LZ4 = 0; TWaterLineRecord LWaterline; int LNSlipPoints = 0; LNSlipPoints = FSlipPoints.Length; for (i = 0; i < FWaterLines.Length; i++) { LWaterline = WaterLines[i]; for (j = 0; j < LWaterline.Waterline.Length; j++) { NextSlice(LWaterline.Waterline[j].XCoor); } // Intersection is possible for (j = 1; j < LWaterline.Waterline.Length; j++) { Lx1 = LWaterline.Waterline[j - 1].XCoor; LZ1 = LWaterline.Waterline[j - 1].ZCoor; LX2 = LWaterline.Waterline[j].XCoor; LZ2 = LWaterline.Waterline[j].ZCoor; for (K = 1; K < LNSlipPoints; K++) { Lx3 = SlipPoints[K - 1].XCoor; LZ3 = SlipPoints[K - 1].ZCoor; LX4 = SlipPoints[K].XCoor; LZ4 = SlipPoints[K].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref Lxs, ref LZs)) { NextSlice(Lxs); } } } } } // ======================================================================================================================= // Date ID Modification // 2010-06-15 Created // ======================================================================================================================= private void DetermineSpencerIntersectionpointsWithHeadLines() { int i = 0; int j = 0; int K = 0; double Lx1 = 0; double LX2 = 0; double LZ1 = 0; double LZ2 = 0; double Lxs = 0; double LZs = 0; double Lx3 = 0; double LX4 = 0; double LZ3 = 0; double LZ4 = 0; TPoints[] LPlLine; int LNSlipPoints; LNSlipPoints = FSlipPoints.Length; for (i = FPLLines.GetLowerBound(0); i <= FPLLines.GetUpperBound(0); i++) { LPlLine = PLLines[i]; for (j = 0; j < LPlLine.Length; j++) { NextSlice(LPlLine[j].XCoor); } // Intersection is possible for (j = 1; j < LPlLine.Length; j++) { Lx1 = LPlLine[j - 1].XCoor; LZ1 = LPlLine[j - 1].ZCoor; LX2 = LPlLine[j].XCoor; LZ2 = LPlLine[j].ZCoor; for (K = 1; K < LNSlipPoints; K++) { Lx3 = SlipPoints[K - 1].XCoor; LZ3 = SlipPoints[K - 1].ZCoor; LX4 = SlipPoints[K].XCoor; LZ4 = SlipPoints[K].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref Lxs, ref LZs)) { NextSlice(Lxs); } } } } } // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private void DetermineLayerIntersectionPointsWithFreaticLine() { double LX2 = 0; double LZ2 = 0; double LXS = 0; double LZS = 0; for (int i = 0; i < FLayers.Length; i++) { // see if the area can possibly be in the reach of a slide plane bool LFinish = Layers[i].MinX > FXRightSurface; if (!LFinish) { LFinish = Layers[i].MaxX < FxLeftSurface; } if (!LFinish) { LFinish = Layers[i].MaxZ < FLowestZ; } if (!LFinish) { // Intersection is possible for (int j = 1; j <= Layers[i].NumberOfLayerPoints; j++) { double Lx1 = Layers[i].Layerpoints[j - 1].XCoor; double LZ1 = Layers[i].Layerpoints[j - 1].ZCoor; if ((j == Layers[i].NumberOfLayerPoints)) { LX2 = Layers[i].Layerpoints[0].XCoor; LZ2 = Layers[i].Layerpoints[0].ZCoor; } else { LX2 = Layers[i].Layerpoints[j].XCoor; LZ2 = Layers[i].Layerpoints[j].ZCoor; } if (FFreaticLine != null) { for (int k = 1; k < FFreaticLine.Length; k++) { double Lx3 = FreaticLine[k - 1].XCoor; double LZ3 = FreaticLine[k - 1].ZCoor; double LX4 = FreaticLine[k].XCoor; double LZ4 = FreaticLine[k].ZCoor; if (MStabDatafunctions.IntersectLines(Lx1, LZ1, LX2, LZ2, Lx3, LZ3, LX4, LZ4, ref LXS, ref LZS)) { NextSlice(LXS); } } } } } } } // ======================================================================================================================= // Date ID Modification // 2008-04-09 Best Created // ======================================================================================================================= private void SliceDivisionCircle() { int i; AddFirstSlice(); // the last slice is a dummy slice only used for slice division // The left side of this slice is the Rightsurface AddLastSlice(); // Punten uit de puntentabel (die laagscheidingen/PN-lijnen vormen for (i = 0; i < FGeometryPoints.Length; i++) { // Only relevant geomery points if ((GeometryPoints[i].XCoor > FxLeftSurface) && (GeometryPoints[i].XCoor < FXRightSurface)) { if ((MStabDatafunctions.Distance2D(GeometryPoints[i].XCoor, GeometryPoints[i].ZCoor, FXMidActive, FZMidActive) <= FRadius + Constants.CGeoAccu)) { NextSlice(GeometryPoints[i].XCoor); } } } // IOntersection points with layer boundaries DetermineCircleIntersectionPointsWithLayers(); // Intersection with freatic line DetermineCircleIntersectionpointsWithFreaticLine(); // intersection layers with freatic line DetermineLayerIntersectionPointsWithFreaticLine(); // Intersection with waterlines DetermineCircleIntersectionpointsWithWaterLines(); // add a slice at possible changes of pl-lines for (i = 0; i < FPLLinePoints.Count; i++) { NextSlice(PLLinePoints[i].XCoor); } // sorteer de x koordinaten van de lamellen Slices.Sort(); // Divide large slices in smaller ones DivideLargeSlicesInSmaller(); // Sort slices again Slices.Sort(); // Fill the Right side too FillRightSide(); // gooi de laatste dumy lamel weg Slices.RemoveAt(FNSlices - 1); FNSlices -= 1; } // --- End procedure slicedevisionCircle --- // ======================================================================================================================= // Date ID Modification // 2008-08-06 Best Created // ======================================================================================================================= private bool IsSliceInSoil(Tslice ASlice) { bool result; double LZCoor; double LXCoor; double LZSurface; LZCoor = (ASlice.ZBottomMid + ASlice.ZTopMid)/2; LXCoor = (ASlice.xRight + ASlice.xLeft)/2; LZSurface = MStabDatafunctions.ZBottomAtSurface(LXCoor, FSurfaceLine); result = (LZCoor < LZSurface); return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-06 Best Created // ======================================================================================================================= private bool SliceDivisionLift() { bool result; int i; int LTotSlices; bool LOK; int LNFreaticLinePoints; double LXCoor; double LZCoor; AddFirstSlice(); AddLastSlice(); // points below the center points NextSlice(FXMidActive); NextSlice(FXMidpassive); // Points from the geometry for (i = 0; i < FGeometryPoints.Length; i++) { // Only relevant geomery points if ((GeometryPoints[i].XCoor > FxLeftSurface) && (GeometryPoints[i].XCoor < FXRightSurface) && (GeometryPoints[i].ZCoor > FZtangent)) { NextSlice(GeometryPoints[i].XCoor); } } // points from freatic line if (FreaticLine != null) { LNFreaticLinePoints = FFreaticLine.Length; for (i = 0; i < LNFreaticLinePoints; i++) { LXCoor = FreaticLine[i].XCoor; LZCoor = FreaticLine[i].ZCoor; // Only relevant geomery points if ((LXCoor > FxLeftSurface) && (LXCoor < FXRightSurface) && (LZCoor > FZtangent)) { NextSlice(LXCoor); } } } DetermineUpliftIntersectionPointsWithLayers(); DetermineLayerIntersectionPointsWithFreaticLine(); DetermineUpliftIntersectionPointsWithPiezolines(); // Intersection with waterlines // DetermineUpliftIntersectionpointsWithWaterLines; // add a slice at possible changes of pl-lines for (i = 0; i < FPLLinePoints.Count; i++) { NextSlice(PLLinePoints[i].XCoor); } // sorteer de x koordinaten van de lamellen Slices.Sort(); // Divide large slices in smaller ones DivideLargeSlicesInSmaller(); Slices.Sort(); // Fill the Right side too FillRightSide(); // gooi de laatste dumy lamel weg //@ Unsupported property or method(C): 'Free' Slices.RemoveAt(FNSlices - 1); FNSlices -= 1; // nu eventuele lege slices verwijderen LTotSlices = FNSlices; for (i = LTotSlices - 1; i >= 1; i--) { // Fill mid values Slices[i - 1].addCalculatedProperties(); if (!(IsSliceInSoil(Slices[i - 1]))) { RemoveASlice(i - 1); } } // See if no holes arised in the middle LOK = true; for (i = 0; i <= FNSlices - 2; i++) { LOK = LOK && (Math.Abs(Slices[i].xRight - Slices[i + 1].xLeft) < Constants.CSameSliceDist); } LOK = LOK && (FNSlices > 0); result = LOK; // (* // {ter controle schrijf geometrie van slices weg } // writeln(lfd,' XR XL YBotR YBotL YTopR YTopL XMid YBotM YTopM Width'); // for i := 1 to FnSlices do // begin // with FSlices[i] do // begin // writeln(lfd,xRight:5:2,' ',xLeft:5:2,' ',yBottomRight:5:2,' ', // YBottomLeft:5:2,' ',yTopRight:5:2,' ',YTopLeft :5:2,' ', // XMid:5:2,' ',YBottomMid:5:2,' ',YTopMid:5:2,' ',Width:5:2); // end; // end; *) return result; } // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private bool SliceDivisionSpencer() { bool result; int LNSlipPoints; double LZCoor; string LErrorNote; int i; bool LOk; LErrorNote = ""; LNSlipPoints = FSlipPoints.Length; // See if the points are below the surface // The first and last points may be above the surface line LOk = true; for (i = 1; i <= (LNSlipPoints - 2); i++) { LZCoor = MStabDatafunctions.ZBottomAtSurface(SlipPoints[i].XCoor, FSurfaceLine); LOk = LOk && (LZCoor > SlipPoints[i].ZCoor); } if (!LOk) { LErrorNote = LErrorNote + "Points of Spencer plane above geometry.@"; } // vul de uiterste punten in if (LOk) { AddFirstSpencerSlice(); AddLastSpencerSlice(LNSlipPoints); // points on the slide plane surface for (i = 1; i <= LNSlipPoints - 2; i++) { NextSlice(SlipPoints[i].XCoor); } // Points from the geometry for (i = 0; i < FGeometryPoints.Length; i++) { // Only relevant geomery points LZCoor = DetermineZBottom(GeometryPoints[i].XCoor); if ((GeometryPoints[i].XCoor > FxLeftSurface) && (GeometryPoints[i].XCoor < FXRightSurface) && (GeometryPoints[i].ZCoor > LZCoor)) { NextSlice(GeometryPoints[i].XCoor); } } DetermineSpencerIntersectionPointsWithLayers(); // Spencer plane with freatic line DetermineSpencerIntersectionpointsWithFreaticLine(); // Intersection with waterlines DetermineSpencerIntersectionpointsWithWaterLines(); DetermineSpencerIntersectionpointsWithHeadLines(); DetermineLayerIntersectionPointsWithFreaticLine(); // sorteer de x koordinaten van de lamellen Slices.Sort(); // Divide large slices in smaller ones DivideLargeSlicesInSmaller(); // Nogmaals sorteren Slices.Sort(); // Fill the Right side too FillRightSide(); // gooi de laatste dumy lamel weg Slices.RemoveAt(FNSlices - 1); FNSlices -= 1; } result = LOk; return result; } // --- End procedure slicedevision --- // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private bool SliceDevisionHorizontalBalanceCalculation() { bool result; Tslice LSlice; int i; int LTotslices; bool Ok; Ok = true; // vul de uiterste punten in LSlice = new Tslice(); LSlice.xLeft = FxLeftSurface; LSlice.ZTopLeft = MStabDatafunctions.ZBottomAtSurface(FxLeftSurface, FSurfaceLine); LSlice.ZBottomLeft = FZtangent; AddSlices(LSlice); // De laatste slice is een dummy slice alleen voor de indeling // De left side van deze slice is de Fxrightsurface LSlice = new Tslice(); LSlice.xLeft = FXRightSurface; LSlice.ZTopLeft = MStabDatafunctions.ZBottomAtSurface(FXRightSurface, FSurfaceLine); LSlice.ZBottomLeft = FZtangent; AddSlices(LSlice); // Punten uit de puntentabel (die laagscheidingen in het glijvlak // Of PN-lijnen vormen for (i = 0; i < FGeometryPoints.Length; i++) { // Only relevant geomery points if ((GeometryPoints[i].XCoor > FxLeftSurface) && (GeometryPoints[i].XCoor < FXRightSurface) && (GeometryPoints[i].ZCoor > FZtangent)) { NextSlice(GeometryPoints[i].XCoor); } } // snijpunten glijvlak met laagscheidingen DetermineHorizontalBalanceIntersectionPointsWithLayers(); // INntersection slide plane with freatic line DetermineLayerIntersectionPointsWithFreaticLine(); // sorteer de x koordinaten van de lamellen Slices.Sort(); // Divide large slices in smaller ones DivideLargeSlicesInSmaller(); Slices.Sort(); // Fill the Right side too FillRightSide(); // remove the last (dummy) slice //@ Unsupported property or method(C): 'Free' Slices[FNSlices - 1] = null; FNSlices -= 1; // nu eventuele lege slices verwijderen LTotslices = FNSlices; for (i = LTotslices - 1; i >= 0; i--) { Slices[i].addCalculatedProperties(); if (!(IsSliceInSoil(Slices[i]))) { RemoveASlice(i); } } // controleren of er geen gaten in het midden zijn ontstaan for (i = 0; i <= FNSlices - 2; i++) { Ok = Ok && (Math.Abs(Slices[i].xRight - Slices[i + 1].xLeft) < Constants.CSameSliceDist); } Ok = Ok && (FNSlices > 0); result = Ok; // (* // {ter controle schrijf geometrie van slices weg } // writeln(lfd,' XR XL YBotR YBotL YTopR YTopL XMid YBotM YTopM Width'); // for i := 1 to FnSlices do // begin // with FSlices[i] do // begin // writeln(lfd,xRight:5:2,' ',xLeft:5:2,' ',yBottomRight:5:2,' ', // YBottomLeft:5:2,' ',yTopRight:5:2,' ',YTopLeft :5:2,' ', // XMid:5:2,' ',YBottomMid:5:2,' ',YTopMid:5:2,' ',Width:5:2); // end; // end; *) return result; } // --- End procedure slicedevision --- // ======================================================================================================================= // Date ID Modification // 2008-08-13 Best Created // ======================================================================================================================= private double DetermineLowestSlidePlaneZ() { double result; int i; result = 0; switch (FCalculationType) { case TCalculationTypeSet.csBishop: case TCalculationTypeSet.csFellenius: case TCalculationTypeSet.csBishopProb: result = FZMidActive - FRadius; break; case TCalculationTypeSet.csLift: case TCalculationTypeSet.csLiftSpencer: result = FZtangent; break; case TCalculationTypeSet.csSpencer: result = SlipPoints[0].ZCoor; for (i = FSlipPoints.GetLowerBound(0); i <= FSlipPoints.GetUpperBound(0); i++) { result = Math.Min(result, SlipPoints[i].ZCoor); } break; case TCalculationTypeSet.csHorizontalBalance: result = FZtangent; break; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-09 Best Created // ======================================================================================================================= } // end TSliceDivision }