// Copyright (C) Stichting Deltares 2018. 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.DamMacroStabilityCommon; using Deltares.DamEngine.Calculators.KernelWrappers.DamMacroStabilityHorizontalBalance; using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; using Deltares.DamEngine.Calculators.Tests.KernelWrappers.DamMacroStabilityCommon; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamEngine.TestHelpers.Factories; using NUnit.Framework; namespace Deltares.DamEngine.Calculators.Tests.KernelWrappers.DamMacroStabilityHorizontalBalance { [TestFixture] public class DamMacroStabilityHorizontalBalanceKernelWrapperTests { private const string testFolder = @"..\..\Deltares.DamEngine.Calculators.Tests\KernelWrappers\DamMacroStabilityCommon\TestData"; [Test] public void TestNotRelevantCalculationForProcess() { // expected is that preparation of this calculation is not done. var absoluteFolder = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testFolder)); var workingDir = Path.Combine(absoluteFolder, "FullOut"); // Relative paths in ini file do not work yet in DGeoStability 16.2. This is fixed in 18.1. if (Directory.Exists(workingDir)) { Directory.Delete(workingDir, true); } var damKernelInput = CreateDamKernelInput(); damKernelInput.CalculationDir = workingDir; var failureMechanismParametersMStab = new FailureMechanismParametersMStab { ProjectWorkingPath = workingDir }; var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper { FailureMechanismParametersMStab = failureMechanismParametersMStab }; // Set the requested mechanism for this subsoil to StabilityInside to make it irrelevant damKernelInput.SubSoilScenario.SegmentFailureMechanismType = FailureMechanismSystemType.StabilityInside; // Prepare the wrapper. This should fail as the given mechanism is not relevant for this kernel IKernelDataInput damStabilityInput; IKernelDataOutput kernelOutput; var result = kernelWrapper.Prepare(damKernelInput, 0, out damStabilityInput, out kernelOutput); Assert.AreEqual(result, PrepareResult.NotRelevant); } [Test] public void TestFullCalculationForProcess() // based on CanCalculateStabilitySafetyFactorGeometry1DUsingSlopeW DamClassic { const double cToleranceSafetyFactor = 0.001; const double cTrafficLoad = 10.0; const double cMinimalCircleDepth = 1.0; var absoluteFolder = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testFolder)); var workingDir = Path.Combine(absoluteFolder, "FullOut"); // Relative paths in ini file do not work yet in DGeoStability 16.2. This is fixed in 18.1. if (Directory.Exists(workingDir)) { Directory.Delete(workingDir, true); } var line = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location(); var scenario = DamMacroStabilityTestHelper.CreateScenarioForLocation(location, line); scenario.RiverLevel = 4.0; scenario.Location.PolderLevel = -1.0; scenario.Location.StabilityOptions = new StabilityOptions { TrafficLoad = cTrafficLoad }; var soilDbName = Path.Combine(testFolder, "soilmaterials.mdb"); scenario.Location.StabilityOptions.SoilDatabaseName = soilDbName; var soilProfile = CreateSoilProfile(); //var modelParametersForPLLines = new ModelParametersForPlLines(); MStabParameters mstabParameters = new MStabParameters { ShearStrength = MStabShearStrength.CPhi, IsProbabilistic = false, Model = MStabModelType.HorizontalBalance, SearchMethod = MStabSearchMethod.Grid, GridPosition = MStabGridPosition.Right, ZonesType = MStabZonesType.NoZones, CalculationOptions = { MinimalCircleDepth = cMinimalCircleDepth } }; var subSoilScenario = new SoilGeometryProbability { SoilProfile1D = soilProfile, SoilProfileType = SoilProfileType.ProfileType1D, SegmentFailureMechanismType = FailureMechanismSystemType.HorizontalBalance }; var damFailureMechanismeCalculationSpecification = new DamFailureMechanismeCalculationSpecification { FailureMechanismSystemType = FailureMechanismSystemType.HorizontalBalance, FailureMechanismParametersMStab = new FailureMechanismParametersMStab() { MStabParameters = mstabParameters } }; var damKernelInput = new DamKernelInput { DamFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification, Location = location, SubSoilScenario = subSoilScenario, CalculationDir = workingDir }; var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper() { FailureMechanismParametersMStab = damFailureMechanismeCalculationSpecification.FailureMechanismParametersMStab }; // Prepare the wrapper. Result is input for the calculation dll IKernelDataInput damStabilityInput; IKernelDataOutput kernelOutput; var result = kernelWrapper.Prepare(damKernelInput, 0, out damStabilityInput, out kernelOutput); Assert.AreEqual(result, PrepareResult.Successful); // Validate the input List messages; kernelWrapper.Validate(damStabilityInput, kernelOutput, out messages); Assert.AreEqual(0, messages.Count); // Run the dll kernelWrapper.Execute(damStabilityInput, kernelOutput, out messages); DamMacroStabilityOutput damMacroStabilityOutput = (DamMacroStabilityOutput)kernelOutput; Assert.AreEqual(0, messages.Count); Assert.AreEqual(10.169, damMacroStabilityOutput.StabilityOutputItems[0].Zone1Results.SafetyFactor, cToleranceSafetyFactor); Assert.IsNull(damMacroStabilityOutput.StabilityOutputItems[0].Zone2Results); // Fill the design results List results; kernelWrapper.PostProcess(damKernelInput, damMacroStabilityOutput, null, "", out results); Assert.AreEqual(10.169, results[0].StabilityDesignResults.SafetyFactor, cToleranceSafetyFactor); Assert.AreEqual("", results[0].StabilityDesignResults.ResultMessage); Assert.AreEqual(CalculationResult.Succeeded, results[0].CalculationResult); } [Test] [ExpectedException(typeof(MStabXmlDocException), ExpectedMessage = "Model Horizontaal Evenwicht ondersteunt geen 2D profielen.")] [SetUICulture("nl-NL")] public void TestLanguageNLThrowsExceptionWhenInputUses2DProfile() { CreateKerneWrapperInputWith2DProfile(); } [Test] [ExpectedException(typeof(MStabXmlDocException), ExpectedMessage = "Model horizontal balance does not support 2d-geometries.")] [SetUICulture("en-US")] public void TestLanguageENThrowsExceptionWhenInputUses2DProfile() { CreateKerneWrapperInputWith2DProfile(); } [Test] [ExpectedException(typeof(NoNullAllowedException), ExpectedMessage = "Geen invoer object gedefinieerd voor Macrostabiliteit")] [SetUICulture("nl-NL")] public void TestLanguageNLThrowsExceptionWhenInputIsNull() { DamMacroStabilityHorizontalBalanceKernelWrapper.StabilityCalculator(null); } [Test] [ExpectedException(typeof(NoNullAllowedException), ExpectedMessage = "No input object defined for Macro Stability")] [SetUICulture("en-US")] public void TestLanguageENThrowsExceptionWhenInputIsNull() { DamMacroStabilityHorizontalBalanceKernelWrapper.StabilityCalculator(null); } [Test] [ExpectedException(typeof(NoNullAllowedException), ExpectedMessage = "No input object defined for Macro Stability")] [SetUICulture("en-US")] public void PostProcessTestLanguageENThrowsExceptionWhenInputIsNull() { var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper(); List results; kernelWrapper.PostProcess(null, null, null, "", out results); } [Test] [ExpectedException(typeof(NoNullAllowedException), ExpectedMessage = "Geen uitvoer object gedefinieerd voor Macrostabiliteit")] [SetUICulture("nl-NL")] public void PostProcessTestThrowsExceptionWhenOutputIsNull() { var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper(); List results; var damKernelInput = CreateDamKernelInput(); kernelWrapper.PostProcess(damKernelInput, null, null, "", out results); } [Test] public void TestPostProcess() { var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper(); var damKernelInput = CreateDamKernelInput(); DamMacroStabilityOutputItem outputItem = new DamMacroStabilityOutputItem(); var zone1 = new DamMacroStabilityOutputItem.ResultsSingleZone { SafetyFactor = 1.1, CircleSurfacePointLeftXCoordinate = 1.2, CircleSurfacePointRightXCoordinate = 1.3 }; outputItem.Zone1Results = zone1; DamMacroStabilityOutput output = new DamMacroStabilityOutput { StabilityOutputItems = new List { outputItem } }; var designScenario = new DesignScenario { Location = damKernelInput.Location }; List results; kernelWrapper.PostProcess(damKernelInput, output, designScenario, "", out results); Assert.AreEqual(1.1, results[0].StabilityDesignResults.SafetyFactor); Assert.AreEqual(1.1, results[0].StabilityDesignResults.Zone1SafetyFactor); // Horizontal Balance does not have results for zone 2 Assert.AreEqual(null, results[0].StabilityDesignResults.Zone2SafetyFactor); } private static DamKernelInput CreateDamKernelInput(bool realOut = false) { var absoluteFolder = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testFolder)); var soilDbName = Path.Combine(testFolder, "soilmaterials.mdb"); var soilGeometry2DName = "1D1.sti"; var line = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location(); if (realOut) { soilDbName = Path.Combine(absoluteFolder, "soilmaterialsOutwards.mdb"); soilGeometry2DName = "OutwardsZones.sti"; foreach (var characteristicPoint in line.CharacteristicPoints) { characteristicPoint.Z = characteristicPoint.Z - 3; } location.PolderLevel = -11; } var scenario = DamMacroStabilityTestHelper.CreateScenarioForLocation(location, line); scenario.Location.StabilityOptions = new StabilityOptions { TrafficLoad = 10.0, SoilGeometries2DPath = absoluteFolder, SoilDatabaseName = soilDbName }; scenario.ModelFactors.RequiredSafetyFactorStabilityOuterSlope = 1.1; var subSoilScenario = new SoilGeometryProbability { StiFileName = soilGeometry2DName, SoilProfileType = SoilProfileType.ProfileTypeStiFile, SegmentFailureMechanismType = FailureMechanismSystemType.HorizontalBalance }; var damFailureMechanismeCalculationSpecification = new DamFailureMechanismeCalculationSpecification() { FailureMechanismSystemType = FailureMechanismSystemType.HorizontalBalance, StabilityModelType = MStabModelType.Bishop }; var damKernelInput = new DamKernelInput { DamFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification, Location = location, SubSoilScenario = subSoilScenario }; return damKernelInput; } private static void CreateKerneWrapperInputWith2DProfile() { var absoluteFolder = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), testFolder)); var workingDir = Path.Combine(absoluteFolder, "FullOut"); // Relative paths in ini file do not work yet in DGeoStability 16.2. This is fixed in 18.1. if (Directory.Exists(workingDir)) { Directory.Delete(workingDir, true); } var damKernelInput = CreateDamKernelInput(); damKernelInput.ProjectDir = absoluteFolder; damKernelInput.CalculationDir = workingDir; var failureMechanismParametersMStab = new FailureMechanismParametersMStab { MStabParameters = { GridPosition = MStabGridPosition.Left, SearchMethod = MStabSearchMethod.Grid, CalculationOptions = { MinimalCircleDepth = 1.0 } }, ProjectWorkingPath = workingDir }; var kernelWrapper = new DamMacroStabilityHorizontalBalanceKernelWrapper() { FailureMechanismParametersMStab = failureMechanismParametersMStab }; // Prepare the wrapper. Result is input for the calculation dll IKernelDataInput damStabilityInput; IKernelDataOutput kernelOutput; kernelWrapper.Prepare(damKernelInput, 0, out damStabilityInput, out kernelOutput); } /// /// Create standard 4 layer soilprofile for tests /// /// public static SoilProfile1D CreateSoilProfile() { SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(); soilProfile.Name = "SoilProfileName"; soilProfile.Layers[0].Soil.Name = "DKN3"; soilProfile.Layers[1].Soil.Name = "zand"; soilProfile.Layers[2].Soil.Name = "DKN3"; soilProfile.Layers[3].Soil.Name = "zand"; return soilProfile; } } }