// Copyright (C) Stichting Deltares and State of the Netherlands 2025. All rights reserved. // // This file is part of Riskeer. // // Riskeer is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using Core.Common.Base.Data; using Core.Common.Base.IO; using log4net; using Riskeer.Common.Data.AssessmentSection; using Riskeer.Common.Service; using Riskeer.HydraRing.Calculation.Exceptions; using Riskeer.Revetment.Data; using Riskeer.Revetment.Service; using Riskeer.StabilityStoneCover.Data; using Riskeer.StabilityStoneCover.Service.Properties; using RevetmentServiceResources = Riskeer.Revetment.Service.Properties.Resources; namespace Riskeer.StabilityStoneCover.Service { /// /// Service that provides methods for performing Hydra-Ring wave conditions calculations for the stability of stone revetment failure mechanism. /// public class StabilityStoneCoverWaveConditionsCalculationService : WaveConditionsCalculationServiceBase { private readonly ILog log = LogManager.GetLogger(typeof(StabilityStoneCoverWaveConditionsCalculationService)); /// /// Performs a wave conditions calculation for the stability of stone revetment failure mechanism based on the supplied /// and sets /// if the calculation was successful. /// Error and status information is logged during the execution of the operation. /// /// The that holds all the information required to perform the calculation. /// The that holds information about the target probability used in the calculation. /// Calculation input parameters that apply to all instances. /// Thrown when , /// or is null. /// Thrown when the hydraulic boundary database file path contains invalid characters. /// Thrown when: /// /// no hydraulic boundary settings database could be found; /// the hydraulic boundary settings database cannot be opened; /// the required data cannot be read from the hydraulic boundary settings database. /// /// /// Thrown when the target probability or /// calculated probability falls outside the [0.0, 1.0] range and is not . /// Thrown when an error occurs during parsing of the Hydra-Ring output. /// Thrown when an error occurs during the calculation. public void Calculate(StabilityStoneCoverWaveConditionsCalculation calculation, IAssessmentSection assessmentSection, GeneralStabilityStoneCoverWaveConditionsInput generalWaveConditionsInput) { if (calculation == null) { throw new ArgumentNullException(nameof(calculation)); } if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } if (generalWaveConditionsInput == null) { throw new ArgumentNullException(nameof(generalWaveConditionsInput)); } StabilityStoneCoverWaveConditionsInput calculationInput = calculation.InputParameters; StabilityStoneCoverWaveConditionsCalculationType calculationType = calculationInput.CalculationType; if (!Enum.IsDefined(typeof(StabilityStoneCoverWaveConditionsCalculationType), calculationType)) { throw new InvalidEnumArgumentException(nameof(calculationType), (int) calculationType, typeof(StabilityStoneCoverWaveConditionsCalculationType)); } CalculationServiceHelper.LogCalculationBegin(); double targetProbability = WaveConditionsInputHelper.GetTargetProbability(calculationInput, assessmentSection); RoundedDouble assessmentLevel = WaveConditionsInputHelper.GetAssessmentLevel(calculationInput, assessmentSection); int waterLevelCount = calculationInput.GetWaterLevels(assessmentLevel).Count(); TotalWaterLevelCalculations = calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both ? waterLevelCount * 2 : waterLevelCount; try { IEnumerable blocksOutputs = null; if (calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both || calculationType == StabilityStoneCoverWaveConditionsCalculationType.Blocks) { CurrentCalculationType = Resources.StabilityStoneCoverWaveConditions_Blocks_DisplayName; blocksOutputs = CalculateBlocks(calculation, assessmentSection, assessmentLevel, generalWaveConditionsInput.GeneralBlocksWaveConditionsInput, targetProbability); } if (Canceled) { return; } IEnumerable columnsOutputs = null; if (calculationType == StabilityStoneCoverWaveConditionsCalculationType.Both || calculationType == StabilityStoneCoverWaveConditionsCalculationType.Columns) { CurrentCalculationType = Resources.StabilityStoneCoverWaveConditions_Columns_DisplayName; columnsOutputs = CalculateColumns(calculation, assessmentSection, assessmentLevel, generalWaveConditionsInput.GeneralColumnsWaveConditionsInput, targetProbability); } if (!Canceled) { calculation.Output = CreateOutput(calculationType, blocksOutputs, columnsOutputs); } } finally { CalculationServiceHelper.LogCalculationEnd(); } } private static StabilityStoneCoverWaveConditionsOutput CreateOutput(StabilityStoneCoverWaveConditionsCalculationType calculationType, IEnumerable blocksOutputs, IEnumerable columnsOutputs) { if (calculationType == StabilityStoneCoverWaveConditionsCalculationType.Blocks) { return StabilityStoneCoverWaveConditionsOutputFactory.CreateOutputWithBlocks(blocksOutputs); } if (calculationType == StabilityStoneCoverWaveConditionsCalculationType.Columns) { return StabilityStoneCoverWaveConditionsOutputFactory.CreateOutputWithColumns(columnsOutputs); } return StabilityStoneCoverWaveConditionsOutputFactory.CreateOutputWithColumnsAndBlocks(columnsOutputs, blocksOutputs); } private IEnumerable CalculateColumns(StabilityStoneCoverWaveConditionsCalculation calculation, IAssessmentSection assessmentSection, RoundedDouble assessmentLevel, GeneralWaveConditionsInput generalInput, double targetProbability) { return Calculate(calculation, assessmentSection, assessmentLevel, generalInput, targetProbability, Resources.StabilityStoneCoverWaveConditions_Columns_DisplayName); } private IEnumerable CalculateBlocks(StabilityStoneCoverWaveConditionsCalculation calculation, IAssessmentSection assessmentSection, RoundedDouble assessmentLevel, GeneralWaveConditionsInput generalInput, double targetProbability) { return Calculate(calculation, assessmentSection, assessmentLevel, generalInput, targetProbability, Resources.StabilityStoneCoverWaveConditions_Blocks_DisplayName); } private IEnumerable Calculate(StabilityStoneCoverWaveConditionsCalculation calculation, IAssessmentSection assessmentSection, RoundedDouble assessmentLevel, GeneralWaveConditionsInput generalInput, double targetProbability, string calculationType) { log.InfoFormat(RevetmentServiceResources.WaveConditionsCalculationService_Calculate_calculationType_0_started, calculationType); IEnumerable outputs = CalculateWaveConditions(calculation.InputParameters, assessmentLevel, generalInput.A, generalInput.B, generalInput.C, targetProbability, assessmentSection.HydraulicBoundaryData); log.InfoFormat(RevetmentServiceResources.WaveConditionsCalculationService_Calculate_calculationType_0_ended, calculationType); return outputs; } } }