Exemple #1
0
        public void Run_InvalidHydraulicBoundaryDatabase_PerformValidationAndLogStartAndEndAndError()
        {
            // Setup
            string invalidFilePath = Path.Combine(testDataPath, "notexisting.sqlite");

            const string calculationIdentifier = "1/100";
            const string locationName          = "locationName";

            var settings = new HydraulicBoundaryCalculationSettings(invalidFilePath,
                                                                    validHlcdFilePath,
                                                                    false,
                                                                    string.Empty);
            var activity = new DuneLocationCalculationActivity(new DuneLocationCalculation(new TestDuneLocation(locationName)),
                                                               settings,
                                                               0.01,
                                                               calculationIdentifier);

            // Call
            void Call() => activity.Run();

            // Assert
            TestHelper.AssertLogMessages(Call, messages =>
            {
                string[] msgs = messages.ToArray();
                Assert.AreEqual(4, msgs.Length);
                Assert.AreEqual($"Hydraulische belastingen berekenen voor locatie '{locationName}' ({calculationIdentifier}) is gestart.", msgs[0]);
                CalculationServiceTestHelper.AssertValidationStartMessage(msgs[1]);
                StringAssert.StartsWith("Herstellen van de verbinding met de hydraulische belastingendatabase is mislukt. Fout bij het lezen van bestand", msgs[2]);
                CalculationServiceTestHelper.AssertValidationEndMessage(msgs[3]);
            });
            Assert.AreEqual(ActivityState.Failed, activity.State);
        }
Exemple #2
0
        public void Run_InvalidPreprocessorDirectory_PerformValidationAndLogStartAndEndAndError()
        {
            // Setup
            const string calculationIdentifier = "1/100";
            const string locationName          = "locationName";

            var settings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                    validHlcdFilePath,
                                                                    false,
                                                                    "NonExistingPreprocessorDirectory");
            var activity = new DuneLocationCalculationActivity(new DuneLocationCalculation(new TestDuneLocation(locationName)),
                                                               settings,
                                                               0.01,
                                                               calculationIdentifier);

            // Call
            void Call() => activity.Run();

            // Assert
            TestHelper.AssertLogMessages(Call, messages =>
            {
                string[] msgs = messages.ToArray();
                Assert.AreEqual(4, msgs.Length);
                Assert.AreEqual($"Hydraulische belastingen berekenen voor locatie '{locationName}' ({calculationIdentifier}) is gestart.", msgs[0]);
                CalculationServiceTestHelper.AssertValidationStartMessage(msgs[1]);
                Assert.AreEqual("De bestandsmap waar de preprocessor bestanden opslaat is ongeldig. De bestandsmap bestaat niet.", msgs[2]);
                CalculationServiceTestHelper.AssertValidationEndMessage(msgs[3]);
            });
            Assert.AreEqual(ActivityState.Failed, activity.State);
        }
