Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.Designer.cs =================================================================== diff -u -r1586 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1586) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 1644) @@ -344,6 +344,33 @@ } /// + /// Looks up a localized string similar to Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The calculation failed with error message '{4}'.. + /// + internal static string OperationalCalculatorGeneralException { + get { + return ResourceManager.GetString("OperationalCalculatorGeneralException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The preparation for this calculation failed.. + /// + internal static string OperationalCalculatorPrepareError { + get { + return ResourceManager.GetString("OperationalCalculatorPrepareError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The validation for this calculation failed.. + /// + internal static string OperationalCalculatorValidationFailed { + get { + return ResourceManager.GetString("OperationalCalculatorValidationFailed", resourceCulture); + } + } + + /// /// Looks up a localized string similar to Adapting the slope of the dike failed. Probably the slope is too steep or too shallow.. /// internal static string SlopeErrorNoIntersection { Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.resx =================================================================== diff -u -r1586 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.resx (.../Resources.resx) (revision 1586) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.resx (.../Resources.resx) (revision 1644) @@ -273,4 +273,13 @@ No output object defined for WBI Sellmeijer Revised + + Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The calculation failed with error message '{4}'. + + + Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The preparation for this calculation failed. + + + Location '{0}', subsoil scenario '{1}', timestep '{2}', timestamp '{3}': The validation for this calculation failed. + \ No newline at end of file Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs =================================================================== diff -u -r1582 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs (.../DesignCalculator.cs) (revision 1582) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs (.../DesignCalculator.cs) (revision 1644) @@ -61,6 +61,8 @@ { damProjectData.CalculationMessages.Clear(); } + + // Prepare the designCalculatorTasks var designCalculatorTasks = new List(); for (int locationIndex = 0; locationIndex < damProjectData.Dike.Locations.Count; locationIndex++) { @@ -165,21 +167,21 @@ if (prepareResult == PrepareResult.Failed) { calculationMessages.Add(new LogMessage(LogMessageType.Error, null, - string.Format(Resources.DesignCalculatorPrepareError, - location.Name, - soiProfileProbability, - designScenario.LocationScenarioID))); + string.Format(Resources.DesignCalculatorPrepareError, + location.Name, + soiProfileProbability, + designScenario.LocationScenarioID))); } } } catch (Exception e) { calculationMessages.Add(new LogMessage(LogMessageType.Error, null, - string.Format(Resources.DesignCalculatorGeneralException, - location.Name, - soiProfileProbability, - designScenario.LocationScenarioID, - e.Message))); + string.Format(Resources.DesignCalculatorGeneralException, + location.Name, + soiProfileProbability, + designScenario.LocationScenarioID, + e.Message))); } } Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.nl-NL.resx =================================================================== diff -u -r1586 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.nl-NL.resx (.../Resources.nl-NL.resx) (revision 1586) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Properties/Resources.nl-NL.resx (.../Resources.nl-NL.resx) (revision 1644) @@ -169,7 +169,7 @@ Geen uitvoer object gedefinieerd voor Sellmeijer VNK - Locatie '{0}', ondergrond scenario '{1}', ontwerp scenario '{2}': De berekening is gefaald met de volgende foutmelding '{3}'. + Locatie '{0}', ondergrond scenario '{1}', ontwerp scenario '{2}': De berekening is mislukt met de volgende foutmelding '{3}'. Gekozen rekenkernel is nog niet beschikbaar @@ -210,6 +210,15 @@ Er is geen hoogtegeometrie gedefinieerd voor locatie '{0}'. + + Locatie '{0}', ondergrond profiel '{1}', tijdstap '{2}', tijdstip '{3}': De berekening is mislukt met de volgende foutmelding '{4}'. + + + Locatie '{0}', ondergrond profiel '{1}', tijdstap '{2}', tijdstip '{3}': Het klaarzetten van deze berekening is mislukt. + + + Locatie '{0}', ondergrond profiel '{1}', tijdstap '{2}', tijdstip '{3}': Validatie is gefaald. + Het aanpassen van de helling van het dijkprofiel is mislukt. Waarschijnlijk is de nieuwe helling te steil of te flauw. Fisheye: Tag 1644 refers to a dead (removed) revision in file `DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationCalculatorTask.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationalCalculator.cs =================================================================== diff -u -r1640 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationalCalculator.cs (.../OperationalCalculator.cs) (revision 1640) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationalCalculator.cs (.../OperationalCalculator.cs) (revision 1644) @@ -22,8 +22,14 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; +using System.IO; using System.Linq; -using Deltares.DamEngine.Calculators.DikesDesign; +using System.Text; +using Deltares.DamEngine.Calculators.General; +using Deltares.DamEngine.Calculators.KernelWrappers.Common; +using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; +using Deltares.DamEngine.Calculators.Properties; using Deltares.DamEngine.Calculators.Sensors; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Results; @@ -32,6 +38,7 @@ using Deltares.DamEngine.Data.General.TimeSeries; using Deltares.DamEngine.Data.General.Sensors; using Deltares.DamEngine.Data.Standard; +using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; namespace Deltares.DamEngine.Calculators.DikesOperational @@ -94,43 +101,194 @@ damProjectData.CalculationMessages.Add(new LogMessage(LogMessageType.Error, null, "No location to process.")); return; } - var designCalculatorTasks = new List(); + + // Prepare the designCalculatorTasks + var operationalCalculatorTasks = new List(); foreach (var series in outputTimeSerieCollection.Series) { + int entryIndex = 0; foreach (var entry in series.Entries) { var location = locations.First(l => series.LocationId == l.Name); var sensorValues = values[entry.DateTime][location]; if (!ContainsMissingValues(sensorValues, series.MissVal)) { - //var soiProfileProbability = location.Segment.GetMostProbableProfile2DStiFileName() - + var soiProfileProbability = location.Segment.GetMostProbableSoilGeometryProbability(damProjectData.DamProjectCalculationSpecification.CurrentSpecification.FailureMechanismSystemType); + var projectPath = damProjectData.ProjectPath != "" ? damProjectData.ProjectPath : Directory.GetCurrentDirectory(); + var calculationMessages = new List(); + operationalCalculatorTasks.Add(new OperationalCalculatorTask() + { + Location = location, + SoiProfileProbability = soiProfileProbability, + ProjectPath = projectPath, + CalculationMap = damProjectData.CalculationMap, + FailureMechanismeCalculationSpecification = damProjectData.DamProjectCalculationSpecification.CurrentSpecification, + TimeSerieEntry = entry, + TimeStepIndex = entryIndex, + CalculationMessages = calculationMessages + }); } else { damProjectData.CalculationMessages.Add(new LogMessage(LogMessageType.Warning, null, String.Format("In location '{0}' missing values are found in timestep {1}", location.Name, entry.DateTime))); } + entryIndex++; } } + + // Perform the calculation + Parallel.Run(operationalCalculatorTasks, RunOperationalCalculatorTask, null, damProjectData.MaxCalculationCores); damProjectData.OutputTimeSerieCollection = outputTimeSerieCollection; } - private void RunDesignCalculatorTask(object designCalculatorTask) + private void RunOperationalCalculatorTask(object operationalCalculatorTask) { - DesignCalculatorTask task = (DesignCalculatorTask)designCalculatorTask; + OperationalCalculatorTask task = (OperationalCalculatorTask)operationalCalculatorTask; Debug.WriteLine("Start calculation Location '{0}', soilprofile '{1}'", task.Location, task.SoiProfileProbability); - CalculateOneScenario(task.Location, task.SoiProfileProbability, task.ProjectPath, - task.CalculationMap, task.FailureMechanismeCalculationSpecification, task.DesignResults, task.CalculationMessages); + CalculateOneTimeEntry(task.Location, task.SoiProfileProbability, task.ProjectPath, + task.CalculationMap, task.FailureMechanismeCalculationSpecification, + task.TimeSerieEntry, task.TimeStepIndex, + task.CalculationMessages); Debug.WriteLine("End calculation Location '{0}', soilprofile '{1}'", task.Location, task.SoiProfileProbability); } - private void CalculateOneScenario(Location location, SoilGeometryProbability soiProfileProbability, + private void CalculateOneTimeEntry(Location location, SoilGeometryProbability soiProfileProbability, string projectPath, string calculationMap, DamFailureMechanismeCalculationSpecification damFailureMechanismeCalculationSpecification, - List designResults, List calculationMessages) + TimeSerieEntry timeSerieEntry, int timeStepIndex, + List calculationMessages) { + try + { + // Prepare input + var damKernelInput = new DamKernelInput(); + damKernelInput.ProjectDir = projectPath; + damKernelInput.CalculationDir = Path.Combine(projectPath, calculationMap); + damKernelInput.Location = location; + damKernelInput.SubSoilScenario = soiProfileProbability; + damKernelInput.DamFailureMechanismeCalculationSpecification = damFailureMechanismeCalculationSpecification; + damKernelInput.RiverLevelHigh = Double.NaN; + damKernelInput.RiverLevelLow = null; + damKernelInput.FilenamePrefix = String.Format("Dik(dike)_Loc({0})_Stp({1})_Mdl({2})_{3}", + location.Name, + timeStepIndex, + damFailureMechanismeCalculationSpecification.StabilityModelType, + DateToTimeStamp(timeSerieEntry.DateTime)); + //SynchronizeScenarioDataWithLocationData(designScenario, location); + IKernelDataInput kernelDataInput; + IKernelDataOutput kernelDataOutput; + // Create kernelwrapper + IKernelWrapper kernelWrapper = KernelWrapperHelper.CreateKernelWrapper(damFailureMechanismeCalculationSpecification); + if (kernelWrapper == null) + { + throw new NotImplementedException(Resources.DesignCalculatorKernelNotImplemented); + } + + PrepareResult prepareResult = kernelWrapper.Prepare(damKernelInput, 0, out kernelDataInput, out kernelDataOutput); + + // Sometimes the kernelDataInput is not created (p.e when soilprofileprobablility is meant for + // stability where Piping calc is wanted). In that case, do nothing but just skip. + if (prepareResult == PrepareResult.Successful) + { + CalculationResult calculationResult; + PerformOperationalCalculation( + kernelWrapper, kernelDataInput, kernelDataOutput, + damKernelInput, timeStepIndex, timeSerieEntry, out calculationResult, + calculationMessages); + } + else + { + if (prepareResult == PrepareResult.NotRelevant) + { + // Do nothing. Calculation will be skipped. + } + if (prepareResult == PrepareResult.Failed) + { + calculationMessages.Add(new LogMessage(LogMessageType.Error, null, + string.Format(Resources.OperationalCalculatorPrepareError, + location.Name, + soiProfileProbability, + timeStepIndex, + DateToTimeStamp(timeSerieEntry.DateTime)))); + } + } + } + catch (Exception e) + { + calculationMessages.Add(new LogMessage(LogMessageType.Error, null, + string.Format(Resources.OperationalCalculatorGeneralException, + location.Name, + soiProfileProbability, + timeStepIndex, + DateToTimeStamp(timeSerieEntry.DateTime), + e.Message))); + } + } + + private void PerformOperationalCalculation(IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, + IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, + int timeStepIndex, TimeSerieEntry timeSerieEntry, + out CalculationResult calculationResult, + List calculationMessages) + { + // Perform validation + var designResults = new List(); + List locationCalculationMessages = new List(); + List validationMessages; + calculationResult = CalculationResult.NoRun; + try + { + int errorCount = kernelWrapper.Validate(kernelDataInput, kernelDataOutput, out validationMessages); + if (errorCount > 0) + { + locationCalculationMessages.Add(new LogMessage(LogMessageType.Error, null, + string.Format(Resources.OperationalCalculatorValidationFailed, + damKernelInput.Location.Name, + damKernelInput.SubSoilScenario, + timeStepIndex, + DateToTimeStamp(timeSerieEntry.DateTime)))); + locationCalculationMessages.AddRange(validationMessages); + } + else + { + // Perform calculation + kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out locationCalculationMessages); + } + // Process output + calculationMessages.AddRange(locationCalculationMessages); + StringBuilder sb = new StringBuilder(); + foreach (var message in locationCalculationMessages) + { + sb.Append(message.Message + Environment.NewLine); + } + string resultMessage = sb.ToString(); + + calculationResult = CalculationResult.Succeeded; + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, null, resultMessage, out designResults); + } + catch (Exception exception) + { + string resultMessage = exception.Message; + calculationResult = CalculationResult.RunFailed; + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, null, resultMessage, out designResults); + } + finally + { + // collect results + } + } + + public static string DateToTimeStamp(DateTime dateTime) + { + // Following 2 lines is an example how to handle customization of this format. + // TNO at the last moment decided they did not need this change so we change it back to + // the default format + // string customFormat = "yyyy-MM-dd_HH-mm-ss"; + // return dateTime.ToString(customFormat); + return dateTime.ToString("s", DateTimeFormatInfo.InvariantInfo); + } private string DetermineOutputParameter(DamFailureMechanismeCalculationSpecification currentSpecification) { string parameter = ""; Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationCalculatorTask.cs =================================================================== diff -u -r1640 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationCalculatorTask.cs (.../OperationCalculatorTask.cs) (revision 1640) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesOperational/OperationCalculatorTask.cs (.../OperationalCalculatorTask.cs) (revision 1644) @@ -19,25 +19,24 @@ // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. -using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Deltares.DamEngine.Data.General; -using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.General.TimeSeries; +using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; namespace Deltares.DamEngine.Calculators.DikesOperational { - public class OperationCalculatorTask + public class OperationalCalculatorTask { public Location Location { get; set; } public SoilGeometryProbability SoiProfileProbability { get; set; } public string ProjectPath { get; set; } public string CalculationMap { get; set; } public DamFailureMechanismeCalculationSpecification FailureMechanismeCalculationSpecification { get; set; } - public List DesignResults { get; set; } + public TimeSerieEntry TimeSerieEntry { get; set; } + public int TimeStepIndex { get; set; } + public CalculationResult CalculationResult { get; set; } public List CalculationMessages { get; set; } } } Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj =================================================================== diff -u -r1641 -r1644 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1641) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/Deltares.DamEngine.Calculators.csproj (.../Deltares.DamEngine.Calculators.csproj) (revision 1644) @@ -70,7 +70,7 @@ - +