// Copyright (C) Stichting Deltares 2023. 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.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Interface;
using Deltares.DamEngine.Io;
using Deltares.DamEngine.Io.XmlOutput;
using Deltares.DamEngine.TestHelpers;
using NUnit.Framework;
using ConversionHelper = Deltares.DamEngine.Interface.ConversionHelper;
namespace Deltares.DamEngine.IntegrationTests.IntegrationTests;
[TestFixture]
public class WtiPipingSellmeijerRevisedTests
{
private const double tolerance = 0.0005;
private const string workingDir = @"TestFiles\";
private string oldWorkingDir;
[SetUp]
public void TestFixtureSetup()
{
oldWorkingDir = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(workingDir);
}
[TearDown]
public void TestFixtureTearDown()
{
Directory.SetCurrentDirectory(oldWorkingDir);
}
/// Test for different segmentFailureMechanismType
/// The soilprobabilities are set tot the specified segmentFailureMechanismType
[Test]
[TestCase(ConversionHelper.InputSegmentFailureMechanismPiping)]
[TestCase(ConversionHelper.InputSegmentFailureMechanismAll)]
public void CanPerformWtiDesignNoAdaptionPipingVoorbeeld1(int segmentFailureMechanismType)
{
// Based on ".\data\DamEngineTestProjects\PipingVoorbeeld1\PipingVoorbeeld1.damx"
// Set Analysis type to "No Adaption"
// Change Failure mechanism Piping to model Sellmeijer Revised (WBI)
const string fileName = @"PipingVoorbeeld1_WtiSellmeijerRevisedInputFile.xml";
string inputString = File.ReadAllText(fileName);
inputString = XmlAdapter.ChangeValueInXml(inputString, "SegmentFailureMechanismType", segmentFailureMechanismType.ToString());
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
Assert.IsNotNull(outputString);
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
Assert.IsNotNull(output.Results.CalculationResults, "No results available");
DamProjectData actualDamProjectData = FillDamFromXmlOutput.CreateDamProjectData(null, output);
SurfaceLine2 redesignedSurfaceLine = actualDamProjectData.DesignCalculations[0].PipingDesignResults.RedesignedSurfaceLine;
// The expected values below where calculated with DamEngine rev.2012,
// Piping factor = 0.432
Assert.AreEqual(0.432, output.Results.CalculationResults[0].PipingDesignResults.Wti2017FactorOverall, tolerance);
// H critical = 1.983
Assert.AreEqual(1.983, output.Results.CalculationResults[0].PipingDesignResults.Wti2017HcriticalOverall, tolerance);
// Piping exit point = 35.0
Assert.AreEqual(35.0, output.Results.CalculationResults[0].PipingDesignResults.ExitPointX, tolerance);
// Dike length = 25.00
Assert.That(redesignedSurfaceLine.GetDikeLength(), Is.EqualTo(25.00).Within(tolerance));
// Uplift = true
Assert.AreEqual(true, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.IsUplift);
// Uplift factor = 0.582
Assert.AreEqual(0.582, output.Results.CalculationResults[0].PipingDesignResults.UpliftFactor, tolerance);
// The adjusted PL3/PL4: for piping no adjustment has to be made
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3LocationXMinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4LocationXMinUplift, tolerance);
}
[Test]
public void CanPerformWtiSellmeijerRevisedDesignWithAdaptionPipingVoorbeeld1()
{
// Based on ".\data\DamEngineTestProjects\PipingVoorbeeld1\PipingVoorbeeld1.damx"
// Set Analysis type to "Adapt geometry"
// Change Failure mechanism Piping to model Sellmeijer Revised (WBI)
const string fileName = @"PipingVoorbeeld1_WtiSellmeijerRevisedDesignInputFile.xml";
string inputString = File.ReadAllText(fileName);
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
Assert.IsNotNull(outputString);
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
DamProjectData actualDamProjectData = FillDamFromXmlOutput.CreateDamProjectData(null, output);
SurfaceLine2 redesignedSurfaceLine = actualDamProjectData.DesignCalculations[0].PipingDesignResults.RedesignedSurfaceLine;
// The expected values below where calculated with DamEngine rev.2012,
// uplift = true
Assert.AreEqual(true, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.IsUplift);
// shoulder height = 1.995
Assert.AreEqual(1.995, redesignedSurfaceLine.DetermineShoulderHeight(), tolerance);
// Note Bka: Anwers here are 17 meter longer shoulder than Sellmeijer4Forces from which these tests are derived.
// dike length = 66.986 + 17
Assert.That(redesignedSurfaceLine.GetDikeLength(), Is.EqualTo(83.986).Within(tolerance));
// ShoulderWidth = X_Kruin binnenberm - X_Insteek binnenberm = 65.01 + 17 - 29.01 = 53.0
Assert.AreEqual(53.0, redesignedSurfaceLine.DetermineShoulderLength(), tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3LocationXMinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4LocationXMinUplift, tolerance);
// ExitPointX = X_Teen dijk binnenwaarts = 76.986 + 17
Assert.AreEqual(93.986, output.Results.CalculationResults[0].PipingDesignResults.ExitPointX, tolerance);
// expected value = 1.280
Assert.AreEqual(1.280, output.Results.CalculationResults[0].PipingDesignResults.Wti2017BackwardErosionFactor, tolerance);
// expected value = 4.697
Assert.AreEqual(4.697, output.Results.CalculationResults[0].PipingDesignResults.Wti2017BackwardErosionHcritical, tolerance);
// expected value = 0.582
Assert.AreEqual(0.582, output.Results.CalculationResults[0].PipingDesignResults.UpliftFactor, tolerance);
}
[Test]
public void CanPerformWtiSellmeijerRevisedDesignWithAdaptionWithHeightPipingVoorbeeld1()
{
// Based on ".\data\DamEngineTestProjects\PipingVoorbeeld1\PipingVoorbeeld1.damx"
// Set Analysis type to "Adapt geometry"
// Change Failure mechanism Piping to model Sellmeijer Revised (WBI)
// Set DTH = 4.5 for location "profiel 1"
const string fileName = @"PipingVoorbeeld1_WtiSellmeijerRevisedDesignHeightInputFile.xml";
string inputString = File.ReadAllText(fileName);
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
Assert.IsNotNull(outputString);
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
DamProjectData actualDamProjectData = FillDamFromXmlOutput.CreateDamProjectData(null, output);
SurfaceLine2 redesignedSurfaceLine = actualDamProjectData.DesignCalculations[0].PipingDesignResults.RedesignedSurfaceLine;
// The expected values below where calculated with DamEngine rev.2012,
// The following test are different from CanPerformWtiSellmeijerRevisedDesignWithAdaptionPipingVoorbeeld1()
Assert.AreEqual(4.5, redesignedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z, tolerance);
Assert.AreEqual(4.5, redesignedSurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z, tolerance);
// Note Bka: Anwers here are 17 meter longer shoulder than Sellmeijer4Forces from which these tests are derived.
// ShoulderWidth = X_Kruin binnenberm - X_Insteek binnenberm = 65.01 - 32.01 = 33.0 + 17 = 50
// Read from PipingSellmeijer4Forces_Piping_CharacteristicPoints.csv by export surfacelines in Release
Assert.AreEqual(50.0, redesignedSurfaceLine.DetermineShoulderLength(), tolerance);
// The following test are the same as for CanPerformWtiSellmeijerRevisedDesignWithAdaptionPipingVoorbeeld1()
Assert.AreEqual(true, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.IsUplift);
Assert.AreEqual(1.995, redesignedSurfaceLine.DetermineShoulderHeight(), tolerance);
Assert.That(redesignedSurfaceLine.GetDikeLength(), Is.EqualTo(83.986).Within(tolerance));
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl3LocationXMinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4MinUplift, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4HeadAdjusted, tolerance);
Assert.AreEqual(0.0, output.Results.CalculationResults[0].PipingDesignResults.UpliftSituation.Pl4LocationXMinUplift, tolerance);
Assert.AreEqual(1.280, output.Results.CalculationResults[0].PipingDesignResults.Wti2017BackwardErosionFactor, tolerance);
Assert.AreEqual(4.697, output.Results.CalculationResults[0].PipingDesignResults.Wti2017BackwardErosionHcritical, tolerance);
Assert.AreEqual(0.582, output.Results.CalculationResults[0].PipingDesignResults.UpliftFactor, tolerance);
}
[Test]
public void CanPerformWtiDesignNoAdaptionRechterDiezedijk()
{
// Based on ".\data\DamEngineTestProjects\Larenstein_AaenMaas\Rechter Diezedijk.damx"
// Set Analysis type to "No Adaption"
// Set model to Piping Sellmeijer Revised (WBI)
// Select all locations
const string fileName = @"Rechter Diezedijk_WtiSellmeijerRevisedInputFile.xml";
string inputString = File.ReadAllText(fileName);
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
Assert.IsNotNull(outputString);
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
// The expected values below where calculated with DamEngine rev.2016,
Assert.AreEqual(112, output.Results.CalculationResults.Length);
// result 1: safety factor = 90.000
Assert.AreEqual(CalculationResult.Succeeded, ConversionHelper.ConvertToCalculationResult(output.Results.CalculationResults[0].CalculationResult));
Assert.AreEqual(90.000, output.Results.CalculationResults[0].PipingDesignResults.Wti2017FactorOverall, tolerance);
// result 2: safety factor = 58.243
Assert.AreEqual(CalculationResult.Succeeded, ConversionHelper.ConvertToCalculationResult(output.Results.CalculationResults[2].CalculationResult));
Assert.AreEqual(58.241, output.Results.CalculationResults[2].PipingDesignResults.Wti2017FactorOverall, tolerance);
// result 3: safety factor = 0 NB. In 18.1.3 it was 90, but now we use Uplift calculation from WBI, before from DAM
Assert.AreEqual(CalculationResult.RunFailed, ConversionHelper.ConvertToCalculationResult(output.Results.CalculationResults[111].CalculationResult));
Assert.AreEqual(0.000, output.Results.CalculationResults[111].PipingDesignResults.Wti2017FactorOverall, tolerance);
}
[Test]
// This test runs the same project as CanPerformWtiDesignNoAdaptionRechterDiezedijk
// except that it runs it with both single core and multi core.
// The output of both runs must be the same
public void CompareResultFromMultiCoreRunWithSingleCoreRun()
{
var calcDir = "TestWtiPipingSingleCore";
var outputFileName = @"WtiPipingSingleCore.output.xml";
Output output = RunTestProjectCores(calcDir, outputFileName, 1);
string outputSingleCore = DamXmlSerialization.SaveOutputAsXmlString(output);
calcDir = "TestWtiPipingMultiCore";
outputFileName = @"WtiPipingMultiCore.output.xml";
output = RunTestProjectCores(calcDir, outputFileName, 4);
string outputMultiCore = DamXmlSerialization.SaveOutputAsXmlString(output);
Assert.AreEqual(outputSingleCore, outputMultiCore);
}
[Test]
[SetUICulture("en-US")]
public void CanPerformWtiSellmeijerRevisedFailingDesignRechterDiezedijk1Location()
{
// Based on ".\data\DamEngineTestProjects\Larenstein_AaenMaas\Rechter Diezedijk.damx"
// Set Analysis type to "No Adaption"
// Set model to Piping Sellmeijer Revised (WBI)
// Select first location (100)
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
const string fileName = @"Rechter Diezedijk_WtiSellmeijerRevisedFailedDesignInputFile_1Location.xml";
string inputString = File.ReadAllText(fileName);
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
Assert.AreEqual(2, output.Results.CalculationResults.Length);
// Expected an english message, but this can not be fixed with version 16.2 of the kernel, see MWDAM-1395
Assert.AreEqual("De effectieve spanning mag niet negatief zijn.\r\n", output.Results.CalculationResults[1].PipingDesignResults.ResultMessage);
Assert.AreEqual(CalculationResult.RunFailed, ConversionHelper.ConvertToCalculationResult(output.Results.CalculationResults[1].CalculationResult));
Assert.AreEqual("Location '100', subsoil scenario 'segment1_1D2', design scenario '1': " +
"The calculation failed with error message " +
"'The design was not successful. " +
"De effectieve spanning mag niet negatief zijn.\r\n'",
output.Results.CalculationMessages[0].Message1);
}
private Output RunTestProjectCores(string calcDir, string outputFileName, int coreCount)
{
if (Directory.Exists(calcDir))
{
Directory.Delete(calcDir, true); // delete previous results
}
Directory.CreateDirectory(calcDir);
const string inputFileName = @"Rechter Diezedijk_WtiSellmeijerRevisedInputFile.xml";
string inputString = File.ReadAllText(inputFileName);
inputString = XmlAdapter.ChangeValueInXml(inputString, "ProjectPath", ""); // Current directory will be used
inputString = XmlAdapter.ChangeValueInXml(inputString, "CalculationMap", calcDir); // Current directory will be used
inputString = XmlAdapter.ChangeValueInXml(inputString, "MaxCalculationCores", coreCount.ToString());
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
string outputString = engineInterface.Run();
File.WriteAllText(outputFileName, outputString, Encoding.Unicode);
Assert.IsNotNull(outputString);
return DamXmlSerialization.LoadOutputFromXmlString(outputString);
}
[Test]
[TestCase(1)]
[TestCase(4)]
public void TestWtiPipingSellmeijerRevisedWithoutUplift(int maxCores)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
const string fileName = @"WtiPipingSellmeijerRevisedWithoutUplift.xml";
string inputString = File.ReadAllText(fileName);
var engineInterface = new EngineInterface(inputString);
Assert.IsNotNull(engineInterface.DamProjectData);
engineInterface.DamProjectData.MaxCalculationCores = maxCores;
string result = engineInterface.Validate();
Assert.IsTrue(result == null, "Validation must succeed but does not, see output xml in debugger");
string outputString = engineInterface.Run();
string outputName = "Output" + maxCores + ".xml";
File.WriteAllText(outputName, outputString);
Output output = DamXmlSerialization.LoadOutputFromXmlString(outputString);
int errorCount = GeneralHelper.DetermineNumberOfCalculationErrors(engineInterface.DamProjectData.CalculationMessages);
Assert.AreEqual(0, errorCount, "There should be no errors during the calculation.");
Assert.AreNotEqual(null, output.Results.CalculationResults);
Assert.AreEqual(6, output.Results.CalculationResults.Length);
Assert.AreEqual(26.006, output.Results.CalculationResults[0].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(90.000, output.Results.CalculationResults[1].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(90.000, output.Results.CalculationResults[2].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(90.000, output.Results.CalculationResults[3].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(9.316, output.Results.CalculationResults[4].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(90.000, output.Results.CalculationResults[5].PipingDesignResults.Wti2017FactorOverall, tolerance);
Assert.AreEqual(5, output.Results.CalculationMessages.Length);
Assert.IsTrue(output.Results.CalculationMessages[0].Message1.Contains("no uplift"));
Assert.IsTrue(output.Results.CalculationMessages[1].Message1.Contains("no uplift"));
Assert.IsTrue(output.Results.CalculationMessages[2].Message1.Contains("no uplift"));
Assert.IsTrue(output.Results.CalculationMessages[3].Message1.Contains("no uplift"));
Assert.IsTrue(output.Results.CalculationMessages[4].Message1.Contains("no uplift"));
}
}