// Copyright (C) Stichting Deltares 2019. 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.AssessmentSection;
using Riskeer.Common.Data.Calculation;
namespace Riskeer.Piping.Data
{
///
/// Extension methods for obtaining detailed assessment probabilities from output for an assessment of the piping failure mechanism.
///
public static class PipingFailureMechanismSectionResultDetailedAssessmentExtensions
{
///
/// 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 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 PipingFailureMechanismSectionResult sectionResult,
IEnumerable calculationScenarios,
PipingFailureMechanism failureMechanism,
IAssessmentSection assessmentSection)
{
if (sectionResult == null)
{
throw new ArgumentNullException(nameof(sectionResult));
}
if (calculationScenarios == null)
{
throw new ArgumentNullException(nameof(calculationScenarios));
}
if (failureMechanism == null)
{
throw new ArgumentNullException(nameof(failureMechanism));
}
if (assessmentSection == null)
{
throw new ArgumentNullException(nameof(assessmentSection));
}
PipingCalculationScenario[] 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 (PipingCalculationScenario scenario in relevantScenarios)
{
DerivedPipingOutput derivedOutput = DerivedPipingOutputFactory.Create(scenario.Output, failureMechanism, assessmentSection);
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 PipingFailureMechanismSectionResult 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 PipingFailureMechanismSectionResult 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));
}
}
}