Index: Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Service/MacroStabilityInwardsInputValidator.cs =================================================================== diff -u -ra5907a9c3b963642ff426af2ed7e4a9a146c2556 -rb231bcbf451d747c2ed6f828f320cececad73ece --- Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Service/MacroStabilityInwardsInputValidator.cs (.../MacroStabilityInwardsInputValidator.cs) (revision a5907a9c3b963642ff426af2ed7e4a9a146c2556) +++ Ringtoets/MacroStabilityInwards/src/Ringtoets.MacroStabilityInwards.Service/MacroStabilityInwardsInputValidator.cs (.../MacroStabilityInwardsInputValidator.cs) (revision b231bcbf451d747c2ed6f828f320cececad73ece) @@ -175,20 +175,58 @@ double maximumXCoordinateSoilProfile = soilProfileXCoordinates.Max(); double maxXCoordinate = Math.Min(maximumXCoordinateSoilProfile, maximumXCoordinateSurfaceLine); - var xCoordinates = new List(); double minimumXCoordinateSurfaceLine = surfaceLineXCoordinates.Min(); double minimumXCoordinateSoilProfile = soilProfileXCoordinates.Min(); - double x = Math.Max(minimumXCoordinateSoilProfile, minimumXCoordinateSurfaceLine); - while (x < maxXCoordinate) + double minXCoordinate = Math.Max(minimumXCoordinateSoilProfile, minimumXCoordinateSurfaceLine); + + IEnumerable clippedSoilProfileXCoordinates = soilProfileXCoordinates.Where(xCoordinate => IsXCoordinateInRange(xCoordinate, minXCoordinate, maxXCoordinate)); + IEnumerable clippedSurfaceLineXCoordinates = surfaceLineXCoordinates.Where(xCoordinate => IsXCoordinateInRange(xCoordinate, minXCoordinate, maxXCoordinate)); + + double[] uniqueClippedXCoordinates = clippedSoilProfileXCoordinates.Concat(clippedSurfaceLineXCoordinates) + .Distinct() + .OrderBy(xCoordinate => xCoordinate) + .ToArray(); + + var xCoordinates = new List(); + for (var i = 0; i < uniqueClippedXCoordinates.Length - 1; i++) { - xCoordinates.Add(x); - x += withinSurfaceLineLevelLimit; + double firstXCoordinate = uniqueClippedXCoordinates[i]; + double secondXCoordinate = uniqueClippedXCoordinates[i + 1]; + + xCoordinates.AddRange(GetDiscretizedXCoordinatesBetweenInterval(firstXCoordinate, secondXCoordinate)); } - xCoordinates.Add(maxXCoordinate); + xCoordinates.Add(uniqueClippedXCoordinates.Last()); return xCoordinates; } + private static IEnumerable GetDiscretizedXCoordinatesBetweenInterval(double startXCoordinate, double endXCoordinate) + { + if (Math.Abs(endXCoordinate - startXCoordinate) < withinSurfaceLineLevelLimit) + { + return new[] + { + startXCoordinate + }; + } + + double xCoordinate = startXCoordinate; + var discretizedXCoordinates = new List(); + while (xCoordinate < endXCoordinate) + { + discretizedXCoordinates.Add(xCoordinate); + xCoordinate += withinSurfaceLineLevelLimit; + } + + return discretizedXCoordinates; + } + + private static bool IsXCoordinateInRange(double xCoordinate, double minXCoordinate, double maxXCoordinate) + { + return xCoordinate <= maxXCoordinate + && xCoordinate >= minXCoordinate; + } + private static IEnumerable> GetLayerPolygons(MacroStabilityInwardsSoilProfile2D soilProfile2D) { return soilProfile2D.Layers Index: Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Service.Test/MacroStabilityInwardsInputValidatorTest.cs =================================================================== diff -u -rba06f85a75504d30e937dcbce92f08ea31ca9e49 -rb231bcbf451d747c2ed6f828f320cececad73ece --- Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Service.Test/MacroStabilityInwardsInputValidatorTest.cs (.../MacroStabilityInwardsInputValidatorTest.cs) (revision ba06f85a75504d30e937dcbce92f08ea31ca9e49) +++ Ringtoets/MacroStabilityInwards/test/Ringtoets.MacroStabilityInwards.Service.Test/MacroStabilityInwardsInputValidatorTest.cs (.../MacroStabilityInwardsInputValidatorTest.cs) (revision b231bcbf451d747c2ed6f828f320cececad73ece) @@ -399,6 +399,64 @@ } /// + /// The soil profile used in this test contains one outer layer (outer ring) and a surfaceline: + /// Soil layer (X) is defined as shown below: + /// + /// + /// 20 X X ---------------- X + /// | \ / | + /// | \ / | + /// 15 | \ / | + /// | \ / | + /// | \ / | + /// 10 | X | + /// | | + /// | | + /// 5 X ------------------------------- X + /// 0 0.025 0.05 ... 0.2 + /// + /// + [Test] + public void Validate_SurfaceLineNear2DProfileWithLayersWithSmallInflectionDefinition_ReturnsError() + { + // Setup + var surfaceLine = new MacroStabilityInwardsSurfaceLine("Test"); + surfaceLine.SetGeometry(new[] + { + new Point3D(0, 0.0, 20), + new Point3D(0.2, 0.0, 20) + }); + + var soilProfile = new MacroStabilityInwardsSoilProfile2D( + "profile", + new[] + { + new MacroStabilityInwardsSoilLayer2D(new Ring(new[] + { + new Point2D(0, 20), + new Point2D(0.025, 10), + new Point2D(0.05, 20), + new Point2D(0.2, 20), + new Point2D(0.2, 5), + new Point2D(0, 5) + })) + }, new MacroStabilityInwardsPreconsolidationStress[0]); + + input.StochasticSoilProfile = new MacroStabilityInwardsStochasticSoilProfile(0.0, + soilProfile); + input.SurfaceLine = surfaceLine; + + // Call + IEnumerable messages = MacroStabilityInwardsInputValidator.Validate(input).ToArray(); + + // Assert + CollectionAssert.AreEqual(new[] + { + "De profielschematisatie moet op de ondergrondschematisatie liggen." + }, messages); + } + + /// /// The soil profile used in this test contains two outer layers (outer rings) and a surfaceline: /// /// Soil layer (1) is defined as shown below: @@ -869,7 +927,7 @@ new Point2D(0, 10), new Point2D(1, 20), new Point2D(2, 10) - })), + })) }, new MacroStabilityInwardsPreconsolidationStress[0])) .SetName("Top soilLayer offset above surfaceline and not within limit"); }