Exemple #3
0
 /// <summary>
 /// Asserts whether the <see cref="HydraRingCalculationSettings"/> contains the correct
 /// data from <see cref="HydraulicBoundaryCalculationSettings"/>.
 /// </summary>
 /// <param name="expectedSettings">The <see cref="HydraulicBoundaryCalculationSettings"/>
 /// to assert against.</param>
 /// <param name="actualSettings">The <see cref="HydraRingCalculationSettings"/> to be asserted.</param>
 /// <exception cref="AssertionException">Thrown when:
 /// <list type="bullet">
 /// <item>The HLCD file paths do not match.</item>
 /// <item>The preprocessor directories do not match.</item>
 /// <item>The use preprocessor closure indicators do not match.</item>
 /// </list>
 /// </exception>
 public static void AssertHydraRingCalculationSettings(HydraulicBoundaryCalculationSettings expectedSettings,
                                                       HydraRingCalculationSettings actualSettings)
 {
     Assert.AreEqual(expectedSettings.HlcdFilePath, actualSettings.HlcdFilePath);
     Assert.AreEqual(expectedSettings.PreprocessorDirectory, actualSettings.PreprocessorDirectory);
     Assert.AreEqual(expectedSettings.UsePreprocessorClosure, actualSettings.UsePreprocessorClosure);
 }
        /// <summary>
        /// Creates the input for a calculation for the given <paramref name="waterLevel"/>.
        /// </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="WaveConditionsCalculationInput"/>.</returns>
        /// <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 static WaveConditionsCosineCalculationInput CreateInput(RoundedDouble waterLevel,
                                                                        RoundedDouble a,
                                                                        RoundedDouble b,
                                                                        RoundedDouble c,
                                                                        double targetProbability,
                                                                        WaveConditionsInput input,
                                                                        HydraulicBoundaryCalculationSettings calculationSettings)
        {
            var waveConditionsCosineCalculationInput = new WaveConditionsCosineCalculationInput(
                1,
                input.Orientation,
                input.HydraulicBoundaryLocation.Id,
                targetProbability,
                HydraRingInputParser.ParseForeshore(input),
                HydraRingInputParser.ParseBreakWater(input),
                waterLevel,
                a,
                b,
                c);

            HydraRingSettingsDatabaseHelper.AssignSettingsFromDatabase(waveConditionsCosineCalculationInput,
                                                                       calculationSettings.HydraulicBoundaryDatabaseFilePath,
                                                                       !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory));

            return(waveConditionsCosineCalculationInput);
        }
        /// <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 Calculate_ValidData_CalculationStartedWithRightParameters(bool usePreprocessor)
        {
            // Setup
            const double targetProbability     = 1.0 / 30;
            string       preprocessorDirectory = usePreprocessor
                                               ? validPreprocessorDirectory
                                               : string.Empty;
            var calculationSettings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                               validHlcdFilePath,
                                                                               false,
                                                                               preprocessorDirectory);

            var calculator = new TestDunesBoundaryConditionsCalculator
            {
                Converged = true
            };

            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateDunesBoundaryConditionsCalculator(Arg <HydraRingCalculationSettings> .Is.NotNull))
            .WhenCalled(invocation =>
            {
                HydraRingCalculationSettingsTestHelper.AssertHydraRingCalculationSettings(
                    calculationSettings, (HydraRingCalculationSettings)invocation.Arguments[0]);
            })
            .Return(calculator);
            var calculationMessageProvider = mockRepository.StrictMock <ICalculationMessageProvider>();

            mockRepository.ReplayAll();

            var duneLocation = new DuneLocation(1300001, "test", new Point2D(0, 0),
                                                new DuneLocation.ConstructionProperties
            {
                CoastalAreaId = 0,
                Offset        = 0,
                Orientation   = 0,
                D50           = 0.000007
            });

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                new DuneLocationCalculationService().Calculate(new DuneLocationCalculation(duneLocation),
                                                               targetProbability,
                                                               calculationSettings,
                                                               calculationMessageProvider);

                // Assert
                DunesBoundaryConditionsCalculationInput expectedInput = CreateInput(duneLocation, targetProbability);
                DunesBoundaryConditionsCalculationInput actualInput   = calculator.ReceivedInputs.Single();
                AssertInput(expectedInput, actualInput);
                Assert.AreEqual(usePreprocessor, actualInput.PreprocessorSetting.RunPreprocessor);
            }

            mockRepository.VerifyAll();
        }
