private static IEnumerable <string> ValidateWaveConditionsInput(WaveConditionsInput input,
                                                                        RoundedDouble assessmentLevel)
        {
            var messages = new List <string>();

            if (input.HydraulicBoundaryLocation == null)
            {
                messages.Add(RiskeerCommonServiceResources.CalculationService_ValidateInput_No_hydraulic_boundary_location_selected);
            }
            else if (double.IsNaN(assessmentLevel))
            {
                messages.Add(Resources.WaveConditionsCalculationService_ValidateInput_No_AssessmentLevel_calculated);
            }
            else
            {
                if (!input.GetWaterLevels(assessmentLevel).Any())
                {
                    messages.Add(Resources.WaveConditionsCalculationService_ValidateInput_No_derived_WaterLevels);
                }

                messages.AddRange(new UseBreakWaterRule(input).Validate());
                messages.AddRange(new NumericInputRule(input.Orientation, ParameterNameExtractor.GetFromDisplayName(RiskeerCommonFormsResources.Orientation_DisplayName)).Validate());
            }

            return(messages);
        }
        public void Calculate_VariousHydraulicBoundaryDatabaseConfigurations_StartsCalculationWithRightParameters(
            HydraulicBoundaryDatabase hydraulicBoundaryDatabase)
        {
            // Setup
            var          waterLevel        = (RoundedDouble)4.20;
            var          a                 = (RoundedDouble)1.0;
            var          b                 = (RoundedDouble)0.8;
            var          c                 = (RoundedDouble)0.4;
            const double targetProbability = 0.2;
            var          input             = new WaveConditionsInput
            {
                HydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(),
                ForeshoreProfile          = new TestForeshoreProfile(true),
                UpperBoundaryRevetment    = (RoundedDouble)4,
                LowerBoundaryRevetment    = (RoundedDouble)3,
                StepSize    = WaveConditionsInputStepSize.Two,
                Orientation = (RoundedDouble)0
            };

            var calculator      = new TestWaveConditionsCosineCalculator();
            int nrOfCalculators = input.GetWaterLevels(waterLevel).Count();

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

            calculatorFactory.Expect(cf => cf.CreateWaveConditionsCosineCalculator(Arg <HydraRingCalculationSettings> .Is.NotNull))
            .WhenCalled(invocation =>
            {
                HydraRingCalculationSettingsTestHelper.AssertHydraRingCalculationSettings(
                    HydraulicBoundaryCalculationSettingsFactory.CreateSettings(hydraulicBoundaryDatabase),
                    (HydraRingCalculationSettings)invocation.Arguments[0]);
            })
            .Return(calculator)
            .Repeat
            .Times(nrOfCalculators);
            mockRepository.ReplayAll();

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                new TestWaveConditionsCalculationService().PublicCalculate(a,
                                                                           b,
                                                                           c,
                                                                           targetProbability,
                                                                           input,
                                                                           waterLevel,
                                                                           hydraulicBoundaryDatabase);

                // Assert
                for (var i = 0; i < nrOfCalculators; i++)
                {
                    Assert.AreEqual(hydraulicBoundaryDatabase.HydraulicLocationConfigurationSettings.UsePreprocessor,
                                    calculator.ReceivedInputs.ElementAt(i).PreprocessorSetting.RunPreprocessor);
                }
            }

            mockRepository.VerifyAll();
        }
        public void Calculate_WithoutBreakWater_StartsCalculationWithRightParameters(bool useForeshore)
        {
            // Setup
            var          waterLevel        = (RoundedDouble)4.20;
            var          a                 = (RoundedDouble)1.0;
            var          b                 = (RoundedDouble)0.8;
            var          c                 = (RoundedDouble)0.4;
            const double targetProbability = 0.2;
            var          input             = new WaveConditionsInput
            {
                HydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(),
                ForeshoreProfile          = new TestForeshoreProfile(true),
                UpperBoundaryRevetment    = (RoundedDouble)4,
                LowerBoundaryRevetment    = (RoundedDouble)3,
                StepSize      = WaveConditionsInputStepSize.Two,
                UseBreakWater = false,
                UseForeshore  = useForeshore,
                Orientation   = (RoundedDouble)0
            };

            var calculator = new TestWaveConditionsCosineCalculator();

            RoundedDouble[] waterLevels     = input.GetWaterLevels(waterLevel).ToArray();
            int             nrOfCalculators = waterLevels.Length;

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

            calculatorFactory.Expect(cf => cf.CreateWaveConditionsCosineCalculator(null))
            .IgnoreArguments()
            .Return(calculator)
            .Repeat
            .Times(nrOfCalculators);
            mockRepository.ReplayAll();

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                new TestWaveConditionsCalculationService().PublicCalculate(a,
                                                                           b,
                                                                           c,
                                                                           targetProbability,
                                                                           input,
                                                                           waterLevel,
                                                                           GetValidHydraulicBoundaryDatabase());

                // Assert
                for (var i = 0; i < nrOfCalculators; i++)
                {
                    WaveConditionsCosineCalculationInput expectedInput = CreateInput(waterLevels[i], a, b, c, targetProbability, input, useForeshore, false);
                    HydraRingDataEqualityHelper.AreEqual(expectedInput, calculator.ReceivedInputs.ElementAt(i));
                }
            }

            mockRepository.VerifyAll();
        }
        public void GetWaterLevels_AssessmentLevelNaN_ReturnsEmptyEnumerable()
        {
            // Setup
            var waveConditionsInput = new WaveConditionsInput
            {
                LowerBoundaryRevetment = (RoundedDouble)1.0,
                UpperBoundaryRevetment = (RoundedDouble)10.0,
                StepSize = WaveConditionsInputStepSize.One,
                LowerBoundaryWaterLevels = (RoundedDouble)1.0,
                UpperBoundaryWaterLevels = (RoundedDouble)10.0
            };

            // Call
            IEnumerable <RoundedDouble> waterLevels = waveConditionsInput.GetWaterLevels(RoundedDouble.NaN);

            // Assert
            CollectionAssert.IsEmpty(waterLevels);
        }
        public void GetWaterLevels_WaveConditionsInputWithWithAllBoundariesAboveUpperBoundaryAssessmentLevel_ReturnsEmptyEnumerable()
        {
            // Setup
            var waveConditionsInput = new WaveConditionsInput
            {
                LowerBoundaryRevetment   = (RoundedDouble)6,
                UpperBoundaryRevetment   = (RoundedDouble)6.10,
                LowerBoundaryWaterLevels = (RoundedDouble)6.20,
                UpperBoundaryWaterLevels = (RoundedDouble)10,
                StepSize = WaveConditionsInputStepSize.Half
            };

            // Call
            IEnumerable <RoundedDouble> waterLevels = waveConditionsInput.GetWaterLevels((RoundedDouble)5.78);

            // Assert
            CollectionAssert.IsEmpty(waterLevels);
        }
        public void GetWaterLevels_InvalidWaveConditionsInput_ReturnsEmptyEnumerable(double lowerBoundaryRevetments,
                                                                                     double upperBoundaryRevetments,
                                                                                     double assessmentLevel)
        {
            // Setup
            var waveConditionsInput = new WaveConditionsInput
            {
                LowerBoundaryRevetment = (RoundedDouble)lowerBoundaryRevetments,
                UpperBoundaryRevetment = (RoundedDouble)upperBoundaryRevetments,
                StepSize = WaveConditionsInputStepSize.One,
                LowerBoundaryWaterLevels = (RoundedDouble)1.0,
                UpperBoundaryWaterLevels = (RoundedDouble)10.0
            };

            // Call
            IEnumerable <RoundedDouble> waterLevels = waveConditionsInput.GetWaterLevels((RoundedDouble)assessmentLevel);

            // Assert
            CollectionAssert.IsEmpty(waterLevels);
        }
