/// <summary>
        /// Performs a piping calculation based on the supplied <see cref="ProbabilisticPipingCalculation"/> and sets <see cref="ProbabilisticPipingCalculation.Output"/>
        /// if the calculation was successful. Error and status information is logged during the execution of the operation.
        /// </summary>
        /// <param name="calculation">The <see cref="ProbabilisticPipingCalculation"/> that holds all the information required to perform the calculation.</param>
        /// <param name="generalInput">The <see cref="GeneralPipingInput"/> to derive values from during the calculation.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="sectionLength">The length of the section the calculation belongs to.</param>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="calculation"/>, <paramref name="generalInput"/>
        /// or <paramref name="calculationSettings"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when the hydraulic boundary database file path
        /// contains invalid characters.</exception>
        /// <exception cref="CriticalFileReadException">Thrown when:
        /// <list type="bullet">
        /// <item>No settings database file could be found at the location of the hydraulic boundary database file path
        /// with the same name.</item>
        /// <item>Unable to open settings database file.</item>
        /// <item>Unable to read required data from database file.</item>
        /// </list></exception>
        /// <exception cref="HydraRingFileParserException">Thrown when an error occurs during parsing of the Hydra-Ring output.</exception>
        /// <exception cref="HydraRingCalculationException">Thrown when an error occurs during the calculation.</exception>
        internal void Calculate(ProbabilisticPipingCalculation calculation, GeneralPipingInput generalInput,
                                HydraulicBoundaryCalculationSettings calculationSettings, double sectionLength)
        {
            if (calculation == null)
            {
                throw new ArgumentNullException(nameof(calculation));
            }

            if (generalInput == null)
            {
                throw new ArgumentNullException(nameof(generalInput));
            }

            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            string hydraulicBoundaryDatabaseFilePath = calculationSettings.HydraulicBoundaryDatabaseFilePath;
            bool   usePreprocessor = !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory);

            HydraRingCalculationSettings hydraRingCalculationSettings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings);

            profileSpecificCalculator = HydraRingCalculatorFactory.Instance.CreatePipingCalculator(
                hydraRingCalculationSettings);
            sectionSpecificCalculator = HydraRingCalculatorFactory.Instance.CreatePipingCalculator(
                hydraRingCalculationSettings);

            CalculationServiceHelper.LogCalculationBegin();

            try
            {
                IPartialProbabilisticPipingOutput profileSpecificOutput = CalculateProfileSpecific(
                    calculation, generalInput, hydraulicBoundaryDatabaseFilePath, usePreprocessor);

                if (canceled)
                {
                    return;
                }

                IPartialProbabilisticPipingOutput sectionSpecificOutput = CalculateSectionSpecific(
                    calculation, generalInput, sectionLength, hydraulicBoundaryDatabaseFilePath, usePreprocessor);

                if (canceled)
                {
                    return;
                }

                calculation.Output = new ProbabilisticPipingOutput(sectionSpecificOutput, profileSpecificOutput);
            }
            finally
            {
                CalculationServiceHelper.LogCalculationEnd();

                profileSpecificCalculator = null;
                sectionSpecificCalculator = null;
            }
        }
        public void CreateSettings_HydraulicBoundaryCalculationSettingsNull_ThrowsArgumentNullException()
        {
            // Call
            TestDelegate call = () => HydraRingCalculationSettingsFactory.CreateSettings(null);

            // Assert
            var exception = Assert.Throws <ArgumentNullException>(call);

            Assert.AreEqual("hydraulicBoundaryCalculationSettings", exception.ParamName);
        }
        public void CreateSettings_WithHydraulicBoundaryCalculationSettings_ReturnsExpectedSettings()
        {
            // Setup
            var hydraulicBoundaryCalculationSettings = new HydraulicBoundaryCalculationSettings("HydraulicBoundaryDataBaseFilePath",
                                                                                                "hlcdFilePath",
                                                                                                false,
                                                                                                "preprocessorDirectory");

            // Call
            HydraRingCalculationSettings hydraRingCalculationSettings = HydraRingCalculationSettingsFactory.CreateSettings(hydraulicBoundaryCalculationSettings);

            // Assert
            Assert.AreEqual(hydraulicBoundaryCalculationSettings.HlcdFilePath, hydraRingCalculationSettings.HlcdFilePath);
            Assert.AreEqual(hydraulicBoundaryCalculationSettings.PreprocessorDirectory, hydraRingCalculationSettings.PreprocessorDirectory);
            Assert.AreEqual(hydraulicBoundaryCalculationSettings.UsePreprocessorClosure, hydraRingCalculationSettings.UsePreprocessorClosure);
        }
        private int CreateCalculators(GrassCoverErosionInwardsCalculation calculation,
                                      HydraulicBoundaryCalculationSettings calculationSettings)
        {
            var numberOfCalculators = 1;

            HydraRingCalculationSettings hydraRingCalculationSettings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings);

            overtoppingCalculator = HydraRingCalculatorFactory.Instance.CreateOvertoppingCalculator(
                hydraRingCalculationSettings);

            if (calculation.InputParameters.ShouldDikeHeightBeCalculated)
            {
                dikeHeightCalculator = HydraRingCalculatorFactory.Instance.CreateDikeHeightCalculator(hydraRingCalculationSettings);
                numberOfCalculators++;
            }

            if (calculation.InputParameters.ShouldOvertoppingRateBeCalculated)
            {
                overtoppingRateCalculator = HydraRingCalculatorFactory.Instance.CreateOvertoppingRateCalculator(hydraRingCalculationSettings);
                numberOfCalculators++;
            }

            return(numberOfCalculators);
        }
