// 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 readonly string inputXmlForDamEngine = Path.Combine(TestFolder, "StabilityDesign1Dbased.xml"); [Test] public void TestPrepare() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan } } }; DamKernelInput kernelInput = CreateDamKernelInputForTest(); // Situation 1: no uplift. Expected PrepareResult.NotRelevant kernelInput.Location.ModelFactors.UpliftCriterionStability = 0.8; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out IKernelDataOutput kernelDataOutput); Assert.AreEqual(PrepareResult.NotRelevant, prepareResult); var damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult); Assert.AreEqual(false, damMacroStabilityOutput.UpliftSituation.IsUplift); // Situation 2: there is uplift and prepare succeeds. Expected PrepareResult.Successful kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4; prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out kernelDataOutput); Assert.AreEqual(PrepareResult.Successful, prepareResult); damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult); Assert.AreEqual(true, damMacroStabilityOutput.UpliftSituation.IsUplift); // Situation 3: prepare fails. Expected PrepareResult.Failed kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.2; kernelInput.Location.SurfaceLine.CharacteristicPoints.Clear(); prepareResult = kernelWrapper.Prepare(kernelInput, 0, out _, out kernelDataOutput); Assert.AreEqual(PrepareResult.Failed, prepareResult); damMacroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.AreEqual(CalculationResult.NoRun, damMacroStabilityOutput.CalculationResult); } [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.IsTrue(errorCount > 0); Assert.AreEqual(CalculationResult.InvalidInputData, macroStabilityOutput.CalculationResult); // Validate the input when valid input is provided. Expected no messages. DamKernelInput kernelInput = CreateDamKernelInputForTest(); kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.IsTrue(prepareResult == PrepareResult.Successful); messages.Clear(); errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out messages); Assert.IsTrue(errorCount == 0); Assert.AreEqual(CalculationResult.NoRun, ((MacroStabilityOutput) kernelDataOutput).CalculationResult); } [Test] [TestCase(MStabModelType.Bishop)] [TestCase(MStabModelType.UpliftVan)] [TestCase(MStabModelType.BishopUpliftVan)] public void TestPostProcess(MStabModelType modelType) { var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = modelType } } }; DamKernelInput kernelInput = CreateDamKernelInputForTest(); 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 }; 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, Cohesion = 14.5, CohesionCalculated = 15.5, FrictionAngleInput = 30, FrictionAngle = 30.5, YieldStress = 22, OCR = 23, POP = 24, DegreeOfConsolidationPorePressure = 25, PorePressureDueToDegreeOfConsolidationLoad = 26, DilatancyInput = 27, Dilatancy = 28, 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, ShearStress = 45, SoilStress = 46, TotalPorePressure = 47, TotalStress = 48, Weight = 49, Su = 50, 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.AreEqual(1, results.Count); break; case MStabModelType.BishopUpliftVan: Assert.AreEqual(3, results.Count); 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, null }; 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.AreEqual(CalculationResult.Succeeded, result.CalculationResult); Assert.AreEqual(true, ((UpliftSituation) result.StabilityDesignResults.UpliftSituation).IsUplift); if (index == 0) { Assert.AreEqual(Path.GetFileNameWithoutExtension(inputXmlForDamEngine), result.BaseFileName); Assert.AreEqual(TestFolder + "@\testpath", result.CalculationSubDir); } Assert.AreEqual(expectedNumberOfIterations[index], result.StabilityDesignResults.NumberOfIterations); Assert.AreEqual(expectedSafetyFactor[index], result.StabilityDesignResults.SafetyFactor); Assert.AreEqual(kernelInput.Location.SurfaceLine, result.StabilityDesignResults.RedesignedSurfaceLine); Assert.AreEqual(kernelInput.SubSoilScenario.ToString(), result.ProfileName); Assert.AreEqual(expectedStabilityModelType[index], result.StabilityDesignResults.StabilityModelType); Assert.AreEqual(10, result.StabilityDesignResults.ActiveCenterPoint.X); Assert.AreEqual(10, result.StabilityDesignResults.ActiveCenterPoint.Z); Assert.AreEqual(8, result.StabilityDesignResults.ActiveCenterPointRadius); if (result.StabilityDesignResults.StabilityModelType != MStabModelType.Bishop) { Assert.AreEqual(22, result.StabilityDesignResults.PassiveCenterPoint.X); Assert.AreEqual(11, result.StabilityDesignResults.PassiveCenterPoint.Z); Assert.AreEqual(7, result.StabilityDesignResults.PassiveCenterPointRadius); } Assert.AreEqual(9, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X); Assert.AreEqual(3, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z); Assert.AreEqual(9.2, result.StabilityDesignResults.ResultSlices[0].TopRightPoint.X); Assert.AreEqual(3.01, result.StabilityDesignResults.ResultSlices[0].TopRightPoint.Z); Assert.AreEqual(9, result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.X); Assert.AreEqual(-3, result.StabilityDesignResults.ResultSlices[0].BottomLeftPoint.Z); Assert.AreEqual(9.2, result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.X); Assert.AreEqual(-3.1, result.StabilityDesignResults.ResultSlices[0].BottomRightPoint.Z); Assert.AreEqual("slice1", result.StabilityDesignResults.ResultSlices[0].Name); Assert.AreEqual(0.2, result.StabilityDesignResults.ResultSlices[0].Width); Assert.AreEqual(0.22, result.StabilityDesignResults.ResultSlices[0].ArcLength); Assert.AreEqual(0, result.StabilityDesignResults.ResultSlices[0].TopAngle); Assert.AreEqual(12.2, result.StabilityDesignResults.ResultSlices[0].BottomAngle); Assert.AreEqual(14, result.StabilityDesignResults.ResultSlices[0].CohesionInput); Assert.AreEqual(14.5, result.StabilityDesignResults.ResultSlices[0].Cohesion); Assert.AreEqual(15.5, result.StabilityDesignResults.ResultSlices[0].CohesionCalculated); Assert.AreEqual(30, result.StabilityDesignResults.ResultSlices[0].FrictionAngleInput); Assert.AreEqual(30.5, result.StabilityDesignResults.ResultSlices[0].FrictionAngle); Assert.AreEqual(22, result.StabilityDesignResults.ResultSlices[0].YieldStress); Assert.AreEqual(23, result.StabilityDesignResults.ResultSlices[0].OCR); Assert.AreEqual(24, result.StabilityDesignResults.ResultSlices[0].POP); Assert.AreEqual(25, result.StabilityDesignResults.ResultSlices[0].DegreeOfConsolidationPorePressure); Assert.AreEqual(26, result.StabilityDesignResults.ResultSlices[0].PorePressureDueToDegreeOfConsolidationLoad); Assert.AreEqual(27, result.StabilityDesignResults.ResultSlices[0].DilatancyInput); Assert.AreEqual(28, result.StabilityDesignResults.ResultSlices[0].Dilatancy); Assert.AreEqual(29, result.StabilityDesignResults.ResultSlices[0].ExternalLoad); Assert.AreEqual(30, result.StabilityDesignResults.ResultSlices[0].HydrostaticPorePressure); Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[0].LeftForce); Assert.AreEqual(32, result.StabilityDesignResults.ResultSlices[0].LeftForceAngle); Assert.AreEqual(33, result.StabilityDesignResults.ResultSlices[0].LeftForceY); Assert.AreEqual(34, result.StabilityDesignResults.ResultSlices[0].RightForce); Assert.AreEqual(35, result.StabilityDesignResults.ResultSlices[0].RightForceAngle); Assert.AreEqual(36, result.StabilityDesignResults.ResultSlices[0].RightForceY); Assert.AreEqual(37, result.StabilityDesignResults.ResultSlices[0].LoadStress); Assert.AreEqual(38, result.StabilityDesignResults.ResultSlices[0].NormalStress); Assert.AreEqual(39, result.StabilityDesignResults.ResultSlices[0].PorePressure); Assert.AreEqual(40, result.StabilityDesignResults.ResultSlices[0].HorizontalPorePressure); Assert.AreEqual(41, result.StabilityDesignResults.ResultSlices[0].VerticalPorePressure); Assert.AreEqual(42, result.StabilityDesignResults.ResultSlices[0].PiezometricPorePressure); Assert.AreEqual(43, result.StabilityDesignResults.ResultSlices[0].EffectiveStress); Assert.AreEqual(44, result.StabilityDesignResults.ResultSlices[0].ExcessPorePressure); Assert.AreEqual(45, result.StabilityDesignResults.ResultSlices[0].ShearStress); Assert.AreEqual(46, result.StabilityDesignResults.ResultSlices[0].SoilStress); Assert.AreEqual(47, result.StabilityDesignResults.ResultSlices[0].TotalPorePressure); Assert.AreEqual(48, result.StabilityDesignResults.ResultSlices[0].TotalStress); Assert.AreEqual(49, result.StabilityDesignResults.ResultSlices[0].Weight); Assert.AreEqual(50, result.StabilityDesignResults.ResultSlices[0].Su); Assert.AreEqual(51, result.StabilityDesignResults.ResultSlices[0].HorizontalSoilQuakeStress); Assert.AreEqual(52, result.StabilityDesignResults.ResultSlices[0].StrengthIncreaseExponent); Assert.AreEqual(53, result.StabilityDesignResults.ResultSlices[0].UpliftFactor); Assert.AreEqual(54, result.StabilityDesignResults.ResultSlices[0].VerticalSoilQuakeStress); Assert.AreEqual(55, result.StabilityDesignResults.ResultSlices[0].WaterQuakeStress); Assert.AreEqual(56, result.StabilityDesignResults.ResultSlices[0].UpliftReductionFactor); Assert.AreEqual(57, result.StabilityDesignResults.ResultSlices[0].RatioCuPc); Assert.AreEqual(58, result.StabilityDesignResults.ResultSlices[0].ResultantForce); Assert.AreEqual(59, result.StabilityDesignResults.ResultSlices[0].ResultantMoment); Assert.AreEqual(60, result.StabilityDesignResults.ResultSlices[0].ResultantAngle); Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel); } } [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.IsTrue(messages.Count > 0); // as there is no data at all, expect unexpected error Assert.AreEqual(CalculationResult.UnexpectedError, macroStabilityOutput.CalculationResult); } [Test] public void TestFullCalculationSucceedsWithWarningsWithBadTangentLines() { var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan } } }; // Prepare the wrapper. Result is input for the calculation dll DamKernelInput kernelInput = CreateDamKernelInputForTest(); kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4; SlipCircleDefinition sd = kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab .MStabParameters.SlipCircleDefinition; sd.UpliftVanTangentLinesDefinition = TangentLinesDefinition.Specified; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.AreEqual(PrepareResult.Successful, prepareResult); // Validate the input int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages); Assert.IsTrue(errorCount == 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.AreEqual(51, messages.Count); Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult); Assert.IsTrue(messages[0].Message.Contains("A slice is beyond the geometry at x")); } [Test] public void TestFullCalculationSucceeds() { const double diff = 0.0001; var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan } } }; // Prepare the wrapper. Result is input for the calculation dll DamKernelInput kernelInput = CreateDamKernelInputForTest(); // To ensure uplift occurs, set criterion to 1.4 kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.AreEqual(PrepareResult.Successful, prepareResult); // Validate the input int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages); Assert.IsTrue(errorCount == 0); // Run the dll kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages); var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.AreEqual(2, messages.Count); Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult); Assert.AreEqual(1, macroStabilityOutput.StabilityOutputItems.Count); Assert.AreEqual(1.5211, macroStabilityOutput.StabilityOutputItems[0].SafetyFactor, diff); // ToDo replace by actual value when calculation is done and output is parsed // Fill the design results var designScenario = new DesignScenario { LocationName = kernelInput.Location.Name }; kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results); Assert.IsTrue(results.Count > 0); foreach (DesignResult result in results) { Assert.AreEqual("Loc(TestLocation)_Sce(1)_Pro(DefaultNameSoilProfile1D)", result.BaseFileName); Assert.AreEqual("..\\Test\\Stability\\UpliftVan", result.CalculationSubDir); Assert.AreEqual(CalculationResult.Succeeded, result.CalculationResult); Assert.That(result.StabilityDesignResults.SafetyFactor, Is.EqualTo(1.5211).Within(diff)); Assert.AreEqual(50.5, result.StabilityDesignResults.ActiveCenterPoint.X, diff); Assert.AreEqual(12, result.StabilityDesignResults.ActiveCenterPoint.Z, diff); Assert.AreEqual(22, result.StabilityDesignResults.ActiveCenterPointRadius, diff); Assert.AreEqual(50.5, result.StabilityDesignResults.PassiveCenterPoint.X); Assert.AreEqual(2.2, result.StabilityDesignResults.PassiveCenterPoint.Z); Assert.AreEqual(12.2, result.StabilityDesignResults.PassiveCenterPointRadius); Assert.AreEqual(40, result.StabilityDesignResults.ResultSlices.Count); Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[0].ShearStrengthModel); Assert.AreEqual(15.8180658, result.StabilityDesignResults.ResultSlices[0].EffectiveStress, diff); Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[0].FrictionAngle, diff); Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[0].OCR, diff); Assert.AreEqual(8.8710528, result.StabilityDesignResults.ResultSlices[0].NormalStress, diff); Assert.AreEqual(29.9769477, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.X, diff); Assert.AreEqual(4.0750819, result.StabilityDesignResults.ResultSlices[0].TopLeftPoint.Z, diff); Assert.AreEqual(0.6946544, result.StabilityDesignResults.ResultSlices[0].Width, diff); Assert.AreEqual(10.9880897, result.StabilityDesignResults.ResultSlices[0].Weight, diff); var index = 21; Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel); Assert.AreEqual(116.6794325, result.StabilityDesignResults.ResultSlices[index].EffectiveStress, diff); Assert.AreEqual(10, result.StabilityDesignResults.ResultSlices[index].FrictionAngle, diff); Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[index].OCR, diff); Assert.AreEqual(114.2973685, result.StabilityDesignResults.ResultSlices[index].NormalStress, diff); Assert.AreEqual(46.8636363, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, diff); Assert.AreEqual(1.8181818, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, diff); Assert.AreEqual(0.9090909, result.StabilityDesignResults.ResultSlices[index].Width, diff); Assert.AreEqual(193.1479678, result.StabilityDesignResults.ResultSlices[index].Weight, diff); index = result.StabilityDesignResults.ResultSlices.Count - 1; Assert.AreEqual(ShearStrengthModel.CPhi, result.StabilityDesignResults.ResultSlices[index].ShearStrengthModel); Assert.AreEqual(5.5185653, result.StabilityDesignResults.ResultSlices[index].EffectiveStress, diff); Assert.AreEqual(31, result.StabilityDesignResults.ResultSlices[index].FrictionAngle, diff); Assert.AreEqual(double.NaN, result.StabilityDesignResults.ResultSlices[index].OCR, diff); Assert.AreEqual(7.2892231, result.StabilityDesignResults.ResultSlices[index].NormalStress, diff); Assert.AreEqual(61.5363037, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.X, diff); Assert.AreEqual(-1.9273925, result.StabilityDesignResults.ResultSlices[index].TopLeftPoint.Z, diff); Assert.AreEqual(0.9636962, result.StabilityDesignResults.ResultSlices[index].Width, diff); Assert.AreEqual(10.3883614, result.StabilityDesignResults.ResultSlices[index].Weight, diff); } } [Test] public void TestFullCalculationSucceedsWithBeeSwarmAsSearchMethod() { const double diff = 0.0001; var kernelWrapper = new MacroStabilityInwardsKernelWrapper { FailureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { Model = MStabModelType.UpliftVan, SearchMethod = MStabSearchMethod.BeeSwarm } } }; // Prepare the wrapper. Result is input for the calculation dll DamKernelInput kernelInput = CreateDamKernelInputForTest(); kernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters .SearchMethod = MStabSearchMethod.BeeSwarm; // To ensure uplift occurs, set criterion to 1.4 kernelInput.Location.ModelFactors.UpliftCriterionStability = 1.4; PrepareResult prepareResult = kernelWrapper.Prepare(kernelInput, 0, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput); Assert.AreEqual(PrepareResult.Successful, prepareResult); // Validate the input int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out List messages); Assert.AreEqual(0, errorCount); // Run the dll kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out messages); var macroStabilityOutput = (MacroStabilityOutput) kernelDataOutput; Assert.AreEqual(3, messages.Count); Assert.AreEqual(CalculationResult.Succeeded, macroStabilityOutput.CalculationResult); Assert.AreEqual(1, macroStabilityOutput.StabilityOutputItems.Count); // SafetyFactor as obtained when running the skx file with this input in the stability kernel directly = 1.9882432331086863 Assert.AreEqual(1.99423, macroStabilityOutput.StabilityOutputItems[0].SafetyFactor, diff); // Fill the design results var designScenario = new DesignScenario { LocationName = kernelInput.Location.Name }; kernelWrapper.PostProcess(kernelInput, macroStabilityOutput, designScenario, "", out List results); Assert.IsTrue(results.Count > 0); } [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.IsNotNull(engineInterface.DamProjectData); engineInterface.DamProjectData.DamProjectCalculationSpecification.CurrentSpecification.StabilityModelType = MStabModelType.UpliftVan; Output output = GeneralHelper.RunAfterInputValidation(engineInterface); Assert.AreEqual(1.638, output.Results.CalculationResults[0].StabilityDesignResults.SafetyFactor, 0.001); } [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 DamKernelInput CreateDamKernelInputForTest() { 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 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(); 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, StiFileName = "", FullStiFileName = "", 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.OnBoundaryLines; sd.UpliftVanTangentLinesDistance = 1; sd.GridSizeDetermination = GridSizeDetermination.Specified; damKernelInput.DamFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab.MStabParameters.Model = MStabModelType.UpliftVan; return damKernelInput; } private static void SetWaterpressureInterpolationModel(IEnumerable layers) { foreach (SoilLayer1D layer in layers) { layer.WaterpressureInterpolationModel = WaterpressureInterpolationModel.Hydrostatic; } } }