// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of the application DAM - UI. // // DAM - UI is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using Deltares.Dam.Data; using Deltares.Dam.Data.DamEngineIo; using Deltares.DamEngine.Io; using Deltares.DamEngine.Io.XmlInput; using Deltares.Geometry; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Standard.EventPublisher; using KellermanSoftware.CompareNetObjects; using NUnit.Framework; using Location = Deltares.Dam.Data.Location; using Segment = Deltares.Dam.Data.Segment; using Soil = Deltares.Geotechnics.Soils.Soil; using SoilProfile1D = Deltares.Geotechnics.Soils.SoilProfile1D; namespace Deltares.Dam.Tests.DamEngineIo { [TestFixture] public class FillXmlInputFromDamUiTests { const AnalysisType expectedAnalysisType = AnalysisType.AdaptGeometry; const AnalysisType notExpectedAnalysisType = AnalysisType.NoAdaption; [Test] public void CanWriteAndReadDamProjectDataToXmlFile() { const string inputFilename = "InputFile.xml"; DamProjectData expectedDamProjectData = CreateExampleDamProjectData(); // Write input file Input input = FillXmlInputFromDamUi.CreateInput(expectedDamProjectData); DamXmlSerialization.SaveInputAsXmlFile(inputFilename, input); // Init static that is to be loaded with not expected value DamProjectCalculationSpecification.SelectedAnalysisType = notExpectedAnalysisType; // Load input file input = DamXmlSerialization.LoadInputFromXmlFile(inputFilename); DamProjectData actualDamProjectData = FillDamUiFromXmlInput.CreateDamProjectData(input); CompareDamProjectData(actualDamProjectData, expectedDamProjectData); } [Test] public void CanWriteAndReadDamProjectDataToXmlString() { DataEventPublisher.IsDataEventPublishStopped = true; DamProjectData expectedDamProjectData = CreateExampleDamProjectData(); // Write input string Input input = FillXmlInputFromDamUi.CreateInput(expectedDamProjectData); string inputXml = DamXmlSerialization.SaveInputAsXmlString(input); // Init static that is to be loaded with not expected value DamProjectCalculationSpecification.SelectedAnalysisType = notExpectedAnalysisType; // Load input string input = DamXmlSerialization.LoadInputFromXmlString(inputXml); DamProjectData actualDamProjectData = FillDamUiFromXmlInput.CreateDamProjectData(input); CompareDamProjectData(actualDamProjectData, expectedDamProjectData); } private DamProjectData CreateExampleDamProjectData() { var damProjectData = new DamProjectData(); FillAnalysisSpecification(damProjectData); damProjectData.WaterBoard = new WaterBoard(); damProjectData.WaterBoard.Dikes = new List(); damProjectData.WaterBoard.Dikes.Add(new Dike()); Dike dike = damProjectData.WaterBoard.Dikes[0]; var surfaceLines = CreateSurfaceLines(); FillSoils(dike); FillSoilProfiles1D(dike); FillSegments(damProjectData); AddLocations(dike, surfaceLines, damProjectData.WaterBoard.Segments); foreach (LocationJob locationJob in damProjectData.LocationJobs) { locationJob.Run = true; } return damProjectData; } private static void FillAnalysisSpecification(DamProjectData damProjectData) { damProjectData.DamProjectType = DamProjectType.Design; damProjectData.DamProjectCalculationSpecification = new DamProjectCalculationSpecification(); DamProjectCalculationSpecification.SelectedAnalysisType = expectedAnalysisType; 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.AbovePhreaticLevel = 7 + 0.1 * i; soil.BelowPhreaticLevel = 8 + 0.1 * i; soil.DryUnitWeight = 9 + 0.1 * i; 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 static void AddLocations(Dike dike, List surfaceLines, IList segments) { const int locationCount = 3; for (int i = 0; i < locationCount; i++) { var location = new Location(); location.Name = "Location " + (i + 1).ToString(); location.PLLineCreationMethod = (PLLineCreationMethod) i; location.IntrusionVerticalWaterPressure = (IntrusionVerticalWaterPressureType) i; location.PolderLevel = 1.0 * i + 0.11; location.DampingFactorPL4 = 1.0 * i + 0.12; location.DampingFactorPL3 = 1.0 * i + 0.13; location.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.LocalXZSurfaceLine2 = surfaceLines[i]; location.Segment = segments[i % 2]; // alternate between the 2 available segments for (int j = 0; j < 3; j++) { var designScenario = FillDesignScenario(i, j); location.Scenarios.Add(designScenario); } location.DikeEmbankmentMaterial = "DikeMat"; location.MapForSoilGeometries2D = "TestMap"; location.StabilityZoneType = MStabZonesType.NoZones; location.ForbiddenZoneFactor = 1.23; location.ZoneAreaRestSlopeCrestWidth = 8.23; location.TrafficLoad = 11.11; location.MinimalCircleDepth = 1.21; dike.Locations.Add(location); dike.Locations.Add(location); } } private static Scenario FillDesignScenario(int locationIndex, int designScenarioIndex) { int factor = locationIndex * designScenarioIndex; var designScenario = new Scenario(); designScenario.LocationScenarioID = (designScenarioIndex + 1).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 List CreateSurfaceLines() { var surfaceLines = new List(); 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); surfaceLines.Add(surfaceLine); } return surfaceLines; } 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 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 { Id = "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 void FillSegments(DamProjectData damProjectData) { var segmentCount = 2; Dike dike = damProjectData.WaterBoard.Dikes[0]; 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.SoilGeometry2DName = "Profile2D " + (i + 1).ToString(); //TODO: soilProfileProbability.SoilProfile2D = FillDamUiFromXmlInput.FindSoilProfile2DByName(damProjectData.WaterBoard.Dikes[0]., // soilProfileProbability.SoilGeometry2DName); } else { soilProfileProbability.SegmentFailureMechanismType = FailureMechanismSystemType.Piping; string soilProfile1DName = "Profile1D " + (i + 1).ToString(); soilProfileProbability.SoilProfile = FillDamUiFromXmlInput.FindSoilProfile1DByName(dike.SoilProfiles, soilProfile1DName); } soilProfileProbability.Probability = 0.003 * (i + 1); segment.SoilProfileProbabilities.Add(soilProfileProbability); damProjectData.WaterBoard.Segments.Add(segment); } } private void CompareDamProjectData(DamProjectData actual, DamProjectData expected) { var compare = new CompareLogic { Config = { MaxDifferences = 10 } }; compare.Config.MembersToIgnore = new List { "SheetPilePoint", "SheetPilePointX", "SheetPilePointY", "SheetPilePointZ", "LocalXZSheetPilePoint", "SoilbaseDB", "SoildatabaseName", "WaterBoardJob", "LocationJobs", "SelectedLocationJobs", "MapForSoilGeometries2D" }; var result = compare.Compare(expected, actual); Assert.AreEqual(0, result.Differences.Count, "Differences found read/write Input object"); } } }