Fisheye: Tag 8f646c91322788de2f62f8c1681d051de089b56a refers to a dead (removed) revision in file `Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultDetailedAssessmentExtensions.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensions.cs =================================================================== diff -u --- Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensions.cs (revision 0) +++ Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensions.cs (revision 8f646c91322788de2f62f8c1681d051de089b56a) @@ -0,0 +1,131 @@ +// Copyright (C) Stichting Deltares 2021. 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.Linq; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using Riskeer.Common.Data.Calculation; +using Riskeer.Piping.Data.SemiProbabilistic; + +namespace Riskeer.Piping.Data +{ + /// + /// Extension methods for obtaining detailed assessment probabilities from output for an assessment of the piping failure mechanism. + /// + public static class PipingFailureMechanismSectionResultOldDetailedAssessmentExtensions + { + /// + /// 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 calculation scenarios in the failure mechanism. + /// The norm to assess for. + /// The calculated detailed assessment probability; or when there + /// are no relevant calculations, when not all relevant calculations are performed or when the + /// contribution of the relevant calculations don't add up to 1. + /// Thrown when any parameter is null. + public static double GetDetailedAssessmentProbability(this PipingFailureMechanismSectionResultOld sectionResult, + IEnumerable calculationScenarios, + double norm) + { + if (sectionResult == null) + { + throw new ArgumentNullException(nameof(sectionResult)); + } + + if (calculationScenarios == null) + { + throw new ArgumentNullException(nameof(calculationScenarios)); + } + + SemiProbabilisticPipingCalculationScenario[] relevantScenarios = sectionResult.GetCalculationScenarios(calculationScenarios).ToArray(); + + if (relevantScenarios.Length == 0 || !relevantScenarios.All(s => s.HasOutput) || Math.Abs(sectionResult.GetTotalContribution(relevantScenarios) - 1.0) > 1e-6) + { + return double.NaN; + } + + double totalDetailedAssessmentProbability = 0; + foreach (SemiProbabilisticPipingCalculationScenario scenario in relevantScenarios) + { + DerivedSemiProbabilisticPipingOutput derivedOutput = DerivedSemiProbabilisticPipingOutputFactory.Create(scenario.Output, norm); + + totalDetailedAssessmentProbability += derivedOutput.PipingProbability * (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 PipingFailureMechanismSectionResultOld 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 PipingFailureMechanismSectionResultOld sectionResult, + IEnumerable calculationScenarios) + { + if (sectionResult == null) + { + throw new ArgumentNullException(nameof(sectionResult)); + } + + if (calculationScenarios == null) + { + throw new ArgumentNullException(nameof(calculationScenarios)); + } + + IEnumerable lineSegments = Math2D.ConvertPointsToLineSegments(sectionResult.Section.Points); + + return calculationScenarios + .Where(pc => pc.IsRelevant && pc.IsSurfaceLineIntersectionWithReferenceLineInSection(lineSegments)); + } + } +} \ No newline at end of file Fisheye: Tag 8f646c91322788de2f62f8c1681d051de089b56a refers to a dead (removed) revision in file `Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultDetailedAssessmentExtensionsTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensionsTest.cs =================================================================== diff -u --- Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensionsTest.cs (revision 0) +++ Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultOldDetailedAssessmentExtensionsTest.cs (revision 8f646c91322788de2f62f8c1681d051de089b56a) @@ -0,0 +1,358 @@ +// Copyright (C) Stichting Deltares 2021. 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.Linq; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using NUnit.Framework; +using Riskeer.Common.Data.FailureMechanism; +using Riskeer.Common.Data.TestUtil; +using Riskeer.Piping.Data.SemiProbabilistic; +using Riskeer.Piping.Data.TestUtil; +using Riskeer.Piping.Data.TestUtil.SemiProbabilistic; + +namespace Riskeer.Piping.Data.Test +{ + [TestFixture] + public class PipingFailureMechanismSectionResultOldDetailedAssessmentExtensionsTest + { + [Test] + public void GetDetailedAssessmentProbability_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => PipingFailureMechanismSectionResultOldDetailedAssessmentExtensions.GetDetailedAssessmentProbability( + null, Enumerable.Empty(), 0.1); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("sectionResult", exception.ParamName); + } + + [Test] + public void GetDetailedAssessmentProbability_CalculationScenariosNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + // Call + void Call() => failureMechanismSectionResult.GetDetailedAssessmentProbability(null, 0.1); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void GetDetailedAssessmentProbability_MultipleScenarios_ReturnsValueBasedOnRelevantScenarios() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + var pipingCalculationScenario1 = + SemiProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario2 = + SemiProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario3 = + SemiProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + + pipingCalculationScenario1.IsRelevant = true; + pipingCalculationScenario1.Contribution = (RoundedDouble) 0.2111; + pipingCalculationScenario1.Output = PipingTestDataGenerator.GetSemiProbabilisticPipingOutput(1.1, 2.2, 3.3); + + pipingCalculationScenario2.IsRelevant = true; + pipingCalculationScenario2.Contribution = (RoundedDouble) 0.7889; + pipingCalculationScenario2.Output = PipingTestDataGenerator.GetSemiProbabilisticPipingOutput(4.4, 5.5, 6.6); + + pipingCalculationScenario3.IsRelevant = false; + + SemiProbabilisticPipingCalculationScenario[] calculations = + { + pipingCalculationScenario1, + pipingCalculationScenario2, + pipingCalculationScenario3 + }; + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetDetailedAssessmentProbability(calculations, 0.1); + + // Assert + Assert.AreEqual(4.2467174336864661e-7, detailedAssessmentProbability); + } + + [Test] + public void GetDetailedAssessmentProbability_NoScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetDetailedAssessmentProbability(Enumerable.Empty(), 0.1); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + public void GetDetailedAssessmentProbability_NoRelevantScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + SemiProbabilisticPipingCalculationScenario[] calculationScenarios = + { + CreateIrrelevantPipingCalculationScenario(section) + }; + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetDetailedAssessmentProbability(calculationScenarios, 0.1); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + public void GetDetailedAssessmentProbability_ScenarioNotCalculated_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + var pipingCalculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetDetailedAssessmentProbability(new[] + { + pipingCalculationScenario + }, 0.1); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + public void GetDetailedAssessmentProbability_ScenarioWithNaNResults_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + const double contribution1 = 0.2; + const double contribution2 = 0.8; + + var pipingCalculationScenario1 = + SemiProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario2 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + pipingCalculationScenario1.IsRelevant = true; + pipingCalculationScenario1.Contribution = (RoundedDouble) contribution1; + + pipingCalculationScenario2.IsRelevant = true; + pipingCalculationScenario2.Contribution = (RoundedDouble) contribution2; + pipingCalculationScenario2.Output = new SemiProbabilisticPipingOutput(new SemiProbabilisticPipingOutput.ConstructionProperties()); + + SemiProbabilisticPipingCalculationScenario[] calculations = + { + pipingCalculationScenario1, + pipingCalculationScenario2 + }; + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetDetailedAssessmentProbability(calculations, 0.1); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + [TestCase(0.0, 0.0)] + [TestCase(0.0, 0.5)] + [TestCase(0.3, 0.7 + 1e-5)] + public void GetDetailedAssessmentProbability_RelevantScenarioContributionsDoNotAddUpTo1_ReturnNaN(double contributionA, double contributionB) + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var pipingCalculationScenarioA = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + var pipingCalculationScenarioB = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenarioA.Contribution = (RoundedDouble) contributionA; + pipingCalculationScenarioB.Contribution = (RoundedDouble) contributionB; + + var result = new PipingFailureMechanismSectionResultOld(section); + + // Call + double detailedAssessmentProbability = result.GetDetailedAssessmentProbability(new[] + { + pipingCalculationScenarioA, + pipingCalculationScenarioB + }, 0.1); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + public void GetTotalContribution_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => ((PipingFailureMechanismSectionResultOld) null).GetTotalContribution(Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("sectionResult", exception.ParamName); + } + + [Test] + public void GetTotalContribution_CalculationScenariosNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var sectionResult = new PipingFailureMechanismSectionResultOld(section); + + // Call + void Call() => sectionResult.GetTotalContribution(null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void GetTotalContribution_WithScenarios_ReturnsTotalRelevantScenarioContribution() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResultOld(section); + + var pipingCalculationScenario1 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenario1.Contribution = (RoundedDouble) 0.3211; + + var pipingCalculationScenario2 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenario2.Contribution = (RoundedDouble) 0.5435; + + SemiProbabilisticPipingCalculationScenario pipingCalculationScenario3 = CreateIrrelevantPipingCalculationScenario(section); + + SemiProbabilisticPipingCalculationScenario[] calculationScenarios = + { + pipingCalculationScenario1, + pipingCalculationScenario2, + pipingCalculationScenario3 + }; + + // Call + RoundedDouble totalContribution = failureMechanismSectionResult.GetTotalContribution(calculationScenarios); + + // Assert + Assert.AreEqual((RoundedDouble) 0.8646, totalContribution); + } + + [Test] + public void GetCalculationScenarios_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => ((PipingFailureMechanismSectionResultOld) null).GetCalculationScenarios(Enumerable.Empty()); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("sectionResult", exception.ParamName); + } + + [Test] + public void GetCalculationScenarios_CalculationScenariosNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var sectionResult = new PipingFailureMechanismSectionResultOld(section); + + // Call + void Call() => sectionResult.GetCalculationScenarios(null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void GetCalculationScenarios_WithRelevantAndIrrelevantScenarios_ReturnsRelevantCalculationScenarios() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var sectionResult = new PipingFailureMechanismSectionResultOld(section); + var calculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + SemiProbabilisticPipingCalculationScenario calculationScenario2 = CreateIrrelevantPipingCalculationScenario(section); + + // Call + IEnumerable relevantScenarios = sectionResult.GetCalculationScenarios(new[] + { + calculationScenario, + calculationScenario2 + }); + + // Assert + Assert.AreEqual(calculationScenario, relevantScenarios.Single()); + } + + [Test] + public void GetCalculationScenarios_WithoutScenarioIntersectingSection_ReturnsNoCalculationScenarios() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(new[] + { + new Point2D(999, 999), + new Point2D(998, 998) + }); + var sectionResult = new PipingFailureMechanismSectionResultOld(section); + var calculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation( + FailureMechanismSectionTestFactory.CreateFailureMechanismSection()); + + // Call + IEnumerable relevantScenarios = sectionResult.GetCalculationScenarios(new[] + { + calculationScenario + }); + + // Assert + CollectionAssert.IsEmpty(relevantScenarios); + } + + private static SemiProbabilisticPipingCalculationScenario CreateIrrelevantPipingCalculationScenario(FailureMechanismSection section) + { + var calculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + calculationScenario.IsRelevant = false; + + return calculationScenario; + } + } +} \ No newline at end of file