//-----------------------------------------------------------------------
//
// Copyright (c) 2011 Deltares. All rights reserved.
//
// J. Bokma
// j.bokma@deltares.nl
// 02-02-2011
// n.a.
//-----------------------------------------------------------------------
using Deltares.Standard.EventPublisher;
using System;
using System.IO;
using Deltares.Standard;
namespace Deltares.Dam.Data
{
[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 DamProject damProject = null;
private string mstabExePath = @".\DGeoStability.exe";
private int failureMechanismIndex = 0;
private ProgressDelegate progressDelegate = null;
private int maxCalculationCores = 255;
private SendMessageDelegate sendMessageDelegate = null;
//private int calculationHandle = -1;
///
/// 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 DamProject DamProject
{
get { return damProject; }
set { damProject = 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();
foreach (DamJob damJob in (damProjectData.WaterBoardJob as WaterBoardJob).Jobs)
{
DikeJob dikeJob = damJob 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)
{
damProjectData = damProject;
// Set default working directory
if (ProjectWorkingDirectory.Equals(""))
{
ProjectWorkingDirectory = DamProject.ProjectWorkingPath;
}
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)
{
DataEventPublisher.InvokeWithoutPublishingEvents(() =>
{
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);
}
}
}
}