using System; using System.Collections.Generic; using System.IO; using System.Xml.Linq; using Deltares.DamEngine.Calculators.General; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability.Assemblers; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Logging; namespace Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability { public static class MStabXmlDoc { /// /// Create XML definition for Stability calculation /// /// /// /// /// /// /// /// /// /// /// /// public static XDocument CreateMStabXmlDoc(string mstabProjectFilename, DesignScenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName, double riverLevel, MStabDesignEmbankment mstabDesignEmbankment, SurfaceLine2 surfaceLine, double trafficLoad, double requiredSafetyFactor, out List errorMessages) { errorMessages = new List(); SoilProfile1D profile1D = soilProfile; ConsistencyCheck(scenario, profile1D, soilGeometry2DName); FailureMechanismeParamatersMStab failureMechanismeParamatersMStab = new FailureMechanismeParamatersMStab(); failureMechanismeParamatersMStab.Location = scenario.Location; if (profile1D != null) { failureMechanismeParamatersMStab.SoilProfile = profile1D; // 1d-geometry failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilProfileType = SoilProfileType.ProfileType1D; } else { // 2d-geometry failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilProfileType = SoilProfileType.ProfileType2D; } // Geometry Creation Options failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.SoilGeometry2DFilename = soilGeometry2DName; failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForDike = scenario.Location.DikeEmbankmentMaterial; failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.MaterialForShoulder = scenario.Location.ShoulderEmbankmentMaterial; failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsUseOriginalPLLineAssignments = scenario.Location.IsUseOriginalPLLineAssignments; failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IsDesign = (mstabDesignEmbankment != null); failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.XOffsetSoilGeometry2DOrigin = -scenario.Location.XSoilGeometry2DOrigin; //ToDo zant PLLineCreationMethod is no longer property of Location // failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PLLineAssignment = // CalculationHelper.PLLineCreationMethod2PLLineAssignment(scenario.Location.PLLineCreationMethod); failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.IntrusionVerticalWaterPressureType = scenario.Location.IntrusionVerticalWaterPressure.Value; //ToDo zant PenetrationLength is no longer property of Location // failureMechanismeParamatersMStab.MStabParameters.GeometryCreationOptions.PenetrationLength = // scenario.Location.PenetrationLength; // End of Geometry Creation Options // Design options failureMechanismeParamatersMStab.Design = mstabDesignEmbankment; failureMechanismeParamatersMStab.SurfaceLine = surfaceLine; failureMechanismeParamatersMStab.RiverLevel = riverLevel; // scenario.RiverLevel; failureMechanismeParamatersMStab.DikeTableHeight = scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? 0; failureMechanismeParamatersMStab.TrafficLoad = trafficLoad; // Horizontal balance; TODO: Combine with code in StabilityCalculation if (failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.HorizontalBalance) { if (profile1D == null) { throw new DamFailureMechanismeCalculatorException( "Model horizontal balance does not support 2d-geometries"); } failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea = new HorizontalBalanceArea(); failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XLeft = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.XRight = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop = riverLevel; failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom = profile1D.InBetweenAquiferLayer != null ? profile1D.InBetweenAquiferLayer.TopLevel : profile1D.BottomAquiferLayer.TopLevel; int planeCount = (int)(Math.Round((failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YTop - failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.YBottom) / 0.25)); failureMechanismeParamatersMStab.MStabParameters.HorizontalBalanceArea.PlaneCount = Math.Min(planeCount, 50); } // Zonestype is ZoneAreas; TODO: Combine with code in StabilityCalculation var dikeTopAtPolder = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); if ( failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals( MStabZonesType.ZoneAreas)) { double? dikeTableHeight = scenario.DikeTableHeight ?? surfaceLine.GetDefaultDikeTableHeight() ?? null; if (!dikeTableHeight.HasValue) throw new DamFailureMechanismeCalculatorException("Surface line has no dike table height."); failureMechanismeParamatersMStab.MStabParameters.ZoneAreas = new MStabZoneAreas { DikeTableHeight = dikeTableHeight.Value, DikeTableWidth = scenario.Location.ZoneAreaRestSlopeCrestWidth, SafetyFactorZone1A = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? requiredSafetyFactor, SafetyFactorZone1B = scenario.ModelFactors.RequiredSafetyFactorStabilityInnerSlope ?? requiredSafetyFactor, XCoordinateDikeTopAtPolder = dikeTopAtPolder.X, XCoordinateDikeTopAtRiver = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X, XCoordinateStartRestProfile = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).X }; } //ToDo zant Tmp disabled // if (failureMechanismeParamatersMStab.MStabParameters.CalculationOptions.ZonesType.Equals(MStabZonesType.ForbiddenZone)) // { // CreateForbiddenZone(scenario, surfaceLine); // } // Make sure riverlevel is correct with respect to surfaceline double riverLevelLow = double.NaN; if (failureMechanismeParamatersMStab.MStabParameters.GridPosition == MStabGridPosition.Left && scenario.RiverLevelLow.HasValue) { riverLevelLow = scenario.RiverLevelLow.Value; } double? riverLevelHigh = riverLevel; var surfaceLevelOutside = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelOutside); if (riverLevelHigh < surfaceLevelOutside.Z) { var riverLevelHighIsBelowSurfaceLevelOutside = Path.GetFileName(mstabProjectFilename) + ": " + //ToDo zant // LocalizationManager.GetTranslatedText(this.GetType(), // "riverLevelHighIsBelowSurfaceLevelOutside"); "riverLevelHighIsBelowSurfaceLevelOutside"; LogMessage logMessage = new LogMessage(LogMessageType.Warning, null, String.Format(riverLevelHighIsBelowSurfaceLevelOutside, riverLevelHigh, surfaceLevelOutside.Z)); errorMessages.Add(logMessage); } var currentSurfaceLine = scenario.GetMostRecentSurfaceLine(soilProfile, Path.GetFileName(soilGeometry2DName)); if (currentSurfaceLine == null) { currentSurfaceLine = surfaceLine; } //ToDo zant CreateAllPLLines was changed // failureMechanismeParamatersMStab.PLLines = CalculationHelper.CreateAllPLLines(scenario.Location, currentSurfaceLine, // soilProfile, soilGeometry2DName, riverLevelHigh.Value, riverLevelLow); // Slip circle definition for Uplift Van; TODO: Combine with code in StabilityCalculation if (failureMechanismeParamatersMStab.MStabParameters.Model == MStabModelType.UpliftVan) { // Determine right side of slip plane grid (right grid) // This is the location with the lowest uplift factor or, if present, the second NWO point var upliftLocationAndResult = CalculationHelper.GetLocationWithLowestUpliftFactor(currentSurfaceLine, soilProfile, soilGeometry2DName, failureMechanismeParamatersMStab.PLLines, scenario.Location); double upliftCriterion = scenario.GetUpliftCriterionStability(scenario.Location.ModelFactors.UpliftCriterionStability); bool isUplift = !(upliftLocationAndResult == null) && (upliftLocationAndResult.UpliftFactor < upliftCriterion); double xCoordinateLastUpliftPoint = isUplift ? upliftLocationAndResult.X : currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X; var nonWaterRetaining2 = currentSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.NonWaterRetainingObjectPoint2); if (nonWaterRetaining2 != null) { xCoordinateLastUpliftPoint = nonWaterRetaining2.X; } failureMechanismeParamatersMStab.MStabParameters.SlipCircleDefinition.XCoordinateLastUpliftPoint = xCoordinateLastUpliftPoint; } failureMechanismeParamatersMStab.MStabParameters.ProjectFileName = mstabProjectFilename; failureMechanismeParamatersMStab.MStabParameters.SoilDatabaseName = scenario.Location.SoildatabaseName; if (!failureMechanismeParamatersMStab.IsComplete) { throw new Exception("Not all required data is available"); } DamMStabAssembler assembler = new DamMStabAssembler(); XDocument mstabXML = assembler.CreateDataTransferObject(failureMechanismeParamatersMStab); return mstabXML; } /// /// /// /// /// /// public static void ConsistencyCheck(DesignScenario scenario, SoilProfile1D soilProfile, string soilGeometry2DName) { if (soilProfile != null) { if (soilProfile.BottomAquiferLayer == null) { throw new DamFailureMechanismeCalculatorException( String.Format("Soilprofile '{0}' does not contain aquifer layers.", soilProfile.Name)); } } } } }