// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets 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.Geometry; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Calculation; namespace Ringtoets.MacroStabilityInwards.Data { /// /// Extension methods for obtaining detailed assessment probabilities from output for an assessment of /// the macro stability inwards failure mechanism. /// public static class MacroStabilityInwardsFailureMechanismSectionResultDetailedAssessmentExtensions { /// /// Gets the value for the detailed assessment of safety per failure mechanism section as a probability. /// /// The section result to get the detailed assessment probability for. /// All calculations in the failure mechanism. /// The failure mechanism the calculations belong to. /// The assessment section the calculations belong to. /// The calculated detailed assessment probability; or when there are no /// performed or relevant calculations. /// Thrown when any parameter is null. public static double GetDetailedAssessmentProbability(this MacroStabilityInwardsFailureMechanismSectionResult sectionResult, IEnumerable calculations, MacroStabilityInwardsFailureMechanism failureMechanism, IAssessmentSection assessmentSection) { if (sectionResult == null) { throw new ArgumentNullException(nameof(sectionResult)); } if (calculations == null) { throw new ArgumentNullException(nameof(calculations)); } if (failureMechanism == null) { throw new ArgumentNullException(nameof(failureMechanism)); } if (assessmentSection == null) { throw new ArgumentNullException(nameof(assessmentSection)); } MacroStabilityInwardsCalculationScenario[] relevantScenarios = sectionResult.GetCalculationScenarios(calculations).ToArray(); bool relevantScenarioAvailable = relevantScenarios.Length != 0; if (relevantScenarioAvailable && Math.Abs(sectionResult.GetTotalContribution(relevantScenarios) - 1.0) > 1e-6) { return double.NaN; } if (!relevantScenarioAvailable || sectionResult.GetCalculationScenarioStatus(relevantScenarios) != CalculationScenarioStatus.Done) { return double.NaN; } double totalDetailedAssessmentProbability = 0; foreach (MacroStabilityInwardsCalculationScenario scenario in relevantScenarios) { DerivedMacroStabilityInwardsOutput derivedOutput = DerivedMacroStabilityInwardsOutputFactory.Create(scenario.Output, failureMechanism, assessmentSection); totalDetailedAssessmentProbability += derivedOutput.MacroStabilityInwardsProbability * (double) scenario.Contribution; } return totalDetailedAssessmentProbability; } /// /// Gets the total contribution of all relevant calculation scenarios. /// /// The section result to get the total contribution for. /// The calculation scenarios to get the total contribution for. /// The total contribution of all relevant calculation scenarios. /// Thrown when any parameter is null. public static RoundedDouble GetTotalContribution(this MacroStabilityInwardsFailureMechanismSectionResult sectionResult, IEnumerable calculationScenarios) { if (sectionResult == null) { throw new ArgumentNullException(nameof(sectionResult)); } if (calculationScenarios == null) { throw new ArgumentNullException(nameof(calculationScenarios)); } return (RoundedDouble) sectionResult .GetCalculationScenarios(calculationScenarios) .Aggregate(0, (current, calculationScenario) => current + calculationScenario.Contribution); } /// /// Gets a collection of the relevant . /// /// The section result to get the relevant scenarios for. /// The calculation scenarios to get the relevant scenarios from. /// A collection of relevant calculation scenarios. /// Thrown when any parameter is null. public static IEnumerable GetCalculationScenarios( this MacroStabilityInwardsFailureMechanismSectionResult sectionResult, IEnumerable calculationScenarios) { if (sectionResult == null) { throw new ArgumentNullException(nameof(sectionResult)); } if (calculationScenarios == null) { throw new ArgumentNullException(nameof(calculationScenarios)); } IEnumerable lineSegments = Math2D.ConvertLinePointsToLineSegments(sectionResult.Section.Points); return calculationScenarios .Where(pc => pc.IsRelevant && pc.IsSurfaceLineIntersectionWithReferenceLineInSection(lineSegments)); } /// /// Gets the status of the section result depending on the relevant calculation scenarios. /// /// The section result to get the calculation status for. /// The calculation scenarios to get the calculation status for. /// The calculation scenario status for the section result. /// Thrown when any parameter is null. /// Thrown when any of the relevant calculations /// in has an invalid . /// Thrown when any of the relevant scenarios has an unsupported /// value of . public static CalculationScenarioStatus GetCalculationScenarioStatus( this MacroStabilityInwardsFailureMechanismSectionResult sectionResult, IEnumerable calculationScenarios) { if (sectionResult == null) { throw new ArgumentNullException(nameof(sectionResult)); } if (calculationScenarios == null) { throw new ArgumentNullException(nameof(calculationScenarios)); } var failed = false; var notCalculated = false; foreach (MacroStabilityInwardsCalculationScenario calculationScenario in sectionResult.GetCalculationScenarios(calculationScenarios).Where(cs => cs.IsRelevant)) { CalculationScenarioStatus calculationScenarioStatus = calculationScenario.Status; if (!Enum.IsDefined(typeof(CalculationScenarioStatus), calculationScenarioStatus)) { throw new InvalidEnumArgumentException(nameof(sectionResult), (int) calculationScenarioStatus, typeof(CalculationScenarioStatus)); } switch (calculationScenario.Status) { case CalculationScenarioStatus.Failed: failed = true; break; case CalculationScenarioStatus.NotCalculated: notCalculated = true; break; case CalculationScenarioStatus.Done: continue; default: throw new NotSupportedException($"The enum value {nameof(CalculationScenarioStatus)}.{calculationScenarioStatus} is not supported."); } } if (failed) { return CalculationScenarioStatus.Failed; } if (notCalculated) { return CalculationScenarioStatus.NotCalculated; } return CalculationScenarioStatus.Done; } } }