// Copyright (C) Stichting Deltares 2016. 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 MathNet.Numerics.Distributions; using Ringtoets.Piping.Data; using Ringtoets.Piping.Service.Properties; namespace Ringtoets.Piping.Service { /// /// This class is responsible for calculating a factor of safety for piping based on the sub calculations. /// public class PipingSemiProbabilisticCalculationService { // Inputs private readonly double upliftFactorOfSafety; private readonly double heaveFactorOfSafety; private readonly double sellmeijerFactorOfSafety; private readonly int returnPeriod; private readonly double constantA; private readonly double constantB; private readonly double assessmentSectionLength; private readonly double upliftCriticalSafetyFactor; private readonly double heaveNormDependentFactor; private readonly double sellmeijerNormDependentFactor; private readonly double contribution; // Intermediate results private double heaveReliability; private double sellmeijerReliability; private double heaveProbability; private double upliftProbability; private double sellmeijerProbability; private double pipingProbability; private double pipingReliability; private double requiredProbability; private double requiredReliability; private double pipingFactorOfSafety; /// /// Creates a new instance of . /// /// The factor of safety for the uplift sub calculation. /// The factor of safety for the heave sub calculation. /// The factor of safety for the Sellmeijer sub calculation. /// The return period. /// The constant a. /// The constant b. /// The length of the assessment section. /// The critical safety factor which is compared to the safety factor of uplift to determine a probability. /// The norm dependent factor used in determining the reliability of heave. /// The norm dependent factor used in determining the reliability of Sellmeijer. /// The contribution of piping to the total failure. private PipingSemiProbabilisticCalculationService(double upliftFactorOfSafety, double heaveFactorOfSafety, double sellmeijerFactorOfSafety, int returnPeriod, double constantA, double constantB, double assessmentSectionLength, double upliftCriticalSafetyFactor, double heaveNormDependentFactor, double sellmeijerNormDependentFactor, double contribution) { this.heaveFactorOfSafety = heaveFactorOfSafety; this.upliftFactorOfSafety = upliftFactorOfSafety; this.sellmeijerFactorOfSafety = sellmeijerFactorOfSafety; this.returnPeriod = returnPeriod; this.constantA = constantA; this.constantB = constantB; this.assessmentSectionLength = assessmentSectionLength; this.upliftCriticalSafetyFactor = upliftCriticalSafetyFactor; this.heaveNormDependentFactor = heaveNormDependentFactor; this.sellmeijerNormDependentFactor = sellmeijerNormDependentFactor; this.contribution = contribution; } /// /// Calculates the semi-probabilistic results given a with . /// /// The calculation which is used as input for the semi-probabilistic assessment. If the semi- /// probabilistic calculation is successful, is set. /// General input that influences the probability estimate for a piping /// assessment. /// The return period to assess for. /// The contribution of piping as a percentage (0-100) to the total of the failure probability /// of the assessment section. /// Thrown when calculation has no output from a piping calculation. public static void Calculate(PipingCalculation calculation, PipingProbabilityAssessmentInput pipingProbabilityAssessmentInput, int norm, double contribution) { ValidateOutputOnCalculation(calculation); PipingOutput pipingOutput = calculation.Output; var calculator = new PipingSemiProbabilisticCalculationService( pipingOutput.UpliftFactorOfSafety, pipingOutput.HeaveFactorOfSafety, pipingOutput.SellmeijerFactorOfSafety, norm, pipingProbabilityAssessmentInput.A, pipingProbabilityAssessmentInput.B, pipingProbabilityAssessmentInput.SectionLength, pipingProbabilityAssessmentInput.UpliftCriticalSafetyFactor, pipingProbabilityAssessmentInput.GetHeaveNormDependentFactor(norm), pipingProbabilityAssessmentInput.GetSellmeijerNormDependentFactor(norm), contribution/100); calculator.Calculate(); calculation.SemiProbabilisticOutput = new PipingSemiProbabilisticOutput( calculator.upliftFactorOfSafety, calculator.upliftProbability, calculator.heaveFactorOfSafety, calculator.heaveReliability, calculator.heaveProbability, calculator.sellmeijerFactorOfSafety, calculator.sellmeijerReliability, calculator.sellmeijerProbability, calculator.requiredProbability, calculator.requiredReliability, calculator.pipingProbability, calculator.pipingReliability, calculator.pipingFactorOfSafety ); } /// /// Performs the full semi-probabilistic calculation while setting intermediate results. /// private void Calculate() { CalculatePipingReliability(); CalculateRequiredReliability(); pipingFactorOfSafety = pipingReliability/requiredReliability; } /// /// Calculates the required reliability based on the norm and length of the assessment section and the contribution of piping. /// private void CalculateRequiredReliability() { requiredProbability = RequiredProbability(); requiredReliability = ProbabilityToReliability(requiredProbability); } /// /// Calculates the reliability of piping based on the factors of safety from the sub-mechanisms. /// private void CalculatePipingReliability() { upliftProbability = UpliftProbability(); heaveReliability = HeaveReliability(heaveFactorOfSafety); heaveProbability = ReliabilityToProbability(heaveReliability); sellmeijerReliability = SellmeijerReliability(sellmeijerFactorOfSafety); sellmeijerProbability = ReliabilityToProbability(sellmeijerReliability); pipingProbability = PipingProbability(upliftProbability, heaveProbability, sellmeijerProbability); pipingReliability = ProbabilityToReliability(pipingProbability); } /// /// Calculates the probability of occurrence of the piping failure mechanism. /// /// The calculated probability of the heave sub-mechanism. /// The calculated probability of the uplift sub-mechanism. /// The calculated probability of the Sellmeijer sub-mechanism. /// A value representing the probability of occurrence of piping. private static double PipingProbability(double probabilityOfHeave, double probabilityOfUplift, double probabilityOfSellmeijer) { return Math.Min(Math.Min(probabilityOfHeave, probabilityOfUplift), probabilityOfSellmeijer); } /// /// Calculates the required probability of the piping failure mechanism for the complete assessment section. /// /// A value representing the required probability. private double RequiredProbability() { return (contribution/returnPeriod)/(1 + (constantA*assessmentSectionLength)/constantB); } private double UpliftProbability() { return upliftFactorOfSafety <= upliftCriticalSafetyFactor ? 1 : 0; } private double HeaveReliability(double factorOfSafety) { return 2.08*Math.Log(factorOfSafety/heaveNormDependentFactor); } private double SellmeijerReliability(double factorOfSafety) { return 2.7*Math.Log(factorOfSafety/sellmeijerNormDependentFactor); } private static void ValidateOutputOnCalculation(PipingCalculation calculation) { if (!calculation.HasOutput) { throw new ArgumentException(Resources.PipingSemiProbabilisticCalculationService_ValidateOutputOnCalculation_Factor_of_safety_cannot_be_calculated); } } private static double ReliabilityToProbability(double reliability) { return Normal.CDF(0, 1, -reliability); } private static double ProbabilityToReliability(double probability) { return Normal.InvCDF(0, 1, 1 - probability); } } }