Index: Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs
===================================================================
diff -u -r35db69dfe64b7e7deeaf9ef85d4df42ff6009b11 -r2363244674e6b7b97bead9a6855806420d368d80
--- Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs (.../DerivedPipingInput.cs) (revision 35db69dfe64b7e7deeaf9ef85d4df42ff6009b11)
+++ Ringtoets/Piping/src/Ringtoets.Piping.Data/DerivedPipingInput.cs (.../DerivedPipingInput.cs) (revision 2363244674e6b7b97bead9a6855806420d368d80)
@@ -20,11 +20,13 @@
// All rights reserved.
using System;
+using System.Linq;
using Core.Common.Base.Data;
using Ringtoets.Common.Data.Probabilistics;
using Ringtoets.HydraRing.Data;
using Ringtoets.Piping.InputParameterCalculation;
using Ringtoets.Piping.Primitives;
+using Ringtoets.Piping.Primitives.Exceptions;
namespace Ringtoets.Piping.Data
{
@@ -65,7 +67,8 @@
}
///
- /// Gets the piezometric head exit.
+ /// Gets the piezometric head at the exit point.
+ /// [m]
///
public RoundedDouble PiezometricHeadExit
{
@@ -79,7 +82,8 @@
}
///
- /// Gets the seepage length.
+ /// Gets the horizontal distance between entry and exit point.
+ /// [m]
///
public LogNormalDistribution SeepageLength
{
@@ -96,99 +100,272 @@
}
///
- /// Gets the thickness coverage layer.
+ /// Gets the total thickness of the coverage layers at the exit point.
+ /// [m]
///
public LogNormalDistribution ThicknessCoverageLayer
{
get
{
LogNormalDistribution thicknessCoverageLayer = new LogNormalDistribution(2)
{
+ Mean = (RoundedDouble) double.NaN,
StandardDeviation = (RoundedDouble) 0.5
};
- if (input.SurfaceLine != null && input.StochasticSoilProfile != null && input.StochasticSoilProfile.SoilProfile != null & !double.IsNaN(input.ExitPointL))
- {
- TrySetThicknessCoverageLayer(thicknessCoverageLayer);
- }
- else
- {
- thicknessCoverageLayer.Mean = (RoundedDouble) double.NaN;
- }
+ UpdateThicknessCoverageLayerMean(thicknessCoverageLayer);
return thicknessCoverageLayer;
}
}
///
- /// gets the thickness aquifer layer.
+ /// Gets the total thickness of the aquifer layers at the exit point.
+ /// [m]
///
public LogNormalDistribution ThicknessAquiferLayer
{
get
{
LogNormalDistribution thicknessAquiferLayer = new LogNormalDistribution(2)
{
+ Mean = (RoundedDouble) double.NaN,
StandardDeviation = (RoundedDouble) 0.5
};
+ UpdateThicknessAquiferLayerMean(thicknessAquiferLayer);
- StochasticSoilProfile stochasticSoilProfile = input.StochasticSoilProfile;
+ return thicknessAquiferLayer;
+ }
+ }
- RingtoetsPipingSurfaceLine surfaceLine = input.SurfaceLine;
- RoundedDouble exitPointL = input.ExitPointL;
+ ///
+ /// Gets the sieve size through which 70% fraction of the grains of the top part of the aquifer passes.
+ /// [m]
+ ///
+ public LogNormalDistribution DiameterD70
+ {
+ get
+ {
+ var distribution = new LogNormalDistribution(6)
+ {
+ Mean = (RoundedDouble) double.NaN,
+ StandardDeviation = (RoundedDouble) double.NaN
+ };
+ UpdateDiameterD70Parameters(distribution);
- if (stochasticSoilProfile != null && stochasticSoilProfile.SoilProfile != null && surfaceLine != null && !double.IsNaN(exitPointL))
+ return distribution;
+ }
+ }
+
+ ///
+ /// Gets or sets the Darcy-speed with which water flows through the aquifer layer.
+ /// [m/s]
+ ///
+ public LogNormalDistribution DarcyPermeability
+ {
+ get
+ {
+ var distribution = new LogNormalDistribution(6)
{
- double thicknessTopAquiferLayer = GetThicknessTopAquiferLayer(stochasticSoilProfile.SoilProfile, surfaceLine, exitPointL);
- TrySetThicknessAquiferLayerMean(thicknessAquiferLayer, thicknessTopAquiferLayer);
+ Mean = (RoundedDouble) double.NaN,
+ StandardDeviation = (RoundedDouble) double.NaN
+ };
+ UpdateDarcyPermeabilityParameters(distribution);
+
+ return distribution;
+ }
+ }
+
+ ///
+ /// Gets or sets the volumic weight of the saturated coverage layer.
+ ///
+ public ShiftedLogNormalDistribution SaturatedVolumicWeightOfCoverageLayer
+ {
+ get
+ {
+ var distribution = new ShiftedLogNormalDistribution(2)
+ {
+ Mean = (RoundedDouble) double.NaN,
+ StandardDeviation = (RoundedDouble) double.NaN,
+ Shift = (RoundedDouble) double.NaN
+ };
+ UpdateSaturatedVolumicWeightOfCoverageLayerParameters(distribution);
+
+ return distribution;
+ }
+ }
+
+ private void UpdateThicknessAquiferLayerMean(LogNormalDistribution thicknessAquiferLayer)
+ {
+ StochasticSoilProfile stochasticSoilProfile = input.StochasticSoilProfile;
+ RingtoetsPipingSurfaceLine surfaceLine = input.SurfaceLine;
+ RoundedDouble exitPointL = input.ExitPointL;
+
+ if (stochasticSoilProfile != null && stochasticSoilProfile.SoilProfile != null && surfaceLine != null && !double.IsNaN(exitPointL))
+ {
+ var thicknessTopAquiferLayer = new RoundedDouble(thicknessAquiferLayer.Mean.NumberOfDecimalPlaces,
+ GetThicknessTopAquiferLayer(stochasticSoilProfile.SoilProfile, surfaceLine, exitPointL));
+
+ if (thicknessTopAquiferLayer > 0)
+ {
+ thicknessAquiferLayer.Mean = thicknessTopAquiferLayer;
}
- else
+ }
+ }
+
+ private void UpdateThicknessCoverageLayerMean(LogNormalDistribution thicknessCoverageLayerDistribution)
+ {
+ if (input.SurfaceLine != null && input.StochasticSoilProfile != null && input.StochasticSoilProfile.SoilProfile != null && !double.IsNaN(input.ExitPointL))
+ {
+ var weightedMean = new RoundedDouble(thicknessCoverageLayerDistribution.Mean.NumberOfDecimalPlaces,
+ InputParameterCalculationService.CalculateThicknessCoverageLayer(
+ input.WaterVolumetricWeight,
+ PipingSemiProbabilisticDesignValueFactory.GetPhreaticLevelExit(input).GetDesignValue(),
+ input.ExitPointL,
+ input.SurfaceLine,
+ input.StochasticSoilProfile.SoilProfile));
+
+ if (weightedMean > 0)
{
- thicknessAquiferLayer.Mean = (RoundedDouble) double.NaN;
+ thicknessCoverageLayerDistribution.Mean = weightedMean;
}
+ }
+ }
- return thicknessAquiferLayer;
+ private void UpdateDiameterD70Parameters(LogNormalDistribution diameterD70Distribution)
+ {
+ PipingSoilLayer topMostAquiferLayer = GetConsecutiveAquiferLayers().FirstOrDefault();
+ if (topMostAquiferLayer != null)
+ {
+ var diameterD70Mean = new RoundedDouble(diameterD70Distribution.Mean.NumberOfDecimalPlaces, topMostAquiferLayer.DiameterD70Mean);
+
+ if (diameterD70Mean > 0)
+ {
+ diameterD70Distribution.Mean = diameterD70Mean;
+ }
+ diameterD70Distribution.StandardDeviation = (RoundedDouble) topMostAquiferLayer.DiameterD70Deviation;
}
}
- private static void TrySetThicknessAquiferLayerMean(LogNormalDistribution thicknessAquiferLayer, double thicknessTopAquiferLayer)
+ private void UpdateDarcyPermeabilityParameters(LogNormalDistribution darcyPermeabilityDistribution)
{
- if (thicknessTopAquiferLayer > 0)
+ PipingSoilLayer topMostAquiferLayer = GetConsecutiveAquiferLayers().FirstOrDefault();
+ if (topMostAquiferLayer != null)
{
- thicknessAquiferLayer.Mean = (RoundedDouble) thicknessTopAquiferLayer;
+ var darcyPermeabilityMean = new RoundedDouble(darcyPermeabilityDistribution.Mean.NumberOfDecimalPlaces, topMostAquiferLayer.PermeabilityMean);
+
+ if (darcyPermeabilityMean > 0)
+ {
+ darcyPermeabilityDistribution.Mean = darcyPermeabilityMean;
+ }
+ darcyPermeabilityDistribution.StandardDeviation = (RoundedDouble) topMostAquiferLayer.PermeabilityDeviation;
}
- else
+ }
+
+
+ private void UpdateSaturatedVolumicWeightOfCoverageLayerParameters(ShiftedLogNormalDistribution volumicWeightDistribution)
+ {
+ PipingSoilLayer[] aquitardLayers = GetConsecutiveAquitardLayers();
+
+ if (HasUniqueShiftAndDeviationSaturatedWeightDefinition(aquitardLayers))
{
- thicknessAquiferLayer.Mean = (RoundedDouble) double.NaN;
+ PipingSoilLayer topMostAquitardLayer = aquitardLayers.First();
+ volumicWeightDistribution.Shift = (RoundedDouble) topMostAquitardLayer.BelowPhreaticLevelShift;
+ volumicWeightDistribution.StandardDeviation = (RoundedDouble) topMostAquitardLayer.BelowPhreaticLevelDeviation;
+
+ var weightedMean = new RoundedDouble(volumicWeightDistribution.Mean.NumberOfDecimalPlaces,
+ GetWeightedMeanForVolumicWeightOfCoverageLayer(
+ aquitardLayers,
+ input.StochasticSoilProfile.SoilProfile,
+ input.SurfaceLine.GetZAtL(input.ExitPointL)));
+
+ if (weightedMean > 0)
+ {
+ volumicWeightDistribution.Mean = weightedMean;
+ }
}
}
- private static double GetThicknessTopAquiferLayer(PipingSoilProfile soilProfile, RingtoetsPipingSurfaceLine surfaceLine, RoundedDouble exitPointL)
+ private static double GetWeightedMeanForVolumicWeightOfCoverageLayer(PipingSoilLayer[] aquitardLayers, PipingSoilProfile profile, double surfaceLevel)
{
- try
+ double totalThickness = 0.0;
+ double weighedTotal = 0.0;
+
+ foreach (var layer in aquitardLayers)
{
- var zAtL = surfaceLine.GetZAtL(exitPointL);
- return soilProfile.GetTopmostConsecutiveAquiferLayerThicknessBelowLevel(zAtL);
+ double layerThickness = profile.GetLayerThickness(layer);
+ double bottom = layer.Top - layerThickness;
+ double thicknessUnderSurface = Math.Min(layer.Top, surfaceLevel) - bottom;
+
+ totalThickness += thicknessUnderSurface;
+ weighedTotal += layer.BelowPhreaticLevelMean*thicknessUnderSurface;
}
- catch (ArgumentException)
+
+ return weighedTotal/totalThickness;
+ }
+
+ private bool HasUniqueShiftAndDeviationSaturatedWeightDefinition(PipingSoilLayer[] consecutiveAquitardLayers)
+ {
+ if (!consecutiveAquitardLayers.Any())
{
- return double.NaN;
+ return false;
}
+ if (consecutiveAquitardLayers.Length == 1)
+ {
+ return true;
+ }
+
+ return consecutiveAquitardLayers.All(al =>
+ AlmostEquals(al.BelowPhreaticLevelDeviation, consecutiveAquitardLayers[0].BelowPhreaticLevelDeviation)
+ && AlmostEquals(al.BelowPhreaticLevelShift, consecutiveAquitardLayers[0].BelowPhreaticLevelShift));
}
+
+ private PipingSoilLayer[] GetConsecutiveAquiferLayers()
+ {
+ RingtoetsPipingSurfaceLine surfaceLine = input.SurfaceLine;
+ PipingSoilProfile soilProfile = input.StochasticSoilProfile != null ? input.StochasticSoilProfile.SoilProfile : null;
+ RoundedDouble exitPointL = input.ExitPointL;
- private void TrySetThicknessCoverageLayer(LogNormalDistribution thicknessCoverageLayer)
+ if (surfaceLine != null && soilProfile != null && !double.IsNaN(exitPointL))
+ {
+ return soilProfile.GetConsecutiveAquiferLayersBelowLevel(surfaceLine.GetZAtL(exitPointL)).ToArray();
+ }
+
+ return new PipingSoilLayer[0];
+ }
+
+ private PipingSoilLayer[] GetConsecutiveAquitardLayers()
{
+ RingtoetsPipingSurfaceLine surfaceLine = input.SurfaceLine;
+ PipingSoilProfile soilProfile = input.StochasticSoilProfile != null ? input.StochasticSoilProfile.SoilProfile : null;
+ RoundedDouble exitPointL = input.ExitPointL;
+
+ if (surfaceLine != null && soilProfile != null && !double.IsNaN(exitPointL))
+ {
+ return soilProfile.GetConsecutiveAquitardLayersBelowLevel(surfaceLine.GetZAtL(exitPointL)).ToArray();
+ }
+
+ return new PipingSoilLayer[0];
+ }
+
+ private bool AlmostEquals(double a, double b)
+ {
+ return Math.Abs(a - b) < 1e-6;
+ }
+
+ private static double GetThicknessTopAquiferLayer(PipingSoilProfile soilProfile, RingtoetsPipingSurfaceLine surfaceLine, RoundedDouble exitPointL)
+ {
try
{
- thicknessCoverageLayer.Mean = (RoundedDouble) InputParameterCalculationService.CalculateThicknessCoverageLayer(
- input.WaterVolumetricWeight,
- PipingSemiProbabilisticDesignValueFactory.GetPhreaticLevelExit(input).GetDesignValue(),
- input.ExitPointL,
- input.SurfaceLine,
- input.StochasticSoilProfile.SoilProfile);
+ double zAtL = surfaceLine.GetZAtL(exitPointL);
+ return soilProfile.GetTopmostConsecutiveAquiferLayerThicknessBelowLevel(zAtL);
}
- catch (ArgumentOutOfRangeException)
+ catch (Exception e)
{
- thicknessCoverageLayer.Mean = (RoundedDouble) double.NaN;
+ if (e is RingtoetsPipingSurfaceLineException || e is InvalidOperationException || e is ArgumentException)
+ {
+ return double.NaN;
+ }
+ throw;
}
}
}