// 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 System.Collections.Generic; using System.Data; using System.IO; using Deltares.DamEngine.Calculators.KernelWrappers.Common; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; using Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityInwards; using Deltares.DamEngine.Calculators.Tests.KernelWrappers.TestHelpers; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamEngine.Interface; using Deltares.DamEngine.Io.XmlOutput; using Deltares.DamEngine.TestHelpers; using Deltares.DamEngine.TestHelpers.Factories; using NUnit.Framework; using DesignResult = Deltares.DamEngine.Data.General.Results.DesignResult; using UpliftSituation = Deltares.DamEngine.Data.General.UpliftSituation; namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.MacroStabilityInwards; [TestFixture] public class MacroStabilityInwardsKernelWrapperTests { private const string testFolder = @"..\..\..\Deltares.DamEngine.IntegrationTests\TestFiles"; private const double tolerance4Decimals = 0.000051; private readonly string inputXmlForDamEngine = Path.Combine(testFolder, "StabilityDesign1Dbased.xml"); [Test] [TestCase(0.8, true, false, PrepareResult.NotRelevant)] [TestCase(1.4, true, true, PrepareResult.Successful)] [TestCase(1.2, false, false, PrepareResult.Failed)] public void TestPrepare(double upliftCriterionStability, bool isInputValid, bool expectedIsUplift, PrepareResult expectedPrepareResult) { // Setup DamKernelInput kernelInput = CreateDamKernelInputForTest(MStabModelType.UpliftVan); kernelInput.Location.ModelFactors.UpliftCriterionStability = upliftCriterionStability; var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model, SearchMethod = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.SearchMethod } } }; if (!isInputValid) { kernelInput.Location.SurfaceLine.CharacteristicPoints.Clear(); } // Call PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out IKernelDataOutput kernelDataOutput); // Assert var damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.Multiple(() => { Assert.That(prepareResult, Is.EqualTo(expectedPrepareResult)); Assert.That(damMacroStabilityOutput.CalculationResult, Is.EqualTo(CalculationResult.NoRun)); Assert.That(damMacroStabilityOutput.UpliftSituation.IsUplift, Is.EqualTo(expectedIsUplift)); }); } [Test] public void TestValidate() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan } } }; // Validate without setting values. Expected error messages. var macroStabilityInput = new MacroStabilityKernelDataInput(); var macroStabilityOutput = new MacroStabilityOutput { CalculationResult = CalculationResult.NoRun }; int errorCount = kernelWrapper.Validate(macroStabilityInput, macroStabilityOutput, out List messages); Assert.Multiple(() => { Assert.That(errorCount, Is.GreaterThan(0)); Assert.That(macroStabilityOutput.CalculationResult, Is.EqualTo(CalculationResult.InvalidInputData)); }); // Validate the input when valid input is provided. Expected no messages. DamKernelInput kernelInput = CreateDamKernelInputForTest(MStabModelType.UpliftVan); PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.That(prepareResult, Is.EqualTo(PrepareResult.Successful)); messages.Clear(); errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out messages); Assert.Multiple(() => { Assert.That(errorCount, Is.EqualTo(0)); Assert.That(((MacroStabilityOutput) kernelDataOutput).CalculationResult, Is.EqualTo(CalculationResult.NoRun)); }); } [Test] [TestCase(MStabModelType.Bishop)] [TestCase(MStabModelType.UpliftVan)] [TestCase(MStabModelType.BishopUpliftVan)] public void TestPostProcess(MStabModelType modelType) { DamKernelInput kernelInput = CreateDamKernelInputForTest(modelType); var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model, SearchMethod = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.SearchMethod } } }; var macroStabilityOutput = new MacroStabilityOutput { CalculationResult = CalculationResult.Succeeded, UpliftSituation = new UpliftSituation { IsUplift = true }, StabilityOutputItems = new List { new MacroStabilityOutputItem { StabilityModelType = modelType != MStabModelType.BishopUpliftVan ? modelType : MStabModelType.Bishop, CalculationResult = CalculationResult.Succeeded, SafetyFactor = 2.34, CalculationPath = testFolder + "@\testpath", ProjectName = Path.GetFileNameWithoutExtension(inputXmlForDamEngine), ActiveCenterPoint = new Point2D(10, 10), ActiveCenterPointRadius = 8, PassiveCenterPoint = new Point2D(22, 11), PassiveCenterPointRadius = 7 } } }; if (modelType == MStabModelType.BishopUpliftVan) { var macroStabilityOutputItem = new MacroStabilityOutputItem { StabilityModelType = MStabModelType.UpliftVan, CalculationResult = CalculationResult.Succeeded, SafetyFactor = 2.01, ActiveCenterPoint = new Point2D(10, 10), ActiveCenterPointRadius = 8, PassiveCenterPoint = new Point2D(22, 11), PassiveCenterPointRadius = 7 }; macroStabilityOutput.StabilityOutputItems.Add(macroStabilityOutputItem); } var designScenario = new DesignScenario { LocationName = kernelInput.Location.Name, CalculationResult = CalculationResult.Succeeded }; var resultSlice = new StabilityResultSlice { TopLeftPoint = new Point2D(9, 3), TopRightPoint = new Point2D(9.2, 3.01), BottomLeftPoint = new Point2D(9, -3), BottomRightPoint = new Point2D(9.2, -3.1), Name = "slice1", Width = 0.2, ArcLength = 0.22, TopAngle = 0, BottomAngle = 12.2, CohesionInput = 14, CohesionOutput = 15.5, FrictionAngleInput = 30, FrictionAngleOutput = 30.5, YieldStress = 22, OCR = 23, POP = 24, DegreeOfConsolidationPorePressure = 25, PorePressureDueToDegreeOfConsolidationLoad = 26, DilatancyInput = 27, ExternalLoad = 29, HydrostaticPorePressure = 30, LeftForce = 31, LeftForceAngle = 32, LeftForceY = 33, RightForce = 34, RightForceAngle = 35, RightForceY = 36, LoadStress = 37, NormalStress = 38, PorePressure = 39, HorizontalPorePressure = 40, VerticalPorePressure = 41, PiezometricPorePressure = 42, EffectiveStress = 43, ExcessPorePressure = 44, ShearStressInput = 45, ShearStressOutput = 45.5, SoilStress = 46, TotalPorePressure = 47, TotalStress = 48, Weight = 49, SuInput = 50, SuOutput = 50.5, ShearStrengthModel = ShearStrengthModel.CPhi, HorizontalSoilQuakeStress = 51, StrengthIncreaseExponent = 52, UpliftFactor = 53, VerticalSoilQuakeStress = 54, WaterQuakeStress = 55, UpliftReductionFactor = 56, RatioCuPc = 57, ResultantForce = 58, ResultantMoment = 59, ResultantAngle = 60 }; macroStabilityOutput.StabilityOutputItems[0].ResultSlices = new List { resultSlice }; if (modelType == MStabModelType.BishopUpliftVan) { macroStabilityOutput.StabilityOutputItems[1].ResultSlices = new List { resultSlice }; } kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results); switch (modelType) { case MStabModelType.Bishop: case MStabModelType.UpliftVan: Assert.That(results.Count, Is.EqualTo(1)); break; case MStabModelType.BishopUpliftVan: Assert.That(results.Count, Is.EqualTo(3)); break; } var expectedNumberOfIterations = new List(); var expectedStabilityModelType = new List(); var expectedSafetyFactor = new List(); switch (modelType) { case MStabModelType.Bishop: expectedNumberOfIterations = new List { 0 }; expectedStabilityModelType = new List { MStabModelType.Bishop }; expectedSafetyFactor = new List { 2.34 }; break; case MStabModelType.UpliftVan: expectedNumberOfIterations = new List { 0 }; expectedStabilityModelType = new List { MStabModelType.UpliftVan }; expectedSafetyFactor = new List { 2.34 }; break; case MStabModelType.BishopUpliftVan: expectedNumberOfIterations = new List { 0, 0, 0 }; expectedStabilityModelType = new List { MStabModelType.Bishop, MStabModelType.UpliftVan, MStabModelType.BishopUpliftVan }; expectedSafetyFactor = new List { 2.34, 2.01, 2.01 }; break; } for (var index = 0; index < results.Count; index++) { DesignResult result = results[index]; Assert.Multiple(() => { Assert.That(result.CalculationResult, Is.EqualTo(CalculationResult.Succeeded)); Assert.That(((UpliftSituation) result.StabilityDesignResults.UpliftSituation).IsUplift, Is.True); }); if (index == 0) { Assert.Multiple(() => { Assert.That(result.BaseFileName, Is.EqualTo(Path.GetFileNameWithoutExtension(inputXmlForDamEngine))); Assert.That(result.CalculationSubDir, Is.EqualTo(testFolder + "@\testpath")); }); } Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.NumberOfIterations, Is.EqualTo(expectedNumberOfIterations[index])); Assert.That(result.StabilityDesignResults.SafetyFactor, Is.EqualTo(expectedSafetyFactor[index])); Assert.That(result.StabilityDesignResults.RedesignedSurfaceLine, Is.EqualTo(kernelInput.Location.SurfaceLine)); Assert.That(result.ProfileName, Is.EqualTo(kernelInput.SubSoilScenario.ToString())); Assert.That(result.StabilityDesignResults.StabilityModelType, Is.EqualTo(expectedStabilityModelType[index])); Assert.That(result.StabilityDesignResults.ActiveCenterPoint.X, Is.EqualTo(10)); Assert.That(result.StabilityDesignResults.ActiveCenterPoint.Z, Is.EqualTo(10)); Assert.That(result.StabilityDesignResults.ActiveCenterPointRadius, Is.EqualTo(8)); }); if (result.StabilityDesignResults.StabilityModelType != MStabModelType.Bishop) { Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.PassiveCenterPoint.X, Is.EqualTo(22)); Assert.That(result.StabilityDesignResults.PassiveCenterPoint.Z, Is.EqualTo(11)); Assert.That(result.StabilityDesignResults.PassiveCenterPointRadius, Is.EqualTo(7)); }); } Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X, Is.EqualTo(9)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z, Is.EqualTo(3)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopRightPoint.X, Is.EqualTo(9.2)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopRightPoint.Z, Is.EqualTo(3.01)); Assert.That(result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.X, Is.EqualTo(9)); Assert.That(result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.Z, Is.EqualTo(-3)); Assert.That(result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.X, Is.EqualTo(9.2)); Assert.That(result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.Z, Is.EqualTo(-3.1)); Assert.That(result.StabilityDesignResults.ResultSlices[0].Name, Is.EqualTo("slice1")); Assert.That(result.StabilityDesignResults.ResultSlices[0].Width, Is.EqualTo(0.2)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ArcLength, Is.EqualTo(0.22)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopAngle, Is.EqualTo(0)); Assert.That(result.StabilityDesignResults.ResultSlices[0].BottomAngle, Is.EqualTo(12.2)); Assert.That(result.StabilityDesignResults.ResultSlices[0].CohesionInput, Is.EqualTo(14)); Assert.That(result.StabilityDesignResults.ResultSlices[0].CohesionOutput, Is.EqualTo(15.5)); Assert.That(result.StabilityDesignResults.ResultSlices[0].FrictionAngleInput, Is.EqualTo(30)); Assert.That(result.StabilityDesignResults.ResultSlices[0].FrictionAngleOutput, Is.EqualTo(30.5)); Assert.That(result.StabilityDesignResults.ResultSlices[0].YieldStress, Is.EqualTo(22)); Assert.That(result.StabilityDesignResults.ResultSlices[0].OCR, Is.EqualTo(23)); Assert.That(result.StabilityDesignResults.ResultSlices[0].POP, Is.EqualTo(24)); Assert.That(result.StabilityDesignResults.ResultSlices[0].DegreeOfConsolidationPorePressure, Is.EqualTo(25)); Assert.That(result.StabilityDesignResults.ResultSlices[0].PorePressureDueToDegreeOfConsolidationLoad, Is.EqualTo(26)); Assert.That(result.StabilityDesignResults.ResultSlices[0].DilatancyInput, Is.EqualTo(27)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ExternalLoad, Is.EqualTo(29)); Assert.That(result.StabilityDesignResults.ResultSlices[0].HydrostaticPorePressure, Is.EqualTo(30)); Assert.That(result.StabilityDesignResults.ResultSlices[0].LeftForce, Is.EqualTo(31)); Assert.That(result.StabilityDesignResults.ResultSlices[0].LeftForceAngle, Is.EqualTo(32)); Assert.That(result.StabilityDesignResults.ResultSlices[0].LeftForceY, Is.EqualTo(33)); Assert.That(result.StabilityDesignResults.ResultSlices[0].RightForce, Is.EqualTo(34)); Assert.That(result.StabilityDesignResults.ResultSlices[0].RightForceAngle, Is.EqualTo(35)); Assert.That(result.StabilityDesignResults.ResultSlices[0].RightForceY, Is.EqualTo(36)); Assert.That(result.StabilityDesignResults.ResultSlices[0].LoadStress, Is.EqualTo(37)); Assert.That(result.StabilityDesignResults.ResultSlices[0].NormalStress, Is.EqualTo(38)); Assert.That(result.StabilityDesignResults.ResultSlices[0].PorePressure, Is.EqualTo(39)); Assert.That(result.StabilityDesignResults.ResultSlices[0].HorizontalPorePressure, Is.EqualTo(40)); Assert.That(result.StabilityDesignResults.ResultSlices[0].VerticalPorePressure, Is.EqualTo(41)); Assert.That(result.StabilityDesignResults.ResultSlices[0].PiezometricPorePressure, Is.EqualTo(42)); Assert.That(result.StabilityDesignResults.ResultSlices[0].EffectiveStress, Is.EqualTo(43)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ExcessPorePressure, Is.EqualTo(44)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ShearStressInput, Is.EqualTo(45)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ShearStressOutput, Is.EqualTo(45.5)); Assert.That(result.StabilityDesignResults.ResultSlices[0].SoilStress, Is.EqualTo(46)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TotalPorePressure, Is.EqualTo(47)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TotalStress, Is.EqualTo(48)); Assert.That(result.StabilityDesignResults.ResultSlices[0].Weight, Is.EqualTo(49)); Assert.That(result.StabilityDesignResults.ResultSlices[0].SuInput, Is.EqualTo(50)); Assert.That(result.StabilityDesignResults.ResultSlices[0].SuOutput, Is.EqualTo(50.5)); Assert.That(result.StabilityDesignResults.ResultSlices[0].HorizontalSoilQuakeStress, Is.EqualTo(51)); Assert.That(result.StabilityDesignResults.ResultSlices[0].StrengthIncreaseExponent, Is.EqualTo(52)); Assert.That(result.StabilityDesignResults.ResultSlices[0].UpliftFactor, Is.EqualTo(53)); Assert.That(result.StabilityDesignResults.ResultSlices[0].VerticalSoilQuakeStress, Is.EqualTo(54)); Assert.That(result.StabilityDesignResults.ResultSlices[0].WaterQuakeStress, Is.EqualTo(55)); Assert.That(result.StabilityDesignResults.ResultSlices[0].UpliftReductionFactor, Is.EqualTo(56)); Assert.That(result.StabilityDesignResults.ResultSlices[0].RatioCuPc, Is.EqualTo(57)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ResultantForce, Is.EqualTo(58)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ResultantMoment, Is.EqualTo(59)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ResultantAngle, Is.EqualTo(60)); Assert.That(result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel, Is.EqualTo(ShearStrengthModel.CPhi)); }); } } [Test] public void TestFullCalculationFails() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan } } }; IKernelDataInput kernelDataInput = new MacroStabilityKernelDataInput(); IKernelDataOutput kernelDataOutput = new MacroStabilityOutput(); // Run the dll kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out List messages); var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.Multiple(() => { Assert.That(messages, Is.Not.Empty); // as there is no data at all, expect unexpected error Assert.That(macroStabilityOutput.CalculationResult, Is.EqualTo(CalculationResult.UnexpectedError)); }); } [Test] public void TestFullCalculationSucceedsWithWarningsWithBadTangentLines() { // Prepare the wrapper. Result is input for the calculation dll DamKernelInput kernelInput = CreateDamKernelInputForTest(MStabModelType.UpliftVan); var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model, SearchMethod = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.SearchMethod } } }; SlipCircleDefinition sd = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab .MStabParameters.SlipCircleDefinition; sd.UpliftVanTangentLinesDefinition = TangentLinesDefinition.Specified; kernelInput.CurrentEmbankmentSoil = kernelInput.Location.GetDikeEmbankmentSoil(); PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.That(prepareResult, Is.EqualTo(PrepareResult.Successful)); // Validate the input int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages); Assert.That(errorCount, Is.EqualTo(0)); // Run the dl; the tangent line position is defined in such a way that this calculation will result in // several failed attempted slip planes so there should be warnings. kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages); var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.Multiple(() => { Assert.That(messages, Has.Count.EqualTo(24)); Assert.That(macroStabilityOutput.CalculationResult, Is.EqualTo(CalculationResult.Succeeded)); Assert.That(messages[0].Message, Does.Contain("A slice is beyond the geometry at x")); }); } /// /// For a given search method and a given grid determination method, expected is that tangent lines Automatic give a lower /// safety factor than On boundary lines because there are extra tangent lines. /// [Test] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Specified, TangentLinesDefinition.OnBoundaryLines, 1.2812, 4)] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Specified, TangentLinesDefinition.Automatic, 1.2360, 2)] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Specified, TangentLinesDefinition.Specified, 0.4909, 24)] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Automatic, TangentLinesDefinition.OnBoundaryLines, 1.4752, 3)] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Automatic, TangentLinesDefinition.Automatic, 1.1437, 3)] [TestCase(MStabSearchMethod.Grid, GridSizeDetermination.Automatic, TangentLinesDefinition.Specified, 1.1475, 3)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Specified, TangentLinesDefinition.OnBoundaryLines, 2.2763, 3)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Specified, TangentLinesDefinition.Automatic, 2.0267, 3)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Specified, TangentLinesDefinition.Specified, 1.7680, 3)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Automatic, TangentLinesDefinition.OnBoundaryLines, 1.1205, 926)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Automatic, TangentLinesDefinition.Automatic, 1.1123, 800)] [TestCase(MStabSearchMethod.BeeSwarm, GridSizeDetermination.Automatic, TangentLinesDefinition.Specified, 1.1146, 826)] public void GivenUpliftVanModel_WhenCalculatingWithDifferentSearchAreaSettings_ReturnsLogicalResults(MStabSearchMethod searchMethod, GridSizeDetermination gridSizeDetermination, TangentLinesDefinition tangentLinesDefinition, double expectedSafetyFactor, int expectedLogMessageCount) { // Prepare the wrapper. Result is input for the calculation dll DamKernelInput kernelInput = CreateDamKernelInputForTest(MStabModelType.UpliftVan, searchMethod, gridSizeDetermination, tangentLinesDefinition); var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model, SearchMethod = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.SearchMethod } } }; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.That(prepareResult, Is.EqualTo(PrepareResult.Successful)); // Validate the input int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages); Assert.That(errorCount, Is.EqualTo(0)); // Run the dll kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages); var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.Multiple(() => { Assert.That(messages, Has.Count.EqualTo(expectedLogMessageCount)); Assert.That(macroStabilityOutput.CalculationResult, Is.EqualTo(CalculationResult.Succeeded)); Assert.That(macroStabilityOutput.StabilityOutputItems, Has.Count.EqualTo(1)); }); Assert.That(macroStabilityOutput.StabilityOutputItems[0].SafetyFactor, Is.EqualTo(expectedSafetyFactor).Within(tolerance4Decimals)); if (searchMethod == MStabSearchMethod.Grid && gridSizeDetermination == GridSizeDetermination.Specified && tangentLinesDefinition == TangentLinesDefinition.OnBoundaryLines) { CheckDesignResultsForUpliftVanSpecifiedGrid(kernelInput, kernelWrapper, macroStabilityOutput); } } [Test] public void CalculationUpliftBasedOnDamEngineXmlWorks() { const string calcDir = "TestStabInwardsBishop"; if (Directory.Exists(calcDir)) { Directory.Delete(calcDir, true); // delete previous results } Directory.CreateDirectory(calcDir); string inputString = File.ReadAllText(inputXmlForDamEngine); inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used var engineInterface = new EngineInterface(inputString); Assert.That(engineInterface.DamProjectData, Is.Not.Null); engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType = MStabModelType.UpliftVan; Output output = GeneralHelper.RunAfterInputValidation(engineInterface); Assert.That(output.Results.CalculationResults[0].StabilityDesignResults.SafetyFactor, Is.EqualTo(1.6099).Within(tolerance4Decimals)); } [Test] [SetUICulture("nl-NL")] public void TestLanguageNLThrowsExceptionWhenInputIsNull() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper(); Assert.That(() => kernelWrapper.Execute(null, null, out _), Throws.InstanceOf().With.Message.EqualTo("Geen invoer object gedefinieerd voor Macrostabiliteit")); } [Test] [SetUICulture("en-US")] public void TestLanguageENThrowsExceptionWhenStabilityInputIsNull() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper(); Assert.That(() => kernelWrapper.Execute(null, null, out _), Throws.InstanceOf().With.Message.EqualTo("No input object defined for Macro Stability")); } [Test] [SetUICulture("nl-NL")] public void TestThrowsExceptionWhenStabilityOutputIsNull() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper(); Assert.That(() => kernelWrapper.PostProcess(new DamKernelInput(), null, null, "", out _), Throws.InstanceOf().With.Message.EqualTo("Geen uitvoer object gedefinieerd voor Macrostabiliteit")); } [Test] [SetUICulture("nl-NL")] public void TestThrowsExceptionWhenDamKernelInputIsNull() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper(); Assert.That(() => kernelWrapper.PostProcess(null, null, null, "", out _), Throws.InstanceOf().With.Message.EqualTo("Geen Dam invoer object gedefinieerd voor Macrostabiliteit")); } private static void CheckDesignResultsForUpliftVanSpecifiedGrid(DamKernelInput kernelInput, MacroStabilityInwardsKernelWrapper kernelWrapper, MacroStabilityOutput macroStabilityOutput) { // Fill the design results var designScenario = new DesignScenario { LocationName = kernelInput.Location.Name, CalculationResult = CalculationResult.Succeeded }; kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results); Assert.That(results, Is.Not.Empty); foreach (DesignResult result in results) { Assert.Multiple(() => { Assert.That(result.BaseFileName, Is.EqualTo("Loc(TestLocation)_Sce(1)_Pro(DefaultNameSoilProfile1D)")); Assert.That(result.CalculationSubDir, Is.EqualTo("..\\Test\\Stability\\UpliftVan")); Assert.That(result.CalculationResult, Is.EqualTo(CalculationResult.Succeeded)); Assert.That(result.StabilityDesignResults.SafetyFactor, Is.EqualTo(1.2812).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ActiveCenterPoint.X, Is.EqualTo(52.75).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ActiveCenterPoint.Z, Is.EqualTo(16.75).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ActiveCenterPointRadius, Is.EqualTo(17).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.PassiveCenterPoint.X, Is.EqualTo(58.5)); Assert.That(result.StabilityDesignResults.PassiveCenterPoint.Z, Is.EqualTo(1.95)); Assert.That(result.StabilityDesignResults.PassiveCenterPointRadius, Is.EqualTo(2.2)); Assert.That(result.StabilityDesignResults.ResultSlices, Has.Count.EqualTo(22)); }); Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel, Is.EqualTo(ShearStrengthModel.CPhi)); Assert.That(result.StabilityDesignResults.ResultSlices[0].EffectiveStress, Is.EqualTo(0.3364).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].FrictionAngleInput, Is.EqualTo(31).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].OCR, Is.EqualTo(double.NaN).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].NormalStress, Is.EqualTo(0.2370).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X, Is.EqualTo(40.4643).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z, Is.EqualTo(5.000).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].Width, Is.EqualTo(0.0357).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[0].Weight, Is.EqualTo(0.0120).Within(tolerance4Decimals)); }); var index = 11; Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel, Is.EqualTo(ShearStrengthModel.CPhi)); Assert.That(result.StabilityDesignResults.ResultSlices[index].EffectiveStress, Is.EqualTo(3.4795).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].FrictionAngleInput, Is.EqualTo(31).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].OCR, Is.EqualTo(double.NaN).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].NormalStress, Is.EqualTo(3.2772).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, Is.EqualTo(49.8453).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, Is.EqualTo(0.3274).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].Width, Is.EqualTo(0.6547).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].Weight, Is.EqualTo(2.6007).Within(tolerance4Decimals)); }); index = result.StabilityDesignResults.ResultSlices.Count - 1; Assert.Multiple(() => { Assert.That(result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel, Is.EqualTo(ShearStrengthModel.CPhi)); Assert.That(result.StabilityDesignResults.ResultSlices[index].EffectiveStress, Is.EqualTo(1.2862).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].FrictionAngleInput, Is.EqualTo(31).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].OCR, Is.EqualTo(double.NaN).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].NormalStress, Is.EqualTo(1.3009).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, Is.EqualTo(58.5000).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, Is.EqualTo(0.0000).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].Width, Is.EqualTo(0.1233).Within(tolerance4Decimals)); Assert.That(result.StabilityDesignResults.ResultSlices[index].Weight, Is.EqualTo(0.3097).Within(tolerance4Decimals)); }); } } private static DamKernelInput CreateDamKernelInputForTest(MStabModelType modelType, MStabSearchMethod searchMethod = MStabSearchMethod.Grid, GridSizeDetermination gridSizeDetermination = GridSizeDetermination.Specified, TangentLinesDefinition tangentLinesDefinition = TangentLinesDefinition.OnBoundaryLines) { Location location = DamEngineDataTestFactory.CreateLocation(FactoryForSurfaceLines.CreateSurfaceLineTutorial1()); // Correction needed in order to make surface line as lengthy as needed to perform a proper calculation. location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X = 100; // Correction needed in order to make surface line points strictly increasing (ditch was vertical at polderside, // now this not allowed by the kernel validator!) So that needs to be fixed in the kernel). location.SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DitchPolderSide).X = 62.5; location.SurfaceLine.Geometry.SyncCalcPoints(); // To ensure uplift occurs, set criterion to 1.4 location.ModelFactors.UpliftCriterionStability = 1.4; SoilProfile1D soilProfile = DamEngineDataTestFactory.CreateSoilProfile1D(location.SoilList); SetWaterPressureInterpolationModel(soilProfile.Layers); // This test is based on a 1D profile, to be combined with the surface line. var subSoilScenario = new SoilGeometryProbability { SoilProfileType = SoilProfileType.ProfileType1D, SoilProfile2D = null, SegmentFailureMechanismType = SegmentFailureMechanismType.Stability, SoilProfile1D = soilProfile }; var damKernelInput = new DamKernelInput { FilenamePrefix = "Loc(TestLocation)_Sce(1)", CalculationDir = "..\\Test", Location = location, SubSoilScenario = subSoilScenario, RiverLevelLow = null, DamFailureMechanismeCalculationSpecification = new DamFailureMechanismeCalculationSpecification() }; SlipCircleDefinition sd = damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab .MStabParameters.SlipCircleDefinition; sd.UpliftVanLeftGridHorizontalPointCount = 3; sd.UpliftVanLeftGridVerticalPointCount = 3; sd.UpliftVanLeftGridHorizontalPointDistance = 1; sd.UpliftVanLeftGridVerticalPointDistance = 1; sd.UpliftVanRightGridHorizontalPointCount = 3; sd.UpliftVanRightGridVerticalPointCount = 3; sd.UpliftVanRightGridHorizontalPointDistance = 1; sd.UpliftVanRightGridVerticalPointDistance = 1; sd.UpliftVanTangentLinesDefinition = tangentLinesDefinition; sd.UpliftVanTangentLinesDistance = 1; sd.UpliftVanGridSizeDetermination = gridSizeDetermination; damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model = modelType; damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.SearchMethod = searchMethod; damKernelInput.CurrentEmbankmentSoil = damKernelInput.Location.GetDikeEmbankmentSoil(); return damKernelInput; } private static void SetWaterPressureInterpolationModel(IEnumerable layers) { foreach (SoilLayer1D layer in layers) { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic; } } }