using System; using System.Collections.Generic; using System.Runtime.Serialization; using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.Consolidation; using Deltares.Geotechnics.Soils; using Deltares.Mathematics; using Deltares.Stability.Calculation.Inner; using Deltares.Standard; using Deltares.Standard.Extensions; using Deltares.Standard.Language; #if DELPHI using Dump; using slice; using ProbabilisticTypes; #else #endif namespace Deltares.Stability.Calculation { [Serializable] public class MStabCalculationResultsException : Exception { // // For guidelines regarding the creation of new exception types, see // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp // and // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp // public MStabCalculationResultsException() {} public MStabCalculationResultsException(string message) : base(message) {} public MStabCalculationResultsException(string message, Exception inner) : base(message, inner) {} protected MStabCalculationResultsException( SerializationInfo info, StreamingContext context) : base(info, context) {} } internal static class ConvertDumpData2CalculationResults { public static SlidingModel Convert(TDump dumpdata, SoilProfile2D soilProfile) { if (dumpdata == null) { throw new MStabCalculationResultsException("dumpdata object not instantiated"); } var slipModel = new SlidingModel(); if (dumpdata.Circles.Count > 0) { GetMinimumCircleResult(dumpdata, slipModel.SafetyZones); } if (dumpdata.CentrePoints.Count > 0) { GetSlidingCircles(dumpdata, slipModel); } if (dumpdata.SpencerPlanes.Count > 0) { GetMinimumSpencerResult(dumpdata, slipModel.SafetyZones); } if (dumpdata.UpliftCircles.Count > 0) { GetUpliftResult(dumpdata, slipModel.SafetyZones); } if (dumpdata.Horizontalbalance.Count > 0) { GetHorizontalBalanceResult(dumpdata, slipModel.SafetyZones); } slipModel.RestProfile.Points.Clear(); foreach (var point in dumpdata.RestProfile) { slipModel.RestProfile.Points.Add(new GeometryPoint(point.XCoor, 0, point.YCoor)); } slipModel.RestProfile.Points.Sort(); slipModel.SafeProfile.Points.Clear(); foreach (var point in dumpdata.SafeProfile) { slipModel.SafeProfile.Points.Add(new GeometryPoint(point.XCoor, 0, point.YCoor)); } slipModel.SafeProfile.Points.Sort(); if (dumpdata.ProbResults.Count > 0) { GetProbabilisticResults(dumpdata, slipModel.ProbabilisticResults, soilProfile); } return slipModel; } private static void GetProbabilisticResults(TDump dumpdata, List results, SoilProfile2D soilProfile) { results.Clear(); #if DELPHI for (int i = 0; i < dumpdata.ProbResults.Length; i++) #else for (int i = 0; i < dumpdata.ProbResults.Count; i++) #endif { var result = new ProbabilisticResult(); result.Beta = dumpdata.ProbResults[i].beta; result.Failure = dumpdata.ProbResults[i].Faalkans; result.WaterLevel = dumpdata.ProbResults[i].WaterLevel; result.WaterLevelName = dumpdata.ProbResults[i].WaterlevelName; foreach (var soilContribution in dumpdata.ProbResults[i].SoilContributions) { if (soilContribution.IndicationArray != null) { foreach (var propertyContribution in soilContribution.IndicationArray) { if (propertyContribution.ContributionName != null) { string key = soilContribution.SoilName + " " + propertyContribution.ContributionName; if (!result.InfluenceFactors.ContainsKey(key)) { result.InfluenceFactors.Add(key, propertyContribution.ContributionValue); } } } } } foreach (var degreeOfConsolidationContribution in dumpdata.ProbResults[i].DegreeofConsolidation) { if (Math.Abs(degreeOfConsolidationContribution.ContributionValue) > 1E-8) { string fromLayer = soilProfile.Surfaces[degreeOfConsolidationContribution.FromLayer].Name; string toLayer = soilProfile.Surfaces[degreeOfConsolidationContribution.InLayer].Name; string key = LocalizationManager.GetTranslatedText(typeof(DegreeofConsolidationMatrix), "DegreeOfConsolidation") + " " + fromLayer + "->" + toLayer; if (!result.InfluenceFactors.ContainsKey(key)) { result.InfluenceFactors.Add(key, degreeOfConsolidationContribution.ContributionValue); } } } if (Math.Abs(dumpdata.ProbResults[i].ModelFactor.ContributionValue) > 1E-8) { result.InfluenceFactors.Add(dumpdata.ProbResults[i].ModelFactor.ContributionName, dumpdata.ProbResults[i].ModelFactor.ContributionValue); } results.Add(result); } } private static void GetSlidingCircles(TDump dumpdata, SlidingModel slipModel) { #if DELPHI for (int circleIndex = 0; circleIndex < dumpdata.CentrePoints.Length; circleIndex++) #else for (int circleIndex = 0; circleIndex < dumpdata.CentrePoints.Count; circleIndex++) #endif { var slidingCircle = new SlidingCircle(); if (dumpdata.CentrePoints[circleIndex].MinFactor != 1001) { dumpdata.CentrePoints[circleIndex].DetermineMinimumSafetyFactor(); slidingCircle.Radius = dumpdata.CentrePoints[circleIndex].RadMinFactor; slidingCircle.Center.X = dumpdata.CentrePoints[circleIndex].XMid; slidingCircle.Center.Y = dumpdata.CentrePoints[circleIndex].ZMid; slidingCircle.SafetyFactor = dumpdata.CentrePoints[circleIndex].MinFactor; slidingCircle.Slices.Clear(); if (slidingCircle.SafetyFactor < 9999) { slipModel.SlidingCurves.Add(slidingCircle); } } } } private static void GetSlidingCircles(TDump dumpdata, ref List slidingCircles) {} /// /// Get the minimum safety factor along with the slipplane and slices. /// With the option safetyzone it is possible to have several minimum safety factors /// /// /// private static void GetMinimumSpencerResult(TDump dumpdata, List safetyZones) { #if DELPHI for (int planeIndex = 0; planeIndex < dumpdata.SpencerPlanes.Length; planeIndex++) #else for (int planeIndex = 0; planeIndex < dumpdata.SpencerPlanes.Count; planeIndex++) #endif { var zone = new Zone(); var slidingPlane = new SlidingPlane(); slidingPlane.SafetyFactor = dumpdata.SpencerPlanes[planeIndex].StabilityFactor; GetSliceResult(dumpdata.SpencerPlanes[planeIndex].GetSlices(), slidingPlane); zone.ZoneId = dumpdata.SpencerPlanes[planeIndex].ZoneNr; zone.MinimumSafetyCurve = slidingPlane; zone.SubZones = dumpdata.SubZones; safetyZones.Add(zone); } } /// /// Get the minimum safety factor along with the slipplane and slices. /// With the option safetyzone it is possible to have several minimum safety factors /// /// /// private static void GetHorizontalBalanceResult(TDump dumpdata, List safetyZones) { #if DELPHI for (int planeIndex = 0; planeIndex < dumpdata.SpencerPlanes.Length; planeIndex++) #else for (int planeIndex = 0; planeIndex < dumpdata.Horizontalbalance.Count; planeIndex++) #endif { var zone = new Zone(); var slidingPlane = new SlidingHorizontalPlane(); slidingPlane.SafetyFactor = dumpdata.Horizontalbalance[planeIndex].MinStability; TSingleHorizontalBalanceResult result = dumpdata.Horizontalbalance[planeIndex].AllResults[0]; slidingPlane.XLeft = result.XLeft; slidingPlane.XRight = result.XRight; slidingPlane.Z = result.ZTangent; slidingPlane.HorizontalForceLeft = result.HorizontalForceleft; slidingPlane.HorizontalForceRight = result.HorizontalForceRight; slidingPlane.ResistingForce = result.Resisting; GetSliceResult(dumpdata.Horizontalbalance[planeIndex].Slices, slidingPlane); zone.ZoneId = planeIndex + 1; zone.MinimumSafetyCurve = slidingPlane; zone.SubZones = dumpdata.SubZones; safetyZones.Add(zone); } } /// /// Get the minimum safety factor along with the slipplane and slices. /// With the option safetyzone it is possible to have several minimum safety factors /// /// /// private static void GetUpliftResult(TDump dumpdata, List safetyZones) { #if DELPHI for (int upliftIndex = 0; upliftIndex < dumpdata.UpliftCircles.Length; upliftIndex++) #else for (int upliftIndex = 0; upliftIndex < dumpdata.UpliftCircles.Count; upliftIndex++) #endif { var zone = new Zone(); var upliftCircle = new SlidingDualCircle { SafetyFactor = dumpdata.UpliftCircles[upliftIndex].StabilityFactor, ActiveCircle = new Point2D(dumpdata.UpliftCircles[upliftIndex].XCenterPoint, dumpdata.UpliftCircles[upliftIndex].ZCenterPoint), PassiveCircle = new Point2D(dumpdata.UpliftCircles[upliftIndex].XPassiveCentre, dumpdata.UpliftCircles[upliftIndex].ZPassiveCentre), TangentLine = dumpdata.UpliftCircles[upliftIndex].StabilityFactor, // The following output are not available in the dumpfile: ActiveForce0 = dumpdata.UpliftCircles[upliftIndex].ActiveForce0, PassiveForce0 = dumpdata.UpliftCircles[upliftIndex].PassiveForce0, HorizontalForce0 = dumpdata.UpliftCircles[upliftIndex].HorizontalForce0, ActiveForce = dumpdata.UpliftCircles[upliftIndex].ActiveForce, PassiveForce = dumpdata.UpliftCircles[upliftIndex].PassiveForce, HorizontalForce = dumpdata.UpliftCircles[upliftIndex].HorizontalForce, DrivingMomentActive = dumpdata.UpliftCircles[upliftIndex].ActiveDMoment, ResistingMomentActive = dumpdata.UpliftCircles[upliftIndex].ActiveRMoment, DrivingMomentPassive = dumpdata.UpliftCircles[upliftIndex].PassiveDMoment, ResistingMomentPassive = dumpdata.UpliftCircles[upliftIndex].PassiveRMoment, PassiveRadius = dumpdata.UpliftCircles[upliftIndex].PassiveRadius, ActiveRadius = dumpdata.UpliftCircles[upliftIndex].Radius } ; GetSliceResult(dumpdata.UpliftCircles[upliftIndex].GetSlices(), upliftCircle); zone.ZoneId = dumpdata.UpliftCircles[upliftIndex].ZoneNr; zone.MinimumSafetyCurve = upliftCircle; zone.SubZones = dumpdata.SubZones; safetyZones.Add(zone); } } /// /// Get the minimum safety factor along with the slipcircle and slices. /// With the option safetyzone it is possible to have several minimum safety factors /// /// /// private static void GetMinimumCircleResult(TDump dumpdata, List safetyZones) { #if DELPHI for (int circleIndex = 0; circleIndex < dumpdata.Circles.Length; circleIndex++) #else for (int circleIndex = 0; circleIndex < dumpdata.Circles.Count; circleIndex++) #endif { if (dumpdata.Circles[circleIndex].StabilityFactor != 1001) { var zone = new Zone(); var slidingcircle = new SlidingCircle(); slidingcircle.Radius = dumpdata.Circles[circleIndex].Radius; slidingcircle.Center.X = dumpdata.Circles[circleIndex].XCenterPoint; slidingcircle.Center.Y = dumpdata.Circles[circleIndex].ZCenterPoint; slidingcircle.SafetyFactor = dumpdata.Circles[circleIndex].StabilityFactor; slidingcircle.DrivingMoment = dumpdata.Circles[circleIndex].DrivingMoment; slidingcircle.EndSectionMoment = dumpdata.Circles[circleIndex].EndsectionMom; slidingcircle.HorizontalQuakeMoment = dumpdata.Circles[circleIndex].HorQuakeMom; slidingcircle.LoadMoment = dumpdata.Circles[circleIndex].LoadMoment; slidingcircle.NailMoment = dumpdata.Circles[circleIndex].NailMoment; slidingcircle.ResistingMoment = dumpdata.Circles[circleIndex].ResistingMom; slidingcircle.ResistingMomentUniterated = dumpdata.Circles[circleIndex].ResistingMomUniterated; slidingcircle.SoilMoment = dumpdata.Circles[circleIndex].SoilMoment; slidingcircle.TextileMoment = dumpdata.Circles[circleIndex].TextileMoment; slidingcircle.WaterMoment = dumpdata.Circles[circleIndex].Watermoment; GetGeotextileResults(dumpdata.Circles[circleIndex].GeotextileResults, slidingcircle); GetSliceResult(dumpdata.Circles[circleIndex].GetSlices(), slidingcircle); if (dumpdata.ProbResults.Count > 0) { zone.SpecialName = dumpdata.ProbResults[circleIndex].WaterlevelName; } zone.ZoneId = dumpdata.Circles[circleIndex].ZoneNr; zone.MinimumSafetyCurve = slidingcircle; zone.SubZones = dumpdata.SubZones; safetyZones.Add(zone); } } } /// /// map geotextile data from TGeotextiles to Geotextile /// /// /// private static void GetGeotextileResults(List geotextileResults, SlidingCurve slidingCurve) { foreach (var geotextileResult in geotextileResults) { var result = new GeotextileResults(); result.ResistingMoment = geotextileResult.Moment; result.MobilizedTensile = geotextileResult.MobilizedEmbTensileStr; result.EmbeddingLength = geotextileResult.EmbeddingLength; if (geotextileResult.IntersectionPoints.Count > 1) { result.IntersectionX = geotextileResult.IntersectionPoints[0].XCoor; result.IntersectionZ = geotextileResult.IntersectionPoints[0].ZCoor; result.Intersection2X = geotextileResult.IntersectionPoints[1].XCoor; result.Intersection2Z = geotextileResult.IntersectionPoints[1].ZCoor; } else { result.IntersectionX = geotextileResult.IntersectionPoints[0].XCoor; result.IntersectionZ = geotextileResult.IntersectionPoints[0].ZCoor; } slidingCurve.GeotextileResults.Add(result); } } private static void GetSliceResult(Tslice[] calculationSlice, SlidingCurve slidingCurve) { if (calculationSlice != null) { for (int sliceIndex = 0; sliceIndex < calculationSlice.Length; sliceIndex++) { var resultSlice = new Slice(); resultSlice.Index = sliceIndex; SetSliceOrientation(calculationSlice, sliceIndex, resultSlice); SetSliceProperties(calculationSlice, sliceIndex, resultSlice); slidingCurve.Slices.Add(resultSlice); } } } private static void SetSliceProperties(Tslice[] calculationSlice, int sliceIndex, Slice resultSlice) { resultSlice.Cohesion = calculationSlice[sliceIndex].CohBottom; resultSlice.Phi = calculationSlice[sliceIndex].PhiBottom; resultSlice.ShearStress = calculationSlice[sliceIndex].ShearStress; resultSlice.TotalPorePressure = calculationSlice[sliceIndex].TotalPore; resultSlice.Weight = calculationSlice[sliceIndex].Weight; resultSlice.EffectiveStress = calculationSlice[sliceIndex].EffectiveStress; resultSlice.TotalStress = calculationSlice[sliceIndex].TotalStress; resultSlice.HydrostaticPorePressure = calculationSlice[sliceIndex].HydrostaticPore; resultSlice.PiezometricPorePressure = calculationSlice[sliceIndex].PnLinePore; resultSlice.DegreeofConsolidationPorePressure = calculationSlice[sliceIndex].AanpasPore; resultSlice.ExcessPorePressure = calculationSlice[sliceIndex].ExcessPore; resultSlice.VPoreOnSurface = calculationSlice[sliceIndex].VPoreOnSurface; resultSlice.HPoreOnSurface = calculationSlice[sliceIndex].HPoreOnSurface; resultSlice.PoreOnSurface = calculationSlice[sliceIndex].PoreOnSurface; resultSlice.ExternalLoad = calculationSlice[sliceIndex].ExternalLoad; resultSlice.SigmaSoilQuake = calculationSlice[sliceIndex].SigmaSoilQuake; resultSlice.NormalStress = calculationSlice[sliceIndex].NormalStress; resultSlice.LeftForce = calculationSlice[sliceIndex].LeftForce; resultSlice.RightForce = calculationSlice[sliceIndex].RightForce; resultSlice.LeftForceAngle = calculationSlice[sliceIndex].LeftForceAngle; resultSlice.RightForceAngle = calculationSlice[sliceIndex].RightForceAngle; } private static void SetSliceOrientation(Tslice[] calculationSlice, int sliceIndex, Slice resultSlice) { resultSlice.TopLeft.X = calculationSlice[sliceIndex].xLeft; resultSlice.TopLeft.Y = calculationSlice[sliceIndex].ZTopLeft; resultSlice.TopRight.X = calculationSlice[sliceIndex].xRight; resultSlice.TopRight.Y = calculationSlice[sliceIndex].ZTopRight; resultSlice.BottomLeft.X = calculationSlice[sliceIndex].xLeft; resultSlice.BottomLeft.Y = calculationSlice[sliceIndex].ZBottomLeft; resultSlice.BottomRight.X = calculationSlice[sliceIndex].xRight; resultSlice.BottomRight.Y = calculationSlice[sliceIndex].ZBottomRight; } } }