Exemple #7
0
        public void CreateSettings_WithHydraulicBoundaryDatabaseWithVariousPreprocessorConfigurations_ReturnsExpectedSettings(
            HydraulicBoundaryDatabase database,
            string expectedPreprocessorDirectory)
        {
            // Call
            HydraulicBoundaryCalculationSettings settings = HydraulicBoundaryCalculationSettingsFactory.CreateSettings(database);

            // Assert
            Assert.AreEqual(expectedPreprocessorDirectory, settings.PreprocessorDirectory);
        }
        public void Calculate_PreprocessorDirectorySet_InputPropertiesCorrectlySentToCalculator(bool usePreprocessor)
        {
            // Setup
            string preprocessorDirectory = usePreprocessor
                                               ? validPreprocessorDirectory
                                               : string.Empty;
            var calculationSettings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                               validHlcdFilePath,
                                                                               false,
                                                                               preprocessorDirectory);

            var failureMechanism = new HeightStructuresFailureMechanism();

            var mockRepository = new MockRepository();
            IAssessmentSection assessmentSection = AssessmentSectionTestHelper.CreateAssessmentSectionStub(failureMechanism,
                                                                                                           mockRepository);
            var calculator        = new TestStructuresCalculator <StructuresOvertoppingCalculationInput>();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateStructuresCalculator <StructuresOvertoppingCalculationInput>(
                                         Arg <HydraRingCalculationSettings> .Is.NotNull))
            .WhenCalled(invocation =>
            {
                HydraRingCalculationSettingsTestHelper.AssertHydraRingCalculationSettings(
                    calculationSettings, (HydraRingCalculationSettings)invocation.Arguments[0]);
            })
            .Return(calculator);
            mockRepository.ReplayAll();

            var calculation = new TestHeightStructuresCalculationScenario
            {
                InputParameters =
                {
                    HydraulicBoundaryLocation = assessmentSection.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001)
                }
            };

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                new HeightStructuresCalculationService().Calculate(calculation,
                                                                   failureMechanism.GeneralInput,
                                                                   calculationSettings);

                // Assert
                StructuresOvertoppingCalculationInput[] calculationInputs = calculator.ReceivedInputs.ToArray();
                Assert.AreEqual(1, calculationInputs.Length);

                StructuresOvertoppingCalculationInput actualInput = calculationInputs[0];
                Assert.AreEqual(usePreprocessor, actualInput.PreprocessorSetting.RunPreprocessor);
            }

            mockRepository.VerifyAll();
        }
        public void Calculate_ValidData_StartsCalculationWithRightParameters(bool usePreprocessor)
        {
            // Setup
            const double targetProbability     = 1.0 / 30;
            string       preprocessorDirectory = usePreprocessor
                                               ? validPreprocessorDirectory
                                               : string.Empty;

            var calculator = new TestDesignWaterLevelCalculator
            {
                Converged = true
            };

            var calculationSettings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                               validHlcdFilePath,
                                                                               false,
                                                                               preprocessorDirectory);

            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateDesignWaterLevelCalculator(Arg <HydraRingCalculationSettings> .Is.NotNull))
            .WhenCalled(invocation =>
            {
                HydraRingCalculationSettingsTestHelper.AssertHydraRingCalculationSettings(
                    calculationSettings, (HydraRingCalculationSettings)invocation.Arguments[0]);
            })
            .Return(calculator);

            var calculationMessageProvider = mockRepository.StrictMock <ICalculationMessageProvider>();

            mockRepository.ReplayAll();

            var hydraulicBoundaryLocation            = new TestHydraulicBoundaryLocation();
            var hydraulicBoundaryLocationCalculation = new HydraulicBoundaryLocationCalculation(hydraulicBoundaryLocation);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                new DesignWaterLevelCalculationService().Calculate(hydraulicBoundaryLocationCalculation,
                                                                   calculationSettings,
                                                                   targetProbability,
                                                                   calculationMessageProvider);

                // Assert
                AssessmentLevelCalculationInput expectedInput = CreateInput(hydraulicBoundaryLocation.Id, targetProbability);
                AssessmentLevelCalculationInput actualInput   = calculator.ReceivedInputs.Single();
                AssertInput(expectedInput, actualInput);
                Assert.IsFalse(calculator.IsCanceled);
                Assert.AreEqual(usePreprocessor, actualInput.PreprocessorSetting.RunPreprocessor);
            }

            mockRepository.VerifyAll();
        }
        /// <summary>
        /// Creates a new instance of a <see cref="HydraRingCalculationSettings"/>
        /// based on a <see cref="HydraulicBoundaryCalculationSettings"/>.
        /// </summary>
        /// <param name="hydraulicBoundaryCalculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/>
        /// to create a <see cref="HydraRingCalculationSettings"/> for.</param>
        /// <returns>A <see cref="HydraRingCalculationSettings"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="hydraulicBoundaryCalculationSettings"/>
        /// is <c>null</c>.</exception>
        public static HydraRingCalculationSettings CreateSettings(HydraulicBoundaryCalculationSettings hydraulicBoundaryCalculationSettings)
        {
            if (hydraulicBoundaryCalculationSettings == null)
            {
                throw new ArgumentNullException(nameof(hydraulicBoundaryCalculationSettings));
            }

            return(new HydraRingCalculationSettings(hydraulicBoundaryCalculationSettings.HlcdFilePath,
                                                    hydraulicBoundaryCalculationSettings.PreprocessorDirectory,
                                                    hydraulicBoundaryCalculationSettings.UsePreprocessorClosure));
        }
        /// <summary>
        /// Creates the input used in the calculation.
        /// </summary>
        /// <param name="duneLocation">The <see cref="DuneLocation"/> to create the input for.</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>
        /// <returns>A <see cref="DunesBoundaryConditionsCalculationInput"/> with all needed
        /// input data.</returns>
        /// <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 static DunesBoundaryConditionsCalculationInput CreateInput(DuneLocation duneLocation,
                                                                           double targetProbability,
                                                                           HydraulicBoundaryCalculationSettings calculationSettings)
        {
            var dunesBoundaryConditionsCalculationInput = new DunesBoundaryConditionsCalculationInput(1, duneLocation.Id, targetProbability);

            HydraRingSettingsDatabaseHelper.AssignSettingsFromDatabase(dunesBoundaryConditionsCalculationInput,
                                                                       calculationSettings.HydraulicBoundaryDatabaseFilePath,
                                                                       !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory));
            return(dunesBoundaryConditionsCalculationInput);
        }
