public void CreateOvertoppingRateCalculator_Always_ReturnsHydraulicLoadsCalculator()
        {
            // Setup
            HydraRingCalculationSettings settings = HydraRingCalculationSettingsTestFactory.CreateSettings();

            // Call
            IHydraulicLoadsCalculator calculator = HydraRingCalculatorFactory.Instance.CreateOvertoppingRateCalculator(settings);

            // Assert
            Assert.IsInstanceOf <HydraulicLoadsCalculator>(calculator);
        }
        /// <summary>
        /// Creates the output of an overtopping rate calculation.
        /// </summary>
        /// <param name="calculator">The calculator used for performing the calculation.</param>
        /// <param name="calculationName">The name of the calculation.</param>
        /// <param name="targetReliability">The target reliability for the calculation.</param>
        /// <param name="targetProbability">The target probability for the calculation.</param>
        /// <param name="shouldIllustrationPointsBeCalculated">Indicates whether the illustration points
        /// should be calculated for the calculation.</param>
        /// <returns>A <see cref="OvertoppingRateOutput"/>.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="targetProbability"/>
        /// or the calculated probability falls outside the [0.0, 1.0] range and is not <see cref="double.NaN"/>.</exception>
        private static OvertoppingRateOutput CreateOvertoppingRateOutput(IHydraulicLoadsCalculator calculator,
                                                                         string calculationName,
                                                                         double targetReliability,
                                                                         double targetProbability,
                                                                         bool shouldIllustrationPointsBeCalculated)
        {
            double overtoppingRate = calculator.Value;
            double reliability     = calculator.ReliabilityIndex;
            double probability     = StatisticsConverter.ReliabilityToProbability(reliability);

            CalculationConvergence converged = RiskeerCommonDataCalculationService.GetCalculationConvergence(calculator.Converged);

            if (converged != CalculationConvergence.CalculatedConverged)
            {
                log.Warn(
                    string.Format(Resources.GrassCoverErosionInwardsCalculationService_Calculation_of_type_0_for_calculation_with_name_1_not_converged,
                                  Resources.GrassCoverErosionInwardsCalculationService_OvertoppingRate,
                                  calculationName));
            }

            GeneralResult <TopLevelFaultTreeIllustrationPoint> generalResult = null;

            try
            {
                generalResult = shouldIllustrationPointsBeCalculated
                                    ? ConvertIllustrationPointsResult(calculator.IllustrationPointsResult,
                                                                      calculator.IllustrationPointsParserErrorMessage)
                                    : null;
            }
            catch (ArgumentException e)
            {
                log.Warn(string.Format(Resources.GrassCoverErosionInwardsCalculationService_CalculateOvertopping_Error_in_reading_illustrationPoints_for_CalculationName_0_overtopping_rate_with_ErrorMessage_1,
                                       calculationName,
                                       e.Message));
            }

            return(new OvertoppingRateOutput(overtoppingRate, targetProbability,
                                             targetReliability, probability, reliability,
                                             converged, generalResult));
        }
        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);
        }
        /// <summary>
        /// Performs a grass cover erosion inwards calculation based on the supplied <see cref="GrassCoverErosionInwardsCalculation"/>
        /// and sets <see cref="GrassCoverErosionInwardsCalculation.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="GrassCoverErosionInwardsCalculation"/> that holds all the information required to perform the calculation.</param>
        /// <param name="assessmentSection">The <see cref="IAssessmentSection"/> that holds information about the target probability used in the calculation.</param>
        /// <param name="generalInput">Calculation input parameters that apply to all <see cref="GrassCoverErosionInwardsCalculation"/> instances.</param>
        /// <exception cref="ArgumentNullException">Thrown when one of the following parameters is <c>null</c>:
        /// <list type="bullet">
        /// <item><paramref name="calculation"/></item>
        /// <item><paramref name="assessmentSection"/></item>
        /// <item><paramref name="generalInput"/></item>
        /// </list></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="SecurityException">Thrown when the temporary working directory can't be accessed due to missing permissions.</exception>
        /// <exception cref="IOException">Thrown when the specified path is not valid, the network name is not known
        /// or an I/O error occurred while opening the file.</exception>
        /// <exception cref="UnauthorizedAccessException">Thrown when the directory can't be created due to missing
        /// the required permissions.</exception>
        /// <exception cref="NotSupportedException">Thrown when <see cref="HydraRingCalculationInput.FailureMechanismType"/>
        /// is not the same with already added input.</exception>
        /// <exception cref="Win32Exception">Thrown when there was an error in opening the associated file
        /// or the wait setting could not be accessed.</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(GrassCoverErosionInwardsCalculation calculation,
                                IAssessmentSection assessmentSection,
                                GeneralGrassCoverErosionInwardsInput generalInput)
        {
            if (calculation == null)
            {
                throw new ArgumentNullException(nameof(calculation));
            }

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

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

            HydraulicBoundaryCalculationSettings calculationSettings =
                HydraulicBoundaryCalculationSettingsFactory.CreateSettings(assessmentSection.HydraulicBoundaryDatabase);
            int numberOfCalculators = CreateCalculators(calculation, calculationSettings);

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

            CalculationServiceHelper.LogCalculationBegin();

            try
            {
                OvertoppingOutput overtoppingOutput = CalculateOvertopping(calculation,
                                                                           generalInput,
                                                                           hydraulicBoundaryDatabaseFilePath,
                                                                           usePreprocessor,
                                                                           numberOfCalculators);

                if (canceled)
                {
                    return;
                }

                DikeHeightOutput dikeHeightOutput = CalculateDikeHeight(calculation,
                                                                        generalInput,
                                                                        hydraulicBoundaryDatabaseFilePath,
                                                                        usePreprocessor,
                                                                        numberOfCalculators);
                if (canceled)
                {
                    return;
                }

                OvertoppingRateOutput overtoppingRateOutput = CalculateOvertoppingRate(calculation,
                                                                                       generalInput,
                                                                                       hydraulicBoundaryDatabaseFilePath,
                                                                                       usePreprocessor,
                                                                                       numberOfCalculators);

                if (canceled)
                {
                    return;
                }

                calculation.Output = new GrassCoverErosionInwardsOutput(
                    overtoppingOutput,
                    dikeHeightOutput,
                    overtoppingRateOutput);
            }
            finally
            {
                CalculationServiceHelper.LogCalculationEnd();

                overtoppingCalculator     = null;
                dikeHeightCalculator      = null;
                overtoppingRateCalculator = null;
            }
        }