// Copyright (C) Stichting Deltares 2025. 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 System; using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon; using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.TestHelpers.Factories; using NUnit.Framework; namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.MacroStabilityInwards; [TestFixture] public class UpliftVanGridCreatorTests { private const double tolerance = 0.0001; private const double specifiedTangentDistance = 1.5; private const double surfaceLevelSoilProfile1D = 0; private const double bottomLayerSoilProfile1D = -10; [Test] public void GivenGridSpecified_WhenDetermineGridsFromSettings_ThenGridsAreAsExpected() { // Given SlipCircleDefinition slipCircleDefinition = CreateSlipCircleDefinitionSpecified(true); SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineForTestingGrid(10.0, 80.0); // When UpliftVanCalculationGrid upliftVanCalculationGrid = UpliftVanGridCreator.DetermineGridsFromSettings(slipCircleDefinition, surfaceLine); // Then Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.IsGridsAutomatic, Is.False); CheckValuesLeftGrid(upliftVanCalculationGrid); // The right grid starts at either last uplift point X-coordinate - gridWidth or dike toe at polder X-coordinate, whichever is largest // last uplift point X-coordinate - gridWidth = 0.0 - 10.0 = -10.0 // dike toe at polder X-coordinate = 59.96 // The right grid is limited to right boundary (80.0) CheckValuesRightGrid(upliftVanCalculationGrid, 59.96, 69.96); }); } [Test] public void GivenGridSpecifiedWithRightGridOverRightBoundary_WhenDetermineGridsFromSettings_ThenRightGridLimitedToRightBoundary() { // Given SlipCircleDefinition slipCircleDefinition = CreateSlipCircleDefinitionSpecified(true); SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineForTestingGrid(10.0, 65.0); // When UpliftVanCalculationGrid upliftVanCalculationGrid = UpliftVanGridCreator.DetermineGridsFromSettings(slipCircleDefinition, surfaceLine); // Then Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.IsGridsAutomatic, Is.False); CheckValuesLeftGrid(upliftVanCalculationGrid); // The right grid is limited to right boundary 65.0 CheckValuesRightGrid(upliftVanCalculationGrid, 59.96, 65.0); }); } [Test] public void GivenGridSpecifiedWithUpliftPoint_WhenDetermineGridsFromSettings_ThenRightGridStartsAsExpected() { // Given SlipCircleDefinition slipCircleDefinition = CreateSlipCircleDefinitionSpecified(true); slipCircleDefinition.XCoordinateLowestUpliftFactorPoint = 75.0; SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineForTestingGrid(10.0, 80.0); // When UpliftVanCalculationGrid upliftVanCalculationGrid = UpliftVanGridCreator.DetermineGridsFromSettings(slipCircleDefinition, surfaceLine); // Then Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.IsGridsAutomatic, Is.False); CheckValuesLeftGrid(upliftVanCalculationGrid); // The right grid starts at either last uplift point X-coordinate - gridWidth or dike toe at polder X-coordinate, whichever is largest // last uplift point X-coordinate - gridWidth = 75.0 - 10.0 = 65.0 // dike toe at polder X-coordinate = 59.96 CheckValuesRightGrid(upliftVanCalculationGrid, 65.0, 75.0); }); } [Test] public void GivenGridAutomatic_WhenDetermineGridsFromSettings_ThenIsGridsAutomatic() { // Given SlipCircleDefinition slipCircleDefinition = CreateSlipCircleDefinitionSpecified(false); SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineForTestingGrid(10.0, 80.0); // When UpliftVanCalculationGrid upliftVanCalculationGrid = UpliftVanGridCreator.DetermineGridsFromSettings(slipCircleDefinition, surfaceLine); // Then Assert.That(upliftVanCalculationGrid.IsGridsAutomatic, Is.True); CheckValuesLeftGrid(upliftVanCalculationGrid, true); CheckValuesRightGrid(upliftVanCalculationGrid, 0.0, 0.0, true); } [Test] [TestCase(TangentLinesDefinition.OnBoundaryLines)] [TestCase(TangentLinesDefinition.Specified)] [TestCase(TangentLinesDefinition.Automatic)] public void GivenSlipCircleDefinitionAndSoilProfile1D_WhenDetermineTangentLines_ThenTangentLinesAreAsExpected(TangentLinesDefinition tangentLinesDefinition) { // Given SlipCircleDefinition slipCircleDefinition = CreateSlipCircleDefinitionSpecified(true, tangentLinesDefinition); SoilProfile1D soilProfile1D = FactoryForSoilProfiles.CreateClaySandProfile(out _, surfaceLevelSoilProfile1D, bottomLayerSoilProfile1D); // When var upliftVanCalculationGrid = new UpliftVanCalculationGrid(); UpliftVanGridCreator.DetermineTangentLines(upliftVanCalculationGrid, slipCircleDefinition, soilProfile1D); // Then Assert.Multiple(() => { CheckValuesTangentLines(upliftVanCalculationGrid); }); } private static void CheckValuesLeftGrid(UpliftVanCalculationGrid upliftVanCalculationGrid, bool isGridsAutomatic = false) { var expectedXLeft = 0.0; var expectedXRight = 0.0; var expectedXCount = 0; var expectedZBottom = 0.0; var expectedZTop = 0.0; var expectedZCount = 0; if (!isGridsAutomatic) { expectedXLeft = 31.52; expectedXRight = 57.52; expectedXCount = 14; expectedZBottom = 3.775; expectedZTop = 73.775; expectedZCount = 36; } Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.LeftGridXLeft, Is.EqualTo(expectedXLeft).Within(tolerance)); Assert.That(upliftVanCalculationGrid.LeftGridXRight, Is.EqualTo(expectedXRight).Within(tolerance)); Assert.That(upliftVanCalculationGrid.LeftGridXCount, Is.EqualTo(expectedXCount)); Assert.That(upliftVanCalculationGrid.LeftGridZBottom, Is.EqualTo(expectedZBottom).Within(tolerance)); Assert.That(upliftVanCalculationGrid.LeftGridZTop, Is.EqualTo(expectedZTop).Within(tolerance)); Assert.That(upliftVanCalculationGrid.LeftGridZCount, Is.EqualTo(expectedZCount)); }); } private static void CheckValuesRightGrid(UpliftVanCalculationGrid upliftVanCalculationGrid, double expectedXLeft, double expectedXRight, bool isGridsAutomatic = false) { var expectedXCount = 0; var expectedZBottom = 0.0; var expectedZTop = 0.0; var expectedZCount = 0; if (!isGridsAutomatic) { expectedXCount = 6; expectedZBottom = -0.09; expectedZTop = 3.91; expectedZCount = 3; } Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.RightGridXLeft, Is.EqualTo(expectedXLeft).Within(tolerance)); Assert.That(upliftVanCalculationGrid.RightGridXRight, Is.EqualTo(expectedXRight).Within(tolerance)); Assert.That(upliftVanCalculationGrid.RightGridXCount, Is.EqualTo(expectedXCount)); Assert.That(upliftVanCalculationGrid.RightGridZBottom, Is.EqualTo(expectedZBottom).Within(tolerance)); Assert.That(upliftVanCalculationGrid.RightGridZTop, Is.EqualTo(expectedZTop).Within(tolerance)); Assert.That(upliftVanCalculationGrid.RightGridZCount, Is.EqualTo(expectedZCount)); }); } private static void CheckValuesTangentLines(UpliftVanCalculationGrid upliftVanCalculationGrid) { var expectedZBottom = 0.0; var expectedZTop = 0.0; var expectedCount = 0; if (upliftVanCalculationGrid.TangentLinesCreationMethod == TangentLinesDefinition.Specified) { expectedZBottom = bottomLayerSoilProfile1D - specifiedTangentDistance; expectedCount = (int) Math.Round((surfaceLevelSoilProfile1D - expectedZBottom) / specifiedTangentDistance) + 1; expectedZTop = expectedZBottom + (expectedCount - 1) * specifiedTangentDistance; } Assert.Multiple(() => { Assert.That(upliftVanCalculationGrid.TangentLineZTop, Is.EqualTo(expectedZTop).Within(tolerance)); Assert.That(upliftVanCalculationGrid.TangentLineZBottom, Is.EqualTo(expectedZBottom).Within(tolerance)); Assert.That(upliftVanCalculationGrid.TangentLineCount, Is.EqualTo(expectedCount)); Assert.That(upliftVanCalculationGrid.TangentLineLevels, Has.Count.EqualTo(expectedCount)); }); } private static SlipCircleDefinition CreateSlipCircleDefinitionSpecified(bool isGridSpecified, TangentLinesDefinition tangentLinesDefinition = TangentLinesDefinition.Automatic) { var slipCircleDefinition = new SlipCircleDefinition { UpliftVanGridSizeDetermination = isGridSpecified ? GridSizeDetermination.Specified : GridSizeDetermination.Automatic, UpliftVanLeftGridVerticalPointCount = 36, UpliftVanLeftGridVerticalPointDistance = 2, UpliftVanLeftGridHorizontalPointCount = 14, UpliftVanLeftGridHorizontalPointDistance = 2, UpliftVanRightGridVerticalPointCount = 3, UpliftVanRightGridVerticalPointDistance = 2, UpliftVanRightGridHorizontalPointCount = 6, UpliftVanRightGridHorizontalPointDistance = 2, UpliftVanTangentLinesDefinition = tangentLinesDefinition, UpliftVanTangentLinesDistance = specifiedTangentDistance }; return slipCircleDefinition; } }