Exemple #12
0
 public DuneLocationCalculationActivityWithState(DuneLocationCalculation duneLocationCalculation,
                                                 HydraulicBoundaryCalculationSettings calculationSettings,
                                                 double targetProbability,
                                                 string calculationIdentifier,
                                                 ActivityState state)
     : base(duneLocationCalculation,
            calculationSettings,
            targetProbability,
            calculationIdentifier)
 {
     State = state;
 }
 public TestDesignWaterLevelCalculationActivity(HydraulicBoundaryLocationCalculation hydraulicBoundaryLocationCalculation,
                                                HydraulicBoundaryCalculationSettings calculationSettings,
                                                double targetProbability,
                                                string calculationIdentifier,
                                                ActivityState state)
     : base(hydraulicBoundaryLocationCalculation,
            calculationSettings,
            targetProbability,
            calculationIdentifier)
 {
     State = state;
 }
        /// <summary>
        /// Creates the input for a design water level calculation.
        /// </summary>
        /// <param name="hydraulicBoundaryLocationId">The id of the hydraulic boundary location.</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>
        /// <returns>An <see cref="AssessmentLevelCalculationInput"/>.</returns>
        /// <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 static AssessmentLevelCalculationInput CreateInput(long hydraulicBoundaryLocationId,
                                                                   double targetProbability,
                                                                   HydraulicBoundaryCalculationSettings calculationSettings)
        {
            var assessmentLevelCalculationInput = new AssessmentLevelCalculationInput(1, hydraulicBoundaryLocationId, targetProbability);

            HydraRingSettingsDatabaseHelper.AssignSettingsFromDatabase(assessmentLevelCalculationInput,
                                                                       calculationSettings.HydraulicBoundaryDatabaseFilePath,
                                                                       !string.IsNullOrEmpty(calculationSettings.PreprocessorDirectory));

            return(assessmentLevelCalculationInput);
        }
        public void Run_ValidInput_PerformCalculationWithCorrectInput(bool usePreprocessor)
        {
            // Setup
            const string locationName          = "locationName";
            const string calculationIdentifier = "1/100";
            const double targetProbability     = 0.01;

            var calculator = new TestDesignWaterLevelCalculator
            {
                Converged = true
            };

            string preprocessorDirectory = usePreprocessor ? validPreprocessorDirectory : string.Empty;
            var    calculationSettings   = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                                    validHlcdFilePath,
                                                                                    false,
                                                                                    preprocessorDirectory);

            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateDesignWaterLevelCalculator(Arg <HydraRingCalculationSettings> .Is.NotNull))
            .WhenCalled(invocation =>
            {
                HydraRingCalculationSettingsTestHelper.AssertHydraRingCalculationSettings(
                    calculationSettings, (HydraRingCalculationSettings)invocation.Arguments[0]);
            })
            .Return(calculator);
            mockRepository.ReplayAll();

            var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(locationName);

            var activity = new DesignWaterLevelCalculationActivity(new HydraulicBoundaryLocationCalculation(hydraulicBoundaryLocation),
                                                                   calculationSettings,
                                                                   targetProbability,
                                                                   calculationIdentifier);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                activity.Run();

                // Assert
                AssessmentLevelCalculationInput designWaterLevelCalculationInput = calculator.ReceivedInputs.Single();
                Assert.AreEqual(hydraulicBoundaryLocation.Id, designWaterLevelCalculationInput.HydraulicBoundaryLocationId);
                Assert.AreEqual(StatisticsConverter.ProbabilityToReliability(targetProbability), designWaterLevelCalculationInput.Beta);
            }

            Assert.AreEqual(ActivityState.Executed, activity.State);
            mockRepository.VerifyAll();
        }
        public void Run_ValidInput_PerformValidationAndCalculationAndLogStartAndEnd()
        {
            // Setup
            const string locationName          = "locationName";
            const string calculationIdentifier = "1/100";
            const double targetProbability     = 0.01;

            var calculator = new TestDesignWaterLevelCalculator
            {
                Converged = true
            };

            HydraulicBoundaryCalculationSettings calculationSettings = CreateCalculationSettings();

            var mockRepository    = new MockRepository();
            var calculatorFactory = mockRepository.StrictMock <IHydraRingCalculatorFactory>();

            calculatorFactory.Expect(cf => cf.CreateDesignWaterLevelCalculator(null))
            .IgnoreArguments()
            .Return(calculator);
            mockRepository.ReplayAll();

            var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(locationName);

            var activity = new DesignWaterLevelCalculationActivity(new HydraulicBoundaryLocationCalculation(hydraulicBoundaryLocation),
                                                                   calculationSettings,
                                                                   targetProbability,
                                                                   calculationIdentifier);

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                void Call() => activity.Run();

                // Assert
                TestHelper.AssertLogMessages(Call, m =>
                {
                    string[] messages = m.ToArray();
                    Assert.AreEqual(6, messages.Length);
                    Assert.AreEqual($"{GetActivityDescription(locationName, calculationIdentifier)} is gestart.", messages[0]);
                    CalculationServiceTestHelper.AssertValidationStartMessage(messages[1]);
                    CalculationServiceTestHelper.AssertValidationEndMessage(messages[2]);
                    CalculationServiceTestHelper.AssertCalculationStartMessage(messages[3]);
                    StringAssert.StartsWith("Waterstand berekening is uitgevoerd op de tijdelijke locatie", messages[4]);
                    CalculationServiceTestHelper.AssertCalculationEndMessage(messages[5]);
                });
            }

            Assert.AreEqual(ActivityState.Executed, activity.State);
            mockRepository.VerifyAll();
        }
        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);
        }
        /// <summary>
        /// Performs validation on the given input parameters. Error and status information is logged during the execution of the operation.
        /// </summary>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <returns><c>true</c> if there were no validation errors; <c>false</c> otherwise.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="calculationSettings"/> is <c>null</c>.</exception>
        public bool Validate(HydraulicBoundaryCalculationSettings calculationSettings)
        {
            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            var isValid = true;

            CalculationServiceHelper.LogValidationBegin();

            string preprocessorDirectory             = calculationSettings.PreprocessorDirectory;
            string databaseFilePathValidationProblem = HydraulicBoundaryDatabaseHelper.ValidateFilesForCalculation(
                calculationSettings.HydraulicBoundaryDatabaseFilePath,
                calculationSettings.HlcdFilePath,
                preprocessorDirectory,
                calculationSettings.UsePreprocessorClosure);

            if (!string.IsNullOrEmpty(databaseFilePathValidationProblem))
            {
                CalculationServiceHelper.LogMessagesAsError(Resources.Hydraulic_boundary_database_connection_failed_0_,
                                                            new[]
                {
                    databaseFilePathValidationProblem
                });

                isValid = false;
            }

            string preprocessorDirectoryValidationProblem = HydraulicBoundaryDatabaseHelper.ValidatePreprocessorDirectory(preprocessorDirectory);

            if (!string.IsNullOrEmpty(preprocessorDirectoryValidationProblem))
            {
                CalculationServiceHelper.LogMessagesAsError(new[]
                {
                    preprocessorDirectoryValidationProblem
                });

                isValid = false;
            }

            CalculationServiceHelper.LogValidationEnd();

            return(isValid);
        }
        public void Constructor_WithArguments_ExpectedValues(string preprocessorDirectory)
        {
            // Setup
            const string hydraulicBoundaryDatabaseFilePath = "D:\\HydraulicBoundaryDatabaseFilePath";
            const string hlcdFilePath           = "D:\\hlcdFilePath";
            bool         usePreprocessorClosure = new Random(21).NextBoolean();

            // Call
            var settings = new HydraulicBoundaryCalculationSettings(hydraulicBoundaryDatabaseFilePath,
                                                                    hlcdFilePath,
                                                                    usePreprocessorClosure,
                                                                    preprocessorDirectory);

            // Assert
            Assert.AreEqual(hydraulicBoundaryDatabaseFilePath, settings.HydraulicBoundaryDatabaseFilePath);
            Assert.AreEqual(hlcdFilePath, settings.HlcdFilePath);
            Assert.AreEqual(usePreprocessorClosure, settings.UsePreprocessorClosure);
            Assert.AreEqual(preprocessorDirectory, settings.PreprocessorDirectory);
        }
