#define DUMP using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using Deltares.Standard; using Deltares.Standard.Language; using Deltares.Standard.Logging; // ======================================================================================================================= // Class name: TBishopSlipCirkel // // Description: // // Copyright (c) 1993-2010 Deltares // // Date ID Modification // 2008-03-26 Best Created // 2008-04-24 Best Remove not used text // ======================================================================================================================= namespace Deltares.Stability.Calculation.Inner { public class TBishopSlipCirkel : TCirculairSlipPlane { private double FAngle = 0; private double FDrivingMoment = 0; private double FEndsectionMom = 0; private double FHorQuakeMom = 0; private double FLoadMoment = 0; private double FNailMoment = 0; private bool FPC_Ring = false; private int FPlotNumber = 0; private double FRemoldFactor = 0; private double FResistingMom = 0; private double FResistingMom0 = 0; private bool FReverseGeom = false; private double FRotatedDrivingMoment = 0; private double FRotatedResistingMom = 0; private double FRotatedSoilMoment = 0; private double FSchemaFactor = 0; private double FSoilMoment = 0; private double FTextileMoment = 0; private int FWaterlevelNumber = 0; private double FWatermoment = 0; private List geotextileResults = new List(); // ======================================================================================================================= // Date ID Modification // 2008-03-26 Best Created // ======================================================================================================================= //Constructor Create() public TBishopSlipCirkel() : base() { FCalculationNote = ""; // TODO: Add any constructor code here } public double StabilityFactor { get { return GetStabilityfactor(); } } public double ReliabilityIndex { get { return GetReliabilityIndex(); } } public double TextileMoment { get { return FTextileMoment; } set { FTextileMoment = value; } } public double NailMoment { get { return FNailMoment; } set { FNailMoment = value; } } public double DrivingMoment { get { return FDrivingMoment; } set { FDrivingMoment = value; } } public double ResistingMom0 { get { return FResistingMom0; } set { FResistingMom0 = value; } } public double ResistingMom { get { return FResistingMom; } set { FResistingMom = value; } } public double EndsectionMom { get { return FEndsectionMom; } set { FEndsectionMom = value; } } public double SoilMoment { get { return FSoilMoment; } set { FSoilMoment = value; } } public double Watermoment { get { return FWatermoment; } set { FWatermoment = value; } } public double LoadMoment { get { return FLoadMoment; } set { FLoadMoment = value; } } public double HorQuakeMom { get { return FHorQuakeMom; } set { FHorQuakeMom = value; } } public double Angle { get { return FAngle; } set { FAngle = value; } } public double RemoldFactor { get { return FRemoldFactor; } set { FRemoldFactor = value; } } public double SchemaFactor { get { return FSchemaFactor; } set { FSchemaFactor = value; } } public double RotateSafety { get { return GetRotatedSafetyFactor(); } } public bool PC_Ring { get { return FPC_Ring; } set { FPC_Ring = value; } } public int WaterlevelNumber { get { return FWaterlevelNumber; } set { FWaterlevelNumber = value; } } public int PlotNumber { get { return FPlotNumber; } set { FPlotNumber = value; } } /// /// get all geotextiles with their result properties /// /// public List GetGeotextileResults() { return geotextileResults; } public override double GetReliabilityIndex() { double result = 0; // geeft aan of verwachtingswaarde als begin // oplossing Moet worden genomen. Bevat de // betrouwbaarheids index na afloop // tijdelijk zolang nog niet in calculation options string Lstr; // bool LIsProbDump; FBeta = -1; base.GetReliabilityIndex(); // LIsProbDump = true; if ((IsCircelValid())) { // Initialise CreateSlices(); // Fill soil,stress data of slices ( in een apparte routine STSliceFill FillSlices(); // nu is bekend welke lagen in het glijvlak zitten, tevens is het goede // waterspanningsbeeld in de geometrie opgebouwd, Nu met probalistisch // rekenen (probab of form) beginen // eerst de variabelen vullen en bijhouden // in StProbFill // Typical for MStab FStabProbabilisticData = new TMStabProbabilisticData(); FStabProbabilisticData.InterfaceData = FInterfaceData; FStabProbabilisticData.Slices = FSlices; try { FStabProbabilisticData.CreateandFillProbArrays(); // Shortcuts FNStochastic = FStabProbabilisticData.NStochastic; FWithCorrelation = FStabProbabilisticData.WithCorrelation; FVerdeling = FStabProbabilisticData.Verdeling; FEx = FStabProbabilisticData.Ex; FSx = FStabProbabilisticData.Sx; FVp = FStabProbabilisticData.Vp; FParamName = FStabProbabilisticData.AParamName; FCovariantie = FStabProbabilisticData.Covariantie; FEivec = FStabProbabilisticData.Eivec; Fx = FStabProbabilisticData.X; FU = FStabProbabilisticData.U; FVarArr = FStabProbabilisticData.VarArr; FAanpasArr = FStabProbabilisticData.AanpasArr; } catch (Exception E) { Lstr = E.Message; throw E; } // (FNSlices, FSlices); //LStabProbabilisticData.CreateandFillProbArrays(FNSlices, FSlices, NTot, Verdeling, // Ex, Sx, U, X, Vp, Covariantie, Eivec, FVarArr, FAAnpasArr, WithCorrelation, LParam); if (FWithCorrelation) { FNumCor = FNStochastic; FNumEivec = FNStochastic; } else { FNumCor = 1; FNumEivec = 1; } // DIDN'T COMPILE: COMMENTED OUT //this.FCalculationProb = new TCalculationProbabilistic(); //this.FCalculationProb.AdaptedStability = AdaptedStability; //FCalculationProb.LimitvalueModel = this.FStabProbabilisticData.LimitvalueModel; //this.FCalculationProb.ZFunction = ZFunction; //this.FCalculationProb.StartCalculation(FNStochastic, FVerdeling, FEx, FSx, ref FBeta, FParamName); // LProbCalculation.ProgresFunction := ProgresF // Programm independent); FProbCalculation = new TProbCalculation(); FProbCalculation.IsTestDump = false; FProbCalculation.TestFileName = "Test" + ".out"; FProbCalculation.ZFunction = ZFunction; FProbCalculation.IsMonteCarlo = FIsMonteCarlo; FProbCalculation.IsForm = FIsForm; FProbCalculation.IsDars = FIsDars; FProbCalculation.StartCalculation(FNStochastic, FVerdeling, FEx, FSx, ref FVp, ref FCovariantie, FNumCor, FEivec, FNumEivec, ref FStuurpar, ref FBeta, ref Fx, ref FU, ref FZes, ref FIerr, ref FIter); // LProbCalculation.ProgresFunction := ProgresFunction; // (* MyGlobals.SoilList.FullFree; // MyGlobals.SoilList := TDSoilList.CreateAndCopy(LBackUpSoilList); // LBackUpSoilList.FullFree; // ResetGlobals(Ex, FVarArr, FAanpasArr); // // if (Ierr = 0) then // begin // {get the apropriate water level} // if (FWaterlevelNumber = 0) then // LLevel := MyGlobals.StochasticWaterList.MHW // else // LLevel := MyGlobals.StochasticWaterList.stochasticWater[FWaterlevelNumber - // 1].Level; // // ShortOutput(Beta, LLevel); // // if (not GSTCalculationSettings.ShortReportOn) then // begin // WriteMeanAndDesign(Ex, Sx, X, Verdeling, LParam); // // LongOutputProbabilistic(NTot, Beta, LLevel, LLevelName, // X, U, SX, FVarArr, FAanpasArr); // end; // // Result := Beta; // // if (FWaterlevelNumber = 0) then // begin // LLevelName := 'Design level'; // end // else // begin // // LLevelName := MyGlobals.StochasticWaterList. // // stochasticWater[FWaterlevelNumber - 1].ItemName; // end; // {Write results from probabilistic calculation to dump} // // ProbabilisticResultDump(NTot, Beta, LLevel, LLevelName, // // X, U, SX, FVarArr, FAanpasArr); // // {Write output for PC-Ring if appropriate} // // if (FPC_Ring) then // // PC_RingResultOutput(FPlotNumber, FWaterlevelNumber, NTot, Beta, U, SX, // // FVarArr, FAanpasArr); // end; // // {... reset the stresstablefactors to their initial values ...} // // InitialiseStresstablefactor; // // {Free dynamic arrays} // x := nil; // U := nil; // Ex := nil; // Sx := nil; // Vp := nil; // Eivec := nil; // FVarArr := nil; // Verdeling := nil; // FAanpasArr := nil; // Covariantie := nil; // LParam := nil; // *) } // ... reset the stresstablefactors to their initial values ... // InitialiseStresstablefactor; result = FBeta; return result; } private double AdaptedStability(double[] X) { int iter = 0; double LSafety; string Lstr; // vul de nieuwe sterkte parameters in en de nieuwe aanpassingen try { FStabProbabilisticData.PutAdjustedParametersInMaterial(X); } catch (Exception E) { Lstr = E.Message; throw E; } // Fill soil,stress data of slices (met nieuwe gegevens // in een apparte routine STSliceFill try { FStabProbabilisticData.AdjustSliceData(FNSlices, ref FSlices); } catch (Exception E) { Lstr = E.Message; throw E; } // Printslices(Lfs, FNSlices, FSlices); // calculate driving moments FSoilMoment = DrivingSoilMoment(); FWatermoment = DrivingWaterMoment(); FLoadMoment = UniformLoadMoment() + LineLoadMoment(); FHorQuakeMom = HorBeefMoment(); LSafety = BishopMethode(ref iter); return LSafety; } // ======================================================================================================================= // Date ID Modification // 2009-04-21 Created // ======================================================================================================================= private void ZFunction(int NTot, double[] X, double theta, ref int IError, ref double Z) { double LSafety; LSafety = AdaptedStability(X); Z = LSafety - FStabProbabilisticData.LimitvalueModel; if ((Z < 900)) { IError = 0; } } // ======================================================================================================================= // Date ID Modification // 2010-03-24 Created // ======================================================================================================================= private void GetRotatedXMiddle() { int i; double LFracx; double LFracy; double LOriginalAngle; double LTotAngle; for (i = 0; i < FNSlices; i++) { LFracy = FSlices[i].ZBottomMid - FZCenterPoint; LFracx = FSlices[i].XMid - FXCenterPoint; LOriginalAngle = Math.Atan2(LFracy, LFracx); // bepaal de nieuwe hoek if (FReverseGeom) { LTotAngle = LOriginalAngle + Angle; } else { LTotAngle = LOriginalAngle - Angle; } GetSlice(i).XMidRotated = FXCenterPoint + Radius*Math.Cos(LTotAngle); } } // ======================================================================================================================= // Date ID Modification // 2010-03-24 Created // ======================================================================================================================= private void FindNonActiveSlices() { int i; double LxLast; // last X on circle if (FReverseGeom) { LxLast = FSlices[0].xLeft; } else { LxLast = FSlices[FNSlices - 1].xRight; } for (i = 0; i < FNSlices; i++) { // Kijk of Ondrkant na rotatie boven maaivels uitkomt if (FReverseGeom) { FSlices[i].IsActive = (FSlices[i].XMidRotated > LxLast); } else { FSlices[i].IsActive = (FSlices[i].XMidRotated < LxLast); } } } // zone data // ======================================================================================================================= // Date ID Modification // 2010-03-24 Created // ======================================================================================================================= private double RotatedDrivingSoilMoment() { double result; double HorDistance; double Moment; int i; Moment = 0; for (i = 0; i < FNSlices; i++) { Tslice _wvar1 = FSlices[i]; if (_wvar1.IsActive) { HorDistance = _wvar1.XMidRotated - FXCenterPoint; // Bereken aandrijvend moment : dx * (lamel gewicht - water gewicht) Moment = Moment - HorDistance*_wvar1.Weight; } } result = Moment; return result; } // ======================================================================================================================= // Date ID Modification // 2010-03-24 Created // ======================================================================================================================= private double BishopRotationMethode() { double result; int i; // Initialisatie FRotatedResistingMom = 0.0; // corigeer het watermoment met de factor voor vrij water FRotatedDrivingMoment = FWatermoment*(1 - FInterfaceData.Earthquake.FreeWaterFactor) + FRotatedSoilMoment + FLoadMoment; // voeg hor aardbevingsmoment toe zodanig dat aandrijvend groter wordt // Het verticale aardbevingsmoment zit verwerkt in gewicht van de lamel if (FRotatedDrivingMoment < 0) { FRotatedDrivingMoment = FRotatedDrivingMoment - -Math.Abs(FHorQuakeMom); } else { FRotatedDrivingMoment = FRotatedDrivingMoment + Math.Abs(FHorQuakeMom); } FTextileMoment = GeotextileMoment(FRotatedDrivingMoment); FNailMoment = SoilNailMoment(); // Controleer aandrijvend moment op 1 kNm if ((Math.Abs(FRotatedDrivingMoment) > 0.001)) { // Bereken tegenwerkend moment FRotatedResistingMom = 0.0; for (i = 0; i < FNSlices; i++) { Tslice _wvar1 = GetSlice(i); if ((_wvar1.IsActive)) { FRotatedResistingMom = FRotatedResistingMom + _wvar1.ArcLength*_wvar1.ShearStress; } } FRotatedResistingMom = FRotatedResistingMom*Radius*FRemoldFactor*FSchemaFactor + FTextileMoment + FNailMoment; result = FRotatedResistingMom/Math.Abs(FRotatedDrivingMoment); } else { result = 1001; } return result; } // ======================================================================================================================= // Date ID Modification // 2010-03-24 Created // ======================================================================================================================= private double GetRotatedSafetyFactor() { double result; result = 1001; GetRotatedXMiddle(); FindNonActiveSlices(); // calculate driving moments FRotatedSoilMoment = RotatedDrivingSoilMoment(); FWatermoment = DrivingWaterMoment(); FLoadMoment = UniformLoadMoment() + LineLoadMoment(); FHorQuakeMom = HorBeefMoment(); if (new ArrayList(new TCalculationTypeSet[] { TCalculationTypeSet.csBishop, TCalculationTypeSet.csFellenius }).Contains(FInterfaceData.ModelData.CalcType)) { result = BishopRotationMethode(); } return result; } // ======================================================================================================================= // Description: Calculates the DrivingSoilMoment // // Date ID Modification // 1997-07-01 Best Created // ======================================================================================================================= private double DrivingSoilMoment() { double result; double HorDistance; double Moment; int i; Moment = 0; for (i = 0; i < FNSlices; i++) { HorDistance = FSlices[i].XMid - FXCenterPoint; // Bereken aandrijvend moment : dx * lamel gewicht Moment = Moment - HorDistance*(FSlices[i].Weight + FSlices[i].SigmaSoilQuake*FSlices[i].Width); } result = Moment; return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-02 Best Created // ======================================================================================================================= private double HorBeefMoment() { double result; double VertDistance; double Moment; int i; Moment = 0; for (i = 0; i < FNSlices; i++) { Tslice _wvar1 = FSlices[i]; VertDistance = FZCenterPoint - _wvar1.Zwaartepunt; // Bereken hor aardbevings moment : dx * factor * (lamel gewicht - water gewicht) Moment = Moment - VertDistance*FInterfaceData.Earthquake.HorizontalQuakeFactor*_wvar1.Weight; } result = Moment; return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-02 Best Created // ======================================================================================================================= private double DrivingWaterMoment() { double result; double HorDistance; double VertDistance; double Moment; int i; Moment = 0; for (i = 0; i < FNSlices; i++) { // Calculate watermoment due to waterforces on slices HorDistance = FSlices[i].XMid - FXCenterPoint; VertDistance = FZCenterPoint - FSlices[i].ZTopMid; Moment = Moment + HorDistance*FSlices[i].VPoreOnSurface + VertDistance*FSlices[i].HPoreOnSurface; } // Calculate extra moments due to water forces on vertical parts of // the geometry within the slip circle area. if ((FInterfaceData.CurrentWaternet.PhreaticLineNumber >= 0)) { if ((FInterfaceData.CurrentWaternet.PLLines[FInterfaceData.CurrentWaternet.PhreaticLineNumber].Length > 1)) { Moment = Moment + WaterMomentOnVerticals(); } } result = Moment; return result; } // --- Einde procedure Momenten --- // ======================================================================================================================= // Date ID Modification // 2008-04-02 Best Created // ======================================================================================================================= private double WaterMomentOnVerticals() { double result = 0; double Ztop = 0; double ZBot = 0; double Ptop = 0; double PBot = 0; double ZFrea = 0; double dZ = 0; double force = 0; double LMom = 0; double LWaterMoment = 0; bool LDown; double LZFreaTop = 0; double LZFreaBottom = 0; int LNS = 0; double LXs1 = 0; double LXS2 = 0; double Lzs1 = 0; double LzS2 = 0; bool LVerticalFound = false; double LX = 0; double LZ1 = 0; double LZ2 = 0; TPoints[] LFreaLine = null; LWaterMoment = 0; LFreaLine = FInterfaceData.CurrentWaternet.PLLines[FInterfaceData.CurrentWaternet.PhreaticLineNumber]; MStabDatafunctions.FindVertical(FInterfaceData.SurfaceLine, ref LVerticalFound, ref LX, ref LZ1, ref LZ2); if ((LVerticalFound && (LX >= FxLeftSurface) && (LX <= FXRightSurface) && (LZ1 != LZ2))) { LDown = (LZ1 > LZ2); // calculate freatop and bottom in case of a sheetpiling LZFreaTop = MStabDatafunctions.ZTopAtSurface(LX, LFreaLine); LZFreaBottom = MStabDatafunctions.ZBottomAtSurface(LX, LFreaLine); if ((Math.Abs(LZFreaTop - LZFreaBottom) < Constants.CGeoAccu)) { ZFrea = LZFreaTop; } else { // Find the correct freatic line in case of a jump in freatic lines if (LDown) { ZFrea = MStabDatafunctions.ZTopAtSurface(LX + Constants.CGeoAccu, LFreaLine); } else { ZFrea = MStabDatafunctions.ZTopAtSurface(LX - Constants.CGeoAccu, LFreaLine); } } 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, XCenterPoint, ZCenterPoint) > Radius) && (MStabDatafunctions.Distance2D(LX, Ztop, XCenterPoint, ZCenterPoint) > Radius)) { // LMom := 0; // Previous line moved before first if statement because Delphi 2006 // sometimes(!) generated a warning that LMom might not be initialised. } else { // Check if entry/exit point is on the curve if ((MStabDatafunctions.Distance2D(LX, ZBot, XCenterPoint, ZCenterPoint) > Radius)) { MStabDatafunctions.Intersect_Circle_line(XCenterPoint, ZCenterPoint, Radius, LX, LX, ZBot, Ztop, ref LNS, ref LXs1, ref Lzs1, ref LXS2, ref LzS2); Debug.Assert(LNS == 2); if ((LNS == 2)) { if ((Lzs1 >= ZBot) && (Lzs1 <= Ztop)) { ZBot = Lzs1; } else { ZBot = LzS2; } } } dZ = Ztop - ZBot; // Case 1: Water level above top point of vertical -> // Calculate trapezium shaped water pressure figure if (ZFrea > Ztop) { Ptop = (ZFrea - Ztop)*FGamWat; PBot = (ZFrea - ZBot)*FGamWat; force = Ptop*(Ztop - ZBot); // Rectangular part LMom = force*(ZCenterPoint - (ZBot + dZ/2)); force = 0.5*dZ*(PBot - Ptop); // Triangular part LMom = LMom + force*(ZCenterPoint - (ZBot + dZ/3)); } else { // Case 2: Water level intersects vertical surface piece. // Calculate triangular shaped water pressure figure if (ZFrea > ZBot) { PBot = (ZFrea - ZBot)*FGamWat; force = 0.5*(ZFrea - ZBot)*PBot; LMom = force*(ZCenterPoint - (ZBot + (ZFrea - ZBot)/3)); } else { // Case 3: Water level below vertical surface piece -> M=0 // LMom := 0 // Previous line moved before first if statement because Delphi 2006 // sometimes(!) generated a warning that LMom might not be initialised. } } // 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 result = LWaterMoment; return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-03 Best Created // ======================================================================================================================= private double UniformLoadMoment() { double result; double Som; int i; Som = 0.0; for (i = FInterfaceData.UniformLoad.GetLowerBound(0); i <= FInterfaceData.UniformLoad.GetUpperBound(0); i++) { TUniformLoad LocLoad = FInterfaceData.UniformLoad[i]; Som = Som + LocLoad.GetMomentRoundX(FXCenterPoint, FxLeftSurface, FXRightSurface); } result = Som; return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-23 Best Created // ======================================================================================================================= private double LineLoadMoment() { double result; double Som; int i; Som = 0.0; for (i = FInterfaceData.LineLoad.GetLowerBound(0); i <= FInterfaceData.LineLoad.GetUpperBound(0); i++) { TLineLoad _wvar1 = FInterfaceData.LineLoad[i]; Som = Som + _wvar1.GetMoment(FXCenterPoint, FZCenterPoint, FRadius, FxLeftSurface, FXRightSurface); } result = Som; return result; } // ======================================================================================================================= // Description: Calculates the moments of the Geotextiles // // Date ID Modification // 1999-03-10 Best Created // ======================================================================================================================= private double GeotextileMoment(double ADrivingMom) { double som = 0; for (int i = 0; i < FInterfaceData.Geotextiles.Length; i++) { TGeotextiles _wvar1 = FInterfaceData.Geotextiles[i]; som = som + _wvar1.GetGeotextilesMoment(XCenterPoint, ZCenterPoint, Radius, ADrivingMom); geotextileResults.Add(_wvar1); } return som; } private double SoilNailMoment() { double som = 0; foreach (var nail in FInterfaceData.Nail) { som = som + nail.CalculateResistingMoment(XCenterPoint, ZCenterPoint, Radius, FInterfaceData); } return som; } // ======================================================================================================================= // Description : Berekent de veiligheidscoeff. uit bij methode // Bishop. // // Name Type Function // ---- ---- -------- // Parameters - IN : Straal Real de sigma-vertikaal bij alfa // watm Real aandrijvend moment tgv. // water op talud // aanm Real aandrijvend moment van de // grondmmot // belm Real aandrijvend moment tgv. // belasting // Mgeot Real tegenwerkend moment tgv. // geotextielen // - OUT : Mtegen0 Real het ongeitereerde tegen // werkend moment // Mtegen Real het geitereerde tegen // werkend moment // fb Real veiligheidscoefficient // // Date ID Modification // 1993-12-07 Gef Documented // 1995-05-23 Best Earthquake moments added // 2007-02-05 Best Special formula tau := c*cos(phi) + Sigma-v' * sin(Phi) (methode c,phi) // ======================================================================================================================= private double BishopMethode(ref int iter) { double result; const double Pir = Math.PI/180.0; int i = 0; int TSPoint = 0; double Fn = 0; double Fo = 0; bool Ready = false; double Salfa = 0; double TgPhi = 0; double Coh = 0; double phi = 0; double alfa = 0; double h = 0; double tgalfa = 0; double CosAlfa; double LEndsectionMom = 0; // Lfw: TextFile; // LFileName: string; // LLocdump: Boolean; // Llocdump := false; // Initialisatie FResistingMom = 0.0; LEndsectionMom = 0.0; Fn = FInterfaceData.CalculationOptions.StartValueSafetyFactor; Ready = false; iter = 0; // corigeer het watermoment met de factor voor vrij water FDrivingMoment = FWatermoment*(1 - FInterfaceData.Earthquake.FreeWaterFactor) + FSoilMoment + FLoadMoment; // voeg hor aardbevingsmoment toe zodanig dat aandrijvend groter wordt // Het verticale aardbevingsmoment zit verwerkt in gewicht van de lamel if (FDrivingMoment < 0) { FDrivingMoment = FDrivingMoment - Math.Abs(FHorQuakeMom); } else { FDrivingMoment = FDrivingMoment + Math.Abs(FHorQuakeMom); } FTextileMoment = GeotextileMoment(FDrivingMoment); geotextileResults = GetGeotextileResults(); FNailMoment = SoilNailMoment(); // (* if (MyGlobals.DumpNaildata) then // begin // LFileName := ChangeFileExt(GDGlobals.InputFileName, '.out'); // AssignFile(lfw, LFileName); // Rewrite(lfw); // CloseFile(lfw); // end; // // FNailMoment := SoilNailMoment(FDrivingMoment); // // if (Llocdump) then // begin // LFileName := ChangeFileExt(GDGlobals.InputFileName, '.out'); // AssignFile(lfw, LFileName); // Rewrite(lfw); // writeln(lfw, 'lamel coh EffectiveStress tgphi tgalfa * tgphi Salfa '); // // end; // *) // Controleer aandrijvend moment op 1 kNm if (Math.Abs(FDrivingMoment) < 0.001) { Ready = true; } #if DUMP { // writer = new StreamWriter("ResMom.txt"); // writer.WriteLine("Slice| Coh | FResMom|ArcLngth| EffStr | TgPhi | tgalfa | Salfa|"); } #endif // Start iteratie if (!Ready) { do { iter++; Fo = Fn; FResistingMom = 0.0; for (i = 0; i < FNSlices; i++) { Tslice LSlice = GetSlice(i); TgPhi = Math.Tan(GetSlice(i).PhiBottom*Pir); // tangens phie Coh = GetSlice(i).CohBottom; // cohesie alfa = LSlice.BottomAngle; // Hoek onderkant lamel [rad] if (FDrivingMoment > 0.0) { alfa = -alfa; // Passieve alfa nagatief maken } // Afsnuiten indien nodig h = 0.5*Math.Atan(TgPhi/Fo) - 0.25*Math.PI; if (alfa <= h) { alfa = h; } tgalfa = Math.Tan(alfa); CosAlfa = Math.Cos(alfa); if (FInterfaceData.ModelData.CalcType == TCalculationTypeSet.csFellenius) { FResistingMom = FResistingMom + LSlice.ArcLength* (Coh + (LSlice.TotalStress*CosAlfa*CosAlfa - LSlice.TotalPore)*TgPhi); } else { // Bereken het tegen werkend moment FResistingMom = FResistingMom + LSlice.ArcLength*(Coh + LSlice.EffectiveStress*TgPhi)/(1 + tgalfa*TgPhi/Fo); } // Vertikaal Evenwicht : Sigma-v' = Salfa' + Tau-alfa*Tgalfa // en Tau volgens Bishop : Tau-alfa = 1/Fo * (coh + Salfa'*tgphi // Uit deze twee vergelijkingen kan Salfa opgelost worden : Salfa = (Fo*LSlice.EffectiveStress - Coh*tgalfa)/(Fo + tgalfa*TgPhi); // (* if (Llocdump) then #if DUMP if (iter == 1) { // writer.WriteLine("{0,4:0} |{1,7:0.00} |{2,7:0.00} |{3,7:0.00} |{4,7:0.00} |{5,7:0.00} |{6,7:0.00} |{7,7:0.00} |", // i + 1, Coh, FResistingMom, LSlice.ArcLength, LSlice.EffectiveStress, TgPhi, tgalfa, Salfa); } #endif if ((new ArrayList(new TCalculationTypeSet[] { TCalculationTypeSet.csBishop, TCalculationTypeSet.csFellenius }).Contains(FInterfaceData.ModelData.CalcType)) && (new ArrayList(new TMatStrengthTypeSet[] { TMatStrengthTypeSet.mstStressTab, TMatStrengthTypeSet.mstPseudoStressTab }).Contains(GetSlice(i).StrengthType))) { // Nieuwe sigma alfa if (Salfa < 0.0) { Salfa = 0.0; // Add message only if not already added earlier if (FCalculationNote.IndexOf("Negative effective stress.") == 0) { FCalculationNote = FCalculationNote + "Negative effective stress.@"; } } LSlice.SigmaAlfa = Salfa; FInterfaceData.StabSoilData[LSlice.SoilNumber].GetCohAndPhiFromTable(LSlice.SigmaAlfa, LSlice.PseudoFactor, ref Coh, ref phi, ref TSPoint); LSlice.PhiBottom = phi; // New phi - alfa LSlice.CohBottom = Coh; // New coh - alfa TgPhi = Math.Tan(LSlice.PhiBottom*Pir); // New tangens phie } // Nieuwe Tau - alfa LSlice.NormalStress = Salfa; if (FInterfaceData.ModelData.CalcType == TCalculationTypeSet.csFellenius) { LSlice.ShearStress = (Coh + (LSlice.TotalStress*CosAlfa*CosAlfa - LSlice.TotalPore)*TgPhi); } else { LSlice.ShearStress = (LSlice.CohBottom + Salfa*TgPhi)/Fo; } } if (FInterfaceData.CalculationOptions.UseEndBearing) { if ((FResistingMom > 0)) { FEndsectionMom = Math.Abs(FEndsectionMom); } else { FEndsectionMom = -Math.Abs(FEndsectionMom); } LEndsectionMom = FEndsectionMom/Fo; } FResistingMom = FResistingMom*FRadius + FTextileMoment + LEndsectionMom + FNailMoment; Fn = FResistingMom/Math.Abs(FDrivingMoment); // Sla ongeitereerd moment, dus bij 1e iteratie op, om te kunnen uitvoeren if (iter == 1) { FResistingMom0 = FResistingMom; } // Stoppen als veiligheidscoefficient oud en nieuw ongeveer gelijk zijn if (Math.Abs(Fn - Fo) < 0.001) { Ready = true; } // Bij fellenius alleen moment evenwicht if ((FInterfaceData.ModelData.CalcType == TCalculationTypeSet.csFellenius)) { Ready = true; } // Teveel iteratie dan stoppen if (iter > Constants.CMaxIter) { Ready = true; } // Als tegenwerkend moment = 0, dan ook stoppen. if ((Math.Abs(FResistingMom) < 0.001) || (Fn < 0.001)) { Ready = true; } } while (!(Ready)); } #if DUMP // writer.Close(); #endif result = Fn; if (Math.Abs(FDrivingMoment) < 0.001) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, LocalizationManager.GetTranslatedText(GetType(), "DrivingMomentTooSmall"))); FCalculationNote = FCalculationNote + "Driving moment too small.@"; } else { if (iter >= Constants.CMaxIter) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, string.Format(LocalizationManager.GetTranslatedText(GetType(), "TooManyIterations"), Constants.CMaxIter))); FCalculationNote = FCalculationNote + "More than maximum " + ((int) (Constants.CMaxIter)).ToString() + " iterations.@"; } else { if ((Math.Abs(FResistingMom) < 0.001) || (Fn < 0.001)) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, LocalizationManager.GetTranslatedText(GetType(), "ResistingMomentTooSmall"))); FCalculationNote = FCalculationNote + "Resisting moment too small.@"; } } } return result; } // ======================================================================================================================= // Description : Berekent de veiligheidscoeff. uit bij methode // Bishop voor stydie berekening. // // 2007-02-05 Best Special formula tau := c*cos(phi) + Sigma-v' * sin(Phi) (methode c,phi) // ======================================================================================================================= private double BishopMethodeStudy(ref int iter) { double result; const double Pir = Math.PI/180.0; int i; double Fn; double Fo; bool Ready; double Salfa; double TgPhi; double LSinPhi; double LCosPhi; double LCosDilet; double LSinDilet; double LTau; double Coh; double alfa; double h; double tgalfa; double LEndsectionMom; // Lfw: TextFile; // LFileName: string; double LCohTerm; double LSigTerm; // Initialisatie FResistingMom = 0.0; LEndsectionMom = 0.0; Fn = FInterfaceData.CalculationOptions.StartValueSafetyFactor; Ready = false; iter = 0; // corigeer het watermoment met de factor voor vrij water FDrivingMoment = FWatermoment*(1 - FInterfaceData.Earthquake.FreeWaterFactor) + FSoilMoment + FLoadMoment; // voeg hor aardbevingsmoment toe zodanig dat aandrijvend groter wordt // Het verticale aardbevingsmoment zit verwerkt in gewicht van de lamel if (FDrivingMoment < 0) { FDrivingMoment = FDrivingMoment - Math.Abs(FHorQuakeMom); } else { FDrivingMoment = FDrivingMoment + Math.Abs(FHorQuakeMom); } FTextileMoment = GeotextileMoment(FDrivingMoment); FNailMoment = SoilNailMoment(); // (* if (MyGlobals.DumpNaildata) then // begin // LFileName := ChangeFileExt(GDGlobals.InputFileName, '.out'); // AssignFile(lfw, LFileName); // Rewrite(lfw); // CloseFile(lfw); // end; // FNailMoment := SoilNailMoment(FDrivingMoment); // *) // Controleer aandrijvend moment op 1 kNm if (Math.Abs(FDrivingMoment) < 0.001) { Ready = true; } // Start iteratie if (!Ready) { do { iter++; Fo = Fn; FResistingMom = 0.0; for (i = 0; i < FNSlices; i++) { Tslice _wvar1 = GetSlice(i); Coh = _wvar1.CohBottom; // cohesie LSinPhi = Math.Sin(GetSlice(i).PhiBottom*Pir); LCosPhi = Math.Cos(_wvar1.PhiBottom*Pir); LCosDilet = Math.Cos(_wvar1.Dilatancy*Pir); LSinDilet = Math.Sin(_wvar1.Dilatancy*Pir); TgPhi = Math.Tan(_wvar1.PhiBottom*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); // Tau-alfa = Coh*LCohTerm + Salfa'*LSigTerm alfa = GetSlice(i).BottomAngle; // Hoek onderkant lamel [rad] if (FDrivingMoment > 0.0) { alfa = -alfa; // Passieve alfa nagatief maken } // Afsnuiten indien nodig h = 0.5*Math.Atan(TgPhi/Fo) - 0.25*Math.PI; if (alfa <= h) { alfa = h; } tgalfa = Math.Tan(alfa); // Bereken het tegen werkend moment LTau = Coh*LCohTerm + GetSlice(i).EffectiveStress*LSigTerm; FResistingMom = FResistingMom + _wvar1.ArcLength*LTau/(1 + tgalfa*LSigTerm/Fo); // Bereken het tegen werkend moment // FResistingMom := FResistingMom + ArcLength * (coh + EffectiveStress * tgphi) / // (1 + tgalfa * tgphi / Fo); // Vertikaal Evenwicht : Sigma-v' = Salfa' + Tau-alfa*Tgalfa // en Tau volgens Bishop : Tau-alfa = 1/Fo * (Coh*LCohTerm + Salfa'*LSigTerm // Uit deze twee vergelijkingen kan Salfa opgelost worden : Salfa = (Fo*_wvar1.EffectiveStress - Coh*LCohTerm*tgalfa)/(Fo + LSigTerm*tgalfa); // Salfa := (Fo * EffectiveStress - LLocCoh * tgalfa) / (Fo + tgalfa * tgphi); // Nieuwe Tau - alfa _wvar1.NormalStress = Salfa; _wvar1.ShearStress = (Coh*LCohTerm + Salfa*LSigTerm)/Fo; } if ((FInterfaceData.CalculationOptions.UseEndBearing)) { if ((FResistingMom > 0)) { FEndsectionMom = Math.Abs(FEndsectionMom); } else { FEndsectionMom = -Math.Abs(FEndsectionMom); } LEndsectionMom = FEndsectionMom/Fo; } FResistingMom = FResistingMom*Radius + FTextileMoment + LEndsectionMom + FNailMoment; Fn = FResistingMom/Math.Abs(FDrivingMoment); // Sla ongeitereerd moment, dus bij 1e iteratie op, om te kunnen uitvoeren if (iter == 1) { FResistingMom0 = FResistingMom; } // Stoppen als veiligheidscoefficient oud en nieuw ongeveer gelijk zijn if (Math.Abs(Fn - Fo) < 0.001) { Ready = true; } // Bij fellenius alleen moment evenwicht if ((FInterfaceData.ModelData.CalcType == TCalculationTypeSet.csFellenius)) { Ready = true; } // Teveel iteratie dan stoppen if (iter > Constants.CMaxIter) { Ready = true; } // Als tegenwerkend moment = 0, dan ook stoppen. if ((Math.Abs(FResistingMom) < 0.001) || (Fn < 0.001)) { Ready = true; } // bij fellenius aleen momenten evenwicht dus direkt stoppen if ((FInterfaceData.ModelData.CalcType == TCalculationTypeSet.csFellenius)) { Ready = true; } } while (!(Ready)); } result = Fn; if (Math.Abs(FDrivingMoment) < 0.001) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, LocalizationManager.GetTranslatedText(GetType(), "DrivingMomentTooSmall"))); FCalculationNote = FCalculationNote + "Driving moment too small.@"; } else { if (iter >= Constants.CMaxIter) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, string.Format(LocalizationManager.GetTranslatedText(GetType(), "TooManyIterations"), Constants.CMaxIter))); FCalculationNote = FCalculationNote + "More than max" + ((int) (Constants.CMaxIter)).ToString() + " iterations.@"; } else { if ((Math.Abs(FResistingMom) < 0.001) || (Fn < 0.001)) { result = 1001; LogManager.Add(new LogMessage(LogMessageType.Error, null, LocalizationManager.GetTranslatedText(GetType(), "ResistingMomentTooSmall"))); FCalculationNote = FCalculationNote + "Resisting moment too small.@"; } } } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-10 Best Created // ======================================================================================================================= private string TestCenterpointInGeometry(double AXMid, double AZMid) { string result; double LZSurface; result = ""; LZSurface = MStabDatafunctions.ZBottomAtSurface(AXMid, FInterfaceData.SurfaceLine); if ((LZSurface >= AZMid)) { result = "Center point in geometry"; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-10 Best Created // ======================================================================================================================= private string TestCirkelOnEntryExitPoints() { string result; double XStart; double ZStart; double XEnd; double ZEnd; var LXIntersect = new List(); var LZIntersect = new List(); double LXS1; double LXS2; double LXHalf; double LZHalf; double LZSurface; double LMaxDif; double LDif; int LIntersectionNumber; result = ""; // find intersection points for (int i = 1; i < FInterfaceData.SurfaceLine.Length; i++) { XStart = FInterfaceData.SurfaceLine[i - 1].XCoor; ZStart = FInterfaceData.SurfaceLine[i - 1].ZCoor; XEnd = FInterfaceData.SurfaceLine[i].XCoor; ZEnd = FInterfaceData.SurfaceLine[i].ZCoor; MStabDatafunctions.SnijCirkelLijnstuk(FXCenterPoint, FZCenterPoint, FRadius, XStart, ZStart, XEnd, ZEnd, LXIntersect, LZIntersect); } MStabDatafunctions.SortIntersectionPoints(LZIntersect, LXIntersect); MStabDatafunctions.RemoveDoubleIntersectionPoints(LXIntersect, LZIntersect); // now find an entry and exit point // Get the cirle with biggest difference in z LIntersectionNumber = 1; if ((LXIntersect.Count > 2)) { LMaxDif = Math.Abs(LZIntersect[0] - LZIntersect[1]); LIntersectionNumber = 1; for (int i = 1; i < LXIntersect.Count; i++) { LXS1 = LXIntersect[i - 1]; LXS2 = LXIntersect[i]; LXHalf = 0.5*(LXS1 + LXS2); LZHalf = MStabDatafunctions.ZAtXOnCircle(LXHalf, FXCenterPoint, FZCenterPoint, FRadius); LZSurface = MStabDatafunctions.ZBottomAtSurface(LXHalf, FInterfaceData.SurfaceLine); if ((LZSurface > LZHalf)) { LDif = Math.Abs(LZIntersect[i] - LZIntersect[i - 1]); if ((LDif > LMaxDif)) { LMaxDif = LDif; LIntersectionNumber = i; } } } } if (LXIntersect.Count >= 2) { FxLeftSurface = LXIntersect[LIntersectionNumber - 1]; FXRightSurface = LXIntersect[LIntersectionNumber]; FZLeftSurface = LZIntersect[LIntersectionNumber - 1]; FZRightSurface = LZIntersect[LIntersectionNumber]; } else { result = "No Correct intersections with surface}"; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-10 Best Created // ======================================================================================================================= private string TestEntyExitPointTooHigh(double AZMid, double AZR, double AZL) { string result; result = ""; if ((AZMid < AZR) || (AZMid < AZL)) { result = " Exit point(s) too high "; } return result; } // ======================================================================================================================= // Date ID Modification // 2008-04-10 Best Created // ======================================================================================================================= private string TestIntersectsForbiddenLines(double AXMid, double AZMid, double ARadius, double AXL, double AXR) { string result; int i; bool LFound; LFound = false; for (i = FInterfaceData.ForbiddenLines.GetLowerBound(0); i <= FInterfaceData.ForbiddenLines.GetUpperBound(0); i++) { if ((FInterfaceData.ForbiddenLines[i].CircleIntersectsForbiddenLine(AXMid, AZMid, ARadius, AXL, AXR))) { LFound = true; } } if (LFound) { result = "circle intersects forbidden line"; } else { result = ""; } return result; } // ======================================================================================================================= // Date ID Modification // 2010-04-22 Created // ======================================================================================================================= private bool IsCircelValid() { bool result; string LErrorString; double LXMid; double LZMid; double LRad; LXMid = FXCenterPoint; LZMid = FZCenterPoint; LRad = FRadius; LErrorString = TestCirkelOnEntryExitPoints(); if ((LErrorString == "")) { LErrorString = TestCenterpointInGeometry(LXMid, LZMid); } if ((LErrorString == "")) { LErrorString = TestEntyExitPointTooHigh(LZMid, FZRightSurface, FZLeftSurface); } if ((LErrorString == "")) { LErrorString = TestIntersectsForbiddenLines(LXMid, LZMid, LRad, FxLeftSurface, FXRightSurface); } result = (LErrorString == ""); return result; } // ======================================================================================================================= // Date ID Modification // 2008-03-26 Best Created // ======================================================================================================================= private double GetStabilityfactor() { double result; int LIter; double LSafetyFactor; result = Constants.CFMinStart; FGamWat = FInterfaceData.CurrentWaternet.GammaWater; if ((IsCircelValid())) { LIter = 0; CreateSlices(); // Fill soil,stress data of slices FillSlices(); // calculate driving moments FSoilMoment = DrivingSoilMoment(); FWatermoment = DrivingWaterMoment(); FLoadMoment = UniformLoadMoment() + LineLoadMoment(); FHorQuakeMom = HorBeefMoment(); // Nu aandrijvende momenten en lamel grootheden bekend zijn, // kunnen de tegenwerkende momenten en de stabiliteits factor bepaald worden // speciaal (niet conform bishop) eventueel rekening houden met eindsectie // (* if (Finterfacedata.CalculationOptions.UseEndBearing) then // begin // FEndsectionMom := GetResistingCuMoment(FZCentrePoint, FNSlices, FSlices); // if (Finterfacedata.CalculationOptions.SectionLength > 0) then // FEndsectionMom := FEndsectionMom / 0.5 * // Finterfacedata.CalculationOptions.SectionLength; // end // else *) FEndsectionMom = 0; if ((new ArrayList(new TCalculationTypeSet[] { TCalculationTypeSet.csBishop, TCalculationTypeSet.csFellenius }).Contains(FInterfaceData.ModelData.CalcType)) && (FInterfaceData.CalculationOptions.IsAlternativeStrengthUsed)) { LSafetyFactor = BishopMethodeStudy(ref LIter); } else { LSafetyFactor = BishopMethode(ref LIter); } result = LSafetyFactor; if ((CalculationNote == "")) { CalculationNote = Constants.cSucces; } } return result; } // ======================================================================================================================= // Date ID Modification // 2009-04-21 Created // ======================================================================================================================= } // end TBishopSlipCirkel }