// 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");
});
}
}