Exemple #20
0
        /// <summary>
        /// Creates a new instance of <see cref="DesignWaterLevelCalculationActivity"/>.
        /// </summary>
        /// <param name="hydraulicBoundaryLocationCalculation">The hydraulic boundary location calculation to perform.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="targetProbability">The target probability to use during the calculation.</param>
        /// <param name="calculationIdentifier">The calculation identifier to use in all messages.</param>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="hydraulicBoundaryLocationCalculation"/> or
        /// <paramref name="calculationSettings"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="calculationIdentifier"/> is <c>null</c> or empty.</exception>
        public DesignWaterLevelCalculationActivity(HydraulicBoundaryLocationCalculation hydraulicBoundaryLocationCalculation,
                                                   HydraulicBoundaryCalculationSettings calculationSettings,
                                                   double targetProbability,
                                                   string calculationIdentifier)
            : base(hydraulicBoundaryLocationCalculation)
        {
            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            messageProvider = new DesignWaterLevelCalculationMessageProvider(calculationIdentifier);

            this.hydraulicBoundaryLocationCalculation = hydraulicBoundaryLocationCalculation;
            this.calculationSettings = calculationSettings;
            this.targetProbability   = targetProbability;

            calculationService = new DesignWaterLevelCalculationService();

            Description = messageProvider.GetActivityDescription(hydraulicBoundaryLocationCalculation.HydraulicBoundaryLocation.Name);
        }
