using System; using Deltares.Geometry; using Deltares.Mathematics; using Deltares.Standard; namespace Deltares.Stability.Calculation2 { public class ControlBishopCalculation : SlidingCurvesProcessor { private GeometryPoint bottomGridLeft = new GeometryPoint(); private GeometryPoint bottomGridRight = new GeometryPoint(); private double bottomTangent; private int boundaryIndicator; private SlipCircleGrid calculationgrid; private double deltaTangent = 0; private double deltaX = 0; private double deltaZ = 0; private bool gridMove = false; private double gridheight; private double gridwidth; private int maxGridMoves = 50; private SlidingCircle minimumSlidingCurve = null; private SlipCircleFixedPoint slipCircleFixedPoint; private SlipCircleTangentLine slipCircleTangentLine; private GeometryPoint topGridLeft = new GeometryPoint(); private GeometryPoint topGridRight = new GeometryPoint(); private double topTangent; public ControlBishopCalculation(SlipCircle slipCircle) { calculationgrid = slipCircle.SlipCircleGrid; slipCircleTangentLine = slipCircle.SlipCircleTangentLine; slipCircleFixedPoint = slipCircle.SlipCircleFixedPoint; } public void DoGridCalCalculation() { for (int gridxLoop = 0; gridxLoop < calculationgrid.XIntervalNumber + 1; gridxLoop++) { for (int gridZLoop = 0; gridZLoop < calculationgrid.ZIntervalNumber + 1; gridZLoop++) { for (int tangentLoop = 0; tangentLoop < slipCircleTangentLine.BoundaryHeights.Count; tangentLoop++) { var slidingCircle = new SlidingCircle(); slidingCircle.Center = new Point2D(bottomGridLeft.X + gridxLoop * deltaX, bottomGridRight.Z + gridZLoop * deltaZ); slidingCircle.Radius = slidingCircle.Center.Y - (topTangent - tangentLoop * deltaTangent); double stabilityFactor = GetSafetyFactor(slidingCircle); if (minimumSlidingCurve == null || stabilityFactor < minimumSlidingCurve.SafetyFactor) { minimumSlidingCurve = slidingCircle; } } } } } public override void Initialize(StabilityModel stabilityModel) { gridMove = stabilityModel.MoveGrid; maxGridMoves = stabilityModel.NumberOfGridMoves; base.Initialize(stabilityModel); } public override SlidingCurve Calculate() { minimumSlidingCurve = null; GridCalculation(); return minimumSlidingCurve; } // ======================================================================================================================= // Description : Find minimum procedure // // 8 4 9 // + + + + + // + + + + + // 1 + + + + + 2 // + + + + + // + + + + + // 6 3 7 // // ----------------------- 12 // ----------------------- // ----------------------- 13 // // Name Type Function // ---- ---- -------- // Parameters - IN/OUT : AutoGridMoves Integer Maximum number of // automatic steps for // findminimum procedure // // Date ID Modification // 2008-04-14 Best Created // ======================================================================================================================= private bool MinimumOnBoundary() { bool result = true; const double error = 0.001; if (minimumSlidingCurve == null) { return false; } double xMidMin = minimumSlidingCurve.Center.X; double zMidMin = minimumSlidingCurve.Center.Y; double tangentMin = minimumSlidingCurve.Center.Y - minimumSlidingCurve.Radius; // with FInterfaceData.SlipCircleData do // TSlipCircleData fLocalSlipData = this.FLocalSlipData; // ... Is Stramien groot genoeg voor een zoekminimum procedure ... boundaryIndicator = 0; if ((calculationgrid.XIntervalNumber < 2) && (calculationgrid.ZIntervalNumber < 2) && (slipCircleTangentLine.TangentLineNumber < 2)) { result = false; } if (result) { // ... Als er in vorig stramien Geen goede cirkels waren, dan Geen zoekminimum ... if (minimumSlidingCurve == null) { result = false; } } if (result) { // Kijk of het minimum op een rand ligt. boundaryIndicator = 0; if ((Math.Abs(xMidMin - bottomGridLeft.X) < error) && (calculationgrid.XIntervalNumber > 1)) { boundaryIndicator = 1; } if ((Math.Abs(xMidMin - bottomGridRight.X) < error) && (calculationgrid.XIntervalNumber > 1)) { boundaryIndicator = 2; } if ((Math.Abs(zMidMin - bottomGridRight.Z) < error) && (calculationgrid.ZIntervalNumber > 1)) { // De mogelijkheid bestaat dat minimum op en hoek ligt. // Dan stramien twee kanten uit schuiven. if (boundaryIndicator == 0) { boundaryIndicator = 3; } else { boundaryIndicator = (boundaryIndicator == 1) ? 6 : 7; } } if ((Math.Abs(zMidMin - topGridRight.Z) < error) && (calculationgrid.ZIntervalNumber > 1)) { if (boundaryIndicator == 0) { boundaryIndicator = 4; } else { boundaryIndicator = (boundaryIndicator == 1) ? 8 : 9; } } // ... check tangent lines only if centre point is enclosed ... if (boundaryIndicator == 0 && slipCircleTangentLine.TangentLineNumber > 1 && !slipCircleTangentLine.IsAutomaticAtBoundaries()) { if (Math.Abs(tangentMin - topTangent) < error) { boundaryIndicator = 12; } if (Math.Abs(tangentMin - bottomTangent) < error) { boundaryIndicator = 13; } } if (boundaryIndicator == 0) { result = false; } } return result; } private void ShiftGridLeft() { topGridRight.X = topGridLeft.X + deltaX; bottomGridRight.X = bottomGridLeft.X + deltaX; topGridLeft.X = topGridRight.X - gridwidth; bottomGridLeft.X = bottomGridRight.X - gridwidth; } private void ShiftGridRight() { topGridLeft.X = topGridRight.X - deltaX; bottomGridLeft.X = bottomGridRight.X - deltaX; topGridRight.X = topGridLeft.X + gridwidth; bottomGridRight.X = bottomGridLeft.X + gridwidth; } private void ShiftGridTop() { bottomGridLeft.Z = topGridLeft.Z - deltaZ; bottomGridRight.Z = topGridRight.Z - deltaZ; topGridLeft.Z = bottomGridLeft.Z + gridheight; topGridRight.Z = bottomGridRight.Z + gridheight; } private void ShiftGridBottom() { topGridLeft.Z = bottomGridLeft.Z + deltaZ; topGridRight.Z = bottomGridRight.Z - deltaZ; bottomGridLeft.Z = topGridLeft.Z - gridheight; bottomGridRight.Z = topGridRight.Z - gridwidth; } private void ShiftTangentTop() { topTangent += deltaTangent; bottomTangent += deltaTangent; } private void ShiftTangentBottom() { topTangent -= deltaTangent; bottomTangent -= deltaTangent; } private void ShiftBoundaries() { if (boundaryIndicator == 1) { ShiftGridLeft(); } if (boundaryIndicator == 2) { ShiftGridRight(); } if (boundaryIndicator == 3) { ShiftGridBottom(); } if (boundaryIndicator == 4) { ShiftGridTop(); } if (boundaryIndicator == 6) { ShiftGridLeft(); ShiftGridBottom(); } if (boundaryIndicator == 7) { ShiftGridRight(); ShiftGridBottom(); } if (boundaryIndicator == 8) { ShiftGridLeft(); ShiftGridTop(); } if (boundaryIndicator == 9) { ShiftGridRight(); ShiftGridTop(); } if (boundaryIndicator == 12) { ShiftTangentTop(); } if (boundaryIndicator == 13) { ShiftTangentBottom(); } } private void GridCalculation() { PutGridparametersIntoLocal(); DetermineLoopParameters(); DoGridCalCalculation(); int gridMoves = 0; if (gridMove) { while (gridMoves < maxGridMoves && MinimumOnBoundary()) { gridMoves++; ShiftBoundaries(); DoGridCalCalculation(); } } } private void PutGridparametersIntoLocal() { // set grid parameters to local parameters bottomGridRight = new GeometryPoint(calculationgrid.GridXRight, 0, calculationgrid.GridZBottom); bottomGridLeft = new GeometryPoint(calculationgrid.GridXLeft, 0, calculationgrid.GridZBottom); topGridRight = new GeometryPoint(calculationgrid.GridXRight, 0, calculationgrid.GridZTop); topGridLeft = new GeometryPoint(calculationgrid.GridXLeft, 0, calculationgrid.GridZTop); topTangent = slipCircleTangentLine.TangentLineZTop; bottomTangent = slipCircleTangentLine.TangentLineZBottom; gridwidth = calculationgrid.GridXRight - calculationgrid.GridXLeft; gridheight = topGridLeft.Z - bottomGridLeft.Z; } private void DetermineLoopParameters() { // determine the interal values if (calculationgrid.XIntervalNumber > 0) { deltaX = (calculationgrid.GridXRight - calculationgrid.GridXLeft)/ (calculationgrid.XIntervalNumber); } if (calculationgrid.ZIntervalNumber > 0) { deltaZ = (calculationgrid.GridZTop - calculationgrid.GridZBottom)/ (calculationgrid.ZIntervalNumber); } if (slipCircleTangentLine.TangentLineNumber > 1) { deltaTangent = (slipCircleTangentLine.TangentLineZTop - slipCircleTangentLine.TangentLineZBottom)/ (slipCircleTangentLine.TangentLineNumber - 1); } } } }