Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverterTests.cs =================================================================== diff -u -r2976 -r2977 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverterTests.cs (.../PlLinesToWaternetConverterTests.cs) (revision 2976) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverterTests.cs (.../PlLinesToWaternetConverterTests.cs) (revision 2977) @@ -5,7 +5,6 @@ using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon; -using Deltares.DamEngine.Calculators.Tests.KernelWrappers.TestHelpers; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using NUnit.Framework; @@ -235,11 +234,12 @@ plLine.Points.Add(new PlLinePoint(rightCoordinate, -8)); // Call - Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength, leftCoordinate, rightCoordinate); + Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength); // Assert AssertGeometry(plLines.Lines[PlLineType.Pl1].Points, waternet.PhreaticLine.Points); + Assert.AreEqual(3, waternet.HeadLineList.Count); AssertGeometry(plLines.Lines[PlLineType.Pl2].Points, waternet.HeadLineList[0].Points); AssertGeometry(plLines.Lines[PlLineType.Pl3].Points, waternet.HeadLineList[1].Points); AssertGeometry(plLines.Lines[PlLineType.Pl4].Points, waternet.HeadLineList[2].Points); @@ -258,6 +258,212 @@ } [Test] + public void ConvertPlLineToWaternet_ValidPLLinesAndSoilProfile2DWithContinuousInBetweenAquiferLayer_ReturnsExpectedWaternet() + { + // Setup + var random = new Random(21); + double leftCoordinate = random.NextDouble(); + double rightCoordinate = leftCoordinate + 1; + double penetrationLength = random.NextDouble(); + + var topLeftUpperLayer = new Point2D(leftCoordinate, 0); + var topRightUpperLayer = new Point2D(rightCoordinate, 0); + var bottomRightUpperLayer = new Point2D(rightCoordinate, -10); + var bottomLeftUpperLayer = new Point2D(leftCoordinate, -10); + SoilLayer2D soilLayer = CreateSoilLayer2D(topLeftUpperLayer, topRightUpperLayer, bottomRightUpperLayer, bottomLeftUpperLayer); + + var topRightInBetweenAquiferLayer = new Point2D(rightCoordinate, -10); + var bottomRightInBetweenAquiferLayer = new Point2D(rightCoordinate, -20); + var bottomLeftInBetweenAquiferLayer = new Point2D(leftCoordinate, -20); + SoilLayer2D soilLayerAquiferInBetween = CreateSoilLayer2D(bottomLeftUpperLayer, topRightInBetweenAquiferLayer, bottomRightInBetweenAquiferLayer, bottomLeftInBetweenAquiferLayer); + soilLayerAquiferInBetween.IsAquifer = true; + + var topRightInBetweenLayer = new Point2D(rightCoordinate, -20); + var bottomRightInBetweenLayer = new Point2D(rightCoordinate, -25); + var bottomLeftInBetweenLayer = new Point2D(leftCoordinate, -25); + SoilLayer2D soilLayerInBetween = CreateSoilLayer2D(bottomLeftInBetweenAquiferLayer, topRightInBetweenLayer, bottomRightInBetweenLayer, bottomLeftInBetweenLayer); + + var topRightBottomAquiferLayer = new Point2D(rightCoordinate, -25); + var bottomRightBottomAquiferLayer = new Point2D(rightCoordinate, -30); + var bottomleftBottomAquiferLayer = new Point2D(leftCoordinate, -30); + SoilLayer2D soilLayerAquiferBottom = CreateSoilLayer2D(bottomLeftInBetweenLayer, topRightBottomAquiferLayer, bottomRightBottomAquiferLayer, bottomleftBottomAquiferLayer); + soilLayerAquiferBottom.IsAquifer = true; + + var soilProfile = new SoilProfile2D + { + Geometry = new GeometryData + { + Left = leftCoordinate, + Right = rightCoordinate, + Bottom = -20 + } + }; + soilProfile.Surfaces.Add(soilLayer); + soilProfile.Surfaces.Add(soilLayerAquiferInBetween); + soilProfile.Surfaces.Add(soilLayerInBetween); + soilProfile.Surfaces.Add(soilLayerAquiferBottom); + + var plLines = new PlLines(); + PlLine plLine = plLines.Lines[PlLineType.Pl1]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -5)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -5)); + + plLine = plLines.Lines[PlLineType.Pl2]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -6)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -6)); + + plLine = plLines.Lines[PlLineType.Pl3]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -7)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -7)); + + plLine = plLines.Lines[PlLineType.Pl4]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -8)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -8)); + + // Call + Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength); + + // Assert + AssertGeometry(plLines.Lines[PlLineType.Pl1].Points, waternet.PhreaticLine.Points); + + Assert.AreEqual(3, waternet.HeadLineList.Count); + AssertGeometry(plLines.Lines[PlLineType.Pl2].Points, waternet.HeadLineList[0].Points); + AssertGeometry(plLines.Lines[PlLineType.Pl3].Points, waternet.HeadLineList[1].Points); + AssertGeometry(plLines.Lines[PlLineType.Pl4].Points, waternet.HeadLineList[2].Points); + + Assert.AreEqual(3, waternet.WaternetLineList.Count); + + var expectedBottomAquiferCoordinates = new [] + { + new GeometryPoint(leftCoordinate, -25), + new GeometryPoint(rightCoordinate, -25) + }; + + WaternetLine pl2WaternetLine = waternet.WaternetLineList[0]; + Assert.AreSame(waternet.HeadLineList[0], pl2WaternetLine.HeadLine); + var offSetAquiferCoordinates = expectedBottomAquiferCoordinates.Select(aquiferCoordinate => new GeometryPoint(aquiferCoordinate.X, aquiferCoordinate.Z + penetrationLength)) + .ToArray(); + AssertGeometry(offSetAquiferCoordinates, pl2WaternetLine.Points); + + WaternetLine pl3WaternetLine = waternet.WaternetLineList[1]; + Assert.AreSame(waternet.HeadLineList[1], pl3WaternetLine.HeadLine); + AssertGeometry(expectedBottomAquiferCoordinates, pl3WaternetLine.Points); + + WaternetLine pl4WaternetLine = waternet.WaternetLineList[2]; + Assert.AreSame(waternet.HeadLineList[2], pl4WaternetLine.HeadLine); + AssertGeometry(new[] + { + new GeometryPoint(leftCoordinate, -10), + new GeometryPoint(rightCoordinate, -10) + }, pl4WaternetLine.Points); + } + + [Test] + [TestCase(true, false)] + [TestCase(false, true)] + public void ConvertPlLineToWaternet_ValidPLLinesAndSoilProfile2DWithDiscontinuousInBetweenAquiferLayer_ReturnsExpectedWaternet( + bool isLeftInBetweenLayerAquifer, bool isRightInBetweenLayerAquifer) + { + // Setup + var random = new Random(21); + double leftCoordinate = random.NextDouble(); + double rightCoordinate = leftCoordinate + 1; + double penetrationLength = random.NextDouble(); + + var topLeftUpperLayer = new Point2D(leftCoordinate, 0); + var topRightUpperLayer = new Point2D(rightCoordinate, 0); + var bottomRightUpperLayer = new Point2D(rightCoordinate, -10); + var bottomLeftUpperLayer = new Point2D(leftCoordinate, -10); + SoilLayer2D soilLayer = CreateSoilLayer2D(topLeftUpperLayer, topRightUpperLayer, bottomRightUpperLayer, bottomLeftUpperLayer); + + var topRightInBetweenAquiferLayerLeft = new Point2D(rightCoordinate / 2, -10); + var bottomRightInBetweenAquiferLayerLeft = new Point2D(rightCoordinate / 2, -20); + var bottomLeftInBetweenAquiferLayerLeft = new Point2D(leftCoordinate, -20); + SoilLayer2D soilLayerAquiferInBetweenLeft = CreateSoilLayer2D(bottomLeftUpperLayer, topRightInBetweenAquiferLayerLeft, bottomRightInBetweenAquiferLayerLeft, bottomLeftInBetweenAquiferLayerLeft); + soilLayerAquiferInBetweenLeft.IsAquifer = isLeftInBetweenLayerAquifer; + + var topRightInBetweenAquiferLayerRight = new Point2D(rightCoordinate, -10); + var bottomRightInBetweenAquiferLayerRight = new Point2D(rightCoordinate, -20); + var bottomLeftInBetweenAquiferLayerRight = new Point2D(leftCoordinate, -20); + SoilLayer2D soilLayerAquiferInBetweenRight = CreateSoilLayer2D(topRightInBetweenAquiferLayerLeft, topRightInBetweenAquiferLayerRight, bottomRightInBetweenAquiferLayerRight, bottomLeftInBetweenAquiferLayerRight); + soilLayerAquiferInBetweenRight.IsAquifer = isRightInBetweenLayerAquifer; + + var topRightInBetweenLayer = new Point2D(rightCoordinate, -20); + var bottomRightInBetweenLayer = new Point2D(rightCoordinate, -25); + var bottomLeftInBetweenLayer = new Point2D(leftCoordinate, -25); + SoilLayer2D soilLayerInBetween = CreateSoilLayer2D(bottomLeftInBetweenAquiferLayerLeft, topRightInBetweenLayer, bottomRightInBetweenLayer, bottomLeftInBetweenLayer); + + var topRightBottomAquiferLayer = new Point2D(rightCoordinate, -25); + var bottomRightBottomAquiferLayer = new Point2D(rightCoordinate, -30); + var bottomleftBottomAquiferLayer = new Point2D(leftCoordinate, -30); + SoilLayer2D soilLayerAquiferBottom = CreateSoilLayer2D(bottomLeftInBetweenLayer, topRightBottomAquiferLayer, bottomRightBottomAquiferLayer, bottomleftBottomAquiferLayer); + soilLayerAquiferBottom.IsAquifer = true; + + var soilProfile = new SoilProfile2D + { + Geometry = new GeometryData + { + Left = leftCoordinate, + Right = rightCoordinate, + Bottom = -20 + } + }; + soilProfile.Surfaces.Add(soilLayer); + soilProfile.Surfaces.Add(soilLayerAquiferInBetweenLeft); + soilProfile.Surfaces.Add(soilLayerAquiferInBetweenRight); + soilProfile.Surfaces.Add(soilLayerInBetween); + soilProfile.Surfaces.Add(soilLayerAquiferBottom); + + var plLines = new PlLines(); + PlLine plLine = plLines.Lines[PlLineType.Pl1]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -5)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -5)); + + plLine = plLines.Lines[PlLineType.Pl2]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -6)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -6)); + + plLine = plLines.Lines[PlLineType.Pl3]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -7)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -7)); + + plLine = plLines.Lines[PlLineType.Pl4]; + plLine.Points.Add(new PlLinePoint(leftCoordinate, -8)); + plLine.Points.Add(new PlLinePoint(rightCoordinate, -8)); + + // Call + Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength); + + // Assert + AssertGeometry(plLines.Lines[PlLineType.Pl1].Points, waternet.PhreaticLine.Points); + + Assert.AreEqual(3, waternet.HeadLineList.Count); + AssertGeometry(plLines.Lines[PlLineType.Pl2].Points, waternet.HeadLineList[0].Points); + AssertGeometry(plLines.Lines[PlLineType.Pl3].Points, waternet.HeadLineList[1].Points); + AssertGeometry(plLines.Lines[PlLineType.Pl4].Points, waternet.HeadLineList[2].Points); + + Assert.AreEqual(2, waternet.WaternetLineList.Count); + + var expectedBottomAquiferCoordinates = new[] + { + new GeometryPoint(leftCoordinate, -25), + new GeometryPoint(rightCoordinate / 2, -25), + new GeometryPoint(rightCoordinate, -25) + }; + + WaternetLine pl2WaternetLine = waternet.WaternetLineList[0]; + Assert.AreSame(waternet.HeadLineList[0], pl2WaternetLine.HeadLine); + var offSetAquiferCoordinates = expectedBottomAquiferCoordinates.Select(aquiferCoordinate => new GeometryPoint(aquiferCoordinate.X, aquiferCoordinate.Z + penetrationLength)) + .ToArray(); + AssertGeometry(offSetAquiferCoordinates, pl2WaternetLine.Points); + + WaternetLine pl3WaternetLine = waternet.WaternetLineList[1]; + Assert.AreSame(waternet.HeadLineList[1], pl3WaternetLine.HeadLine); + AssertGeometry(expectedBottomAquiferCoordinates, pl3WaternetLine.Points); + } + + + [Test] public void ConvertPlLineToWaternet_ValidPLLinesAndSoilProfile2DWithDiscontinuousBottomAquiferLayer_ReturnsExpectedWaternet() { // Setup @@ -316,7 +522,7 @@ plLine.Points.Add(new PlLinePoint(rightCoordinate, -8)); // Call - Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength, leftCoordinate, rightCoordinate); + Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength); // Assert AssertGeometry(plLines.Lines[PlLineType.Pl1].Points, waternet.PhreaticLine.Points); @@ -328,7 +534,6 @@ CollectionAssert.IsEmpty(waternet.WaternetLineList); } - [Test] [TestCase(true, false)] [TestCase(false, true)] @@ -391,7 +596,7 @@ plLine.Points.Add(new PlLinePoint(rightCoordinate, -8)); // Call - Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength, leftCoordinate, rightCoordinate); + Waternet waternet = PlLinesToWaternetConverter.ConvertPlLineToWaternet(plLines, soilProfile, penetrationLength); // Assert AssertGeometry(plLines.Lines[PlLineType.Pl1].Points, waternet.PhreaticLine.Points); @@ -403,21 +608,6 @@ CollectionAssert.IsEmpty(waternet.WaternetLineList); } - - private static void AssertGeometry(IEnumerable expectedPoints, IEnumerable actualPoints) - { - int expectedNrOfPoints = expectedPoints.Count(); - Assert.AreEqual(expectedNrOfPoints, actualPoints.Count()); - - for (int i = 0; i < expectedNrOfPoints; i++) - { - GeometryPoint expectedPoint = expectedPoints.ElementAt(i); - GeometryPoint actualPoint = actualPoints.ElementAt(i); - Assert.AreEqual(expectedPoint.X, actualPoint.X); - Assert.AreEqual(expectedPoint.Z, actualPoint.Z); - } - } - [Test] [ExpectedException(typeof(NoNullAllowedException), ExpectedMessage = "Geen 1D ondergrond profiel gedefinieerd")] [SetUICulture("nl-NL")] @@ -749,5 +939,19 @@ }; return soilLayer; } + + private static void AssertGeometry(IEnumerable expectedPoints, IEnumerable actualPoints) + { + int expectedNrOfPoints = expectedPoints.Count(); + Assert.AreEqual(expectedNrOfPoints, actualPoints.Count()); + + for (int i = 0; i < expectedNrOfPoints; i++) + { + GeometryPoint expectedPoint = expectedPoints.ElementAt(i); + GeometryPoint actualPoint = actualPoints.ElementAt(i); + Assert.AreEqual(expectedPoint.X, actualPoint.X); + Assert.AreEqual(expectedPoint.Z, actualPoint.Z); + } + } } } Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs =================================================================== diff -u -r2971 -r2977 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs (.../PlLinesToWaternetConverter.cs) (revision 2971) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs (.../PlLinesToWaternetConverter.cs) (revision 2977) @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; @@ -87,16 +88,24 @@ return waternet; } - public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile2D soilProfile, double penetrationLength, double xLeft, double xRight) + /// + /// Converts the to a based on a 2D profile. + /// + /// The to convert. + /// The to convert the with. + /// The penetration length. + /// A . + public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile2D soilProfile, double penetrationLength) { // Get all the xCoordinates to make cross sections IEnumerable points = soilProfile.Surfaces.SelectMany(surf => surf.GeometrySurface.OuterLoop.CalcPoints); var xCoordinates = points.Select(point => point.X).OrderBy(x => x).Distinct().ToArray(); - var bottomAquiferCoordinates = GetAquiferCoordinates(xCoordinates, soilProfile).ToArray(); + var bottomAquiferCoordinates = GetAquiferCoordinates(sp => sp.BottomAquiferLayer, xCoordinates, soilProfile).ToArray(); + var inBetweenAquiferCoordinates = GetAquiferCoordinates(sp => sp.InBetweenAquiferLayer, xCoordinates, soilProfile).ToArray(); var waternet = new Waternet(); - var plLine = plLines.Lines[PlLineType.Pl1]; + PlLine plLine = plLines.Lines[PlLineType.Pl1]; if (plLine != null) { waternet.PhreaticLine = CreateLine(plLine); @@ -110,7 +119,7 @@ if (bottomAquiferCoordinates.Any()) { - var waternetLine = CreateWaternetLine(bottomAquiferCoordinates, penetrationLength); + WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates, penetrationLength); waternetLine.HeadLine = headLine; waternet.WaternetLineList.Add(waternetLine); } @@ -124,7 +133,7 @@ if (bottomAquiferCoordinates.Any()) { - var waternetLine = CreateWaternetLine(bottomAquiferCoordinates); + WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates); waternetLine.HeadLine = headLine; waternet.WaternetLineList.Add(waternetLine); } @@ -135,6 +144,12 @@ { var headLine = CreateLine(plLine); waternet.HeadLineList.Add(headLine); + if (inBetweenAquiferCoordinates.Any()) + { + WaternetLine waternetLine = CreateWaternetLine(inBetweenAquiferCoordinates); + waternetLine.HeadLine = headLine; + waternet.WaternetLineList.Add(waternetLine); + } } return waternet; @@ -166,7 +181,8 @@ return line; } - private static IEnumerable GetAquiferCoordinates(IEnumerable xCoordinates, SoilProfile2D soilProfile) + private static IEnumerable GetAquiferCoordinates(Func getSoilLayerFunc, IEnumerable xCoordinates, + SoilProfile2D soilProfile) { SoilLayer1D previousAquiferLayer = null; var coordinates = new List(); @@ -176,7 +192,7 @@ // Determine if the bottom aquifer layer is in range of the previous aquifer layer // If not, return empty coordinates, because the aquifer layer is interrupted - SoilLayer1D currentAquifer = crossSection.BottomAquiferLayer; + SoilLayer1D currentAquifer = getSoilLayerFunc(crossSection); if (previousAquiferLayer != null && currentAquifer != null && !AreVerticallyConnected(previousAquiferLayer, currentAquifer)) @@ -192,11 +208,12 @@ } // Perform a short validation that the coordinates are fully defined from the beginning to the end - // of the profile. If not, the aquifer is not continuous - if (coordinates.First().X != xCoordinates.First() || coordinates.Last().X != xCoordinates.Last()) + // of the profile. If not, the aquifer is not continuous. + if (!coordinates.Any() || coordinates.First().X != xCoordinates.First() || coordinates.Last().X != xCoordinates.Last()) { return Enumerable.Empty(); } + return coordinates; }