using System; using System.Collections.Generic; using Deltares.Geometry; using Deltares.Mathematics; using Deltares.Standard; namespace Deltares.Stability.Calculation2 { public class ControlUpliftcalculation : SlidingCurvesProcessor { private GeometryPoint bottomGridLeft = new GeometryPoint(); private GeometryPoint bottomGridLeftPassive = new GeometryPoint(); private GeometryPoint bottomGridRight = new GeometryPoint(); private GeometryPoint bottomGridRightPassive = new GeometryPoint(); private double bottomTangent; private int boundaryIndicator; private double deltaTangent = 0; private double deltaX = 0; private double deltaXPassive = 0; private double deltaZ = 0; private double deltaZPassive = 0; private bool gridMove = false; private double gridheight; private double gridwidth; private bool isAutomatic = true; private SlipCircleGrid leftGridActive; private GeometryPoint localBottomGridLeft; private GeometryPoint localBottomGridRight; private double localDeltaX; private double localDeltaZ; private double localNumberOfgridIntervalsX; private double localNumberOfgridIntervalsZ; private GeometryPoint localTopGridLeft; private GeometryPoint localTopGridRight; private SlidingDualCircle minimumSlidingCurve = null; private int numberOfMoves; private SlipCircleGrid rightGridPassive; private SlipCircleTangentLine slipCircleTangentLine; private SlipPlaneUpliftVan slipPlaneUpliftVan; private List tangentLevels = new List(); private double tangentheigth; private GeometryPoint topGridLeft = new GeometryPoint(); private GeometryPoint topGridLeftPassive = new GeometryPoint(); private GeometryPoint topGridRight = new GeometryPoint(); private GeometryPoint topGridRightPassive = new GeometryPoint(); // copies for move grid private double topTangent; public ControlUpliftcalculation() {} public void DoGridCalCalculation() { for (int gridxLoop = 0; gridxLoop < leftGridActive.XIntervalNumber + 1; gridxLoop++) { for (int gridZLoop = 0; gridZLoop < leftGridActive.ZIntervalNumber + 1; gridZLoop++) { for (int gridxLoopPassive = 0; gridxLoopPassive < rightGridPassive.XIntervalNumber + 1; gridxLoopPassive++) { for (int gridZLoopPassive = 0; gridZLoopPassive < rightGridPassive.ZIntervalNumber + 1; gridZLoopPassive++) { for (int tangentLoop = 0; tangentLoop < tangentLevels.Count; tangentLoop++) { double xLeft = bottomGridLeft.X + gridxLoop*deltaX; double xRight = bottomGridLeftPassive.X + gridxLoopPassive*deltaXPassive; if (xLeft - 0.001 < xRight) { var slidingCircle = new SlidingDualCircle(); slidingCircle.ActiveCircle = new Point2D(xLeft, bottomGridRight.Z + gridZLoop*deltaZ); slidingCircle.PassiveCircle = new Point2D(xRight, bottomGridRightPassive.Z + gridZLoopPassive*deltaZPassive); slidingCircle.TangentLine = tangentLevels[tangentLoop]; slidingCircle.PassiveRadius = slidingCircle.PassiveCircle.Y - slidingCircle.TangentLine; slidingCircle.ActiveRadius = slidingCircle.ActiveCircle.Y - slidingCircle.TangentLine; slidingCircle.LeftCircleIsActive = (slipPlaneUpliftVan.ActiveSide == ActiveSideType.Left); double stabilityFactor = GetSafetyFactor(slidingCircle); if (minimumSlidingCurve == null || stabilityFactor < minimumSlidingCurve.SafetyFactor) { minimumSlidingCurve = slidingCircle; } } } } } } } } public override void Initialize(StabilityModel stabilityModel) { gridMove = stabilityModel.MoveGrid; isAutomatic = stabilityModel.SlipCircle.Auto; slipPlaneUpliftVan = stabilityModel.SlipPlaneUpliftVan; //TODO: check slipPlaneUplift.SlipPlaneLeftGrid or right leftGridActive = slipPlaneUpliftVan.SlipPlaneLeftGrid; rightGridPassive = slipPlaneUpliftVan.SlipPlaneRightGrid; if (stabilityModel.SlipPlaneUpliftVan.SlipCircleTangentLine.IsAutomaticAtBoundaries()) { for (int i = 0; i < slipPlaneUpliftVan.SlipCircleTangentLine.BoundaryHeights.Count; i++) { tangentLevels.Add(slipPlaneUpliftVan.SlipCircleTangentLine.BoundaryHeights[i].Height); } } else { double deltaTangentLines; if (slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineNumber == 1) { deltaTangentLines = 0; } else { deltaTangentLines = (slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineZTop - slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineZBottom)/ (slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineNumber - 1); } for (int i = 0; i < slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineNumber; i++) { tangentLevels.Add(slipPlaneUpliftVan.SlipPlaneTangentLine.TangentLineZBottom + i*deltaTangentLines); } } slipCircleTangentLine = slipPlaneUpliftVan.SlipPlaneTangentLine; base.Initialize(stabilityModel); } public override SlidingCurve Calculate() { minimumSlidingCurve = null; GridCalculation(); return minimumSlidingCurve; } private void putGridparametersIntoLocal() { // active part bottomGridLeft.X = leftGridActive.GridXLeft; bottomGridLeft.Z = leftGridActive.GridZBottom; bottomGridRight.X = leftGridActive.GridXRight; bottomGridRight.Z = leftGridActive.GridZBottom; topGridLeft.X = leftGridActive.GridXLeft; topGridLeft.Z = leftGridActive.GridZTop; topGridRight.X = leftGridActive.GridXRight; topGridRight.Z = leftGridActive.GridZTop; // passive part bottomGridLeftPassive.X = rightGridPassive.GridXLeft; bottomGridLeftPassive.Z = rightGridPassive.GridZBottom; bottomGridRightPassive.X = rightGridPassive.GridXRight; bottomGridRightPassive.Z = rightGridPassive.GridZBottom; topGridLeftPassive.X = rightGridPassive.GridXLeft; topGridLeftPassive.Z = rightGridPassive.GridZTop; topGridRightPassive.X = rightGridPassive.GridXRight; topGridRightPassive.Z = rightGridPassive.GridZTop; topTangent = slipCircleTangentLine.TangentLineZTop; bottomTangent = slipCircleTangentLine.TangentLineZBottom; tangentheigth = topTangent - bottomTangent; } private void determineLoopParameters() { //slipCircle.SlipCircleGrid.XIntervalNumber // determine the interal values if (leftGridActive.XIntervalNumber > 0) { deltaX = (leftGridActive.GridXRight - leftGridActive.GridXLeft)/(leftGridActive.XIntervalNumber); } if (leftGridActive.ZIntervalNumber > 0) { deltaZ = (leftGridActive.GridZTop - leftGridActive.GridZBottom)/(leftGridActive.ZIntervalNumber); } if (rightGridPassive.XIntervalNumber > 0) { deltaXPassive = (rightGridPassive.GridXRight - rightGridPassive.GridXLeft)/(rightGridPassive.XIntervalNumber); } if (rightGridPassive.ZIntervalNumber > 0) { deltaZPassive = (rightGridPassive.GridZTop - rightGridPassive.GridZBottom)/(rightGridPassive.ZIntervalNumber); } // needed for move grid if not automatic if (slipCircleTangentLine.TangentLineNumber > 1) { deltaTangent = (slipCircleTangentLine.TangentLineZTop - slipCircleTangentLine.TangentLineZBottom)/(slipCircleTangentLine.TangentLineNumber); } } private bool IsMinimumOnBoundary() { bool result = false; bool left = true; if (MinimumOnBoundary(left)) { ShiftBoundaries(); boundaryIndicator = 0; result = true; } left = false; if (MinimumOnBoundary(left)) { ShiftBoundaries(); boundaryIndicator = 0; result = true; } if (MinimumOnTangent()) { // When automatic then the tangent lines are NOT moved. So make sure to stop here to prevent eternal loop. if (!isAutomatic) { ShiftBoundaries(); boundaryIndicator = 0; result = true; } else { result = false; } } return result; } // ======================================================================================================================= // Description : Find minimum procedure for tangent lines // // // ----------------------- 12 // ----------------------- // ----------------------- 13 // // ====================================================================================================================== private bool MinimumOnTangent() { double tangentMin; double error = 0.001; // ... Als er in vorig stramien Geen goede cirkels waren, dan Geen zoekminimum ... if (minimumSlidingCurve == null) { return false; } tangentMin = minimumSlidingCurve.TangentLine; // ... check tangent lines only if centre point is enclosed ... if (boundaryIndicator == 0 && slipCircleTangentLine.TangentLineNumber > 1) { if ((Math.Abs(tangentMin - topTangent) < error)) { boundaryIndicator = 12; } if ((Math.Abs(tangentMin - bottomTangent) < error)) { boundaryIndicator = 13; } } if (boundaryIndicator == 0) { return false; } return true; } // ======================================================================================================================= // Description : Find minimum procedure // // 8 4 9 // + + + + + // + + + + + // 1 + + + + + 2 // + + + + + // + + + + + // 6 3 7 // // 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 Left) { bool result = true; double error = 0.001; double xMidMin; double zMidMin; // ... Als er in vorig stramien Geen goede cirkels waren, dan Geen zoekminimum ... if (minimumSlidingCurve == null) { result = false; return result; } if (Left) { xMidMin = minimumSlidingCurve.ActiveCircle.X; ; zMidMin = minimumSlidingCurve.ActiveCircle.Y; localNumberOfgridIntervalsX = leftGridActive.XIntervalNumber; localNumberOfgridIntervalsZ = leftGridActive.ZIntervalNumber; localBottomGridLeft = bottomGridLeft; // new GeometryPoint(leftGridActive.GridXLeft, 0, leftGridActive.GridZBottom); localBottomGridRight = bottomGridRight; // new GeometryPoint(leftGridActive.GridXRight, 0, leftGridActive.GridZBottom); localTopGridLeft = topGridLeft; //new GeometryPoint(leftGridActive.GridXLeft, 0, leftGridActive.GridZTop); localTopGridRight = topGridRight; //new GeometryPoint(leftGridActive.GridXRight, 0, leftGridActive.GridZTop); localDeltaX = deltaX; localDeltaZ = deltaZ; gridwidth = leftGridActive.GridXRight - leftGridActive.GridXLeft; gridheight = leftGridActive.GridZTop - leftGridActive.GridZBottom; } else { xMidMin = minimumSlidingCurve.PassiveCircle.X; zMidMin = minimumSlidingCurve.PassiveCircle.Y; localNumberOfgridIntervalsX = rightGridPassive.XIntervalNumber; localNumberOfgridIntervalsZ = rightGridPassive.ZIntervalNumber; localBottomGridLeft = bottomGridLeftPassive; localBottomGridRight = bottomGridRightPassive; localTopGridLeft = topGridLeftPassive; localTopGridRight = topGridRightPassive; localDeltaX = deltaXPassive; localDeltaZ = deltaZPassive; gridwidth = rightGridPassive.GridXRight - rightGridPassive.GridXLeft; gridheight = rightGridPassive.GridZTop - rightGridPassive.GridZBottom; } // with FInterfaceData.SlipCircleData do // TSlipCircleData fLocalSlipData = this.FLocalSlipData; // ... Is Stramien groot genoeg voor een zoekminimum procedure ... boundaryIndicator = 0; if ((localNumberOfgridIntervalsX < 2) || (localNumberOfgridIntervalsZ < 2)) { result = false; } if (result) { // Kijk of het minimum op een rand ligt. boundaryIndicator = 0; if ((Math.Abs(xMidMin - localBottomGridLeft.X) < error)) { boundaryIndicator = 1; } if ((Math.Abs(xMidMin - localBottomGridRight.X) < error)) { boundaryIndicator = 2; } if ((Math.Abs(zMidMin - localBottomGridRight.Z) < error)) { // De mogelijkheid bestaat dat minimum op en hoek ligt. // Dan stramien twee kanten uit schuiven. if ((boundaryIndicator == 0)) { boundaryIndicator = 3; } else { if ((boundaryIndicator == 1)) { boundaryIndicator = 6; } else { boundaryIndicator = 7; } } } if ((Math.Abs(zMidMin - localTopGridRight.Z) < error)) { if ((boundaryIndicator == 0)) { boundaryIndicator = 4; } else { if ((boundaryIndicator == 1)) { boundaryIndicator = 8; } else { boundaryIndicator = 9; } } } if ((boundaryIndicator == 0)) { result = false; } } return result; } private void ShiftGridLeft() { localTopGridRight.X = localTopGridLeft.X + localDeltaX; localBottomGridRight.X = localBottomGridLeft.X + localDeltaX; localTopGridLeft.X = localTopGridRight.X - gridwidth; localBottomGridLeft.X = localBottomGridRight.X - gridwidth; } private void ShiftGridRight() { localTopGridLeft.X = localTopGridRight.X - localDeltaX; localBottomGridLeft.X = localBottomGridRight.X - localDeltaX; localTopGridRight.X = localTopGridLeft.X + gridwidth; localBottomGridRight.X = localBottomGridLeft.X + gridwidth; } private void ShiftGridTop() { localBottomGridLeft.Z = localTopGridLeft.Z - localDeltaZ; localBottomGridRight.Z = localTopGridRight.Z - localDeltaZ; localTopGridLeft.Z = localBottomGridLeft.Z + gridheight; localTopGridRight.Z = localBottomGridRight.Z + gridheight; } private void ShiftGridBottom() { localTopGridLeft.Z = localBottomGridLeft.Z + localDeltaZ; localTopGridRight.Z = localBottomGridRight.Z + localDeltaZ; localBottomGridLeft.Z = localTopGridLeft.Z - gridheight; localBottomGridRight.Z = localTopGridRight.Z - gridwidth; } private void ShiftTangentTop() { if (! isAutomatic) { bottomTangent = topTangent - deltaTangent; topTangent = bottomTangent + tangentheigth; } } private void ShiftTangentBottom() { if (!isAutomatic) { topTangent = bottomTangent + deltaTangent; bottomTangent = topTangent - tangentheigth; } } 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(); numberOfMoves = 0; if (gridMove) { while (IsMinimumOnBoundary()) { DoGridCalCalculation(); numberOfMoves++; } } } } }