Exemple #21
0
        /// <summary>
        /// Creates a collection of <see cref="CalculatableActivity"/> based on <paramref name="calculations"/>.
        /// </summary>
        /// <param name="calculations">The calculations to create activities for.</param>
        /// <param name="assessmentSection">The assessment section the calculations belong to.</param>
        /// <param name="targetProbability">The target probability to use during the calculations.</param>
        /// <param name="calculationIdentifier">The calculation identifier to use in all messages.</param>
        /// <returns>A collection of <see cref="CalculatableActivity"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="calculations"/> or
        /// <paramref name="assessmentSection"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="calculationIdentifier"/> is <c>null</c> or empty.</exception>
        public static IEnumerable <CalculatableActivity> CreateCalculationActivities(IEnumerable <DuneLocationCalculation> calculations,
                                                                                     IAssessmentSection assessmentSection,
                                                                                     double targetProbability,
                                                                                     string calculationIdentifier)
        {
            if (calculations == null)
            {
                throw new ArgumentNullException(nameof(calculations));
            }

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

            HydraulicBoundaryCalculationSettings settings = HydraulicBoundaryCalculationSettingsFactory.CreateSettings(assessmentSection.HydraulicBoundaryDatabase);

            return(calculations.Select(calculation => new DuneLocationCalculationActivity(calculation,
                                                                                          settings,
                                                                                          targetProbability,
                                                                                          calculationIdentifier)).ToArray());
        }
Exemple #22
0
        /// <summary>
        /// Creates a new instance of <see cref="DuneLocationCalculationActivity"/>.
        /// </summary>
        /// <param name="duneLocationCalculation">The <see cref="DuneLocationCalculation"/> to perform.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="targetProbability">The target probability to use during the calculation.</param>
        /// <param name="calculationIdentifier">The calculation identifier to use in all messages.</param>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="duneLocationCalculation"/>
        /// or <paramref name="calculationSettings"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when <paramref name="calculationIdentifier"/> is <c>null</c> or empty.</exception>
        public DuneLocationCalculationActivity(DuneLocationCalculation duneLocationCalculation,
                                               HydraulicBoundaryCalculationSettings calculationSettings,
                                               double targetProbability,
                                               string calculationIdentifier)
            : base(duneLocationCalculation)
        {
            if (calculationSettings == null)
            {
                throw new ArgumentNullException(nameof(calculationSettings));
            }

            messageProvider = new DuneLocationCalculationMessageProvider(calculationIdentifier);

            this.duneLocationCalculation = duneLocationCalculation;
            this.calculationSettings     = calculationSettings;
            this.targetProbability       = targetProbability;

            DuneLocation duneLocation = duneLocationCalculation.DuneLocation;

            Description = messageProvider.GetActivityDescription(duneLocation.Name);

            calculationService = new DuneLocationCalculationService();
        }
