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