// 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.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using Deltares.DamEngine.Calculators.Dikes_Assessment_Regional; using Deltares.DamEngine.Calculators.Stability; using Deltares.DamEngine.Data.Design; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.RWScenarios; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Language; using Deltares.DamEngine.Data.Standard.Logging; namespace Deltares.DamEngine.Calculators { public class DamRunner { private readonly DamProjectData damProjectData; private readonly string directory = ""; private int maxCalculationCores = 255; private DateTime startTimeCalculation; public DamRunner(DamProjectData damProjectData, string projectFileName) { this.damProjectData = damProjectData; directory = Path.GetDirectoryName(projectFileName); } private delegate void ProcessResultDelegate(DamProjectData damProject, CalculationResult result, string output); private void ProcessResultLocal(DamProjectData damProject, CalculationResult result, string output) { damProjectData.UpdateCalculations(); damProjectData.UpdateSchematizationFactors(); TimeSpan elapsedTime = DateTime.Now - startTimeCalculation; string timeMessage = String.Format(LocalizationManager.GetTranslatedText(this, "CalculationTime"), elapsedTime.ToString(@"dd\.hh\:mm\:ss")); string paragraphSepatator = Environment.NewLine + Environment.NewLine; if (output.StartsWith("Thread was being aborted")) { // LocalizedMessageBox.Show(this, "CalculationAborted"); ##Bka: most probably unwanted, replace with other mechanism } else if (result == CalculationResult.Succeeded) { string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFinished"); // LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + timeMessage + paragraphSepatator + output); ##Bka: most probably unwanted, replace with other mechanism } else if ((result == CalculationResult.RunFailed) || (result == CalculationResult.UnexpectedError)) { string openingMessage = LocalizationManager.GetTranslatedText(this, "CalculationFailed"); //LocalizedMessageBox.ShowTranslatedText(openingMessage + paragraphSepatator + output); ##Bka: most probably unwanted, replace with other mechanism } } private void ProcessResult(DamProjectData damProject, CalculationResult result, string output) { // if (BindSupport.InvokeControl.InvokeRequired) // { // var d = new ProcessResultDelegate(ProcessResultLocal); // BindSupport.InvokeControl.Invoke(d, new object[] { damProject, result, output }); // } // else ##Bka: most probably unwanted, replace with other mechanism { ProcessResultLocal(damProject, result, output); } } public void PerformCalculation(ProgressDelegate progressDelegate) { startTimeCalculation = DateTime.Now; try { switch (damProjectData.DamProjectType) { case DamProjectType.Calamity: { var damCalculation = new DamCalculation(); damCalculation.RegisterProgress(progressDelegate); damCalculation.RegisterSendMessage(HandleCalculationSendMessage); damCalculation.ProjectWorkingDirectory = ""; // Force default location for working directory damCalculation.ProjectDataDirectory = directory + Path.DirectorySeparatorChar; damCalculation.MStabExePath = StabilityCalculator.MStabExePath; damCalculation.MaxCalculationCores = MaxCalculationCores; damCalculation.CalculateDamProject(damProjectData, DamProjectData.ProjectWorkingPath); //##Bka!? or damCalculation.ProjectDataDirectory var output = FillOutputForMessage(damProjectData.LocationJobs); ProcessResult(damProjectData, CalculationResult.Succeeded, output); break; } case DamProjectType.Assessment: { var rwScenariosCalculation = new RWScenariosCalculation { SchematizationFactorData = damProjectData.SchematizationFactorData, MaxCalculationCores = MaxCalculationCores }; rwScenariosCalculation.RegisterProgress(progressDelegate); rwScenariosCalculation.RegisterSendMessage(HandleCalculationSendMessage); rwScenariosCalculation.MStabExePath = StabilityCalculator.MStabExePath; rwScenariosCalculation.PipingModelType = damProjectData.DamProjectCalculationSpecification.CurrentSpecification.PipingModelType; rwScenariosCalculation.MStabParameters = damProjectData.DamProjectCalculationSpecification.CurrentSpecification .FailureMechanismeParamatersMStab.MStabParameters; EvaluationJob evaluationJob = damProjectData.GetEvaluationJob(); RemoveLogMessages(evaluationJob); CalculationResult calculationResult; try { //rwScenariosCalculation.Load(evaluationJob.XML); ##Bka calculationResult = rwScenariosCalculation.Run(); //DataEventPublisher.DataListModified(LogManager.Messages); } catch (Exception) { calculationResult = CalculationResult.UnexpectedError; } string results = ""; rwScenariosCalculation.GetResults(ref results); //evaluationJob.XML = results; ##Bka evaluationJob.AttachResults(damProjectData.LocationJobs); var output = FillOutputForMessage(damProjectData.LocationJobs); ProcessResult(damProjectData, calculationResult, output); break; } case DamProjectType.Design: { if (damProjectData.DamProjectCalculationSpecification.DamCalculationSpecifications.Count > 0) { List scenarios = CreateScenarioListForCalculation(); var damProjectCalculator = new DamProjectCalculator(damProjectData) { MaxCalculationCores = MaxCalculationCores, MStabProgramPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "DGeoStability.exe"), SlopeWProgramPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Slope2.exe"), ProjectDataDirectory = directory + Path.DirectorySeparatorChar, Progress = progressDelegate, CalculationBaseDirectory = DamProjectData.ProjectWorkingPath + @"\CalculationFiles\" }; damProjectCalculator.Calculate(damProjectData, scenarios); var output = FillOutputForMessage(damProjectData.LocationJobs); ProcessResult(damProjectData, CalculationResult.Succeeded, output); } } break; } } catch (Exception exception) { var sb = new StringBuilder(exception.Message); for (Exception innerException = exception.InnerException; innerException != null; innerException = innerException.InnerException) { sb.Append('\n'); sb.Append(innerException.Message); } ProcessResult(damProjectData, CalculationResult.RunFailed, sb.ToString()); } } private string FillOutputForMessage(IEnumerable locationJobs) { var res = ""; foreach (var locationJob in locationJobs) { if (locationJob.Result == JobResult.Failed) { var failedLocationCalculation = LocalizationManager.GetTranslatedText(GetType(), "failedLocationCalculationId"); res = res + String.Format(failedLocationCalculation, locationJob.Location.Name) + Environment.NewLine; } else { if (locationJob.Result != JobResult.NoRun && !locationJob.HasLocationResults && !locationJob.HasRWScenarioResults && !locationJob.HasScenarioResults) { var noResultsForLocation = LocalizationManager.GetTranslatedText(GetType(), "noResultsForLocationId"); res = res + String.Format(noResultsForLocation, locationJob.Location.Name) + Environment.NewLine; } } } return res; } /// /// Create a list of scenarios to be calculated /// /// List of the generated scenarios private List CreateScenarioListForCalculation() { var scenarios = new List(); // The locations of the scenarios can get out of sync after a calculation, so make sure they are in sync damProjectData.WaterBoard.UpdateLocationsForScenarios(); List selectedLocations = damProjectData.SelectedLocationJobs.Select(x => x.Location).ToList(); foreach (var location in selectedLocations) { scenarios.AddRange(location.Scenarios); } return scenarios; } private void RemoveLogMessages(EvaluationJob evaluationJob) { // foreach (LogMessage logMessage in LogManager.Messages.ToArray()) // { // foreach (var location in evaluationJob.Locations) // { // if (logMessage.SubjectName.Equals(location.ToString())) // { // LogManager.Messages.Remove(logMessage); // } // } // } // // DataEventPublisher.DataListModified(LogManager.Messages); } private void HandleCalculationSendMessage(LogMessage logMessage) { // lock (LogManager.Messages) // { // LogManager.Messages.Add(logMessage); // DataEventPublisher.DataListModified(LogManager.Messages); // } } public int MaxCalculationCores { get { return maxCalculationCores; } set { maxCalculationCores = value; } } } }