// Copyright (C) Stichting Deltares 2017. 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;
using System.IO;
using System.Threading.Tasks;
using Deltares.DamEngine.Calculators.Dikes_Operational;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Calculators.General;
using Deltares.DamEngine.Data.General.TimeSeries;
namespace Deltares.DamEngine.Calculators
{
[Serializable]
public class DamCalculationException : ApplicationException
{
public DamCalculationException(string message)
: base(message)
{
}
}
//Todo handling of the actual messages instead of just CalculationResult has to be added.
///
/// class DamFailureMechanismeCalculation
///
public class DamCalculation : ICalculation
{
private string projectWorkingDirectory = "";
private string projectDataDirectory = "";
private DamProjectData damProjectData;
private DamProjectCalculator damProjectCalculator;
private string mstabExePath = @".\DGeoStability.exe";
private int failureMechanismIndex = 0;
private ProgressDelegate progressDelegate = null;
private int maxCalculationCores = 255;
private SendMessageDelegate sendMessageDelegate = null;
///
/// Constructor
///
public DamCalculation()
{
damProjectData = new DamProjectData();
damProjectCalculator = new DamProjectCalculator(damProjectData);
}
public int MaxCalculationCores
{
get { return maxCalculationCores; }
set { maxCalculationCores = value; }
}
public string Version
{
get
{
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
public string ProjectWorkingDirectory
{
get { return projectWorkingDirectory; }
set { projectWorkingDirectory = value; }
}
public string ProjectDataDirectory
{
get { return projectDataDirectory; }
set { projectDataDirectory = value; }
}
public string MStabExePath
{
get { return mstabExePath; }
set { mstabExePath = value; }
}
#region ICalculation Members
public CalculationResult RegisterUserAbort(UserAbortDelegate userAbortDelegate)
{
if (this.damProjectCalculator == null)
return CalculationResult.UnexpectedError;
else
{
//var lp = (TUserAbortDelegate)Delegate.CreateDelegate(typeof(TUserAbortDelegate), userAbortDelegate.Target, userAbortDelegate.Method.Name);
//this.damProjectCalculator.SetUserAbortDelegate(lp);
return CalculationResult.Succeeded;
}
}
public CalculationResult RegisterProgress(ProgressDelegate progressDelegate)
{
if (damProjectCalculator == null)
{
return CalculationResult.UnexpectedError;
}
this.progressDelegate = progressDelegate;
this.damProjectCalculator.Progress = progressDelegate;
return CalculationResult.Succeeded;
}
public CalculationResult RegisterSendMessage(SendMessageDelegate sendMessageDelegate)
{
this.sendMessageDelegate = sendMessageDelegate;
if (this.damProjectCalculator == null)
return CalculationResult.UnexpectedError;
else
{
//var lp = (TSendMessageDelegate) Delegate.CreateDelegate(typeof (TSendMessageDelegate), sendMessageDelegate.Target, sendMessageDelegate.Method.Name);
//this.damProjectCalculator.SetSendMessageDelegate(lp);
return CalculationResult.Succeeded;
}
}
public CalculationResult RegisterSendDebugInfo(SendDebugInfodelegate sendDebugInfoDelegate)
{
if (this.damProjectCalculator == null)
return CalculationResult.UnexpectedError;
else
{
//var d = (Delegate)sendDebugInfoDelegate;
//this.damProjectCalculator.SetSendDebugInfoDelegate((TSendDebugInfoDelegate)d);
return CalculationResult.Succeeded;
}
}
public CalculationResult RegisterGetValues(GetValuesDelegate getValuesDelegate)
{
if (this.damProjectCalculator == null)
return CalculationResult.UnexpectedError;
else
{
//var lp = (TGetValuesDelegate)Delegate.CreateDelegate(typeof(TGetValuesDelegate), getValuesDelegate.Target, getValuesDelegate.Method.Name);
//this.damProjectCalculator.SetGetValuesDelegate(lp);
return CalculationResult.Succeeded;
}
}
public CalculationResult RegisterSetValues(SetValuesDelegate setValuesDelegate)
{
if (this.damProjectCalculator == null)
return CalculationResult.UnexpectedError;
else
{
//var lp = (TSetValuesDelegate)Delegate.CreateDelegate(typeof(TSetValuesDelegate), setValuesDelegate.Target, setValuesDelegate.Method.Name);
//this.damProjectCalculator.SetSetValuesDelegate(lp);
return CalculationResult.Succeeded;
}
}
public CalculationResult Validate()
{
if (this.damProjectData == null)
{
return CalculationResult.UnexpectedError;
}
else
{
try
{
// first check project data
CalculationResult res = this.damProjectData.Validate();
if (res == CalculationResult.Succeeded)
{
try
{
// then check general calculator data
this.damProjectCalculator.ValidateGeneral();
}
catch (Exception)
{
res = CalculationResult.InvalidInputData;
}
}
return res;
}
catch
{
return CalculationResult.InvalidInputData;
}
}
}
public CalculationResult GetResults(ref string results)
{
results = "No results available.";
return CalculationResult.Succeeded;
}
#endregion
///
/// Calculate failure mechanism
///
///
///
private void CalculateFailureMechanismStabilityInsideMStab(
DamFailureMechanismeCalculationSpecification failureMechanismeCalculationSpecification,
string failureMechanismWorkingDirectory)
{
if (string.IsNullOrWhiteSpace(failureMechanismWorkingDirectory))
throw new ArgumentException("Invalid working directory. The supplied string is empty or null.", "failureMechanismWorkingDirectory");
string stabilityWorkingPath = Path.GetFullPath(failureMechanismWorkingDirectory);
var timeSerieStabilityCalculator = new TimeSerieStabilityCalculator
{
StabilityWorkingPath = stabilityWorkingPath,
IsMStabCalculationOff = false,
MStabExePath = this.mstabExePath,
SendMessageDelegate = sendMessageDelegate
};
if (!Directory.Exists(timeSerieStabilityCalculator.StabilityWorkingPath))
{
Directory.CreateDirectory(timeSerieStabilityCalculator.StabilityWorkingPath);
}
int locationCounter = 0;
var safetyFactorsTimeSerieCollection = new TimeSerieCollection();
DikeJob dikeJob = damProjectData.DikeJob as DikeJob;
foreach (LocationJob locationJob in dikeJob.Jobs)
{
if (locationJob.Run.Value && locationJob.WaterLevelTimeSerie != null)
{
TimeSerie safefactorsTimeSerie = timeSerieStabilityCalculator.CreateStabilityInsideSafetyFactorTimeSerie(
locationJob.WaterLevelTimeSerie,
dikeJob.Dike,
locationJob.Location,
locationCounter,
ProjectDataDirectory,
failureMechanismeCalculationSpecification.FailureMechanismeParamatersMStab.MStabParameters,
null);
locationJob.LocationResult.StabilityTimeSerie = safefactorsTimeSerie;
safefactorsTimeSerie.LocationId = locationJob.Location.Name;
safetyFactorsTimeSerieCollection.Series.Add(safefactorsTimeSerie);
locationCounter++;
}
}
timeSerieStabilityCalculator.IsCalculateAllStabilityProjectsAtOnce = true;
timeSerieStabilityCalculator.CalculateSafetyFactorFromTimeSeries(TimeSerieParameters.StabilityInsideFactor.ToString(),
dikeJob.Dike, safetyFactorsTimeSerieCollection);
ThrowHelper.ThrowWhenConditionIsTrue("No locations specified.",() => locationCounter == 0);
}
public void CalculateDamProject(DamProjectData damProject, string defaultProjectWorkingPath)
{
// damProjectData = damProject; ##Bka
//
// // Set default working directory
// if (ProjectWorkingDirectory.Equals(""))
// {
// ProjectWorkingDirectory = defaultProjectWorkingPath;
// }
//
// this.failureMechanismIndex = -1;
// ThrowHelper.ThrowWhenConditionIsTrue("No actual calculation specified.",
// () => damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count == 0);
//
// Parallel.Run(damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications, this.RunFailureMechanism, this.progressDelegate, this.MaxCalculationCores);
}
private int GetFailureMechanismIndex()
{
lock (this)
{
failureMechanismIndex++;
return failureMechanismIndex;
}
}
// private void RunFailureMechanism(object task)
// {
// DamFailureMechanismeCalculationSpecification failureMechanismCalculationSpecification = (DamFailureMechanismeCalculationSpecification)task;
// string failureMechanismWorkingDirectory = String.Format(@"{0}\FM{1}\", ProjectWorkingDirectory, GetFailureMechanismIndex());
// DeleteDirectoryWithFiles(failureMechanismWorkingDirectory);
// if (failureMechanismCalculationSpecification.FailureMechanismSystemType == FailureMechanismSystemType.StabilityInside)
// {
// CalculateFailureMechanismStabilityInsideMStab(failureMechanismCalculationSpecification, failureMechanismWorkingDirectory);
// }
// }
///
/// Delete all files in directory and all files in it
///
///
private void DeleteDirectoryWithFiles(string directory)
{
if (Directory.Exists(directory))
{
string[] fileNames = Directory.GetFiles(directory);
foreach (string filename in fileNames)
{
File.Delete(filename);
}
Directory.Delete(directory);
}
}
}
}