Beispiel #7
0
        public void CreateWaterLevelsGeometryPoints_WithForeshoreProfile_ReturnsWaterLevelsGeometryPointsCollection(
            IEnumerable <Point2D> foreshoreProfileGeometry)
        {
            // Setup
            RoundedDouble assessmentLevel = GetValidAssessmentLevel();
            var           input           = new WaveConditionsInput
            {
                ForeshoreProfile       = new TestForeshoreProfile(foreshoreProfileGeometry),
                LowerBoundaryRevetment = (RoundedDouble)5,
                UpperBoundaryRevetment = (RoundedDouble)7,
                StepSize = WaveConditionsInputStepSize.One
            };

            // Call
            IEnumerable <IEnumerable <Point2D> > lines = WaveConditionsChartDataPointsFactory.CreateWaterLevelsGeometryPoints(input, assessmentLevel);

            // Assert
            Point2D lastGeometryPoint = foreshoreProfileGeometry.Last();

            IEnumerable <RoundedDouble> waterLevels = input.GetWaterLevels(assessmentLevel);

            var expectedLines = new[]
            {
                new[]
                {
                    new Point2D(foreshoreProfileGeometry.First().X, 6),
                    new Point2D(((waterLevels.ElementAt(0) - lastGeometryPoint.Y) / 3) + lastGeometryPoint.X, 6)
                },
                new[]
                {
                    new Point2D(foreshoreProfileGeometry.First().X, 5),
                    new Point2D(((waterLevels.ElementAt(1) - lastGeometryPoint.Y) / 3) + lastGeometryPoint.X, 5)
                }
            };

            AssertWaterLevelGeometries(expectedLines, lines);
        }
        public void GetWaterLevels_ValidInput_ReturnsExpectedWaterLevels(WaveConditionsInputStepSize stepSize,
                                                                         double lowerBoundaryRevetment,
                                                                         double upperBoundaryRevetment,
                                                                         double lowerBoundaryWaterLevels,
                                                                         double upperBoundaryWaterLevels,
                                                                         double assessmentLevel,
                                                                         IEnumerable <RoundedDouble> expectedWaterLevels)
        {
            // Setup
            var waveConditionsInput = new WaveConditionsInput
            {
                LowerBoundaryRevetment = (RoundedDouble)lowerBoundaryRevetment,
                UpperBoundaryRevetment = (RoundedDouble)upperBoundaryRevetment,
                StepSize = stepSize,
                LowerBoundaryWaterLevels = (RoundedDouble)lowerBoundaryWaterLevels,
                UpperBoundaryWaterLevels = (RoundedDouble)upperBoundaryWaterLevels
            };

            // Call
            IEnumerable <RoundedDouble> waterLevels = waveConditionsInput.GetWaterLevels((RoundedDouble)assessmentLevel);

            // Assert
            CollectionAssert.AreEqual(expectedWaterLevels, waterLevels);
        }
 /// <summary>
 /// Create water levels geometry points in 2D space based on the provided <paramref name="input"/>.
 /// </summary>
 /// <param name="input">The <see cref="WaveConditionsInput"/> to create the water levels geometry points for.</param>
 /// <param name="assessmentLevel">The assessment level to use while determining water levels.</param>
 /// <returns>A collection with collections of points in 2D space or an empty list when:
 /// <list type="bullet">
 /// <item><paramref name="input"/> is <c>null</c>;</item>
 /// <item>no water levels could be determined.</item>
 /// </list>
 /// </returns>
 public static IEnumerable <IEnumerable <Point2D> > CreateWaterLevelsGeometryPoints(WaveConditionsInput input, RoundedDouble assessmentLevel)
 {
     return(input?.GetWaterLevels(assessmentLevel)
            .Select(waterLevel => CreateGeometryPoints(input, () => waterLevel))
            .ToArray() ?? new IEnumerable <Point2D> [0]);
 }
        public void Calculate_ThreeCalculationsFail_ThrowsHydraRingCalculationExceptionAndLogError(bool endInFailure,
                                                                                                   string lastErrorFileContent,
                                                                                                   string detailedReport)
        {
            // Setup
            var waterLevel = (RoundedDouble)4.20;
            var waterLevelUpperBoundaryRevetment = new RoundedDouble(2, 4.00);
            var waterLevelLowerBoundaryRevetment = new RoundedDouble(2, 3.00);

            var input = new WaveConditionsInput
            {
                HydraulicBoundaryLocation = new TestHydraulicBoundaryLocation(),
                ForeshoreProfile          = new TestForeshoreProfile(),
                UpperBoundaryRevetment    = waterLevelUpperBoundaryRevetment,
                LowerBoundaryRevetment    = waterLevelLowerBoundaryRevetment
            };

            int nrOfCalculators = input.GetWaterLevels(waterLevel).Count();

            var calculatorThatFails = new TestWaveConditionsCosineCalculator
            {
                EndInFailure         = endInFailure,
                LastErrorFileContent = lastErrorFileContent
            };

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

            calculatorFactory.Expect(cf => cf.CreateWaveConditionsCosineCalculator(null))
            .IgnoreArguments()
            .Return(calculatorThatFails)
            .Repeat
            .Times(nrOfCalculators);
            mockRepository.ReplayAll();

            var          a = (RoundedDouble)1.0;
            var          b = (RoundedDouble)0.8;
            var          c = (RoundedDouble)0.4;
            const double targetProbability = 0.2;

            HydraRingCalculationException exception = null;

            using (new HydraRingCalculatorFactoryConfig(calculatorFactory))
            {
                // Call
                void Call()
                {
                    try
                    {
                        new TestWaveConditionsCalculationService().PublicCalculate(a, b, c, targetProbability, input, waterLevel,
                                                                                   GetValidHydraulicBoundaryDatabase());
                    }
                    catch (HydraRingCalculationException e)
                    {
                        exception = e;
                    }
                }

                // Assert
                TestHelper.AssertLogMessages(Call, messages =>
                {
                    string[] msgs = messages.ToArray();
                    Assert.AreEqual(13, msgs.Length);

                    var waterLevelMiddleRevetment = new RoundedDouble(2, 3.50);

                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelUpperBoundaryRevetment}' is gestart.", msgs[0]);
                    Assert.AreEqual($"Berekening is mislukt voor waterstand '{waterLevelUpperBoundaryRevetment}'. {detailedReport}", msgs[1]);
                    StringAssert.StartsWith("Golfcondities berekening is uitgevoerd op de tijdelijke locatie", msgs[2]);
                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelUpperBoundaryRevetment}' is beëindigd.", msgs[3]);

                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelMiddleRevetment}' is gestart.", msgs[4]);
                    Assert.AreEqual($"Berekening is mislukt voor waterstand '{waterLevelMiddleRevetment}'. {detailedReport}", msgs[5]);
                    StringAssert.StartsWith("Golfcondities berekening is uitgevoerd op de tijdelijke locatie", msgs[6]);
                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelMiddleRevetment}' is beëindigd.", msgs[7]);

                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelLowerBoundaryRevetment}' is gestart.", msgs[8]);
                    Assert.AreEqual($"Berekening is mislukt voor waterstand '{waterLevelLowerBoundaryRevetment}'. {detailedReport}", msgs[9]);
                    StringAssert.StartsWith("Golfcondities berekening is uitgevoerd op de tijdelijke locatie", msgs[10]);
                    Assert.AreEqual($"Berekening voor waterstand '{waterLevelLowerBoundaryRevetment}' is beëindigd.", msgs[11]);

                    Assert.AreEqual("Berekening is mislukt voor alle waterstanden.", msgs[12]);
                });
                Assert.IsInstanceOf <HydraRingCalculationException>(exception);
                Assert.AreEqual("Berekening is mislukt voor alle waterstanden.", exception.Message);
            }

            mockRepository.VerifyAll();
        }
        /// <summary>
        /// Performs a wave conditions calculation based on the supplied <see cref="WaveConditionsInput"/>
        /// and returns the output. Error and status information is logged during the execution
        /// of the operation.
        /// </summary>
        /// <param name="waveConditionsInput">The <see cref="WaveConditionsInput"/> that holds all the information
        /// required to perform the calculation.</param>
        /// <param name="assessmentLevel">The assessment level to use for determining water levels.</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="hydraulicBoundaryDatabase">The hydraulic boundary database to perform the calculations with.</param>
        /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="WaveConditionsOutput"/>.</returns>
        /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks>
        /// <exception cref="ArgumentNullException">Thrown when <paramref name="waveConditionsInput"/> or
        /// <paramref name="hydraulicBoundaryDatabase"/> 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="HydraRingCalculationException">Thrown when an error occurs during
        /// the calculations.</exception>
        protected IEnumerable <WaveConditionsOutput> CalculateWaveConditions(WaveConditionsInput waveConditionsInput,
                                                                             RoundedDouble assessmentLevel,
                                                                             RoundedDouble a,
                                                                             RoundedDouble b,
                                                                             RoundedDouble c,
                                                                             double targetProbability,
                                                                             HydraulicBoundaryDatabase hydraulicBoundaryDatabase)
        {
            if (waveConditionsInput == null)
            {
                throw new ArgumentNullException(nameof(waveConditionsInput));
            }

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

            var calculationsFailed = 0;
            var outputs            = new List <WaveConditionsOutput>();

            RoundedDouble[] waterLevels = waveConditionsInput.GetWaterLevels(assessmentLevel).ToArray();
            foreach (RoundedDouble waterLevel in waterLevels.TakeWhile(waterLevel => !Canceled))
            {
                try
                {
                    log.Info(string.Format(CultureInfo.CurrentCulture,
                                           Resources.WaveConditionsCalculationService_OnRun_Calculation_for_waterlevel_0_started,
                                           waterLevel));

                    NotifyProgress(waterLevel, currentStep++, TotalWaterLevelCalculations);

                    WaveConditionsOutput output = CalculateWaterLevel(waterLevel,
                                                                      a, b, c, targetProbability,
                                                                      waveConditionsInput,
                                                                      HydraulicBoundaryCalculationSettingsFactory.CreateSettings(hydraulicBoundaryDatabase));

                    if (output != null)
                    {
                        outputs.Add(output);
                    }
                    else
                    {
                        calculationsFailed++;
                        outputs.Add(WaveConditionsOutputFactory.CreateFailedOutput(waterLevel, targetProbability));
                    }
                }
                finally
                {
                    log.Info(string.Format(CultureInfo.CurrentCulture,
                                           Resources.WaveConditionsCalculationService_OnRun_Calculation_for_waterlevel_0_ended,
                                           waterLevel));
                }
            }

            if (calculationsFailed == waterLevels.Length)
            {
                string message = string.Format(CultureInfo.CurrentCulture,
                                               Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_all_waterlevels);
                log.Error(message);
                throw new HydraRingCalculationException(message);
            }

            return(outputs);
        }