using System; using Deltares.Standard; using Deltares.Standard.Logging; namespace Deltares.Stability.Calculation2 { public class UpliftVanCalculation : SlidingCurveCalculation { // internal data private double activeDrivingDMoment = 0; private double activeDrivingMoment = 0; private double activeForce = 0; private double activeForce0 = 0; private double activeResistingMoment = 0; private double drivingMoment = 0; private double horForce = 0; private double horForce0 = 0; private double loadMomentLeft = 0; private double loadMomentRight = 0; private double passiveDrivingMoment = 0; private double passiveForce = 0; private double passiveForce0 = 0; private double passiveResistingMoment = 0; private double radLeft = 0; private double radRight = 0; private double resistingMom = 0; private double resistingMom0 = 0; private bool reverseGeom = false; private double soilMomentLeft = 0; private double soilMomentRight = 0; private double totDrivingLeft = 0; private double totDrivingRight = 0; private double watermomentLeft = 0; private double watermomentRight = 0; private double xActiveCentre = 0; // centre point data in geometry private double xMidLeft = 0; private double xMidRight = 0; private double xPassiveCentre = 0; private double zActiveCentre = 0; private double zMidLeft = 0; private double zMidRight = 0; private double zPassiveCentre = 0; private double zTangent = 0; // destructor Destroy; override; // properties public double XActiveCentre { get { return xActiveCentre; } set { xActiveCentre = value; } } public double ZActiveCentre { get { return zActiveCentre; } set { zActiveCentre = value; } } public double XPassiveCentre { get { return xPassiveCentre; } set { xPassiveCentre = value; } } public double ZPassiveCentre { get { return zPassiveCentre; } set { zPassiveCentre = value; } } public double ActiveRadius { get { return GetActiveRadius(); } } public double PassiveRadius { get { return GetPassiveRadius(); } } public double ZTangent { get { return zTangent; } set { zTangent = value; } } public double ActiveDrivingMoment { get { return activeDrivingMoment; } set { activeDrivingMoment = value; } } public double PassiveDrivingMoment { get { return passiveDrivingMoment; } set { passiveDrivingMoment = value; } } public double ActiveResistingMoment { get { return activeResistingMoment; } set { activeResistingMoment = value; } } public double PassiveResistingMoment { get { return passiveResistingMoment; } set { passiveResistingMoment = value; } } public double ResistingMom0 { get { return resistingMom0; } set { resistingMom0 = value; } } public double ResistingMom { get { return resistingMom; } set { resistingMom = value; } } public double DrivingMoment { get { return drivingMoment; } set { drivingMoment = value; } } public double ActiveForce { get { return activeForce; } } public double PassiveForce { get { return passiveForce; } } public double HorForce { get { return horForce; } } public double ActiveForce0 { get { return activeForce0; } } public double PassiveForce0 { get { return passiveForce0; } } public double HorForce0 { get { return horForce0; } } public double WatermomentLeft { get { return watermomentLeft; } set { watermomentLeft = value; } } public double WatermomentRight { get { return watermomentRight; } set { watermomentRight = value; } } public double LoadMomentRight { get { return loadMomentRight; } set { loadMomentRight = value; } } public double LoadMomentLeft { get { return loadMomentLeft; } set { loadMomentLeft = value; } } public double DetermineWaterMomentOnVertical(double poreTop, double poreBottom, double zTop, double zBottom, double zCentre) { double lDZ = Math.Abs(zTop - zBottom); double lRectPore = Math.Min(poreTop, poreBottom); double lForce = lRectPore*lDZ; double lWaterMoment; lWaterMoment = lForce*(zCentre - 0.5*(zTop + zBottom)); // triangulair part if present lForce = 0.5*lDZ*Math.Abs(poreTop - poreBottom); double lArm; if ((poreTop < poreBottom)) { lArm = (zCentre - zBottom) - lDZ/3; } else { lArm = (zCentre - zTop) + lDZ/3; } lWaterMoment = lWaterMoment + lForce*lArm; return lWaterMoment; } public override void FillSlices(SlidingCurve slidingCurve) { SlidingDualCircle slidingDualCurve = (SlidingDualCircle) slidingCurve; PrepareCalculation(slidingDualCurve); double deltaValue = 0; for (int i = 0; i < slidingCurve.Slices.Count; i++) { var sliceFillerFiller = new SlicesFiller(); sliceFillerFiller.PreProces = PreProcessCalculation; if (i < slidingDualCurve.RightNumber && i > slidingDualCurve.LeftNumber) { // in case of Uplift calculation the most unfavourable plane is searched for, // a plane of 2 cm above the slide plane is compared with a plane 2 cm below the slide plane deltaValue = 0.02; sliceFillerFiller.FillSlicesByInterpolation(slidingCurve.Slices[i], deltaValue); var slice = new Slice(); deltaValue = -0.02; sliceFillerFiller.FillSlicesByInterpolation(slice, deltaValue); // Todo AANSLUITEN /* if ((DetermineShear(Slices[i]) > DetermineShear(LSlice))) { Slices[i].CopySliceData(LSlice); } */ } else { deltaValue = 0; sliceFillerFiller.FillSlicesByInterpolation(slidingCurve.Slices[i], deltaValue); } } } public override double GetSafetyFactor(SlidingCurve slidingCurve) { if (slidingCurve is SlidingDualCircle) { var slidingCircle = (SlidingDualCircle) slidingCurve; // TODO: use sliding circle data instead of internal fields return GetStabilityFactor(slidingCircle); // to be implemented } else { throw new ArgumentException("Sliding curve should be dual circle"); } } //=========================================================================== public override void CreateSlices(SlidingCurve slidingCurve) { var sliceCreatorCreator = new SlicesCreator(); sliceCreatorCreator.ChangingPoints = PreProcessCalculation.ChangingPoints; sliceCreatorCreator.SetSoilProfile2D(PreProcessCalculation.Profile2D); sliceCreatorCreator.SetWaternet(PreProcessCalculation.Waternet); sliceCreatorCreator.SetSurfaceLine(PreProcessCalculation.SurfaceLine); sliceCreatorCreator.StriveWidth = slidingCurve.MaximumSliceWidth; sliceCreatorCreator.CreateUpliftVanSlices((SlidingDualCircle) slidingCurve); } /// /// /// Determine left and right centrepoints /// This is more explicit than active and /// passive centrepoints /// /// private void PrepareCalculation(SlidingDualCircle slidingCurve) { xPassiveCentre = slidingCurve.PassiveCircle.X; zPassiveCentre = slidingCurve.PassiveCircle.Y; xActiveCentre = slidingCurve.ActiveCircle.X; zActiveCentre = slidingCurve.ActiveCircle.Y; zTangent = slidingCurve.TangentLine; if ((xActiveCentre < xPassiveCentre + Constants.CAlmostZero)) { xMidLeft = xActiveCentre; zMidLeft = zActiveCentre; radLeft = zActiveCentre - zTangent; xMidRight = xPassiveCentre; zMidRight = zPassiveCentre; radRight = zPassiveCentre - zTangent; } else { xMidLeft = xPassiveCentre; zMidLeft = zPassiveCentre; radLeft = zPassiveCentre - zTangent; xMidRight = xActiveCentre; zMidRight = zActiveCentre; radRight = zActiveCentre - zTangent; } } private double DrivingSoilMomentLeft(SlidingDualCircle slidingCurve) { double moment = 0; for (int i = 0; i <= slidingCurve.LeftNumber; i++) { double horDistance = xMidLeft - slidingCurve.Slices[i].XCenter; // Bereken aandrijvend moment : dx * (lamel gewicht - water gewicht) moment = moment + horDistance*slidingCurve.Slices[i].Weight; } return moment; } /// /// Calculates the Driving Soil Moment on the right side /// /// /// Driving Soil Moment on the right side private double DrivingSoilMomentRight(SlidingDualCircle slidingCurve) { double moment = 0; for (int i = slidingCurve.RightNumber; i < slidingCurve.Slices.Count; i++) { double horDistance = xMidRight - slidingCurve.Slices[i].XCenter; // Bereken aandrijvend moment : dx * (lamel gewicht - water gewicht) moment = moment + horDistance*slidingCurve.Slices[i].Weight; } return moment; } /// /// A uplift Van calculation consist of two circel parts and a horicontal part. Equilibrium for the circel parts must include Water against such a part /// /// Circle data /// isleft is used to consider if you are calculating on the left or on the right side /// Water moment on circle end private double WaterMomentOnCircleEnd(Circle circle, bool isLeft) { InterpolationColumn column; double zBot = circle.Zcentre - circle.Radius; // find the column (within the horizontal part) where the requested data can be found if (isLeft) { column = PreProcessCalculation.GetColumnAtX(circle.Xcentre + Constants.CGeoAccu); } else { column = PreProcessCalculation.GetColumnAtX(circle.Xcentre - Constants.CGeoAccu); } // Find area number in which the bottom of the bar is situated int areaNumber = column.DetermineAreaNumber(zBot); if (areaNumber < 0) { return 0.0; } double poreTop = 0; double poreBottom = 0; double zTop = 0; double zBottom = 0; double waterMoment = 0; double horizontalInterpolationFactor = (circle.Xcentre - column.XLeft)/(column.XRight - column.XLeft); if (areaNumber == 0) { column.Areas[0].HorizontalInterpolationFactor = horizontalInterpolationFactor; zTop = column.Areas[0].ZCoordinateTop(); zBottom = zBot; poreTop = column.Areas[0].PorePressureTop(); poreBottom = column.Areas[0].PorePressureBottom(); waterMoment = waterMoment + DetermineWaterMomentOnVertical(poreTop, poreBottom, zTop, zBottom, circle.Zcentre); } else { for (int i = 0; i < areaNumber; i++) { column.Areas[i].HorizontalInterpolationFactor = horizontalInterpolationFactor; zTop = column.Areas[i].ZCoordinateTop(); zBottom = column.Areas[i].ZCoordinateBottom(); poreTop = column.Areas[i].PorePressureTop(); poreBottom = column.Areas[i].PorePressureBottom(); waterMoment = waterMoment + DetermineWaterMomentOnVertical(poreTop, poreBottom, zTop, zBottom, circle.Zcentre); } // for area number itself column.Areas[areaNumber].HorizontalInterpolationFactor = horizontalInterpolationFactor; zTop = column.Areas[areaNumber].ZCoordinateTop(); zBottom = zBot; poreTop = column.Areas[areaNumber].PorePressureTop(); poreBottom = column.Areas[areaNumber].PorePressureAtZ(zBottom); waterMoment = waterMoment + DetermineWaterMomentOnVertical(poreTop, poreBottom, zTop, zBottom, circle.Zcentre); } double result; if (isLeft) { result = -waterMoment; } else { result = waterMoment; } return result; } /// /// A uplift Van calculation consist of two circel parts and a horicontal part. Equilibrium for the bar parts must include Water against such a part /// /// Circle data: A Bar start or ends at the x coordinate of the circle centre points /// isleft is used to consider if you are calculating on the left or on the right sideof a Bar /// The water force at the bar private double WaterForceOnBarEnd(Circle circle, bool isLeft) { InterpolationColumn column; double zBot = circle.Zcentre - circle.Radius; // find the column (within the horizontal part) where the requested data can be found if (isLeft) { column = PreProcessCalculation.GetColumnAtX(circle.Xcentre + Constants.CGeoAccu); } else { column = PreProcessCalculation.GetColumnAtX(circle.Xcentre - Constants.CGeoAccu); } // Find area number in which the bottom of the bar is situated int areaNumber = column.DetermineAreaNumber(zBot + Constants.CGeoAccu); if (areaNumber < 0) { return 0.0; } double poreTop = 0; double poreBottom = 0; double zTop = 0; double zBottom = 0; double force = 0; double horizontalInterpolationFactor = (circle.Xcentre - column.XLeft)/(column.XRight - column.XLeft); if (areaNumber == 0) { column.Areas[0].HorizontalInterpolationFactor = horizontalInterpolationFactor; zTop = column.Areas[0].ZCoordinateTop(); zBottom = zBot; poreTop = column.Areas[0].PorePressureTop(); poreBottom = column.Areas[0].PorePressureBottom(); force = force + 0.5*(poreTop + poreBottom)*(zTop - zBottom); } else { for (int i = 0; i < areaNumber; i++) { column.Areas[i].HorizontalInterpolationFactor = horizontalInterpolationFactor; poreTop = column.Areas[i].PorePressureTop(); poreBottom = column.Areas[i].PorePressureBottom(); zTop = column.Areas[i].ZCoordinateTop(); zBottom = column.Areas[i].ZCoordinateBottom(); force = force + 0.5*(poreTop + poreBottom)*(zTop - zBottom); } // for area number itself column.Areas[areaNumber].HorizontalInterpolationFactor = horizontalInterpolationFactor; zTop = column.Areas[areaNumber].ZCoordinateTop(); zBottom = zBot; poreTop = column.Areas[areaNumber].PorePressureTop(); poreBottom = column.Areas[areaNumber].PorePressureAtZ(zBottom); force = force + 0.5*(poreTop + poreBottom)*(zTop - zBottom); } return force; } private double DeterminePoreOnSurface(double aXCoor) { double result = 0; double lTop = PreProcessCalculation.SurfaceLine.Geometry.GetZAtX(aXCoor); double yFrea = PreProcessCalculation.Waternet.PhreaticLine.GetZAtX(aXCoor); if (yFrea > lTop) { result = (yFrea - lTop)*PreProcessCalculation.Waternet.UnitWeight; result = result*0.5*(yFrea - lTop); } return result; } private double DetermineHorizontalWaterForce(SlidingDualCircle slidingCurve) { var circle = new Circle(); double lForce = 0.0; double lLeftForce = 0.0; double lRightForce = 0.0; circle.Xcentre = xMidLeft; circle.Zcentre = zMidLeft; circle.Radius = radLeft; lLeftForce = WaterForceOnBarEnd(circle, true); circle.Xcentre = xMidRight; circle.Zcentre = zMidRight; circle.Radius = radRight; lRightForce = WaterForceOnBarEnd(circle, false); lForce = lLeftForce - lRightForce; double leftPoreOnSurface = DeterminePoreOnSurface(xMidLeft); Double rightPoreonSurface = DeterminePoreOnSurface(xMidRight); return lForce + (leftPoreOnSurface - rightPoreonSurface); } private double DrivingWaterMomentLeft(SlidingDualCircle slidingCurve) { double moment = 0; for (int i = 0; i <= slidingCurve.LeftNumber; i++) { // Calculate watermoment due to waterforces on slices double horDistance = slidingCurve.Slices[i].XCenter - xMidLeft; double vertDistance = zMidLeft - slidingCurve.Slices[i].ZCenterTop; moment = moment + horDistance*slidingCurve.Slices[i].VPoreOnSurface + vertDistance*slidingCurve.Slices[i].HPoreOnSurface; } // Calculate extra moments due to water forces on vertical parts of // the geometry within the slip circle area. var circle = new Circle(); { circle.Xcentre = slidingCurve.ActiveCircle.X; circle.Zcentre = slidingCurve.ActiveCircle.Y; circle.Radius = (circle.Zcentre - zTangent); } moment = moment + WaterMomentOnVerticals(circle); // Calculate extra moments due to water forces on vertical parts of // the geometry within the slip circle area. double waterMoment = WaterMomentOnCircleEnd(circle, true); moment = moment + waterMoment; return moment; } private double DrivingWaterMomentRight(SlidingDualCircle slidingCurve) { double moment = 0; for (int i = slidingCurve.RightNumber; i < slidingCurve.Slices.Count; i++) { // Calculate watermoment due to waterforces on slices double horDistance = slidingCurve.Slices[i].XCenter - xMidRight; double vertDistance = zMidRight - slidingCurve.Slices[i].ZCenterTop; moment = moment + horDistance*slidingCurve.Slices[i].VPoreOnSurface + vertDistance*slidingCurve.Slices[i].HPoreOnSurface; } // Calculate extra moments due to water forces on vertical parts of // the geometry within the slip circle area. var circle = new Circle(); { circle.Xcentre = slidingCurve.PassiveCircle.X; circle.Zcentre = slidingCurve.PassiveCircle.Y; circle.Radius = (circle.Zcentre - zTangent); } moment = moment + WaterMomentOnVerticals(circle); moment = moment + WaterMomentOnCircleEnd(circle, false); return moment; } private double UniformLoadMoment(double Xcentre, double Xstart, double Xend) { double loadMoment = 0; foreach (var uniformLoad in PreProcessCalculation.UniformLoads) { loadMoment += uniformLoad.GetMomentRoundX(Xcentre, Xstart, Xend); } return loadMoment; } private void DetermineDrivingMoments(SlidingDualCircle slidingCurve) { totDrivingLeft = 0.0; totDrivingRight = 0.0; // calculate driving moments soilMomentLeft = DrivingSoilMomentLeft(slidingCurve); soilMomentRight = DrivingSoilMomentRight(slidingCurve); // watermoments from free water watermomentLeft = DrivingWaterMomentLeft(slidingCurve); watermomentRight = DrivingWaterMomentRight(slidingCurve); // load moments if present loadMomentLeft = UniformLoadMoment(xMidLeft, slidingCurve.LeftPoint.X, xMidLeft); loadMomentRight = UniformLoadMoment(xMidRight, xMidRight, slidingCurve.RightPoint.X); // the total driving moments totDrivingLeft = soilMomentLeft + watermomentLeft + loadMomentLeft; totDrivingRight = soilMomentRight + watermomentRight + loadMomentRight; reverseGeom = Math.Abs(totDrivingRight) > Math.Abs(totDrivingLeft); } /// /// Calculates the horizontal shear force between two circle parts /// /// /// /// /// /// private double GetHorResistingForce(SlidingDualCircle slidingCurve, int startSlice, int endSlice, double factorFo) { const double pir = Math.PI/180.0; double som = 0; // double sinPhi = 0; // double cosPhi = 0; double tau = 0; for (int i = startSlice; i <= endSlice; i++) { Slice slice = slidingCurve.Slices[i]; double coh = slice.Cohesion; // cohesie //sinPhi = Math.Sin(slice.Phi*pir); //cosPhi = Math.Cos(slice.Phi*pir); //LCosDilet = Math.Cos(LSlice.Dilatancy * Pir); //LSinDilet = Math.Sin(LSlice.Dilatancy * Pir); //LSigTerm = LCosDilet * LSinPhi / (1 - LSinDilet * LSinPhi); //LCohTerm = LCosDilet * LCosPhi / (1 - LSinDilet * LSinPhi); // bereken de coh en phi uit de spannings tabel //LTau = coh * LCohTerm + LSlice.EffectiveStress * LSigTerm; tau = coh + slice.EffectiveStress*Math.Tan(slice.Phi*pir); som = som + slice.ArcLength*tau; // Nieuwe Tau - alfa slice.NormalStress = slice.EffectiveStress; slice.ShearStress = tau/factorFo; } return som; } /// /// Calculates the resisting moments of a circle part /// /// /// /// /// /// /// private double GetResistingMoment(SlidingDualCircle slidingCurve, int startSlice, int endSlice, double radius, double factorFo) { const double Pir = Math.PI/180.0; int i; double coh; double tgPhi; double Salfa; double alfa; double h; double tgalfa; double SomMoment; // double LCohTerm; /* double LSigTerm; double LSinPhi; double LCosPhi; double LCosDilet; double LSinDilet; */ double LTau; SomMoment = 0.0; for (i = startSlice; i <= endSlice; i++) { coh = slidingCurve.Slices[i].Cohesion; // cohesie /* LSinPhi = Math.Sin(slidingCurve.Slices[i].Phi * Pir); LCosPhi = Math.Cos(slidingCurve.Slices[i].Phi * Pir); LCosDilet = Math.Cos(slidingCurve.Slices[i].Dilatancy * Pir); LSinDilet = Math.Sin(slidingCurve.Slices[i].Dilatancy * Pir); */ tgPhi = Math.Tan(slidingCurve.Slices[i].Phi*Pir); // formula based on Tau-alfa = // 1/Fo * (coh * cotgphi + Salfa')* cospsi*sinphi/(1 - sinphi*sinpsi) // (after tuenissen)) // note that if psi = phi then tau = coh + salfa * tgphi /* LSigTerm = LCosDilet * LSinPhi / (1 - LSinDilet * LSinPhi); LCohTerm = LCosDilet * LCosPhi / (1 - LSinDilet * LSinPhi); */ alfa = slidingCurve.Slices[i].BottomAngle; // Hoek onderkant lamel [rad] if (DrivingMoment > 0.0) { alfa = -alfa; } // Passieve alfa nagatief maken // Afsnuiten indien nodig h = 0.5*Math.Atan(tgPhi/factorFo) - 0.25*Math.PI; if (alfa <= h) { alfa = h; } tgalfa = Math.Tan(alfa); // Bereken het tegen werkend moment LTau = coh + slidingCurve.Slices[i].EffectiveStress*tgPhi; SomMoment = SomMoment + slidingCurve.Slices[i].ArcLength*LTau/(1 + tgalfa*tgPhi/factorFo); Salfa = (factorFo*slidingCurve.Slices[i].EffectiveStress - coh*tgalfa)/(factorFo + tgPhi*tgalfa); slidingCurve.Slices[i].NormalStress = Salfa; slidingCurve.Slices[i].ShearStress = (coh + Salfa*tgPhi)/factorFo; } return SomMoment*radius; } /// /// Calculates the safety factor for Uplift-Van method /// /// The considered sliding curve (2 circles + horizontal part) /// Safety factor for Uplift-Van method private double LiftMethode(SlidingDualCircle slidingCurve) { // Initialisatie resistingMom = 0.0; double fn = StartValueSafetyfactor; bool ready = false; var numberOfIterations = 0; double armLeft = radLeft - 1d/3d*(slidingCurve.Slices[slidingCurve.LeftNumber].TopRight.Y - slidingCurve.Slices[slidingCurve.LeftNumber].BottomRight.Y); double armRight = radRight - 1d/3d*(slidingCurve.Slices[slidingCurve.RightNumber].TopLeft.Y - slidingCurve.Slices[slidingCurve.RightNumber].BottomLeft.Y); drivingMoment = totDrivingLeft/armLeft + totDrivingRight/armRight; double horWaterForce = DetermineHorizontalWaterForce(slidingCurve); // Driving moment is actualy a force drivingMoment = drivingMoment + horWaterForce; // Check driving moment on 1 kNm if ((Math.Abs(drivingMoment) < 0.001)) { ready = true; } // Start iteratie if (!ready) { do { numberOfIterations++; double fo = fn; resistingMom = 0.0; // bereken de momenten van de linker en rechter helfr // rekening houdend met de draairichting (reversegeom of niet ) double leftResMom = GetResistingMoment(slidingCurve, 0, slidingCurve.LeftNumber, radLeft, fo); double rightResMom = GetResistingMoment(slidingCurve, slidingCurve.RightNumber, slidingCurve.Slices.Count - 1, radRight, fo); double horResForce = GetHorResistingForce(slidingCurve, slidingCurve.LeftNumber + 1, slidingCurve.RightNumber - 1, fo); resistingMom = Math.Abs(leftResMom)/armLeft + Math.Abs(rightResMom)/armRight + Math.Abs(horResForce); // bereken de actieve passieve en hor kracht if (reverseGeom) { passiveForce = (Math.Abs(totDrivingLeft) + Math.Abs(leftResMom/fo))/armLeft; activeForce = (Math.Abs(totDrivingRight) - Math.Abs(rightResMom/fo))/armRight; activeDrivingDMoment = totDrivingRight; activeResistingMoment = rightResMom; passiveDrivingMoment = totDrivingLeft; passiveResistingMoment = leftResMom; } else { activeForce = (Math.Abs(totDrivingLeft) - Math.Abs(leftResMom)/fo)/armLeft; passiveForce = (Math.Abs(totDrivingRight) + Math.Abs(rightResMom/fo))/armRight; activeDrivingMoment = totDrivingLeft; activeResistingMoment = leftResMom; passiveDrivingMoment = totDrivingRight; passiveResistingMoment = rightResMom; } horForce = horResForce/fo; if ((numberOfIterations == 1)) { slidingCurve.ActiveForce0 = activeForce; slidingCurve.PassiveForce0 = passiveForce; slidingCurve.HorizontalForce0 = horForce; resistingMom0 = resistingMom; } else { slidingCurve.ActiveForce = activeForce; slidingCurve.PassiveForce = passiveForce; slidingCurve.HorizontalForce = horForce; slidingCurve.DrivingMomentActive = activeDrivingMoment; slidingCurve.DrivingMomentPassive = passiveDrivingMoment; slidingCurve.ResistingMomentActive = activeResistingMoment; slidingCurve.ResistingMomentPassive = passiveResistingMoment; } fn = resistingMom/Math.Abs(drivingMoment); // Stoppen als veiligheidscoefficient oud en nieuw ongeveer gelijk zijn if (Math.Abs(fn - fo) < 0.001) { ready = true; } // Teveel iteratie dan stoppen if (numberOfIterations > Constants.CMaxIter) { ready = true; } // Als tegenwerkend moment = 0, dan ook stoppen. if ((Math.Abs(resistingMom) < 0.001) || (fn < 0.001)) { ready = true; } } while (!(ready)); } double result = fn; if (Math.Abs(drivingMoment) < 0.001) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Warning, this, "Driving moment too small")); } else { if (numberOfIterations >= Constants.CMaxIter) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Warning, this, "More than " + Convert.ToString(Constants.CMaxIter) + " iterations")); } else if ((Math.Abs(resistingMom) < 0.001) || (fn < 0.001)) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Warning, this, "Resisting moment too small")); } } return result; } //=========================================================================== private bool IfMinimalPlanedepthIsNotOk(SlidingDualCircle slidingCurve) { for (int i = 0; i < slidingCurve.Slices.Count; i++) { if ((slidingCurve.Slices[i].ZCenterTop - slidingCurve.Slices[i].ZCenterBottom) > PreProcessCalculation.Constraints.SlipPlaneMinDepth) { return false; } } return true; } private bool IfMinimalPlaneLengthIsNotOk(SlidingDualCircle slidingCurve) { double som = 0; for (int i = 0; i < slidingCurve.Slices.Count; i++) { som = som + slidingCurve.Slices[i].ArcLength; } if (som > PreProcessCalculation.Constraints.SlipPlaneMinLength) { return false; } return true; } private double GetStabilityFactor(SlidingDualCircle slidingCurve) { // Calculate the driving moments DetermineDrivingMoments(slidingCurve); // Calculate stability factor slidingCurve.SafetyFactor = LiftMethode(slidingCurve); return slidingCurve.SafetyFactor; } //=========================================================================== private double GetActiveRadius() { double result; result = Math.Abs(ZActiveCentre - ZTangent); return result; } //=========================================================================== private double GetPassiveRadius() { double result; result = Math.Abs(ZPassiveCentre - ZTangent); return result; } //=========================================================================== //=========================================================================== } }