// Copyright (C) Stichting Deltares 2023. All rights reserved. // // This file is part of the application DAM - Live. // // DAM - Live 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; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading; using Deltares.DamLive.Application; using Deltares.Dam.Data; using Deltares.DamEngine.Interface; using Deltares.DamEngine.Io; using Deltares.DamEngine.Io.XmlInput; using Deltares.DamLive.TestHelper; using NUnit.Framework; using Location = Deltares.Dam.Data.Location; using TimeSerie = Deltares.Dam.Data.TimeSerie; namespace Deltares.DamLive.Tests; public class StabilityInsideUpliftVanBeeSwarmTest { private const string projectIntegrationFilename = @"DAMLive.damx"; private const string input1AFilename = @"live.InputTimeSeriesMHW.xml"; private const string output1AFilename = @"live.OutputTimeSeriesMHW.xml"; private const string calculationParametersIntegrationFilename = @"live.ParametersFile.xml"; private const string testWorkingFolder = @".\damLiveUpliftVanBeeSwarmWork"; private const string testIntegrationDataFolder = @"..\..\TestData\IntegrationTests\StabilityInsideUpliftVanBeeSwarm"; private List locations; private DamEngineRunner runner; private int maxCores; [SetUp] public void SetupFixture() { // ToDo: "Fails when run with multicore, so for now set to 1 core"] //maxCores = Math.Min(GeneralHelper.CMaxCores, Environment.ProcessorCount); maxCores = 1; IoHelper.RemoveTestWorkingDirectory(testWorkingFolder + maxCores); } [TearDown] public void TearDownFixture() { IoHelper.RemoveTestWorkingDirectory(testWorkingFolder + maxCores); } [SetUp] public void SetupTest() {} [Test] [Category("Integration")] [Category("Work_In_Progress")] // "Fails when run with multicore"] public void CalculateStabilityInsideUpliftVanBeeSwarmUsingTestFilesHasExpectedResultsInOutputFile() { const double cTolerance = 0.0005; string testFileName = "CalculateStabilityInsideUpliftVanBeeSwarm" + maxCores; GeneralHelper.SetupIntegrationProject(maxCores, testWorkingFolder, testIntegrationDataFolder, input1AFilename, output1AFilename, testFileName, calculationParametersIntegrationFilename, projectIntegrationFilename, out runner, out locations); runner.Initialize(); runner.MaxCalculationCores = maxCores; Assert.That(runner, Is.Not.Null); Assert.Multiple(() => { Assert.That(runner.DamProjectData, Is.Not.Null); Assert.That(runner.CalculationParameters, Is.Not.Null); }); Assert.Multiple(() => { Assert.That(runner.CalculationParameters.CalculationModules, Is.Not.Null); Assert.That(runner.CalculationParameters.StabilityParameters, Is.Not.Null); }); runner.Run(); runner.OutputTimeSeriesCollection.Save("StabilityInsideUpliftVanBeeSwarmOutputFile" + maxCores + ".xml"); GeneralHelper.AssertNoErrors(runner); // Assertions List series = runner.OutputTimeSeriesCollection.Series; var seriesCount = 0; var resultsCount = 0; string[] validParameterIDs = Enum.GetNames(typeof(TimeSerieParameters)); foreach (TimeSerie timeSeries in series) { Assert.Multiple(() => { Assert.That(validParameterIDs.Any(n => n == timeSeries.ParameterId), Is.True); Assert.That(locations.Any(l => l.Name == timeSeries.LocationId), Is.True); }); // StabilityInside check if (timeSeries.ParameterId == TimeSerieParameters.StabilityInsideFactor.ToString()) { Assert.Multiple(() => { if (timeSeries.LocationId == "Purmer_PU0042+00_K") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.442).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.582).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_K_V") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.358).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.464).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_R") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.235).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.352).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_R_V") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.163).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.256).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_K") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_K_V") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_R") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_R_V") { TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } }); } seriesCount++; } Assert.Multiple(() => { Assert.That(seriesCount, Is.GreaterThan(0), "No output time series"); Assert.That(resultsCount, Is.EqualTo(16), "Incorrect number of results"); }); } [Test] [Category("Integration")] [Category("Work_In_Progress")] // "Fails when run with multicore"] public void OperationalBeeSwarmMultiCoreWithXmlInputFile() { const string inputFilename = "InputForDebuggingBeeSwarm.xml"; string fullInputFilename = Path.Combine(testIntegrationDataFolder, inputFilename); Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string inputString = File.ReadAllText(fullInputFilename); string testName = "InputForDebuggingBeeSwarm" + maxCores + " .xml"; var engineInterface = new EngineInterface(inputString); Assert.That(engineInterface.DamProjectData, Is.Not.Null); engineInterface.DamProjectData.MaxCalculationCores = maxCores; engineInterface.DamProjectData.ProjectPath = testWorkingFolder + maxCores; Input input = DamXmlSerialization.LoadInputFromXmlString(inputString); DamXmlSerialization.SaveInputAsXmlFile(testName, input); string result = engineInterface.Validate(); Assert.That(result, Is.EqualTo(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); List series = engineInterface.DamProjectData.OutputTimeSerieCollection.Series; var seriesCount = 0; var resultsCount = 0; const double cTolerance = 0.0005; foreach (DamEngine.Data.General.TimeSeries.TimeSerie timeSeries in series) { // StabilityInside check if (timeSeries.ParameterId == TimeSerieParameters.StabilityInsideFactor.ToString()) { if (timeSeries.LocationId == "Purmer_PU0042+00_K") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.442).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.565).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_K_V") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.354).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.464).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_R") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.235).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.343).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0042+00_R_V") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(1.161).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(1.257).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_K") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_K_V") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_R") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } if (timeSeries.LocationId == "Purmer_PU0110+20_R_V") { DamEngine.Data.General.TimeSeries.TimeSerieEntry firstEntry = timeSeries.Entries.First(); Assert.That(firstEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; DamEngine.Data.General.TimeSeries.TimeSerieEntry lastEntry = timeSeries.Entries.Last(); Assert.That(lastEntry.Value, Is.EqualTo(double.NaN).Within(cTolerance), "The computed safety factory is not correct"); resultsCount++; } } seriesCount++; } Assert.Multiple(() => { Assert.That(seriesCount, Is.GreaterThan(0), "No output time series"); Assert.That(resultsCount, Is.EqualTo(16), "Incorrect number of results"); }); } }