Exemple #23
0
        public void CreateSettings_WithHydraulicBoundaryDatabaseWithFilePath_ReturnsExpectedSettings()
        {
            // Setup
            const string hydraulicBoundaryDatabaseFilePath = "some//FilePath//HRD dutch coast south.sqlite";
            const string hlcdFilePath           = "some//FilePath//HLCD dutch coast south.sqlite";
            bool         usePreprocessorClosure = new Random(21).NextBoolean();

            var database = new HydraulicBoundaryDatabase
            {
                FilePath = hydraulicBoundaryDatabaseFilePath
            };

            database.HydraulicLocationConfigurationSettings.SetValues(hlcdFilePath, string.Empty, 10, string.Empty,
                                                                      usePreprocessorClosure, null, null, null, null, null, null);

            // Call
            HydraulicBoundaryCalculationSettings settings = HydraulicBoundaryCalculationSettingsFactory.CreateSettings(database);

            // Assert
            Assert.AreEqual(hydraulicBoundaryDatabaseFilePath, settings.HydraulicBoundaryDatabaseFilePath);
            Assert.AreEqual(hlcdFilePath, settings.HlcdFilePath);
            Assert.AreEqual(usePreprocessorClosure, settings.UsePreprocessorClosure);
        }
        public void Validate_UsePreprocessorClosureTrueAndWithoutPreprocessorClosure_LogsErrorAndReturnsFalse()
        {
            // Setup
            var valid = true;
            var calculationSettings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                               validHlcdFilePath,
                                                                               true,
                                                                               string.Empty);

            // Call
            void Call() => valid = calculationService.Validate(calculationSettings);

            // Assert
            TestHelper.AssertLogMessages(Call, messages =>
            {
                string[] msgs = messages.ToArray();
                Assert.AreEqual(3, msgs.Length);
                CalculationServiceTestHelper.AssertValidationStartMessage(msgs[0]);
                StringAssert.StartsWith("Herstellen van de verbinding met de hydraulische belastingendatabase is mislukt. Fout bij het lezen van bestand", msgs[1]);
                CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
            });
            Assert.IsFalse(valid);
        }
        public void Validate_InvalidPreprocessorDirectory_LogsErrorAndReturnsFalse()
        {
            // Setup
            const string invalidPreprocessorDirectory = "NonExistingPreprocessorDirectory";
            var          valid = true;
            var          calculationSettings = new HydraulicBoundaryCalculationSettings(validHydraulicBoundaryDatabaseFilePath,
                                                                                        validHlcdFilePath,
                                                                                        false,
                                                                                        invalidPreprocessorDirectory);

            // Call
            void Call() => valid = calculationService.Validate(calculationSettings);

            // Assert
            TestHelper.AssertLogMessages(Call, messages =>
            {
                string[] msgs = messages.ToArray();
                Assert.AreEqual(3, msgs.Length);
                CalculationServiceTestHelper.AssertValidationStartMessage(msgs[0]);
                Assert.AreEqual("De bestandsmap waar de preprocessor bestanden opslaat is ongeldig. De bestandsmap bestaat niet.", msgs[1]);
                CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
            });
            Assert.IsFalse(valid);
        }
        /// <summary>
        /// Performs a calculation for the design water level.
        /// </summary>
        /// <param name="hydraulicBoundaryLocationCalculation">The hydraulic boundary location calculation to perform.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="targetProbability">The target probability to use during the calculation.</param>
        /// <param name="messageProvider">The object which is used to build log messages.</param>
        /// <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>
        private void PerformCalculation(HydraulicBoundaryLocationCalculation hydraulicBoundaryLocationCalculation,
                                        HydraulicBoundaryCalculationSettings calculationSettings,
                                        double targetProbability,
                                        ICalculationMessageProvider messageProvider)
        {
            HydraulicBoundaryLocation hydraulicBoundaryLocation = hydraulicBoundaryLocationCalculation.HydraulicBoundaryLocation;

            AssessmentLevelCalculationInput calculationInput = CreateInput(hydraulicBoundaryLocation.Id, targetProbability, calculationSettings);

            calculator.Calculate(calculationInput);

            if (canceled || !string.IsNullOrEmpty(calculator.LastErrorFileContent))
            {
                return;
            }

            GeneralResult <TopLevelSubMechanismIllustrationPoint> generalResult = null;

            try
            {
                generalResult = hydraulicBoundaryLocationCalculation.InputParameters.ShouldIllustrationPointsBeCalculated
                                    ? GetGeneralResult(calculator.IllustrationPointsResult)
                                    : null;
            }
            catch (ArgumentException e)
            {
                log.Warn(string.Format(Resources.CalculationService_Error_in_reading_illustrationPoints_for_CalculationName_0_with_ErrorMessage_1,
                                       hydraulicBoundaryLocation.Name,
                                       e.Message));
            }

            HydraulicBoundaryLocationCalculationOutput hydraulicBoundaryLocationCalculationOutput = CreateOutput(
                messageProvider, hydraulicBoundaryLocation.Name, calculationInput.Beta, targetProbability, calculator.Converged, generalResult);

            hydraulicBoundaryLocationCalculation.Output = hydraulicBoundaryLocationCalculationOutput;
        }
        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);
        }
        public void Validate_ValidHydraulicBoundaryDatabaseWithoutSettings_LogsErrorAndReturnsFalse()
        {
            // Setup
            string invalidHydraulicBoundaryDatabaseFilePath = Path.Combine(testDataPath, "HRD nosettings.sqlite");
            var    valid = false;
            var    calculationSettings = new HydraulicBoundaryCalculationSettings(invalidHydraulicBoundaryDatabaseFilePath,
                                                                                  validHlcdFilePath,
                                                                                  false,
                                                                                  string.Empty);

            // Call
            void Call() => valid = calculationService.Validate(calculationSettings);

            // Assert
            TestHelper.AssertLogMessages(Call, messages =>
            {
                string[] msgs = messages.ToArray();
                Assert.AreEqual(3, msgs.Length);
                CalculationServiceTestHelper.AssertValidationStartMessage(msgs[0]);
                StringAssert.StartsWith("Herstellen van de verbinding met de hydraulische belastingendatabase is mislukt. Fout bij het lezen van bestand", msgs[1]);
                CalculationServiceTestHelper.AssertValidationEndMessage(msgs[2]);
            });
            Assert.IsFalse(valid);
        }
