using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStability.Assemblers; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Logging; using NUnit.Framework; namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.DamMacroStability { [TestFixture] public class MStabXmlDocTests { [Test] public void TestCreateMStabXmlDoc() { DamProjectData damProjectData = CreateExampleDamProjectData(); List errorMessages; var stabilityProjectFilename = "testproject"; var soilDbName = "soilmaterials.mdb"; var requiredSafetyFactor = 1.2; var scenario = damProjectData.Dike.Scenarios[0]; scenario.Location.SoilList = damProjectData.Dike.SoilList; scenario.Location.SoildatabaseName = soilDbName; var surfaceLine = scenario.Location.SurfaceLine; var trafficLoad = 10.0; var subSoilScenario = scenario.Location.Segment.SoilProfileProbabilities[0]; subSoilScenario.SoilProfileType = SoilProfileType.ProfileTypeStiFile; // ToDo mStabDesignEmbankment for now set to null XDocument mstabXml = MStabXmlDoc.CreateMStabXmlDoc(stabilityProjectFilename, scenario, subSoilScenario, scenario.RiverLevel, null, surfaceLine, trafficLoad, requiredSafetyFactor, out errorMessages); mstabXml.Save(stabilityProjectFilename + ".xml"); XElement inputElement = (from element in mstabXml.Root.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementNameInput select element).Single(); var attribute = inputElement.Attribute(DamMStabAssembler.XmlAttributeMStabFileName); Assert.IsNotNull(attribute); Assert.AreEqual(stabilityProjectFilename, attribute.Value); attribute = inputElement.Attribute(DamMStabAssembler.XmlAttributeSoilDBName); Assert.IsNotNull(attribute); Assert.AreEqual(soilDbName, attribute.Value); XElement surfaceLineElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementSurfaceLine select element).Single(); var surfacePointElement = surfaceLineElement.Elements().First(); attribute = surfacePointElement.Attributes(DamMStabAssembler.XmlAttributeXCoord).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = surfacePointElement.Attributes(DamMStabAssembler.XmlAttributeYCoord).FirstOrDefault(); Assert.IsNotNull(attribute); XElement characteristicPointsElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementCharacteristicPoints select element).Single(); var characteristicPointElement = characteristicPointsElement.Elements().First(); attribute = characteristicPointElement.Attributes(DamMStabAssembler.XmlAttributeXCoord).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = characteristicPointElement.Attributes(DamMStabAssembler.XmlAttributeYCoord).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = characteristicPointElement.Attributes(DamMStabAssembler.XmlAttributeCharacteristicPointType).FirstOrDefault(); Assert.IsNotNull(attribute); XElement externalPlLinesElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementExternalPLLines select element).Single(); var plLineElement = externalPlLinesElement.Elements().First(); Assert.AreEqual(6, plLineElement.Elements().Count()); attribute = plLineElement.Attributes(DamMStabAssembler.XmlAttributeIsPhreatic).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = plLineElement.Attributes(DamMStabAssembler.XmlAttributeBoundaryLayer).FirstOrDefault(); Assert.IsNotNull(attribute); var plPointElement = plLineElement.Elements().First(); attribute = plPointElement.Attributes(DamMStabAssembler.XmlAttributeXCoord).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = plPointElement.Attributes(DamMStabAssembler.XmlAttributeYCoord).FirstOrDefault(); Assert.IsNotNull(attribute); XElement modelElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementModel select element).Single(); attribute = modelElement.Attributes(DamMStabAssembler.XmlAttributeCalculationModel).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = modelElement.Attributes(DamMStabAssembler.XmlAttributeShearStrength).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = modelElement.Attributes(DamMStabAssembler.XmlAttributeProbabilistic).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = modelElement.Attributes(DamMStabAssembler.XmlAttributeSearchMethod).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = modelElement.Attributes(DamMStabAssembler.XmlAttributeGridPosition).FirstOrDefault(); Assert.IsNotNull(attribute); // ToDo zant To add traffic load, surfaceline needs point with CharacteristicPointType.TrafficLoadInside and point with CharacteristicPointType.TrafficLoadOutside // XElement TrafficLoadElement = (from element in inputElement.Descendants() // where element.Name.LocalName == DamMStabAssembler.XmlElementTrafficLoad // select element).Single(); // attribute = TrafficLoadElement.Attributes(DamMStabAssembler.XmlAttributeXCoordinateAtRiver).FirstOrDefault(); // Assert.IsNotNull(attribute); // attribute = TrafficLoadElement.Attributes(DamMStabAssembler.XmlAttributeXCoordinateAtPolder).FirstOrDefault(); // Assert.IsNotNull(attribute); // attribute = TrafficLoadElement.Attributes(DamMStabAssembler.XmlAttributeLoad).FirstOrDefault(); // Assert.IsNotNull(attribute); XElement calculationOptionsElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementCalculationOptions select element).Single(); attribute = calculationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeMinimalCircleDepth).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = calculationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeZonesType).FirstOrDefault(); Assert.IsNotNull(attribute); XElement geometryCreationOptionsElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementGeometryCreationOptions select element).Single(); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeSoilGeometryType).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeSoilGeometry2DFilename).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeXOffsetSoilGeometry2DOrigin).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeMaterialForDike).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeMaterialForShoulder).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeIsUseOriginalPLLineAssignments).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeIsUseOriginalCalculationOptions).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeIsDrySituation).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributePLLineAssignment).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeIntrusionVerticalWaterPressure).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributePenetrationLength).FirstOrDefault(); Assert.IsNotNull(attribute); attribute = geometryCreationOptionsElement.Attributes(DamMStabAssembler.XmlAttributeIsDesign).FirstOrDefault(); Assert.IsNotNull(attribute); XElement horizontalBalanceAreaElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementHorizontalBalanceArea select element).Single(); Assert.IsTrue(horizontalBalanceAreaElement.HasAttributes); XElement slipCircleElement = (from element in inputElement.Descendants() where element.Name.LocalName == DamMStabAssembler.XmlElementSlipCircleDefinition select element).Single(); Assert.IsTrue(slipCircleElement.HasAttributes); // XElement profileElement = (from element in mstabXml.Root.Descendants() // where element.Name.LocalName == DamMStabAssembler.XmlElementProfile // select element).Single(); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeName); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeXCoordinate); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeYCoordinate); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributePhreaticLevel); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeHasPhreaticLevel); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeBottomLevel); // Assert.IsNotNull(attribute); // attribute = profileElement.Attribute(DamMStabAssembler.XmlAttributeBottomSandLayerID); // Assert.IsNotNull(attribute); // // XElement LayersElement = (from element in profileElement.Descendants() // where element.Name.LocalName == DamMStabAssembler.XmlElementLayers // select element).Single(); // Assert.AreEqual(3, LayersElement.Elements().Count()); // var LayerElement = LayersElement.Elements().First(); // attribute = LayerElement.Attributes(DamMStabAssembler.XmlAttributeID).FirstOrDefault(); // Assert.IsNotNull(attribute); // attribute = LayerElement.Attributes(DamMStabAssembler.XmlAttributeSoilID).FirstOrDefault(); // Assert.IsNotNull(attribute); // attribute = LayerElement.Attributes(DamMStabAssembler.XmlAttributeTopLevel).FirstOrDefault(); // Assert.IsNotNull(attribute); } private DamProjectData CreateExampleDamProjectData() { var damProjectData = new DamProjectData(); FillAnalysisSpecification(damProjectData); damProjectData.Dike = new Dike(); Dike dike = damProjectData.Dike; FillSurfaceLines(dike); FillSoils(dike); FillSoilProfiles1D(dike); FillSoilProfiles2D(dike); FillSegments(damProjectData); FillLocations(dike, damProjectData.Segments); return damProjectData; } private static void FillAnalysisSpecification(DamProjectData damProjectData) { damProjectData.DamProjectType = DamProjectType.Design; damProjectData.DamProjectCalculationSpecification = new DamProjectCalculationSpecification(); DamProjectCalculationSpecification.SelectedAnalysisType = AnalysisType.AdaptGeometry; var calculationSpecification = new DamFailureMechanismeCalculationSpecification(); calculationSpecification.FailureMechanismSystemType = FailureMechanismSystemType.Piping; calculationSpecification.CalculationModel = PipingModelType.Bligh; damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Add(calculationSpecification); } private void FillSoils(Dike dike) { const int soilCount = 3; dike.SoilList = new SoilList(); for (int i = 0; i < soilCount; i++) { Soil soil = new Soil() { Name = String.Format("Soil {0}", i) }; //soil.SoilType = SoilType.Loam; soil.AbovePhreaticLevel = 7 + 0.1 * i; soil.BelowPhreaticLevel = 8 + 0.1 * i; soil.DryUnitWeight = 9 + 0.1 * i; //soil.ShearStrengthModel = ShearStrengthModel.CuMeasured; //soil.Cohesion = 10 + 0.1 * i; //soil.CuBottom = 11 + 0.1 * i; //soil.CuTop = 12 + 0.1 * i; //soil.DilatancyType = DilatancyType.Zero; //soil.FrictionAngle = 13 + 0.1 * i; //soil.Ocr = 14 + 0.1 * i; //soil.PoP = 15 + 0.1 * i; //soil.RatioCuPc = 16 + 0.1 * i; //soil.StrengthIncreaseExponent = 17 + 0.1 * i; //soil.UsePop = true; soil.BeddingAngle = 18 + 0.1 * i; soil.DiameterD70 = 19 + 0.1 * i; soil.DiameterD90 = 20 + 0.1 * i; soil.PermeabKx = 21 + 0.1 * i; soil.WhitesConstant = 22 + 0.1 * i; dike.SoilList.Add(soil); } } private void FillSurfaceLines(Dike dike) { const int surfaceLineCount = 3; for (int i = 0; i < surfaceLineCount; i++) { var surfaceLine = new SurfaceLine2(); surfaceLine.Name = String.Format("SurfaceLine {0}", i); surfaceLine.CharacteristicPoints.Geometry = surfaceLine.Geometry; AddPointsToSurfaceLines(surfaceLine); surfaceLine.Geometry.SyncCalcPoints(); dike.SurfaceLines2.Add(surfaceLine); } } private void AddPointsToSurfaceLines(SurfaceLine2 surfaceLine) { AddPointToSurfaceLine(surfaceLine, 0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); AddPointToSurfaceLine(surfaceLine, 2.0, 0.5, CharacteristicPointType.None); AddPointToSurfaceLine(surfaceLine, 4.0, 0.0, CharacteristicPointType.DikeToeAtRiver); AddPointToSurfaceLine(surfaceLine, 9.0, 5.0, CharacteristicPointType.DikeTopAtRiver); AddPointToSurfaceLine(surfaceLine, 10.0, 5.2, CharacteristicPointType.None); AddPointToSurfaceLine(surfaceLine, 13.0, 5.4, CharacteristicPointType.DikeTopAtPolder); AddPointToSurfaceLine(surfaceLine, 18.0, 1.0, CharacteristicPointType.DikeToeAtPolder); AddPointToSurfaceLine(surfaceLine, 24.0, 1.0, CharacteristicPointType.SurfaceLevelInside); } private void AddPointToSurfaceLine(SurfaceLine2 surfaceLine, double xCoordinate, double zCoordinate, CharacteristicPointType characteristicPointType) { var geometryPoint = new GeometryPoint() { X = xCoordinate, Y = 0.0, Z = zCoordinate, }; surfaceLine.AddCharacteristicPoint(geometryPoint, characteristicPointType); } private static void FillLocations(Dike dike, IList segments) { const int locationCount = 3; for (int i = 0; i < locationCount; i++) { var location = new Data.General.Location(); location.Name = "Location " + (i + 1).ToString(); location.ModelParametersForPLLines.PLLineCreationMethod = (PLLineCreationMethod)i; location.IntrusionVerticalWaterPressure = (IntrusionVerticalWaterPressureType)i; location.PolderLevel = 1.0 * i + 0.11; location.ModelParametersForPLLines.DampingFactorPL4 = 1.0 * i + 0.12; location.ModelParametersForPLLines.DampingFactorPL3 = 1.0 * i + 0.13; location.ModelParametersForPLLines.PenetrationLength = 1.0 * i + 0.14; location.PlLineOffsetBelowDikeCrestMiddle = 1.0 * i + 0.15; location.UsePlLineOffsetFactorBelowShoulderCrest = true; location.PlLineOffsetFactorBelowShoulderCrest = 1.0 * i + 0.16; location.PlLineOffsetDryBelowDikeCrestMiddle = 1.0 * i + 0.17; location.UsePlLineOffsetDryFactorBelowShoulderCrest = true; location.PlLineOffsetDryFactorBelowShoulderCrest = 1.0 * i + 0.18; location.SlopeDampingPiezometricHeightPolderSide = 1.0 * i + 0.19; location.PlLineOffsetBelowDikeTopAtRiver = 1.0 * i + 0.20; location.PlLineOffsetBelowDikeTopAtPolder = 1.0 * i + 0.21; location.PlLineOffsetBelowShoulderBaseInside = 1.0 * i + 0.22; location.PlLineOffsetBelowDikeToeAtPolder = 1.0 * i + 0.23; location.HeadPl2 = 1.0 * i + 0.24; location.HeadPl3 = 1.0 * i + 0.25; location.HeadPl4 = 1.0 * i + 0.21; location.SurfaceLine = dike.SurfaceLines2[i]; location.Segment = segments[i % 2]; // alternate between the 2 available segments for (int j = 0; j < 3; j++) { var designScenario = FillDesignScenario(i, j); designScenario.Location = location; location.Scenarios.Add(designScenario); } dike.Locations.Add(location); } } private static void FillSoilProfiles1D(Dike dike) { dike.SoilProfiles = new List(); const int profilesCount = 2; for (int i = 0; i < profilesCount; i++) { var profile = new SoilProfile1D(); profile.Name = "Profile1D " + (i + 1).ToString(); profile.BottomLevel = -21.12 * (i + 1); const int layerCount = 3; for (int j = 0; j < layerCount; j++) { var layer = new SoilLayer1D { Name = "Layer" + (j + 1).ToString(), Soil = dike.SoilList.Soils[j], TopLevel = 1 * -j }; if (j < 2) { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic; layer.IsAquifer = false; } else { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic; layer.IsAquifer = true; } profile.Layers.Add(layer); } dike.SoilProfiles.Add(profile); } } private static DesignScenario FillDesignScenario(int locationIndex, int scenarioIndex) { // The parameter factor is used to create unique data for the design scenario int factor = (locationIndex + 1) * (scenarioIndex + 1); var designScenario = new DesignScenario(); designScenario.LocationScenarioID = scenarioIndex.ToString(); designScenario.RiverLevel = 1.0 * factor + 0.51; designScenario.RiverLevelLow = 1.0 * factor + 0.52; designScenario.DikeTableHeight = 1.0 * factor + 0.53; designScenario.PlLineOffsetBelowDikeTopAtRiver = 1.0 * factor + 0.54; designScenario.PlLineOffsetBelowDikeTopAtPolder = 1.0 * factor + 0.55; designScenario.PlLineOffsetBelowShoulderBaseInside = 1.0 * factor + 0.56; designScenario.PlLineOffsetBelowDikeToeAtPolder = 1.0 * factor + 0.57; designScenario.PlLineOffsetBelowDikeCrestMiddle = 1.0 * factor + 0.58; designScenario.UsePlLineOffsetBelowDikeCrestMiddle = true; designScenario.PlLineOffsetFactorBelowShoulderCrest = 1.0 * factor + 0.59; designScenario.UsePlLineOffsetFactorBelowShoulderCrest = true; designScenario.HeadPl3 = 1.0 * factor + 0.60; designScenario.HeadPl4 = 1.0 * factor + 0.61; designScenario.UpliftCriterionStability = 1.0 * factor + 0.62; designScenario.UpliftCriterionPiping = 1.0 * factor + 0.63; designScenario.RequiredSafetyFactorStabilityInnerSlope = 1.0 * factor + 0.64; designScenario.RequiredSafetyFactorStabilityOuterSlope = 1.0 * factor + 0.65; designScenario.RequiredSafetyFactorPiping = 1.0 * factor + 0.66; return designScenario; } private static void FillSoilProfiles2D(Dike dike) { dike.SoilProfiles2D = new List(); const int profilesCount = 2; for (int i = 0; i < profilesCount; i++) { var profile = new SoilProfile2D { Name = "Profile2D " + (i + 1).ToString() }; const int preConCount = 2; for (int j = 0; j < preConCount; j++) { var preCon = new PreConsolidationStress { Name = "Precon " + (j + 1).ToString(), StressValue = 3.33 * (i + 1) * (j + 1), X = 12.3 * (i + 1) * (j + 1), Z = 0.3 * (-i - 1) * (j + 1) }; profile.PreconsolidationStresses.Add(preCon); } const int layerCount = 3; for (int j = 0; j < layerCount; j++) { var layer = new SoilLayer2D { Name = "Layer" + (j + 1).ToString(), Soil = dike.SoilList.Soils[j] }; if (j < 2) { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic; layer.IsAquifer = false; } else { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic; layer.IsAquifer = true; } layer.GeometrySurface = new GeometrySurface(); var outerLoop = new GeometryLoop(); outerLoop.Points.Add((new GeometryPoint(0, 0))); outerLoop.Points.Add((new GeometryPoint(0, 10))); outerLoop.Points.Add((new GeometryPoint(10, 10))); layer.GeometrySurface.OuterLoop = outerLoop; var innerloop = new GeometryLoop(); innerloop.Points.Add((new GeometryPoint(1, 1))); innerloop.Points.Add((new GeometryPoint(1, 9))); innerloop.Points.Add((new GeometryPoint(9, 9))); layer.GeometrySurface.InnerLoops.Add(innerloop); profile.Surfaces.Add(layer); } dike.SoilProfiles2D.Add(profile); } } private static void FillSegments(DamProjectData damProjectData) { var segmentCount = 2; for (int i = 0; i < segmentCount; i++) { var segment = new Segment(); segment.Name = "Segment " + i.ToString(); var soilProfileProbability = new SoilGeometryProbability(); if (i == 0) { soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.StabilityInside; soilProfileProbability.SoilProfile2DName = "Profile2D " + (i + 1).ToString(); // soilProfileProbability.SoilProfile2D = FillDamFromXmlInput.FindSoilProfile2DByName(damProjectData.Dike.SoilProfiles2D, // soilProfileProbability.SoilProfile2DName); soilProfileProbability.SoilProfileType = SoilProfileType.ProfileType2D; } else { soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.Piping; soilProfileProbability.SoilProfile1DName = "Profile1D " + (i + 1).ToString(); // soilProfileProbability.SoilProfile1D = FillDamFromXmlInput.FindSoilProfile1DByName(damProjectData.Dike.SoilProfiles, // soilProfileProbability.SoilProfile1DName); soilProfileProbability.SoilProfileType = SoilProfileType.ProfileType1D; } soilProfileProbability.Probability = 0.003 * (i + 1); segment.SoilProfileProbabilities.Add(soilProfileProbability); damProjectData.Segments.Add(segment); } } } }