Index: Riskeer/Piping/src/Riskeer.Piping.Service/Probabilistic/ProbabilisticPipingCalculationService.cs
===================================================================
diff -u -re2b60a183f95fefe71686ac319c22bb7ad644bca -r71c3adcd5c30cb64e6a1b804e6841558e8d2d712
--- Riskeer/Piping/src/Riskeer.Piping.Service/Probabilistic/ProbabilisticPipingCalculationService.cs (.../ProbabilisticPipingCalculationService.cs) (revision e2b60a183f95fefe71686ac319c22bb7ad644bca)
+++ Riskeer/Piping/src/Riskeer.Piping.Service/Probabilistic/ProbabilisticPipingCalculationService.cs (.../ProbabilisticPipingCalculationService.cs) (revision 71c3adcd5c30cb64e6a1b804e6841558e8d2d712)
@@ -21,14 +21,29 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
+using Core.Common.Base.Geometry;
+using Core.Common.Base.IO;
+using log4net;
using Riskeer.Common.Data.AssessmentSection;
+using Riskeer.Common.Data.Exceptions;
+using Riskeer.Common.Data.FailureMechanism;
using Riskeer.Common.Data.Hydraulics;
+using Riskeer.Common.Data.IllustrationPoints;
+using Riskeer.Common.Data.Probabilistics;
using Riskeer.Common.IO.HydraRing;
using Riskeer.Common.Service;
+using Riskeer.Common.Service.IllustrationPoints;
+using Riskeer.HydraRing.Calculation.Calculator;
+using Riskeer.HydraRing.Calculation.Calculator.Factory;
+using Riskeer.HydraRing.Calculation.Data.Input.Piping;
+using Riskeer.HydraRing.Calculation.Exceptions;
using Riskeer.Piping.Data;
using Riskeer.Piping.Data.Probabilistic;
+using Riskeer.Piping.Service.Properties;
using RiskeerCommonServiceResources = Riskeer.Common.Service.Properties.Resources;
+using HydraRingGeneralResult = Riskeer.HydraRing.Calculation.Data.Output.IllustrationPoints.GeneralResult;
namespace Riskeer.Piping.Service.Probabilistic
{
@@ -37,7 +52,19 @@
///
public class ProbabilisticPipingCalculationService
{
+ private const int numberOfCalculators = 2;
+ private static readonly ILog log = LogManager.GetLogger(typeof(ProbabilisticPipingCalculationService));
+
+ private IPipingCalculator profileSpecificCalculator;
+ private IPipingCalculator sectionSpecificCalculator;
+ private bool canceled;
+
///
+ /// Fired when the calculation progress changed.
+ ///
+ public event OnProgressChanged OnProgressChanged;
+
+ ///
/// Performs validation over the values on the given . Error and status information is logged during
/// the execution of the operation.
///
@@ -82,6 +109,297 @@
return !messages.Any();
}
+ ///
+ /// Performs a structures calculation based on the supplied and sets
+ /// if the calculation was successful. Error and status information is logged during the execution of the operation.
+ ///
+ /// The that holds all the information required to perform the calculation.
+ /// The which the belongs to.
+ /// The with the
+ /// hydraulic boundary calculation settings.
+ /// Preprocessing is disabled when the preprocessor directory equals .
+ /// Thrown when any parameter is null.
+ /// Thrown when the hydraulic boundary database file path
+ /// contains invalid characters.
+ /// Thrown when an unexpected
+ /// enum value is encountered.
+ /// Thrown when:
+ ///
+ /// - No settings database file could be found at the location of the hydraulic boundary database file path
+ /// with the same name.
+ /// - Unable to open settings database file.
+ /// - Unable to read required data from database file.
+ ///
+ /// Thrown when an error occurs while performing the calculation.
+ public void Calculate(ProbabilisticPipingCalculation calculation, PipingFailureMechanism failureMechanism,
+ HydraulicBoundaryCalculationSettings calculationSettings)
+ {
+ if (calculation == null)
+ {
+ throw new ArgumentNullException(nameof(calculation));
+ }
+
+ if (failureMechanism == null)
+ {
+ throw new ArgumentNullException(nameof(failureMechanism));
+ }
+
+ if (calculationSettings == null)
+ {
+ throw new ArgumentNullException(nameof(calculationSettings));
+ }
+
+ string hydraulicBoundaryDatabaseFilePath = calculationSettings.HydraulicBoundaryDatabaseFilePath;
+ bool usePreprocessor = !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory);
+
+ profileSpecificCalculator = HydraRingCalculatorFactory.Instance.CreatePipingCalculator(
+ HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings));
+
+ sectionSpecificCalculator = HydraRingCalculatorFactory.Instance.CreatePipingCalculator(
+ HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings));
+
+ CalculationServiceHelper.LogCalculationBegin();
+
+ try
+ {
+ PartialProbabilisticPipingOutput profileSpecificOutput = CalculateProfileSpecific(
+ calculation, failureMechanism, hydraulicBoundaryDatabaseFilePath, usePreprocessor);
+
+ if (canceled)
+ {
+ return;
+ }
+
+ PartialProbabilisticPipingOutput sectionSpecificOutput = CalculateSectionSpecific(
+ calculation, failureMechanism, hydraulicBoundaryDatabaseFilePath, usePreprocessor);
+
+ if (canceled)
+ {
+ return;
+ }
+
+ calculation.Output = new ProbabilisticPipingOutput(sectionSpecificOutput, profileSpecificOutput);
+ }
+ finally
+ {
+ CalculationServiceHelper.LogCalculationEnd();
+
+ profileSpecificCalculator = null;
+ sectionSpecificCalculator = null;
+ }
+ }
+
+ ///
+ /// Cancels any currently running grass cover erosion inwards calculation.
+ ///
+ public void Cancel()
+ {
+ profileSpecificCalculator?.Cancel();
+ sectionSpecificCalculator?.Cancel();
+ canceled = true;
+ }
+
+ private PartialProbabilisticPipingOutput CalculateProfileSpecific(ProbabilisticPipingCalculation calculation, PipingFailureMechanism failureMechanism, string hydraulicBoundaryDatabaseFilePath, bool usePreprocessor)
+ {
+ NotifyProgress(string.Format(Resources.ProbabilisticPipingCalculationService_Calculate_Executing_calculation_of_type_0,
+ Resources.ProbabilisticPipingCalculationService_ProfileSpecific),
+ 1, numberOfCalculators);
+
+ PipingCalculationInput profileSpecificCalculationInput = CreateInput(
+ calculation, failureMechanism.GeneralInput, 0,
+ hydraulicBoundaryDatabaseFilePath, usePreprocessor);
+
+ PerformCalculation(() => profileSpecificCalculator.Calculate(profileSpecificCalculationInput),
+ () => profileSpecificCalculator.LastErrorFileContent,
+ () => profileSpecificCalculator.OutputDirectory,
+ calculation.Name,
+ Resources.ProbabilisticPipingCalculationService_ProfileSpecific);
+
+ GeneralResult generalResult = null;
+ try
+ {
+ generalResult = calculation.InputParameters.ShouldIllustrationPointsBeCalculated
+ ? ConvertIllustrationPointsResult(profileSpecificCalculator.IllustrationPointsResult,
+ profileSpecificCalculator.IllustrationPointsParserErrorMessage)
+ : null;
+ }
+ catch (ArgumentException e)
+ {
+ log.WarnFormat(Resources.PipingProbabailisticCalculationService_Calculate_Error_in_reading_illustrationPoints_for_CalculationName_0_CalculationType_1_overtopping_with_ErrorMessage_2,
+ calculation.Name, Resources.ProbabilisticPipingCalculationService_ProfileSpecific, e.Message);
+ }
+
+ return new PartialProbabilisticPipingOutput(profileSpecificCalculator.ExceedanceProbabilityBeta,
+ generalResult);
+ }
+
+ private PartialProbabilisticPipingOutput CalculateSectionSpecific(ProbabilisticPipingCalculation calculation, PipingFailureMechanism failureMechanism, string hydraulicBoundaryDatabaseFilePath, bool usePreprocessor)
+ {
+ NotifyProgress(string.Format(Resources.ProbabilisticPipingCalculationService_Calculate_Executing_calculation_of_type_0,
+ Resources.ProbabilisticPipingCalculationService_SectionSpecific),
+ 2, numberOfCalculators);
+
+ FailureMechanismSection section = failureMechanism.Sections.First(s => calculation.IsSurfaceLineIntersectionWithReferenceLineInSection(Math2D.ConvertPointsToLineSegments(s.Points)));
+
+ PipingCalculationInput sectionSpecificCalculationInput = CreateInput(
+ calculation, failureMechanism.GeneralInput, section.Length,
+ hydraulicBoundaryDatabaseFilePath, usePreprocessor);
+
+ PerformCalculation(() => sectionSpecificCalculator.Calculate(sectionSpecificCalculationInput),
+ () => sectionSpecificCalculator.LastErrorFileContent,
+ () => sectionSpecificCalculator.OutputDirectory,
+ calculation.Name,
+ Resources.ProbabilisticPipingCalculationService_SectionSpecific);
+
+ GeneralResult generalResult = null;
+ try
+ {
+ generalResult = calculation.InputParameters.ShouldIllustrationPointsBeCalculated
+ ? ConvertIllustrationPointsResult(sectionSpecificCalculator.IllustrationPointsResult,
+ sectionSpecificCalculator.IllustrationPointsParserErrorMessage)
+ : null;
+ }
+ catch (ArgumentException e)
+ {
+ log.WarnFormat(Resources.PipingProbabailisticCalculationService_Calculate_Error_in_reading_illustrationPoints_for_CalculationName_0_CalculationType_1_overtopping_with_ErrorMessage_2,
+ calculation.Name, Resources.ProbabilisticPipingCalculationService_SectionSpecific, e.Message);
+ }
+
+ return new PartialProbabilisticPipingOutput(sectionSpecificCalculator.ExceedanceProbabilityBeta,
+ generalResult);
+ }
+
+ ///
+ /// Performs a grass cover erosion inwards calculation.
+ ///
+ /// The action that performs the calculation.
+ /// The function for obtaining the last error file content.
+ /// The function for obtaining the output directory.
+ /// The name of the calculation to perform.
+ /// The name of the step to perform.
+ /// Thrown when an error occurs while performing the calculation.
+ private void PerformCalculation(Action performCalculation,
+ Func getLastErrorFileContent,
+ Func getOutputDirectory,
+ string calculationName,
+ string stepName)
+ {
+ var exceptionThrown = false;
+
+ try
+ {
+ performCalculation();
+ }
+ catch (HydraRingCalculationException)
+ {
+ if (!canceled)
+ {
+ string lastErrorFileContent = getLastErrorFileContent();
+ if (string.IsNullOrEmpty(lastErrorFileContent))
+ {
+ log.ErrorFormat(
+ Resources.ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_for_calculation_with_name_1_no_error_report,
+ stepName,
+ calculationName);
+ }
+ else
+ {
+ log.ErrorFormat(
+ Resources.ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_for_calculation_with_name_1_click_details_for_last_error_report_2,
+ stepName,
+ calculationName,
+ lastErrorFileContent);
+ }
+
+ exceptionThrown = true;
+ throw;
+ }
+ }
+ finally
+ {
+ string lastErrorFileContent = getLastErrorFileContent();
+ bool errorOccurred = CalculationServiceHelper.HasErrorOccurred(canceled, exceptionThrown, lastErrorFileContent);
+ if (errorOccurred)
+ {
+ log.ErrorFormat(
+ Resources.ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_for_calculation_with_name_1_click_details_for_last_error_report_2,
+ stepName,
+ calculationName,
+ lastErrorFileContent);
+ }
+
+ log.InfoFormat(
+ Resources.ProbabilisticPipingCalculationService_Calculate_Calculation_of_type_0_performed_in_temporary_directory_1,
+ stepName,
+ getOutputDirectory());
+
+ if (errorOccurred)
+ {
+ throw new HydraRingCalculationException(lastErrorFileContent);
+ }
+ }
+ }
+
+ private PipingCalculationInput CreateInput(ProbabilisticPipingCalculation calculation, GeneralPipingInput generalInput, double sectionLength, string hydraulicBoundaryDatabaseFilePath, bool usePreprocessor)
+ {
+ ProbabilisticPipingInput pipingInput = calculation.InputParameters;
+
+ LogNormalDistribution effectiveThicknessCoverageLayer = DerivedPipingInput.GetEffectiveThicknessCoverageLayer(pipingInput, generalInput);
+ LogNormalDistribution saturatedVolumicWeightOfCoverageLayer = DerivedPipingInput.GetSaturatedVolumicWeightOfCoverageLayer(pipingInput);
+ VariationCoefficientLogNormalDistribution seepageLength = DerivedPipingInput.GetSeepageLength(pipingInput);
+ LogNormalDistribution thicknessAquiferLayer = DerivedPipingInput.GetThicknessAquiferLayer(pipingInput);
+ VariationCoefficientLogNormalDistribution darcyPermeability = DerivedPipingInput.GetDarcyPermeability(pipingInput);
+ VariationCoefficientLogNormalDistribution diameterD70 = DerivedPipingInput.GetDiameterD70(pipingInput);
+
+ var input = new PipingCalculationInput(
+ pipingInput.HydraulicBoundaryLocation.Id,
+ sectionLength,
+ generalInput.WaterVolumetricWeight,
+ pipingInput.PhreaticLevelExit.Mean, pipingInput.PhreaticLevelExit.StandardDeviation,
+ generalInput.WaterVolumetricWeight,
+ effectiveThicknessCoverageLayer.Mean, effectiveThicknessCoverageLayer.StandardDeviation,
+ saturatedVolumicWeightOfCoverageLayer.Mean, saturatedVolumicWeightOfCoverageLayer.StandardDeviation,
+ saturatedVolumicWeightOfCoverageLayer.Shift,
+ generalInput.UpliftModelFactor.Mean, generalInput.UpliftModelFactor.StandardDeviation,
+ pipingInput.DampingFactorExit.Mean, pipingInput.DampingFactorExit.StandardDeviation,
+ seepageLength.Mean, seepageLength.CoefficientOfVariation,
+ thicknessAquiferLayer.Mean, thicknessAquiferLayer.StandardDeviation,
+ generalInput.SandParticlesVolumicWeight,
+ generalInput.SellmeijerModelFactor.Mean, generalInput.SellmeijerModelFactor.StandardDeviation,
+ generalInput.BeddingAngle,
+ generalInput.WhitesDragCoefficient,
+ darcyPermeability.Mean, darcyPermeability.CoefficientOfVariation,
+ diameterD70.Mean, diameterD70.CoefficientOfVariation,
+ generalInput.Gravity,
+ generalInput.CriticalHeaveGradient.Mean, generalInput.CriticalHeaveGradient.StandardDeviation);
+
+ HydraRingSettingsDatabaseHelper.AssignSettingsFromDatabase(input, hydraulicBoundaryDatabaseFilePath, usePreprocessor);
+
+ return input;
+ }
+
+ private static GeneralResult ConvertIllustrationPointsResult(HydraRingGeneralResult result, string errorMessage)
+ {
+ if (result == null)
+ {
+ log.Warn(errorMessage);
+ return null;
+ }
+
+ try
+ {
+ GeneralResult generalResult =
+ GeneralResultConverter.ConvertToGeneralResultTopLevelFaultTreeIllustrationPoint(result);
+ return generalResult;
+ }
+ catch (IllustrationPointConversionException e)
+ {
+ log.Warn(RiskeerCommonServiceResources.SetGeneralResult_Converting_IllustrationPointResult_Failed, e);
+ }
+
+ return null;
+ }
+
private static IEnumerable ValidateHydraulicBoundaryDatabase(IAssessmentSection assessmentSection)
{
string preprocessorDirectory = assessmentSection.HydraulicBoundaryDatabase.EffectivePreprocessorDirectory();
@@ -111,5 +429,10 @@
return validationResults;
}
+
+ private void NotifyProgress(string stepName, int currentStepNumber, int totalStepNumber)
+ {
+ OnProgressChanged?.Invoke(stepName, currentStepNumber, totalStepNumber);
+ }
}
}
\ No newline at end of file
Index: Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.Designer.cs
===================================================================
diff -u -r106eeb3a0608bd85eb1fcc8fff72256fd9c3ac5f -r71c3adcd5c30cb64e6a1b804e6841558e8d2d712
--- Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 106eeb3a0608bd85eb1fcc8fff72256fd9c3ac5f)
+++ Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 71c3adcd5c30cb64e6a1b804e6841558e8d2d712)
@@ -1,4 +1,4 @@
-// Copyright (C) Stichting Deltares 2019. All rights reserved.
+// Copyright (C) Stichting Deltares 2019. All rights reserved.
//
// This file is part of Riskeer.
//
@@ -40,7 +40,7 @@
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -230,5 +230,73 @@
"e_larger_than_WaterVolumetricWeight", resourceCulture);
}
}
+
+ ///
+ /// Looks up a localized string similar to Fout bij het uitlezen van de illustratiepunten voor berekening {0} ({1}): {2} Het uitlezen van illustratiepunten wordt overgeslagen..
+ ///
+ internal static string PipingProbabailisticCalculationService_Calculate_Error_in_reading_illustrationPoints_for_CalculationName_0_CalculationType_1_overtopping_with_ErrorMessage_2 {
+ get {
+ return ResourceManager.GetString("PipingProbabailisticCalculationService_Calculate_Error_in_reading_illustrationPoi" +
+ "nts_for_CalculationName_0_CalculationType_1_overtopping_with_ErrorMessage_2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to De {0} berekening is uitgevoerd op de tijdelijke locatie '{1}'. Gedetailleerde invoer en uitvoer kan in de bestanden op deze locatie worden gevonden..
+ ///
+ internal static string ProbabilisticPipingCalculationService_Calculate_Calculation_of_type_0_performed_in_temporary_directory_1 {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_Calculate_Calculation_of_type_0_performed_i" +
+ "n_temporary_directory_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to De {0} berekening voor piping '{1}' is mislukt. Bekijk het foutrapport door op details te klikken.
+ ///{2}.
+ ///
+ internal static string ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_for_calculation_with_name_1_click_details_for_last_error_report_2 {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_fo" +
+ "r_calculation_with_name_1_click_details_for_last_error_report_2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to De {0} berekening voor piping '{1}' is mislukt. Er is geen foutrapport beschikbaar..
+ ///
+ internal static string ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_for_calculation_with_name_1_no_error_report {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_Calculate_Error_in_calculation_of_type_0_fo" +
+ "r_calculation_with_name_1_no_error_report", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Uitvoeren piping berekening voor {0}.
+ ///
+ internal static string ProbabilisticPipingCalculationService_Calculate_Executing_calculation_of_type_0 {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_Calculate_Executing_calculation_of_type_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to doorsnede.
+ ///
+ internal static string ProbabilisticPipingCalculationService_ProfileSpecific {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_ProfileSpecific", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to vak.
+ ///
+ internal static string ProbabilisticPipingCalculationService_SectionSpecific {
+ get {
+ return ResourceManager.GetString("ProbabilisticPipingCalculationService_SectionSpecific", resourceCulture);
+ }
+ }
}
}
Index: Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.resx
===================================================================
diff -u -rbf1fde9d2147a6eeaecebbb371be2c4856759159 -r71c3adcd5c30cb64e6a1b804e6841558e8d2d712
--- Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.resx (.../Resources.resx) (revision bf1fde9d2147a6eeaecebbb371be2c4856759159)
+++ Riskeer/Piping/src/Riskeer.Piping.Service/Properties/Resources.resx (.../Resources.resx) (revision 71c3adcd5c30cb64e6a1b804e6841558e8d2d712)
@@ -165,4 +165,26 @@
Het verzadigd volumetrisch gewicht van de deklaag moet groter zijn dan het volumetrisch gewicht van water.
+
+ Uitvoeren piping berekening voor {0}
+
+
+ De {0} berekening voor piping '{1}' is mislukt. Er is geen foutrapport beschikbaar.
+
+
+ De {0} berekening voor piping '{1}' is mislukt. Bekijk het foutrapport door op details te klikken.
+{2}
+
+
+ De {0} berekening is uitgevoerd op de tijdelijke locatie '{1}'. Gedetailleerde invoer en uitvoer kan in de bestanden op deze locatie worden gevonden.
+
+
+ Fout bij het uitlezen van de illustratiepunten voor berekening {0} ({1}): {2} Het uitlezen van illustratiepunten wordt overgeslagen.
+
+
+ doorsnede
+
+
+ vak
+
\ No newline at end of file
Index: Riskeer/Piping/src/Riskeer.Piping.Service/Riskeer.Piping.Service.csproj
===================================================================
diff -u -ra4047c0251a066635676fb6a1927836a6310d720 -r71c3adcd5c30cb64e6a1b804e6841558e8d2d712
--- Riskeer/Piping/src/Riskeer.Piping.Service/Riskeer.Piping.Service.csproj (.../Riskeer.Piping.Service.csproj) (revision a4047c0251a066635676fb6a1927836a6310d720)
+++ Riskeer/Piping/src/Riskeer.Piping.Service/Riskeer.Piping.Service.csproj (.../Riskeer.Piping.Service.csproj) (revision 71c3adcd5c30cb64e6a1b804e6841558e8d2d712)
@@ -1,4 +1,4 @@
-
+
@@ -10,6 +10,7 @@
+
@@ -32,4 +33,14 @@
Copying.licenseheader
+
+
+ 2.0.8
+ true
+ all
+
+
+
+
+
\ No newline at end of file