Exemple #29
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>
        /// Performs a calculation for the design water level.
        /// </summary>
        /// <param name="hydraulicBoundaryLocationCalculation">The hydraulic boundary location calculation to perform.</param>
        /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> with the
        /// hydraulic boundary calculation settings.</param>
        /// <param name="targetProbability">The target probability to use during the calculation.</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="hydraulicBoundaryLocationCalculation"/>,
        /// <paramref name="calculationSettings"/> or <paramref name="messageProvider"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentException">Thrown when
        /// <list type="bullet">
        /// <item>the hydraulic boundary database file path contains invalid characters.</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 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(HydraulicBoundaryLocationCalculation hydraulicBoundaryLocationCalculation,
                              HydraulicBoundaryCalculationSettings calculationSettings,
                              double targetProbability,
                              ICalculationMessageProvider messageProvider)
        {
            if (hydraulicBoundaryLocationCalculation == null)
            {
                throw new ArgumentNullException(nameof(hydraulicBoundaryLocationCalculation));
            }

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

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

            HydraulicBoundaryLocation hydraulicBoundaryLocation = hydraulicBoundaryLocationCalculation.HydraulicBoundaryLocation;

            CalculationServiceHelper.LogCalculationBegin();

            HydraRingCalculationSettings hydraRingCalculationSettings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings);

            calculator = HydraRingCalculatorFactory.Instance.CreateDesignWaterLevelCalculator(hydraRingCalculationSettings);

            var exceptionThrown = false;

            try
            {
                PerformCalculation(hydraulicBoundaryLocationCalculation,
                                   calculationSettings,
                                   targetProbability,
                                   messageProvider);
            }
            catch (HydraRingCalculationException)
            {
                if (!canceled)
                {
                    string lastErrorContent = calculator.LastErrorFileContent;
                    log.Error(string.IsNullOrEmpty(lastErrorContent)
                                  ? messageProvider.GetCalculationFailedMessage(hydraulicBoundaryLocation.Name)
                                  : messageProvider.GetCalculationFailedWithErrorReportMessage(hydraulicBoundaryLocation.Name, lastErrorContent));

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

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

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