Fisheye: Tag 66ecc69afac94d6ca1656cbcf120994559a2cd3e 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/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.cs =================================================================== diff -u --- Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.cs (revision 0) +++ Riskeer/Piping/src/Riskeer.Piping.Data/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.cs (revision 66ecc69afac94d6ca1656cbcf120994559a2cd3e) @@ -0,0 +1,184 @@ +// 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 Core.Common.Util; +using Riskeer.Common.Data.Calculation; +using Riskeer.Piping.Data.Probabilistic; +using Riskeer.Piping.Data.SemiProbabilistic; + +namespace Riskeer.Piping.Data +{ + /// + /// Extension methods for obtaining initial failure mechanism result probabilities from output for an assessment of the piping failure mechanism. + /// + public static class PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions + { + /// + /// Gets the value for the initial failure mechanism result of safety per failure mechanism section as a probability. + /// + /// The section result to get the detailed assessment probability for. + /// All probabilistic calculation scenarios in the failure mechanism. + /// The func to get the output from a calculation scenario. + /// 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 GetInitialFailureMechanismResultProbability(this PipingFailureMechanismSectionResult sectionResult, + IEnumerable calculationScenarios, + Func getOutputFunc) + { + if (sectionResult == null) + { + throw new ArgumentNullException(nameof(sectionResult)); + } + + if (calculationScenarios == null) + { + throw new ArgumentNullException(nameof(calculationScenarios)); + } + + if (getOutputFunc == null) + { + throw new ArgumentNullException(nameof(getOutputFunc)); + } + + ProbabilisticPipingCalculationScenario[] 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; + } + + return relevantScenarios.Sum(scenario => StatisticsConverter.ReliabilityToProbability(getOutputFunc(scenario).Reliability) * (double) scenario.Contribution); + } + + /// + /// Gets the value for the initial failure mechanism result of safety per failure mechanism section as a probability. + /// + /// The section result to get the detailed assessment probability for. + /// All semi probabilistic 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 GetInitialFailureMechanismResultProbability(this PipingFailureMechanismSectionResult 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 type of the calculation scenarios. + /// The total contribution of all relevant calculation scenarios. + /// Thrown when any parameter is null. + public static RoundedDouble GetTotalContribution(this PipingFailureMechanismSectionResult sectionResult, + IEnumerable> calculationScenarios) + where T : IPipingCalculationScenario + { + if (sectionResult == null) + { + throw new ArgumentNullException(nameof(sectionResult)); + } + + if (calculationScenarios == null) + { + throw new ArgumentNullException(nameof(calculationScenarios)); + } + + return (RoundedDouble) sectionResult.GetCalculationScenarios(calculationScenarios) + .Cast() + .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. + /// The type of the calculation scenarios. + /// A collection of relevant calculation scenarios. + /// Thrown when any parameter is null. + public static IEnumerable GetCalculationScenarios( + this PipingFailureMechanismSectionResult sectionResult, + IEnumerable> calculationScenarios) + where T : IPipingCalculationScenario + { + 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.OfType() + .Where(pc => pc.IsRelevant && pc.IsSurfaceLineIntersectionWithReferenceLineInSection(lineSegments)); + } + } +} \ No newline at end of file Fisheye: Tag 66ecc69afac94d6ca1656cbcf120994559a2cd3e 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/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensionsTest.cs =================================================================== diff -u --- Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensionsTest.cs (revision 0) +++ Riskeer/Piping/test/Riskeer.Piping.Data.Test/PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensionsTest.cs (revision 66ecc69afac94d6ca1656cbcf120994559a2cd3e) @@ -0,0 +1,641 @@ +// 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.Probabilistic; +using Riskeer.Piping.Data.SemiProbabilistic; +using Riskeer.Piping.Data.TestUtil; +using Riskeer.Piping.Data.TestUtil.Probabilistic; +using Riskeer.Piping.Data.TestUtil.SemiProbabilistic; + +namespace Riskeer.Piping.Data.Test +{ + [TestFixture] + public class PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensionsTest + { + [Test] + public void GetTotalContribution_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.GetTotalContribution>( + null, 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 PipingFailureMechanismSectionResult(section); + + // Call + void Call() => sectionResult.GetTotalContribution>(null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void GivenSectionResultWithScenarios_WhenGetTotalContributionForSemiProbabilistic_ThenReturnsTotalRelevantSemiProbabilisticScenarioContribution() + { + // Given + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + var pipingCalculationScenario1 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenario1.Contribution = (RoundedDouble) 0.3211; + + var pipingCalculationScenario2 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenario2.Contribution = (RoundedDouble) 0.5435; + + SemiProbabilisticPipingCalculationScenario pipingCalculationScenario3 = CreateIrrelevantSemiProbabilisticPipingCalculationScenario(section); + var pipingCalculationScenario4 = ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + pipingCalculationScenario4.Contribution = (RoundedDouble) 0.1; + + IPipingCalculationScenario[] calculationScenarios = + { + pipingCalculationScenario1, + pipingCalculationScenario2, + pipingCalculationScenario3, + pipingCalculationScenario4 + }; + + // When + RoundedDouble totalContribution = failureMechanismSectionResult.GetTotalContribution(calculationScenarios); + + // Then + Assert.AreEqual((RoundedDouble) 0.8646, totalContribution); + } + + [Test] + public void GivenSectionResultWithScenarios_WhenGetTotalContributionForProbabilistic_ThenReturnsTotalRelevantProbabilisticScenarioContribution() + { + // Given + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + var pipingCalculationScenario1 = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenario1.Contribution = (RoundedDouble) 0.3211; + + var pipingCalculationScenario2 = ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + pipingCalculationScenario2.Contribution = (RoundedDouble) 0.1; + + var pipingCalculationScenario3 = ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + pipingCalculationScenario3.Contribution = (RoundedDouble) 0.4651; + + ProbabilisticPipingCalculationScenario pipingCalculationScenario4 = CreateIrrelevantProbabilisticPipingCalculationScenario(section); + + IPipingCalculationScenario[] calculationScenarios = + { + pipingCalculationScenario1, + pipingCalculationScenario2, + pipingCalculationScenario3, + pipingCalculationScenario4 + }; + + // When + RoundedDouble totalContribution = failureMechanismSectionResult.GetTotalContribution(calculationScenarios); + + // Then + Assert.AreEqual((RoundedDouble) 0.5651, totalContribution); + } + + [Test] + public void GetCalculationScenarios_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.GetCalculationScenarios>( + null, 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 PipingFailureMechanismSectionResult(section); + + // Call + void Call() => sectionResult.GetCalculationScenarios>(null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + [TestCaseSource(nameof(GetCalculationScenariosTestCases))] + public void GetCalculationScenarios_WithRelevantAndIrrelevantScenarios_ReturnsRelevantCalculationScenarios( + FailureMechanismSection section, + IEnumerable> allScenarios, + Func>, IEnumerable>> getRelevantScenariosFunc, + IPipingCalculationScenario expectedRelevantScenario) + { + // Setup + var sectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + IEnumerable> relevantScenarios = getRelevantScenariosFunc(sectionResult, allScenarios); + + // Assert + Assert.AreEqual(expectedRelevantScenario, 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 PipingFailureMechanismSectionResult(section); + var calculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation( + FailureMechanismSectionTestFactory.CreateFailureMechanismSection()); + + // Call + IEnumerable> relevantScenarios = sectionResult.GetCalculationScenarios>(new[] + { + calculationScenario + }); + + // Assert + CollectionAssert.IsEmpty(relevantScenarios); + } + + private static IEnumerable GetCalculationScenariosTestCases() + { + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + + var semiProbabilisticCalculationScenario1 = SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + SemiProbabilisticPipingCalculationScenario semiProbabilisticCalculationScenario2 = CreateIrrelevantSemiProbabilisticPipingCalculationScenario(section); + + var probabilisticCalculationScenario1 = ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + ProbabilisticPipingCalculationScenario probabilisticCalculationScenario2 = CreateIrrelevantProbabilisticPipingCalculationScenario(section); + + var allScenarios = new IPipingCalculationScenario[] + { + semiProbabilisticCalculationScenario1, + semiProbabilisticCalculationScenario2, + probabilisticCalculationScenario1, + probabilisticCalculationScenario2 + }; + + yield return new TestCaseData(section, allScenarios, + new Func>, IEnumerable>>( + (result, scenarios) => result.GetCalculationScenarios(scenarios)), + semiProbabilisticCalculationScenario1); + yield return new TestCaseData(section, allScenarios, + new Func>, IEnumerable>>( + (result, scenarios) => result.GetCalculationScenarios(scenarios)), + probabilisticCalculationScenario1); + } + + private static ProbabilisticPipingCalculationScenario CreateIrrelevantProbabilisticPipingCalculationScenario(FailureMechanismSection section) + { + var calculationScenario = + ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + calculationScenario.IsRelevant = false; + + return calculationScenario; + } + + private static SemiProbabilisticPipingCalculationScenario CreateIrrelevantSemiProbabilisticPipingCalculationScenario(FailureMechanismSection section) + { + var calculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + calculationScenario.IsRelevant = false; + + return calculationScenario; + } + + #region Probabilistic + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.GetInitialFailureMechanismResultProbability( + null, Enumerable.Empty(), scenario => null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("sectionResult", exception.ParamName); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_CalculationScenariosNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + void Call() => failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(null, scenario => null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_GetOutputFuncNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + void Call() => failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(Enumerable.Empty(), null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("getOutputFunc", exception.ParamName); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_MultipleScenarios_ReturnsValueBasedOnRelevantScenarios() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + var pipingCalculationScenario1 = + ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario2 = + ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario3 = + ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + + pipingCalculationScenario1.IsRelevant = true; + pipingCalculationScenario1.Contribution = (RoundedDouble) 0.2111; + + pipingCalculationScenario2.IsRelevant = true; + pipingCalculationScenario2.Contribution = (RoundedDouble) 0.7889; + + pipingCalculationScenario3.IsRelevant = false; + + ProbabilisticPipingCalculationScenario[] calculations = + { + pipingCalculationScenario1, + pipingCalculationScenario2, + pipingCalculationScenario3 + }; + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability( + calculations, scenario => scenario.Output.ProfileSpecificOutput); + + // Assert + Assert.AreEqual(0.24284668249632746, initialFailureMechanismResultProbability); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_NoScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + double detailedAssessmentProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability( + Enumerable.Empty(), scenario => scenario.Output.ProfileSpecificOutput); + + // Assert + Assert.IsNaN(detailedAssessmentProbability); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_NoRelevantScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + ProbabilisticPipingCalculationScenario[] calculationScenarios = + { + CreateIrrelevantProbabilisticPipingCalculationScenario(section) + }; + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability( + calculationScenarios, scenario => scenario.Output.ProfileSpecificOutput); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_ScenarioNotCalculated_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + var pipingCalculationScenario = + ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(new[] + { + pipingCalculationScenario + }, scenario => scenario.Output.ProfileSpecificOutput); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + public void ProbabilisticGetInitialFailureMechanismResultProbability_ScenarioWithNaNResults_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + const double contribution1 = 0.2; + const double contribution2 = 0.8; + + var pipingCalculationScenario1 = + ProbabilisticPipingCalculationTestFactory.CreateCalculation(section); + var pipingCalculationScenario2 = + ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + pipingCalculationScenario1.IsRelevant = true; + pipingCalculationScenario1.Contribution = (RoundedDouble) contribution1; + + pipingCalculationScenario2.IsRelevant = true; + pipingCalculationScenario2.Contribution = (RoundedDouble) contribution2; + pipingCalculationScenario2.Output = new ProbabilisticPipingOutput(new TestPartialProbabilisticPipingOutput(double.NaN, null), + new TestPartialProbabilisticPipingOutput(double.NaN, null)); + + ProbabilisticPipingCalculationScenario[] calculations = + { + pipingCalculationScenario1, + pipingCalculationScenario2 + }; + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability( + calculations, scenario => scenario.Output.ProfileSpecificOutput); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + [TestCase(0.0, 0.0)] + [TestCase(0.0, 0.5)] + [TestCase(0.3, 0.7 + 1e-5)] + public void ProbabilisticGetInitialFailureMechanismResultProbability_RelevantScenarioContributionsDoNotAddUpTo1_ReturnNaN(double contributionA, double contributionB) + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var pipingCalculationScenarioA = + ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + var pipingCalculationScenarioB = + ProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + pipingCalculationScenarioA.Contribution = (RoundedDouble) contributionA; + pipingCalculationScenarioB.Contribution = (RoundedDouble) contributionB; + + var result = new PipingFailureMechanismSectionResult(section); + + // Call + double initialFailureMechanismResultProbability = result.GetInitialFailureMechanismResultProbability(new[] + { + pipingCalculationScenarioA, + pipingCalculationScenarioB + }, scenario => null); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + #endregion + + #region Semi-probabilistic + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_SectionResultNull_ThrowsArgumentNullException() + { + // Call + void Call() => PipingFailureMechanismSectionResultInitialFailureMechanismResultExtensions.GetInitialFailureMechanismResultProbability( + null, Enumerable.Empty(), 0.1); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("sectionResult", exception.ParamName); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_CalculationScenariosNull_ThrowsArgumentNullException() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + void Call() => failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(null, 0.1); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("calculationScenarios", exception.ParamName); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_MultipleScenarios_ReturnsValueBasedOnRelevantScenarios() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(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 initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(calculations, 0.1); + + // Assert + Assert.AreEqual(4.2467174336864661e-7, initialFailureMechanismResultProbability); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_NoScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(Enumerable.Empty(), 0.1); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_NoRelevantScenarios_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + SemiProbabilisticPipingCalculationScenario[] calculationScenarios = + { + CreateIrrelevantSemiProbabilisticPipingCalculationScenario(section) + }; + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(calculationScenarios, 0.1); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_ScenarioNotCalculated_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(section); + + var pipingCalculationScenario = + SemiProbabilisticPipingCalculationTestFactory.CreateNotCalculatedCalculation(section); + + // Call + double initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(new[] + { + pipingCalculationScenario + }, 0.1); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_ScenarioWithNaNResults_ReturnsNaN() + { + // Setup + FailureMechanismSection section = FailureMechanismSectionTestFactory.CreateFailureMechanismSection(); + var failureMechanismSectionResult = new PipingFailureMechanismSectionResult(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 initialFailureMechanismResultProbability = failureMechanismSectionResult.GetInitialFailureMechanismResultProbability(calculations, 0.1); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + [Test] + [TestCase(0.0, 0.0)] + [TestCase(0.0, 0.5)] + [TestCase(0.3, 0.7 + 1e-5)] + public void SemiProbabilisticGetInitialFailureMechanismResultProbability_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 PipingFailureMechanismSectionResult(section); + + // Call + double initialFailureMechanismResultProbability = result.GetInitialFailureMechanismResultProbability(new[] + { + pipingCalculationScenarioA, + pipingCalculationScenarioB + }, 0.1); + + // Assert + Assert.IsNaN(initialFailureMechanismResultProbability); + } + + #endregion + } +} \ No newline at end of file