/// <summary> /// Calculates values for a single water level. /// </summary> /// <param name="waterLevel">The level of the water.</param> /// <param name="a">The 'a' factor decided on failure mechanism level.</param> /// <param name="b">The 'b' factor decided on failure mechanism level.</param> /// <param name="c">The 'c' factor decided on failure mechanism level.</param> /// <param name="targetProbability">The target probability to use.</param> /// <param name="input">The input that is different per calculation.</param> /// <param name="calculationSettings">The <see cref="HydraulicBoundaryCalculationSettings"/> containing all data /// to perform a hydraulic boundary calculation.</param> /// <returns>A <see cref="WaveConditionsOutput"/> if the calculation was successful; or <c>null</c> if it was canceled.</returns> /// <remarks>Preprocessing is disabled when the preprocessor directory equals <see cref="string.Empty"/>.</remarks> /// <exception cref="ArgumentException">Thrown when the hydraulic boundary database file path /// contains invalid characters.</exception> /// <exception cref="CriticalFileReadException">Thrown when: /// <list type="bullet"> /// <item>No settings database file could be found at the location of the hydraulic boundary database file path /// with the same name.</item> /// <item>Unable to open settings database file.</item> /// <item>Unable to read required data from database file.</item> /// </list> /// </exception> private WaveConditionsOutput CalculateWaterLevel(RoundedDouble waterLevel, RoundedDouble a, RoundedDouble b, RoundedDouble c, double targetProbability, WaveConditionsInput input, HydraulicBoundaryCalculationSettings calculationSettings) { HydraRingCalculationSettings settings = HydraRingCalculationSettingsFactory.CreateSettings(calculationSettings); calculator = HydraRingCalculatorFactory.Instance.CreateWaveConditionsCosineCalculator(settings); WaveConditionsCosineCalculationInput calculationInput = CreateInput(waterLevel, a, b, c, targetProbability, input, calculationSettings); WaveConditionsOutput output; var exceptionThrown = false; try { calculator.Calculate(calculationInput); output = WaveConditionsOutputFactory.CreateOutput(waterLevel, calculator.WaveHeight, calculator.WavePeakPeriod, calculator.WaveAngle, calculator.WaveDirection, targetProbability, calculator.ReliabilityIndex, calculator.Converged); } catch (Exception e) when(e is HydraRingCalculationException || e is ArgumentOutOfRangeException) { if (!Canceled) { string lastErrorContent = calculator.LastErrorFileContent; if (string.IsNullOrEmpty(lastErrorContent)) { log.ErrorFormat(CultureInfo.CurrentCulture, Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_no_error_report, waterLevel); } else { log.ErrorFormat(CultureInfo.CurrentCulture, Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_click_details_for_last_error_report_1, waterLevel, lastErrorContent); } exceptionThrown = true; } output = null; } finally { string lastErrorFileContent = calculator.LastErrorFileContent; bool errorOccurred = CalculationServiceHelper.HasErrorOccurred(Canceled, exceptionThrown, lastErrorFileContent); if (errorOccurred) { log.ErrorFormat(CultureInfo.CurrentCulture, Resources.WaveConditionsCalculationService_CalculateWaterLevel_Error_in_wave_conditions_calculation_for_waterlevel_0_click_details_for_last_error_report_1, waterLevel, lastErrorFileContent); } log.InfoFormat(CultureInfo.CurrentCulture, Resources.WaveConditionsCalculationService_CalculateWaterLevel_Calculation_temporary_directory_can_be_found_on_location_0, calculator.OutputDirectory); if (errorOccurred) { output = null; } } return(output); }
/// <summary> /// Performs 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); }