using System; using Deltares.Geometry; namespace Deltares.Stability.Calculation2 { public class SlidingCurveCalculation { private GeometryPointString freaticline; private double gammaWater; private int leftColumnNumber; private PreProcesStabilityCalculation preProcessCalculation; private int rightColumnNumber; private double startValueSafetyfactor = 1.0; private GeometryPointString surface; public double StartValueSafetyfactor { get { return startValueSafetyfactor; } set { startValueSafetyfactor = value; } } public PreProcesStabilityCalculation PreProcessCalculation { get { return preProcessCalculation; } set { preProcessCalculation = value; } } public GeometryPointString Surface { get { return surface; } set { surface = value; } } public GeometryPointString Freaticline { get { return freaticline; } set { freaticline = value; } } public double GammaWater { get { return gammaWater; } set { gammaWater = value; } } public int LeftColumnNumber { get { return leftColumnNumber; } set { if (leftColumnNumber == value) { return; } leftColumnNumber = value; } } public int RightColumnNumber { get { return rightColumnNumber; } set { if (rightColumnNumber == value) { return; } rightColumnNumber = value; } } public double WaterMomentOnVerticals(Circle circle) { double Ztop; double ZBot; double Ptop; double PBot; double ZFrea; double dZ; double force; double LMom = 0; double LWaterMoment = 0; bool LDown = false; // line direction double LX = 0; double LZ1 = 0; double LZ2 = 0; LWaterMoment = 0; var vertical = MStabDatafunctions.FindVerticalLine(surface); if (vertical.Points.Count > 0) { LX = vertical.Points[0].X; LZ1 = vertical.Points[0].Z; LZ2 = vertical.Points[1].Z; } if ((vertical.Points.Count > 0 && (LX >= circle.XleftSide - Constants.CSameSliceDist) && (LX <= circle.XrightSide + Constants.CSameSliceDist) && (LZ1 != LZ2))) { LDown = (LZ1 > LZ2); // Find the correct freatic line in case of a jump in freatic lines if (LDown) { ZFrea = preProcessCalculation.DetermineZFreaAtX(LX + Constants.CGeoAccu); } else { ZFrea = preProcessCalculation.DetermineZFreaAtX(LX - Constants.CGeoAccu); } Ztop = Math.Max(LZ1, LZ2); ZBot = Math.Min(LZ1, LZ2); // see if vertical line is in reach of circle LMom = 0; if ((MStabDatafunctions.Distance2D(LX, ZBot, circle.Xcentre, circle.Zcentre) < circle.Radius) || (MStabDatafunctions.Distance2D(LX, Ztop, circle.Xcentre, circle.Zcentre) < circle.Radius)) { // Check if entry/exit point is on the curve if ((MStabDatafunctions.Distance2D(LX, ZBot, circle.Xcentre, circle.Zcentre) > circle.Radius)) { var pointString = new GeometryPointString(); pointString.Points.Add(new GeometryPoint(LX, 0, ZBot)); pointString.Points.Add(new GeometryPoint(LX, 0, Ztop)); GeometryPointString gString = MStabDatafunctions.GetIntersectionPointsCircleAndline(circle, pointString); var z1 = gString.Points[0].Z; var z2 = gString.Points[1].Z; if ((gString.Points.Count == 2)) { if ((z1 >= ZBot) && (z1 <= Ztop)) { ZBot = z1; } else { ZBot = z2; } } } dZ = Ztop - ZBot; // Case 1: Water level above top point of vertical -> // Calculate trapezium shaped water pressure figure if (ZFrea > Ztop) { Ptop = (ZFrea - Ztop)*gammaWater; PBot = (ZFrea - ZBot)*gammaWater; force = Ptop*(Ztop - ZBot); // Rectangular part LMom = force*(circle.Zcentre - (ZBot + dZ/2)); force = 0.5*dZ*(PBot - Ptop); // Triangular part LMom = LMom + force*(circle.Zcentre - (ZBot + dZ/3)); } else { // Case 2: Water level intersects vertical surface piece. // Calculate triangular shaped water pressure figure if (ZFrea > ZBot) { PBot = (ZFrea - ZBot)*GammaWater; force = 0.5*(ZFrea - ZBot)*PBot; LMom = force*(circle.Zcentre - (ZBot + (ZFrea - ZBot)/3)); } else { // Case 3: Water level below vertical surface piece -> M=0 LMom = 0; } } // If vertical line goes 'down', the water force points // 'to the left' therefore the moment gets a '-' sign if (LDown) { LMom = -LMom; } } // Sum contributions LWaterMoment = LWaterMoment + LMom; } // Return total moment return LWaterMoment; } public virtual void CreateSlices(SlidingCurve slidingCurve) {} public virtual void FillSlices(SlidingCurve slidingCurve) {} public virtual double GetSafetyFactor(SlidingCurve slidingCurve) { return 0; } } }