Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs =================================================================== diff -u -r5018 -r5019 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (.../MacroStabilityCommonHelper.cs) (revision 5018) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelper.cs (.../MacroStabilityCommonHelper.cs) (revision 5019) @@ -417,24 +417,37 @@ /// Thrown when no SoilProfile2D is defined private static void CombineSoilProfile2DWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) { + ValidateForCombineSoilProfile2DWithSurfaceLine(subSoilScenario, surfaceLine2, dikeEmbankmentSoil); + + FitSoilProfile2DToSurfaceLine(subSoilScenario, surfaceLine2); + } + + private static void ValidateForCombineSoilProfile2DWithSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2, Soil dikeEmbankmentSoil) + { if (subSoilScenario.SoilProfile2D == null) { throw new ArgumentNullException(nameof(subSoilScenario), @"SoilProfile2D cannot be null."); } + if (surfaceLine2 == null) { throw new ArgumentNullException(nameof(surfaceLine2), @"SurfaceLine cannot be null."); } + if (dikeEmbankmentSoil == null) { throw new ArgumentNullException(nameof(dikeEmbankmentSoil), @"DikeEmbankmentSoil cannot be null."); } + if (!SoilProfile2DSurfaceLineHelper.IsSurfaceLineAboveBottomSoilProfile2D(surfaceLine2, subSoilScenario.SoilProfile2D)) { throw new InvalidOperationException(@"SurfaceLine is (partly) below the bottom of the SoilProfile2D."); } - - FitSoilProfile2DToSurfaceLine(subSoilScenario, surfaceLine2); + + if (!SurfaceLine2Validator.AreAllCharacteristicPointsXCoordinatesAscending(surfaceLine2)) + { + throw new InvalidOperationException(@"SurfaceLine points are not strictly ascending"); + } } private static void FitSoilProfile2DToSurfaceLine(SoilGeometryProbability subSoilScenario, SurfaceLine2 surfaceLine2) Index: DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SurfaceLine2ValidatorTests.cs =================================================================== diff -u --- DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SurfaceLine2ValidatorTests.cs (revision 0) +++ DamEngine/trunk/src/Deltares.DamEngine.Data.Tests/Geotechnics/SurfaceLine2ValidatorTests.cs (revision 5019) @@ -0,0 +1,37 @@ +// Copyright (C) Stichting Deltares 2024. All rights reserved. +// +// This file is part of the Dam Engine. +// +// The Dam Engine is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero 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 Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero 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 Deltares.DamEngine.Data.Geotechnics; +using Deltares.DamEngine.TestHelpers.Factories; +using NUnit.Framework; + +namespace Deltares.DamEngine.Data.Tests.Geotechnics; + +[TestFixture] +public class SurfaceLine2ValidatorTests +{ + [Test] + public void GivenSurfaceLineWithNonStrictAscendingPointsWhenValidatingThenValidationFails() + { + SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineDikeNonStrictAscending(); + Assert.That(SurfaceLine2Validator.AreAllCharacteristicPointsXCoordinatesAscending(surfaceLine), Is.False); + } +} \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs =================================================================== diff -u -r5008 -r5019 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (.../SurfaceLine2Validator.cs) (revision 5008) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geotechnics/SurfaceLine2Validator.cs (.../SurfaceLine2Validator.cs) (revision 5019) @@ -136,7 +136,7 @@ { // #Bka: if fact we now should return FALSE immediately but there is a snag. Due to faults with adding characteristic // points to a surface line, some surface lines can have identical points (in Location) but with different - // characteristic (e.g. diktop and trafficload combined). These points should use the same reference to the point + // characteristic (e.g. diketop and trafficload combined). These points should use the same reference to the point // but it occurs that TWO fysical (and identical) points are added. // So these points must now be ignored (so identical points must be seen as OK). This is in fact ok for the purpose // of the validation ast the main problem is that points may never give a vertical part in the geometry. Index: DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs =================================================================== diff -u -r5010 -r5019 --- DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs (.../FactoryForSurfaceLines.cs) (revision 5010) +++ DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs (.../FactoryForSurfaceLines.cs) (revision 5019) @@ -831,9 +831,36 @@ /// /// Creates a surface line, that contains a dike and is cutting the SurfaceLineWithDikeAndDitch. /// - /// surface line + /// The surface line public static SurfaceLine2 CreateSurfaceLineCuttingSurfaceLineDikeAndDitch() { return CreateSurfaceLineDike(-2.0, "AboveSurfaceLineWithDikeAndDitch"); } + + /// + /// Creates a surface line, that contains a dike and with points that are not strictly ascending. + /// + /// The surface line + public static SurfaceLine2 CreateSurfaceLineDikeNonStrictAscending() + { + var surfaceLine = new SurfaceLine2 + { + Name = "DikeNonStrictAscending", + Geometry = new GeometryPointString(), + CharacteristicPoints = + { + GeometryMustContainPoint = true + } + }; + + surfaceLine.EnsurePointOfType(0.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); + surfaceLine.EnsurePointOfType(10.0, 0.0, CharacteristicPointType.DikeToeAtRiver); + surfaceLine.EnsurePointOfType(34.5, 5.0, CharacteristicPointType.DikeTopAtRiver); + surfaceLine.EnsurePointOfType(40.5, 5.0, CharacteristicPointType.DikeTopAtPolder); + surfaceLine.EnsurePointOfType(40.5, 0.0, CharacteristicPointType.DikeToeAtPolder); + surfaceLine.EnsurePointOfType(75.0, 0.0, CharacteristicPointType.SurfaceLevelInside); + + surfaceLine.Geometry.SyncCalcPoints(); + return surfaceLine; + } } \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs =================================================================== diff -u -r5010 -r5019 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs (.../MacroStabilityCommonHelperTests.cs) (revision 5010) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/MacroStabilityCommon/MacroStabilityCommonHelperTests.cs (.../MacroStabilityCommonHelperTests.cs) (revision 5019) @@ -280,6 +280,16 @@ Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); }); } + [Test] + public void GivenSoilGeometryProbabilityWithSoilProfile2DAndSurfaceLineNonSscanedingWhenCombiningThenExceptionIsRaised() + { + SoilGeometryProbability soilGeometryProbability = CreateSoilGeometryProbabilityWithSoilProfile2DWithSurfaceLineDitchDike(); + SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineDikeNonStrictAscending(); + // Now combine the soilGeometryProbability with the surfaceLine which should in an exception, because the surfaceLine + // is not strictly ascending + Assert.Throws(() => { MacroStabilityCommonHelper.CombineSoilProfileWithSurfaceLine(soilGeometryProbability, surfaceLine, new Soil()); }); + } + private static SoilGeometryProbability CreateSoilGeometryProbabilityWithSoilProfile2DWithSurfaceLineDitchDike() { SoilGeometryProbability soilGeometryProbability = FactoryForSoilGeometryProbabilities.CreateSoilGeometryProbabilityWithSoilProfile1D();