// 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.IO; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Interface; using Deltares.DamEngine.Io.XmlOutput; using Deltares.DamEngine.TestHelpers; using NUnit.Framework; namespace Deltares.DamEngine.IntegrationTests.IntegrationTests { [TestFixture] public class ShearStrengthModelsTests { private const double tolerance6Decimals = 0.00000051; /// /// This test compares the safety factor calculated with the different in 2 cases: /// - CASE 1: The shear stress is not constant but almost equals in the 4 following shear strength models: /// - Mohr-Coulomb (c=5, phi=psi=45) leading to a shear stress of Tau = 5 + NormalEffectiveStress /// - SigmaTau table with one segment line (0, 5)-(400, 405) equivalent to Mohr-Coulomb /// - SHANSEP (m=S=1, POP=5) leading to a shear stress of Tau = 5 + VerticalEffectiveStress /// - SuTable with one segment line (0, 5)-(1000, 1005) equivalent to Shansep /// Expected is that both shear strength models Mohr-Coulomb and SigmaTau return the same result. /// However, due to the "cut-off" method (reduction of the bottom angle of the slices when too high) which applies to /// Mohr-Coulomb but not SigmaTau table, a small difference in the safety factor is expected. /// But SHANSEP should return a higher safety factor because the VerticalEffectiveStress is higher than the NormalEffectiveStress. /// Both shear strength models SHANSEP and SigmaTau should return the same result. /// - CASE 2: The shear stress is constant in the 3 following shear strength models: /// - Mohr-Coulomb (c=15, phi=psi=0) leading to a shear stress of Tau = 15 /// - SigmaTau table with one segment line (0, 15)-(400, 15) leading to Tau = 15 /// - SuTable with one segment line (0, 15)-(1000, 15) leading to Tau = 15 /// Expected is that the 3 models return the same result. /// [Test] public void GivenSoilProfilesWithDifferentShearStrengthModelWhenRunningThenExpectedResultsAreReturned() { const string calcDir = "GivenSoilProfilesWithDifferentShearStrengthModelWhenRunningThenExpectedResultsAreReturned"; if (Directory.Exists(calcDir)) { Directory.Delete(calcDir, true); // delete previous results } Directory.CreateDirectory(calcDir); const string fileName = @"TestFiles\ShearStrengthModelsTests\InputFileShearStrengthModelsComparison.xml"; string inputString = File.ReadAllText(fileName); inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used Output output = GeneralHelper.RunAfterInputValidation(inputString); Assert.That(output.Results.CalculationResults, Has.Length.EqualTo(7)); for (var i = 0; i < 7; i++) { Assert.Multiple(() => { Assert.That(output.Results.CalculationResults[i].CalculationResult, Is.EqualTo(ConversionHelper.ConvertToOutputCalculationResult(CalculationResult.Succeeded))); Assert.That(output.Results.CalculationResults[i].StabilityDesignResults.ResultMessage, Is.EqualTo("")); }); } Assert.Multiple(() => { Assert.That(output.Results.CalculationResults[0].LocationName, Is.EqualTo("Comparison models (constant tau)")); Assert.That(output.Results.CalculationResults[0].ProfileName, Is.EqualTo("MohrCoulombPhi0")); Assert.That(output.Results.CalculationResults[0].StabilityDesignResults.SafetyFactor, Is.EqualTo(1.080048).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[1].ProfileName, Is.EqualTo("SigmaTauCsttTau")); Assert.That(output.Results.CalculationResults[1].StabilityDesignResults.SafetyFactor, Is.EqualTo(1.080048).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[2].ProfileName, Is.EqualTo("SuTableCsttSu")); Assert.That(output.Results.CalculationResults[2].StabilityDesignResults.SafetyFactor, Is.EqualTo(1.080048).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[3].LocationName, Is.EqualTo("Comparison models (not constant tau)")); Assert.That(output.Results.CalculationResults[3].ProfileName, Is.EqualTo("MohrCoulombPhi45")); Assert.That(output.Results.CalculationResults[3].StabilityDesignResults.SafetyFactor, Is.EqualTo(3.064123).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[4].ProfileName, Is.EqualTo("SigmaTauPhi45")); Assert.That(output.Results.CalculationResults[4].StabilityDesignResults.SafetyFactor, Is.EqualTo(3.066645).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[5].ProfileName, Is.EqualTo("ShansepPhi45")); Assert.That(output.Results.CalculationResults[5].StabilityDesignResults.SafetyFactor, Is.EqualTo(3.484979).Within(tolerance6Decimals)); Assert.That(output.Results.CalculationResults[6].ProfileName, Is.EqualTo("SuTablePhi45")); Assert.That(output.Results.CalculationResults[6].StabilityDesignResults.SafetyFactor, Is.EqualTo(3.484979).Within(tolerance6Decimals)); }); } /// /// This test uses the same data as location "Comparison models (not constant tau)" in test /// GivenSoilProfilesWithDifferentShearStrengthModelWhenRunningThenExpectedResultsAreReturned (without SuTable), /// except for the sigma-tau curve which starts at 2 instead of 0. /// Expected is that the soil profile SigmaTauMaterial returns no result and that a clear calculation error message is displayed. /// [Test] public void GivenInvalidSigmaTauCurveNotStartingAt0WhenCalculatingReturnsCalculationErrorMessage() { const string calcDir = "GivenInvalidSigmaTauCurveNotStartingAt0WhenCalculatingReturnsCalculationErrorMessage"; if (Directory.Exists(calcDir)) { Directory.Delete(calcDir, true); // delete previous results } Directory.CreateDirectory(calcDir); const string fileName = @"TestFiles\ShearStrengthModelsTests\InputFileInvalidSigmaTauCurveNotStartingAt0.xml"; string inputString = File.ReadAllText(fileName); inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used Output output = GeneralHelper.RunAfterInputValidation(inputString); Assert.That(output.Results.CalculationResults, Has.Length.EqualTo(2)); Assert.Multiple(() => { Assert.That(output.Results.CalculationResults[0].ProfileName, Is.EqualTo("MohrCoulombMaterial")); Assert.That(output.Results.CalculationResults[0].CalculationResult, Is.EqualTo(ConversionHelper.ConvertToOutputCalculationResult(CalculationResult.Succeeded))); Assert.That(output.Results.CalculationResults[1].ProfileName, Is.EqualTo("ShansepMaterial")); Assert.That(output.Results.CalculationResults[1].CalculationResult, Is.EqualTo(ConversionHelper.ConvertToOutputCalculationResult(CalculationResult.Succeeded))); }); Assert.That(output.Results.CalculationMessages, Has.Length.EqualTo(3)); Assert.Multiple(() => { Assert.That(output.Results.CalculationMessages[0].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[0].Message1, Is.EqualTo("Validation failed for location 'Comparison Mohr-Coulomb SigmaTau and SHANSEP', subsoil scenario 'SigmaTauMaterial', design scenario '1'")); Assert.That(output.Results.CalculationMessages[1].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[1].Message1, Is.EqualTo("The first sigma value must be 0 for sigma/tau table ")); Assert.That(output.Results.CalculationMessages[2].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[2].Message1, Is.EqualTo("The first sigma value must be 0 for sigma/tau table ")); }); } /// /// This test uses the same data as test GivenSoilProfilesWithDifferentShearStrengthModelWhenRunningThenExpectedResultsAreReturned, /// except for the su table nr. 2 which starts at 2 instead of 0. /// Expected is that the soil profile SuTableCsttTau returns no result and that a clear calculation error message is displayed. /// [Test] public void GivenInvalidSuTableNotStartingAt0WhenCalculatingReturnsCalculationErrorMessage() { const string calcDir = "GivenInvalidSuTableNotStartingAt0WhenCalculatingReturnsCalculationErrorMessage"; if (Directory.Exists(calcDir)) { Directory.Delete(calcDir, true); // delete previous results } Directory.CreateDirectory(calcDir); const string fileName = @"TestFiles\ShearStrengthModelsTests\InputFileInvalidSuTableNotStartingAt0.xml"; string inputString = File.ReadAllText(fileName); inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used Output output = GeneralHelper.RunAfterInputValidation(inputString); Assert.That(output.Results.CalculationResults, Has.Length.EqualTo(6)); Assert.Multiple(() => { Assert.That(output.Results.CalculationResults[0].ProfileName, Is.EqualTo("MohrCoulombPhi0")); Assert.That(output.Results.CalculationResults[1].ProfileName, Is.EqualTo("SigmaTauCsttTau")); Assert.That(output.Results.CalculationResults[2].ProfileName, Is.EqualTo("MohrCoulombPhi45")); Assert.That(output.Results.CalculationResults[3].ProfileName, Is.EqualTo("SigmaTauPhi45")); Assert.That(output.Results.CalculationResults[4].ProfileName, Is.EqualTo("ShansepPhi45")); Assert.That(output.Results.CalculationResults[5].ProfileName, Is.EqualTo("SuTablePhi45")); Assert.That(output.Results.CalculationMessages, Has.Length.EqualTo(3)); }); Assert.Multiple(() => { Assert.That(output.Results.CalculationMessages[0].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[0].Message1, Is.EqualTo("Validation failed for location 'Comparison models (constant tau)', subsoil scenario 'SuTableCsttSu', design scenario '1'")); Assert.That(output.Results.CalculationMessages[1].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[1].Message1, Is.EqualTo("Su table first point must have an effective stress of 0")); Assert.That(output.Results.CalculationMessages[2].MessageType, Is.EqualTo(MessageMessageType.Error)); Assert.That(output.Results.CalculationMessages[2].Message1, Is.EqualTo("Su table first point must have an effective stress of 0")); }); } } }