Index: Ringtoets/Piping/src/Ringtoets.Piping.Calculation/Ringtoets.Piping.Calculation.csproj =================================================================== diff -u -r1d8e1d2a0bb1d08433a9d6046942fa778b019489 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/src/Ringtoets.Piping.Calculation/Ringtoets.Piping.Calculation.csproj (.../Ringtoets.Piping.Calculation.csproj) (revision 1d8e1d2a0bb1d08433a9d6046942fa778b019489) +++ Ringtoets/Piping/src/Ringtoets.Piping.Calculation/Ringtoets.Piping.Calculation.csproj (.../Ringtoets.Piping.Calculation.csproj) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -42,12 +42,8 @@ ..\..\..\..\lib\Plugins\Wti\Deltares.WTIPiping.dll - - ..\..\..\..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll - - @@ -67,7 +63,6 @@ True Resources.resx - @@ -93,10 +88,6 @@ Core.Common.Version False - - {d4200f43-3f72-4f42-af0a-8ced416a38ec} - Ringtoets.Common.Data - {ce994cc9-6f6a-48ac-b4be-02c30a21f4db} Ringtoets.Piping.Data @@ -113,7 +104,6 @@ Copying.licenseheader - Fisheye: Tag 74e3dea657b90b371e265914bee337c76e509d93 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.Calculation/SemiProbabilistic/PipingSemiProbabilisticResultTransformer.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 74e3dea657b90b371e265914bee337c76e509d93 refers to a dead (removed) revision in file `Ringtoets/Piping/src/Ringtoets.Piping.Calculation/packages.config'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingCalculationActivity.cs =================================================================== diff -u -r1d8e1d2a0bb1d08433a9d6046942fa778b019489 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingCalculationActivity.cs (.../PipingCalculationActivity.cs) (revision 1d8e1d2a0bb1d08433a9d6046942fa778b019489) +++ Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingCalculationActivity.cs (.../PipingCalculationActivity.cs) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -20,7 +20,6 @@ // All rights reserved. using Core.Common.Base.Service; -using Ringtoets.Piping.Calculation.SemiProbabilistic; using Ringtoets.Piping.Data; namespace Ringtoets.Piping.Service @@ -61,7 +60,7 @@ calculation.Output = null; PipingCalculationService.Calculate(calculation); - PipingSemiProbabilisticResultTransformer.Transform(calculation); + PipingSemiProbabilisticCalculationService.Calculate(calculation); } protected override void OnCancel() Index: Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingSemiProbabilisticCalculationService.cs =================================================================== diff -u --- Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingSemiProbabilisticCalculationService.cs (revision 0) +++ Ringtoets/Piping/src/Ringtoets.Piping.Service/PipingSemiProbabilisticCalculationService.cs (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -0,0 +1,164 @@ +using System; +using MathNet.Numerics.Distributions; +using Ringtoets.Piping.Data; + +namespace Ringtoets.Piping.Service +{ + /// + /// This class is responsible for calculating a factor of safety for piping based on the sub-calculations. + /// + public class PipingSemiProbabilisticCalculationService + { + private readonly double heaveFactorOfSafety; + private readonly double upliftFactorOfSafety; + private readonly double sellmeijerFactorOfSafety; + + private readonly int returnPeriod; + private readonly double constantA; + private readonly double constantB; + private readonly double assessmentSectionLength; + private readonly double contribution; + + /// + /// Calculates the semi-probabilistic results given a with . + /// + /// + /// + public static void Calculate(PipingCalculation calculation) + { + GeneralPipingInput semiProbabilisticParameters = calculation.SemiProbabilisticParameters; + var result = calculation.Output; + + var calculator = new PipingSemiProbabilisticCalculationService( + result.SellmeijerFactorOfSafety, + result.UpliftFactorOfSafety, + result.HeaveFactorOfSafety, + semiProbabilisticParameters.Norm, + semiProbabilisticParameters.A, + semiProbabilisticParameters.B, + semiProbabilisticParameters.SectionLength, + semiProbabilisticParameters.Contribution/100); + + calculation.SemiProbabilisticOutput = new PipingSemiProbabilisticOutput + { + PipingFactorOfSafety = calculator.FactorOfSafety() + }; + } + + /// + /// Creates a new instance of . + /// + /// + /// + /// + /// The return period. + /// The constant a. + /// The constant b. + /// The length of the assessment section. + /// The contribution of piping to the total failure. + public PipingSemiProbabilisticCalculationService(double sellmeijerFactorOfSafety, double upliftFactorOfSafety, double heaveFactorOfSafety, int returnPeriod, double constantA, double constantB, double assessmentSectionLength, double contribution) + { + this.heaveFactorOfSafety = heaveFactorOfSafety; + this.upliftFactorOfSafety = upliftFactorOfSafety; + this.sellmeijerFactorOfSafety = sellmeijerFactorOfSafety; + this.returnPeriod = returnPeriod; + this.constantA = constantA; + this.constantB = constantB; + this.assessmentSectionLength = assessmentSectionLength; + this.contribution = contribution; + } + + /// + /// Returns the failure probability of the uplift sub mechanism. + /// + /// A value represening failure probability. + public double FailureProbabilityUplift() + { + return FailureProbability(upliftFactorOfSafety, upliftFactors); + } + + /// + /// Returns the failure probability of the heave sub mechanism. + /// + /// A value represening failure probability. + public double FailureProbabilityHeave() + { + return FailureProbability(heaveFactorOfSafety, heaveFactors); + } + + /// + /// Returns the failure probability of the Sellmeijer sub mechanism. + /// + /// A value represening failure probability. + public double FailureProbabilitySellmeijer() + { + return FailureProbability(sellmeijerFactorOfSafety, sellmeijerFactors); + } + + /// + /// Returns the reliability index of the piping failure mechanism. + /// + /// A value representing the reliability. + public double BetaCrossPiping() + { + var minFailureProbability = Math.Min(Math.Min(FailureProbabilityHeave(), FailureProbabilityUplift()), FailureProbabilitySellmeijer()); + return Normal.InvCDF(0.0, 1.0, 1 - minFailureProbability); + } + + /// + /// Returns the allowed reliability of the piping failure mechanism for the complete assessment section. + /// + /// A value representing the allowed reliability. + public double BetaCrossAllowed() + { + var normCross = (contribution/returnPeriod)/(1 + (constantA*assessmentSectionLength)/constantB); + return Normal.InvCDF(0, 1, 1 - normCross); + } + + /// + /// Returns the safety factor of piping based on the factor of safety of + /// the sub mechanisms. + /// + /// A factor of safety value. + public double FactorOfSafety() + { + return BetaCrossAllowed()/BetaCrossPiping(); + } + + private double FailureProbability(double factorOfSafety, SubCalculationFactors factors) + { + var norm = (1.0/returnPeriod); + var bNorm = Normal.InvCDF(0, 1, 1 - norm); + + var betaCross = (1/factors.A)*(Math.Log(factorOfSafety/factors.B) + (factors.C*bNorm)); + + return Normal.CDF(0, 1, -betaCross); + } + + #region sub-calculation constants + + private struct SubCalculationFactors + { + public double A; + public double B; + public double C; + } + + private readonly SubCalculationFactors upliftFactors = new SubCalculationFactors + { + A = 0.46, B = 0.48, C = 0.27 + }; + + private readonly SubCalculationFactors heaveFactors = new SubCalculationFactors + { + A = 0.48, B = 0.37, C = 0.30 + }; + + private readonly SubCalculationFactors sellmeijerFactors = new SubCalculationFactors + { + A = 0.37, B = 1.04, C = 0.43 + }; + + #endregion + } +} \ No newline at end of file Index: Ringtoets/Piping/src/Ringtoets.Piping.Service/Ringtoets.Piping.Service.csproj =================================================================== diff -u -rc0a3ced404197fd781c6fcbcfc21c6676592be57 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/src/Ringtoets.Piping.Service/Ringtoets.Piping.Service.csproj (.../Ringtoets.Piping.Service.csproj) (revision c0a3ced404197fd781c6fcbcfc21c6676592be57) +++ Ringtoets/Piping/src/Ringtoets.Piping.Service/Ringtoets.Piping.Service.csproj (.../Ringtoets.Piping.Service.csproj) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -43,8 +43,12 @@ ..\..\..\..\packages\log4net.2.0.4\lib\net40-full\log4net.dll True + + ..\..\..\..\packages\MathNet.Numerics.3.8.0\lib\net40\MathNet.Numerics.dll + + @@ -55,6 +59,7 @@ + True Index: Ringtoets/Piping/src/Ringtoets.Piping.Service/packages.config =================================================================== diff -u -r4512af7782ee31b36941bb280b54d9da2953dd71 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/src/Ringtoets.Piping.Service/packages.config (.../packages.config) (revision 4512af7782ee31b36941bb280b54d9da2953dd71) +++ Ringtoets/Piping/src/Ringtoets.Piping.Service/packages.config (.../packages.config) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -24,4 +24,5 @@ --> + \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Calculation.Test/Ringtoets.Piping.Calculation.Test.csproj =================================================================== diff -u -r1d8e1d2a0bb1d08433a9d6046942fa778b019489 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/test/Ringtoets.Piping.Calculation.Test/Ringtoets.Piping.Calculation.Test.csproj (.../Ringtoets.Piping.Calculation.Test.csproj) (revision 1d8e1d2a0bb1d08433a9d6046942fa778b019489) +++ Ringtoets/Piping/test/Ringtoets.Piping.Calculation.Test/Ringtoets.Piping.Calculation.Test.csproj (.../Ringtoets.Piping.Calculation.Test.csproj) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -60,7 +60,6 @@ - @@ -79,10 +78,6 @@ {D749EE4C-CE50-4C17-BF01-9A953028C126} Core.Common.TestUtil - - {d4200f43-3f72-4f42-af0a-8ced416a38ec} - Ringtoets.Common.Data - {ce994cc9-6f6a-48ac-b4be-02c30a21f4db} Ringtoets.Piping.Data Fisheye: Tag 74e3dea657b90b371e265914bee337c76e509d93 refers to a dead (removed) revision in file `Ringtoets/Piping/test/Ringtoets.Piping.Calculation.Test/SemiProbabilistic/PipingSemiProbabilisticResultTransformerTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCalculationTest.cs =================================================================== diff -u -r1d8e1d2a0bb1d08433a9d6046942fa778b019489 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCalculationTest.cs (.../PipingCalculationTest.cs) (revision 1d8e1d2a0bb1d08433a9d6046942fa778b019489) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/PipingCalculationTest.cs (.../PipingCalculationTest.cs) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -3,7 +3,6 @@ using Core.Common.Base; using NUnit.Framework; using Rhino.Mocks; -using Ringtoets.Piping.Calculation.SemiProbabilistic; using Ringtoets.Piping.Calculation.TestUtil; namespace Ringtoets.Piping.Data.Test Index: Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/PipingSemiProbabilisticCalculationServiceTest.cs =================================================================== diff -u --- Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/PipingSemiProbabilisticCalculationServiceTest.cs (revision 0) +++ Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/PipingSemiProbabilisticCalculationServiceTest.cs (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -0,0 +1,175 @@ +using NUnit.Framework; +using Ringtoets.Piping.Data; + +namespace Ringtoets.Piping.Service.Test +{ + [TestFixture] + public class PipingSemiProbabilisticCalculationServiceTest + { + [Test] + [TestCase(30000, 1.2, 7.36633E-06)] + [TestCase(30000, 1.0, 4.13743E-05)] + [TestCase(20000, 1.2, 9.53353E-06)] + [TestCase(20000, 1.0, 5.24017E-05)] + public void FailureProbabilityUplift_DifferentInputs_ReturnsExpectedValue(int norm, double factorOfSafety, double expectedResult) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, factorOfSafety, double.NaN, double.NaN, double.NaN, double.NaN); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, double.NaN, double.NaN, double.NaN, double.NaN); + + // Call + double result = transformer.FailureProbabilityUplift(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-6); + } + + [Test] + [TestCase(30000, 0.6, 0.000233011)] + [TestCase(30000, 0.4, 0.003967252)] + [TestCase(20000, 0.6, 0.000292194)] + [TestCase(20000, 0.4, 0.004742775)] + public void FailureProbabilityHeave_DifferentInputs_ReturnsExpectedValue(int norm, double factorOfSafety, double expectedResult) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, double.NaN, double.NaN, factorOfSafety, double.NaN, double.NaN); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, double.NaN, double.NaN, double.NaN, double.NaN); + + // Call + double result = transformer.FailureProbabilityHeave(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-6); + } + + [Test] + [TestCase(30000, 0.9, 1.09882E-05)] + [TestCase(30000, 0.6, 0.000822098)] + [TestCase(20000, 0.9, 1.808E-05)] + [TestCase(20000, 0.6, 0.001203129)] + public void FailureProbabilitySellmeijer_DifferentInputs_ReturnsExpectedValue(int norm, double factorOfSafety, double expectedResult) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, factorOfSafety); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, double.NaN, double.NaN, double.NaN, double.NaN); + + // Call + double result = transformer.FailureProbabilitySellmeijer(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-8); + } + + [Test] + [TestCase(30000, 1.2, 0.6, 0.9, 4.332647923)] + [TestCase(30000, 1.2, 1.4, 0.9, 5.264767065)] + [TestCase(30000, 1.2, 0.6, 1.1, 4.786155161)] + [TestCase(20000, 1.2, 0.6, 0.9, 4.275544655)] + [TestCase(20000, 1.2, 1.4, 0.9, 5.203962658)] + [TestCase(20000, 1.2, 0.6, 1.1, 4.673091832)] + public void BetaCrossPiping_DifferentInputs_ReturnsExpectedValue(int norm, double fosUplift, double fosHeave, double fosSellmeijer, double expectedResult) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, fosUplift, double.NaN, fosHeave, double.NaN, fosSellmeijer); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, double.NaN, double.NaN, double.NaN, double.NaN); + + // Call + double result = transformer.BetaCrossPiping(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-8); + } + + [Test] + [TestCase(30000, 1, 350, 6000, 0.24, 4.916313847)] + [TestCase(20000, 1, 350, 6000, 0.12, 4.972362935)] + [TestCase(20000, 14, 350, 6000, 0.24, 5.327479413)] + [TestCase(20000, 1, 112, 6000, 0.24, 5.050875101)] + [TestCase(20000, 1, 350, 8000, 0.24, 4.890463519)] + public void BetaCrossAllowed_DifferentInputs_ReturnsExpectedValue(int norm, double a, double b, double assessmentSectionLength, double contribution, double expectedResult) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, a, b, assessmentSectionLength, contribution); + + // Call + double result = transformer.BetaCrossAllowed(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-8); + } + + [Test] + public void FactorOfSafety_SampleInput_ReturnsExpectedValue() + { + // Setup + int norm = 30000; + double a = 1; + double b = 350; + double assessmentSectionLength = 6000; + double contribution = 0.24; + double fosUplift = 1.2; + double fosHeave = 0.6; + double fosSellmeijer = 0.9; + double expectedResult = 1.134713444; + + var calculatorResult = new PipingOutput(double.NaN, fosUplift, double.NaN, fosHeave, double.NaN, fosSellmeijer); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, a, b, assessmentSectionLength, contribution); + + // Call + double result = transformer.FactorOfSafety(); + + // Assert + Assert.AreEqual(expectedResult, result, 1e-8); + } + + [Test] + [Combinatorial] + public void FactorOfSafety_DifferentInputs_ReturnsExpectedValue( + [Values(20000, 30000)] int norm, + [Values(1, 14)] double a, + [Values(112, 350)] double b, + [Values(6000, 8000)] double assessmentSectionLength, + [Values(0.12, 0.24)] double contribution, + [Values(1.2, 1.0)] double fosUplift, + [Values(1.4, 0.6)] double fosHeave, + [Values(0.9, 1.1)] double fosSellmeijer) + { + // Setup + var calculatorResult = new PipingOutput(double.NaN, fosUplift, double.NaN, fosHeave, double.NaN, fosSellmeijer); + var transformer = new PipingSemiProbabilisticCalculationService(calculatorResult.SellmeijerFactorOfSafety, calculatorResult.UpliftFactorOfSafety, calculatorResult.HeaveFactorOfSafety, norm, a, b, assessmentSectionLength, contribution); + + var betaAllowed = transformer.BetaCrossAllowed(); + var betaPiping = transformer.BetaCrossPiping(); + + // Call + double result = transformer.FactorOfSafety(); + + // Assert + Assert.AreEqual(betaAllowed/betaPiping, result, 1e-8); + } + + [Test] + public void Transform_CompleteInput_ReturnsPipingSemiProbabilisticOutputWithValues() + { + // Setup + var generalInput = new GeneralPipingInput + { + SectionLength = 6000, + Norm = 30000, + Contribution = 24 + }; + var pipingOutput = new PipingOutput(double.NaN, 1.2, double.NaN, 0.6, double.NaN, 0.9); + var pipingCalculation = new PipingCalculation(generalInput) + { + Output = pipingOutput + }; + + // Call + PipingSemiProbabilisticCalculationService.Calculate(pipingCalculation); + + // Assert + Assert.AreEqual(1.134713444, pipingCalculation.SemiProbabilisticOutput.PipingFactorOfSafety, 1e-8); + } + } +} \ No newline at end of file Index: Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj =================================================================== diff -u -rc0a3ced404197fd781c6fcbcfc21c6676592be57 -r74e3dea657b90b371e265914bee337c76e509d93 --- Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj (.../Ringtoets.Piping.Service.Test.csproj) (revision c0a3ced404197fd781c6fcbcfc21c6676592be57) +++ Ringtoets/Piping/test/Ringtoets.Piping.Service.Test/Ringtoets.Piping.Service.Test.csproj (.../Ringtoets.Piping.Service.Test.csproj) (revision 74e3dea657b90b371e265914bee337c76e509d93) @@ -61,6 +61,7 @@ +