Example #5
0
        /// <summary>
        /// Performs a structures calculation based on the supplied <see cref="StructuresCalculation{T}"/> and sets <see cref="StructuresCalculation{T}.Output"/>
        /// if the calculation was successful. Error and status information is logged during the execution of the operation.
        /// </summary>
        /// <param name="calculation">The <see cref="StructuresCalculation{T}"/> that holds all the information required to perform the calculation.</param>
        /// <param name="generalInput">General calculation parameters that are the same across all calculations.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when any parameter is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when the hydraulic boundary database file path
        /// contains invalid characters.</exception>
        /// <exception cref="InvalidEnumArgumentException">Thrown when an unexpected
        /// enum value is encountered.</exception>
        /// <exception cref="CriticalFileReadException">Thrown when:
        /// <list type="bullet">
        /// <item>No settings database file could be found at the location of the hydraulic boundary database file path
        /// with the same name.</item>
        /// <item>Unable to open settings database file.</item>
        /// <item>Unable to read required data from database file.</item>
        /// </list></exception>
        /// <exception cref="HydraRingCalculationException">Thrown when an error occurs while performing the calculation.</exception>
        public void Calculate(StructuresCalculation <TStructureInput> calculation,
                              TGeneralInput generalInput,
                              HydraulicBoundaryCalculationSettings calculationSettings)
        {
            if (calculation == null)
            {
                throw new ArgumentNullException(nameof(calculation));
            }

            if (generalInput == null)
            {
                throw new ArgumentNullException(nameof(generalInput));
            }

            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            TCalculationInput input = CreateInput(calculation.InputParameters,
                                                  generalInput,
                                                  calculationSettings.HydraulicBoundaryDatabaseFilePath,
                                                  !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory));

            calculator = HydraRingCalculatorFactory.Instance.CreateStructuresCalculator <TCalculationInput>(
                HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings));
            string calculationName = calculation.Name;

            CalculationServiceHelper.LogCalculationBegin();

            var exceptionThrown = false;

            try
            {
                PerformCalculation(calculation, input);
            }
            catch (HydraRingCalculationException)
            {
                if (!canceled)
                {
                    string lastErrorFileContent = calculator.LastErrorFileContent;

                    string message = string.IsNullOrEmpty(lastErrorFileContent)
                                         ? messageProvider.GetCalculationFailedMessage(calculationName)
                                         : messageProvider.GetCalculationFailedWithErrorReportMessage(calculationName, lastErrorFileContent);

                    log.Error(message);

                    exceptionThrown = true;
                    throw;
                }
            }
            finally
            {
                string lastErrorFileContent = calculator.LastErrorFileContent;
                bool   errorOccurred        = CalculationServiceHelper.HasErrorOccurred(canceled, exceptionThrown, lastErrorFileContent);
                if (errorOccurred)
                {
                    log.Error(messageProvider.GetCalculationFailedWithErrorReportMessage(calculationName, lastErrorFileContent));
                }

                log.Info(messageProvider.GetCalculationPerformedMessage(calculator.OutputDirectory));

                CalculationServiceHelper.LogCalculationEnd();

                if (errorOccurred)
                {
                    throw new HydraRingCalculationException(lastErrorFileContent);
                }
            }
        }
        /// <summary>
        /// Calculates values for a single water level.
        /// </summary>
        /// <param name="waterLevel">The level of the water.</param>
        /// <param name="a">The 'a' factor decided on failure mechanism level.</param>
        /// <param name="b">The 'b' factor decided on failure mechanism level.</param>
        /// <param name="c">The 'c' factor decided on failure mechanism level.</param>
        /// <param name="targetProbability">The target probability to use.</param>
        /// <param name="input">The input that is different per calculation.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> containing all data
        /// to perform a hydraulic boundary calculation.</param>
        /// <returns>A <see cref="WaveConditionsOutput"/> if the calculation was successful; or <c>null</c> if it was canceled.</returns>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentException">Thrown when the hydraulic boundary database file path
        /// contains invalid characters.</exception>
        /// <exception cref="CriticalFileReadException">Thrown when:
        /// <list type="bullet">
        /// <item>No settings database file could be found at the location of the hydraulic boundary database file path
        /// with the same name.</item>
        /// <item>Unable to open settings database file.</item>
        /// <item>Unable to read required data from database file.</item>
        /// </list>
        /// </exception>
        private WaveConditionsOutput CalculateWaterLevel(RoundedDouble waterLevel,
                                                         RoundedDouble a,
                                                         RoundedDouble b,
                                                         RoundedDouble c,
                                                         double targetProbability,
                                                         WaveConditionsInput input,
                                                         HydraulicBoundaryCalculationSettings calculationSettings)
        {
            HydraRingCalculationSettings settings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings);

            calculator = HydraRingCalculatorFactory.Instance.CreateWaveConditionsCosineCalculator(settings);
            WaveConditionsCosineCalculationInput calculationInput = CreateInput(waterLevel, a, b, c, targetProbability, input, calculationSettings);

            WaveConditionsOutput output;
            var exceptionThrown = false;

            try
            {
                calculator.Calculate(calculationInput);

                output = WaveConditionsOutputFactory.CreateOutput(waterLevel,
                                                                  calculator.WaveHeight,
                                                                  calculator.WavePeakPeriod,
                                                                  calculator.WaveAngle,
                                                                  calculator.WaveDirection,
                                                                  targetProbability,
                                                                  calculator.ReliabilityIndex,
                                                                  calculator.Converged);
            }
            catch (Exception e) when(e is HydraRingCalculationException || e is ArgumentOutOfRangeException)
            {
                if (!Canceled)
                {
                    string lastErrorContent = calculator.LastErrorFileContent;
                    if (string.IsNullOrEmpty(lastErrorContent))
                    {
                        log.ErrorFormat(CultureInfo.CurrentCulture,
                                        Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_no_error_report,
                                        waterLevel);
                    }
                    else
                    {
                        log.ErrorFormat(CultureInfo.CurrentCulture,
                                        Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_click_details_for_last_error_report_1,
                                        waterLevel,
                                        lastErrorContent);
                    }

                    exceptionThrown = true;
                }

                output = null;
            }
            finally
            {
                string lastErrorFileContent = calculator.LastErrorFileContent;
                bool   errorOccurred        = CalculationServiceHelper.HasErrorOccurred(Canceled, exceptionThrown, lastErrorFileContent);
                if (errorOccurred)
                {
                    log.ErrorFormat(CultureInfo.CurrentCulture,
                                    Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_click_details_for_last_error_report_1,
                                    waterLevel,
                                    lastErrorFileContent);
                }

                log.InfoFormat(CultureInfo.CurrentCulture,
                               Resources.WaveConditionsCalculationService_CalculateWaterLevel_Calculation_temporary_directory_can_be_found_on_location_0,
                               calculator.OutputDirectory);

                if (errorOccurred)
                {
                    output = null;
                }
            }

            return(output);
        }
        /// <summary>
        /// Performs the provided <see cref="DuneLocationCalculation"/> and sets its output if the calculation is successful.
        /// Error and status information is logged during the execution of the operation.
        /// </summary>
        /// <param name="duneLocationCalculation">The <see cref="DuneLocationCalculation"/> to perform.</param>
        /// <param name="targetProbability">The target probability to use during the calculation.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="messageProvider">The object which is used to build log messages.</param>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="duneLocationCalculation"/>,
        /// <paramref name="calculationSettings"/> or <paramref name="messageProvider"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when:
        /// <list type="bullet">
        /// <item>The hydraulic boundary location database file path contains invalid characters.</item>
        /// <item>The contribution of the failure mechanism is zero.</item>
        /// <item>The target probability or the calculated probability falls outside the [0.0, 1.0]
        /// range and is not <see cref="double.NaN"/>.</item>
        /// </list></exception>
        /// <exception cref="CriticalFileReadException">Thrown when:
        /// <list type="bullet">
        /// <item>No settings database file could be found at the location of the hydraulic boundary database
        /// with the same name.</item>
        /// <item>Unable to open settings database file.</item>
        /// <item>Unable to read required data from database file.</item>
        /// </list></exception>
        /// <exception cref="HydraRingCalculationException">Thrown when an error occurs while performing
        /// the calculation.</exception>
        public void Calculate(DuneLocationCalculation duneLocationCalculation,
                              double targetProbability,
                              HydraulicBoundaryCalculationSettings calculationSettings,
                              ICalculationMessageProvider messageProvider)
        {
            if (duneLocationCalculation == null)
            {
                throw new ArgumentNullException(nameof(duneLocationCalculation));
            }

            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            if (messageProvider == null)
            {
                throw new ArgumentNullException(nameof(messageProvider));
            }

            DuneLocation duneLocation     = duneLocationCalculation.DuneLocation;
            string       duneLocationName = duneLocation.Name;

            CalculationServiceHelper.LogCalculationBegin();

            HydraRingCalculationSettings hydraRingCalculationSettings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings);

            calculator = HydraRingCalculatorFactory.Instance.CreateDunesBoundaryConditionsCalculator(hydraRingCalculationSettings);

            var exceptionThrown = false;

            try
            {
                DunesBoundaryConditionsCalculationInput calculationInput = CreateInput(duneLocation,
                                                                                       targetProbability,
                                                                                       calculationSettings);
                calculator.Calculate(calculationInput);

                if (string.IsNullOrEmpty(calculator.LastErrorFileContent))
                {
                    duneLocationCalculation.Output = CreateDuneLocationCalculationOutput(duneLocationName,
                                                                                         calculationInput.Beta,
                                                                                         targetProbability,
                                                                                         messageProvider);
                }
            }
            catch (HydraRingCalculationException)
            {
                if (!canceled)
                {
                    string lastErrorContent = calculator.LastErrorFileContent;
                    log.Error(string.IsNullOrEmpty(lastErrorContent)
                                  ? messageProvider.GetCalculationFailedMessage(duneLocationName)
                                  : messageProvider.GetCalculationFailedWithErrorReportMessage(duneLocationName, lastErrorContent));

                    exceptionThrown = true;
                    throw;
                }
            }
            finally
            {
                string lastErrorFileContent = calculator.LastErrorFileContent;
                bool   hasErrorOccurred     = CalculationServiceHelper.HasErrorOccurred(canceled, exceptionThrown, lastErrorFileContent);
                if (hasErrorOccurred)
                {
                    log.Error(messageProvider.GetCalculationFailedWithErrorReportMessage(duneLocationName, lastErrorFileContent));
                }

                log.InfoFormat(Resources.DuneLocationCalculationService_Calculate_Calculation_temporary_directory_can_be_found_on_location_0,
                               calculator.OutputDirectory);
                CalculationServiceHelper.LogCalculationEnd();

                if (hasErrorOccurred)
                {
                    throw new HydraRingCalculationException(lastErrorFileContent);
                }
            }
        }