Index: Demo/Ringtoets/test/Demo.Ringtoets.Test/Commands/AddNewDemoAssessmentSectionCommandTest.cs =================================================================== diff -u -r6a19166f5818e07d3430442efc50b8dfabb92e1b -r3254da22c99c7eb680cdb838519684ce314afb0a --- Demo/Ringtoets/test/Demo.Ringtoets.Test/Commands/AddNewDemoAssessmentSectionCommandTest.cs (.../AddNewDemoAssessmentSectionCommandTest.cs) (revision 6a19166f5818e07d3430442efc50b8dfabb92e1b) +++ Demo/Ringtoets/test/Demo.Ringtoets.Test/Commands/AddNewDemoAssessmentSectionCommandTest.cs (.../AddNewDemoAssessmentSectionCommandTest.cs) (revision 3254da22c99c7eb680cdb838519684ce314afb0a) @@ -420,7 +420,7 @@ GetAccuracy(inputParameters.PhreaticLevelExit)); Assert.AreEqual(0.011453, PipingSemiProbabilisticDesignValueFactory.GetDiameter70(inputParameters).GetDesignValue(), GetAccuracy(inputParameters.Diameter70)); - Assert.AreEqual(1.186644, PipingSemiProbabilisticDesignValueFactory.GetDarcyPermeability(inputParameters).GetDesignValue(), + Assert.AreEqual(1.179897, PipingSemiProbabilisticDesignValueFactory.GetDarcyPermeability(inputParameters).GetDesignValue(), GetAccuracy(inputParameters.DarcyPermeability)); Assert.AreEqual(17.5, PipingSemiProbabilisticDesignValueFactory.GetSaturatedVolumicWeightOfCoverageLayer(inputParameters).GetDesignValue(), GetAccuracy(inputParameters.SaturatedVolumicWeightOfCoverageLayer)); @@ -448,8 +448,8 @@ Assert.AreEqual(-0.139, calculation.Output.HeaveZValue, 1e-3); Assert.AreEqual(1.784, calculation.Output.UpliftFactorOfSafety, 1e-3); Assert.AreEqual(2.019, calculation.Output.UpliftZValue, 1e-3); - Assert.AreEqual(1.198, calculation.Output.SellmeijerFactorOfSafety, 1e-3); - Assert.AreEqual(0.234, calculation.Output.SellmeijerZValue, 1e-3); + Assert.AreEqual(1.199, calculation.Output.SellmeijerFactorOfSafety, 1e-3); + Assert.AreEqual(0.237, calculation.Output.SellmeijerZValue, 1e-3); } private static void AssertCalculationInFailureMechanismSectionResult(PipingCalculationScenario calculation, PipingFailureMechanismSectionResult[] sectionResults, IEnumerable calculations) Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs =================================================================== diff -u -r04e39e2be6e56f40de8ca5ade95a2e9c0c736c85 -r3254da22c99c7eb680cdb838519684ce314afb0a --- Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs (.../DerivedPipingInput.cs) (revision 04e39e2be6e56f40de8ca5ade95a2e9c0c736c85) +++ Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs (.../DerivedPipingInput.cs) (revision 3254da22c99c7eb680cdb838519684ce314afb0a) @@ -210,7 +210,7 @@ if (stochasticSoilProfile != null && stochasticSoilProfile.SoilProfile != null && surfaceLine != null && !double.IsNaN(exitPointL)) { - var thicknessTopAquiferLayer = new RoundedDouble(thicknessAquiferLayer.Mean.NumberOfDecimalPlaces, + var thicknessTopAquiferLayer = new RoundedDouble(GetNumberOfDecimals(thicknessAquiferLayer), GetThicknessTopAquiferLayer(stochasticSoilProfile.SoilProfile, surfaceLine, exitPointL)); if (thicknessTopAquiferLayer > 0) @@ -228,7 +228,7 @@ if (stochasticSoilProfile != null && stochasticSoilProfile.SoilProfile != null && surfaceLine != null && !double.IsNaN(exitPointL)) { - var weightedMean = new RoundedDouble(thicknessCoverageLayerDistribution.Mean.NumberOfDecimalPlaces, + var weightedMean = new RoundedDouble(GetNumberOfDecimals(thicknessCoverageLayerDistribution), GetThicknessCoverageLayers(stochasticSoilProfile.SoilProfile, surfaceLine, exitPointL)); if (weightedMean > 0) @@ -242,7 +242,7 @@ { if (input.SurfaceLine != null && input.StochasticSoilProfile != null && input.StochasticSoilProfile.SoilProfile != null && !double.IsNaN(input.ExitPointL)) { - var weightedMean = new RoundedDouble(effectiveThicknessCoverageLayerDistribution.Mean.NumberOfDecimalPlaces, + var weightedMean = new RoundedDouble(GetNumberOfDecimals(effectiveThicknessCoverageLayerDistribution), InputParameterCalculationService.CalculateEffectiveThicknessCoverageLayer( input.WaterVolumetricWeight, PipingSemiProbabilisticDesignValueFactory.GetPhreaticLevelExit(input).GetDesignValue(), @@ -262,7 +262,7 @@ PipingSoilLayer topMostAquiferLayer = GetConsecutiveAquiferLayers().FirstOrDefault(); if (topMostAquiferLayer != null) { - var diameterD70Mean = new RoundedDouble(diameterD70Distribution.Mean.NumberOfDecimalPlaces, topMostAquiferLayer.DiameterD70Mean); + var diameterD70Mean = new RoundedDouble(GetNumberOfDecimals(diameterD70Distribution), topMostAquiferLayer.DiameterD70Mean); if (diameterD70Mean > 0) { @@ -276,32 +276,44 @@ { PipingSoilLayer[] aquiferLayers = GetConsecutiveAquiferLayers(); + int numberOfDecimals = GetNumberOfDecimals(darcyPermeabilityDistribution); + if (HasCorrectDarcyPermeabilityWeightDistributionParameterDefinition( aquiferLayers, - GetNumberOfDecimals(darcyPermeabilityDistribution))) + numberOfDecimals)) { - var weightedMean = new RoundedDouble(2, GetWeightedMeanForDarcyPermeabilityOfAquiferLayer(aquiferLayers, - input.StochasticSoilProfile.SoilProfile, - input.SurfaceLine.GetZAtL(input.ExitPointL))); + PipingSoilLayer topMostAquiferLayer = aquiferLayers.First(); + double deviationFraction = (topMostAquiferLayer.PermeabilityDeviation / topMostAquiferLayer.PermeabilityMean); - darcyPermeabilityDistribution.Mean = weightedMean; - darcyPermeabilityDistribution.StandardDeviation = (RoundedDouble) (weightedMean/2); + var weightedMean = new RoundedDouble(numberOfDecimals, + GetWeightedMeanForDarcyPermeabilityOfAquiferLayer(aquiferLayers, + input.StochasticSoilProfile.SoilProfile, + input.SurfaceLine.GetZAtL(input.ExitPointL))); + + if (weightedMean > 0) + { + darcyPermeabilityDistribution.Mean = weightedMean; + } + + darcyPermeabilityDistribution.StandardDeviation = darcyPermeabilityDistribution.Mean * deviationFraction; } } private void UpdateSaturatedVolumicWeightOfCoverageLayerParameters(LogNormalDistribution volumicWeightDistribution) { PipingSoilLayer[] coverageLayers = GetConsecutiveCoverageLayers(); + int numberOfDecimals = GetNumberOfDecimals(volumicWeightDistribution); + if (HasCorrectSaturatedWeightDistributionParameterDefinition( coverageLayers, - GetNumberOfDecimals(volumicWeightDistribution))) + numberOfDecimals)) { PipingSoilLayer topMostAquitardLayer = coverageLayers.First(); volumicWeightDistribution.Shift = (RoundedDouble) topMostAquitardLayer.BelowPhreaticLevelShift; volumicWeightDistribution.StandardDeviation = (RoundedDouble) topMostAquitardLayer.BelowPhreaticLevelDeviation; - var weightedMean = new RoundedDouble(volumicWeightDistribution.Mean.NumberOfDecimalPlaces, + var weightedMean = new RoundedDouble(numberOfDecimals, GetWeightedMeanForVolumicWeightOfCoverageLayer( coverageLayers, input.StochasticSoilProfile.SoilProfile, @@ -314,7 +326,7 @@ } } - private static int GetNumberOfDecimals(LogNormalDistribution distribution) + private static int GetNumberOfDecimals(IDistribution distribution) { return distribution.Mean.NumberOfDecimalPlaces; } @@ -326,7 +338,7 @@ return false; } - var distributions = GetLayerDistributionDefinitions(consecutiveAquitardLayers, numberOfDecimals); + var distributions = GetLayerSaturatedVolumicWeightDistributionDefinitions(consecutiveAquitardLayers, numberOfDecimals); if (distributions == null) { @@ -357,11 +369,17 @@ return false; } - return distributions.All(currentLayerDistribution - => Math.Abs(currentLayerDistribution.StandardDeviation - (currentLayerDistribution.Mean/2)) < 1e-6); + if (distributions.Length == 1) + { + return true; + } + + return distributions.All(currentLayerDistribution => AreDeviationAndFractionEqual( + currentLayerDistribution, + distributions[0])); } - private static LogNormalDistribution[] GetLayerDistributionDefinitions(IList consecutiveAquitardLayers, int numberOfDecimals) + private static LogNormalDistribution[] GetLayerSaturatedVolumicWeightDistributionDefinitions(IList consecutiveAquitardLayers, int numberOfDecimals) { try { @@ -400,6 +418,13 @@ currentLayerDistribution.Shift == baseLayerDistribution.Shift; } + private static bool AreDeviationAndFractionEqual(LogNormalDistribution currentLayerDistribution, LogNormalDistribution baseLayerDistribution) + { + var baseLayerDeviationFraction = (baseLayerDistribution.StandardDeviation / baseLayerDistribution.Mean); + var currentLayerDeviationFraction = (currentLayerDistribution.StandardDeviation / currentLayerDistribution.Mean); + return Math.Abs(baseLayerDeviationFraction - currentLayerDeviationFraction) < 1e-6; + } + private static double GetWeightedMeanForVolumicWeightOfCoverageLayer(PipingSoilLayer[] aquitardLayers, PipingSoilProfile profile, double surfaceLevel) { double totalThickness = 0.0; Index: Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/DerivedPipingInputTest.cs =================================================================== diff -u -r04e39e2be6e56f40de8ca5ade95a2e9c0c736c85 -r3254da22c99c7eb680cdb838519684ce314afb0a --- Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/DerivedPipingInputTest.cs (.../DerivedPipingInputTest.cs) (revision 04e39e2be6e56f40de8ca5ade95a2e9c0c736c85) +++ Ringtoets/Piping/test/Ringtoets.Piping.Data.Test/DerivedPipingInputTest.cs (.../DerivedPipingInputTest.cs) (revision 3254da22c99c7eb680cdb838519684ce314afb0a) @@ -1064,39 +1064,65 @@ } [Test] - public void DarcyPermeability_SingleAquiferLayer_ReturnsWithWeightedMean() + public void DarcyPermeability_SingleLayerWithIncorrectMean_ReturnsNaNForParameters() { // Setup PipingInput input = PipingInputFactory.CreateInputWithAquiferAndCoverageLayer(); var derivedInput = new DerivedPipingInput(input); - var random = new Random(21); - double mean = random.NextDouble(); - double deviation = mean/2; input.StochasticSoilProfile.SoilProfile = new PipingSoilProfile("", 0.0, new[] { new PipingSoilLayer(0.5) { IsAquifer = true, - PermeabilityDeviation = deviation, - PermeabilityMean = mean + PermeabilityDeviation = 0.3, + PermeabilityMean = 0 } }, SoilProfileType.SoilProfile1D, 0); // Call var result = derivedInput.DarcyPermeability; // Assert - var weightedMean = 0.35 / 0.5; - Assert.AreEqual(weightedMean, result.Mean, result.Mean.GetAccuracy()); - Assert.AreEqual(weightedMean/2, result.StandardDeviation, result.StandardDeviation.GetAccuracy()); + Assert.IsNaN(result.Mean); + Assert.IsNaN(result.StandardDeviation); } [Test] - public void DarcyPermeability_MultipleAquiferLayers_ReturnsWithWeightedMean() + public void DarcyPermeability_MultiplelayersWithOneIncorrectLayerMean_ReturnsNaNForParameters() { // Setup PipingInput input = PipingInputFactory.CreateInputWithAquiferAndCoverageLayer(); var derivedInput = new DerivedPipingInput(input); + input.StochasticSoilProfile.SoilProfile = new PipingSoilProfile("", 0.0, new[] + { + new PipingSoilLayer(0.5) + { + IsAquifer = true, + PermeabilityDeviation = 0.3, + PermeabilityMean = 0 + }, + new PipingSoilLayer(1.5) + { + IsAquifer = true, + PermeabilityDeviation = 0.3, + PermeabilityMean = 2.4 + }, + }, SoilProfileType.SoilProfile1D, 0); + + // Call + var result = derivedInput.DarcyPermeability; + + // Assert + Assert.IsNaN(result.Mean); + Assert.IsNaN(result.StandardDeviation); + } + + [Test] + public void DarcyPermeability_MultipleAquiferLayersWithSameVariation_ReturnsWithWeightedMean() + { + // Setup + PipingInput input = PipingInputFactory.CreateInputWithAquiferAndCoverageLayer(); + var derivedInput = new DerivedPipingInput(input); var random = new Random(21); double mean = random.NextDouble(); double deviation = mean / 2; @@ -1122,13 +1148,13 @@ var result = derivedInput.DarcyPermeability; // Assert - var weightedMean = new RoundedDouble(2, 1.33 / 1.5); + var weightedMean = 0.885136; Assert.AreEqual(weightedMean, result.Mean, result.Mean.GetAccuracy()); Assert.AreEqual(weightedMean / 2, result.StandardDeviation, result.StandardDeviation.GetAccuracy()); } [Test] - public void DarcyPermeability_SingleAquiferLayerWithRandomMeanAndDeviation_ReturnsNaNForParameters() + public void DarcyPermeability_SingleAquiferLayerWithRandomMeanAndDeviation_ReturnsWithWeightedMean() { // Setup PipingInput input = PipingInputFactory.CreateInputWithAquiferAndCoverageLayer(); @@ -1150,8 +1176,10 @@ var result = derivedInput.DarcyPermeability; // Assert - Assert.IsNaN(result.Mean); - Assert.IsNaN(result.StandardDeviation); + var expectedMean = new RoundedDouble(6, permeabilityMean); + var expectedDeviation = new RoundedDouble(6, expectedMean * (permeabilityDeviation / permeabilityMean)); + Assert.AreEqual(expectedMean, result.Mean); + Assert.AreEqual(expectedDeviation, result.StandardDeviation, result.StandardDeviation.GetAccuracy()); } [Test]