Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/DamPipingBligh/DamPipingBlighKernelWrapper.cs =================================================================== diff -u -r1024 -r1040 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/DamPipingBligh/DamPipingBlighKernelWrapper.cs (.../DamPipingBlighKernelWrapper.cs) (revision 1024) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/DamPipingBligh/DamPipingBlighKernelWrapper.cs (.../DamPipingBlighKernelWrapper.cs) (revision 1040) @@ -26,8 +26,11 @@ using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces; using Deltares.DamEngine.Calculators.Properties; using Deltares.DamEngine.Calculators.Uplift; +using Deltares.DamEngine.Data.Standard; using Deltares.DamEngine.Data.General; +using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Data.General.Results; +using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; @@ -69,62 +72,70 @@ var soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile1D; var surfaceLine = damKernelInput.Location.SurfaceLine; var location = damKernelInput.Location; - double riverLevel = damKernelInput.RiverLevelHigh; + double waterLevel = damKernelInput.RiverLevelHigh; UpliftSituation upliftSituation; - var plLines = PlLinesHelper.CreatePlLines(location, soilProfile1D, riverLevel, out upliftSituation); - UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator - { - PLLines = plLines, - SoilProfile = soilProfile1D, - SurfaceLine = surfaceLine, - DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), - XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin - }; - var upliftLocationAndResult = upliftLocationDeterminator.GetLocationAndResult(damKernelInput.DesignScenario.GetUpliftCriterionPiping(null)); - upliftSituation.IsUplift = (upliftLocationAndResult != null); - double xEntry = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; - double xExit = 0.0; - double surfaceLevel = 0.0; - double d70 = 0.0; - double dCoverLayer = 0.0; - double? upliftFactor = null; - if (upliftLocationAndResult != null) - { - xExit = upliftLocationAndResult.X; - surfaceLevel = surfaceLine.Geometry.GetZatX(upliftLocationAndResult.X); - SoilLayer1D heaveLayer = soilProfile1D.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId); - d70 = Physics.FactorMeterToMicroMeter * heaveLayer.Soil.DiameterD70; - var topLevelAquifer = soilProfile1D.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId).TopLevel; - dCoverLayer = DamPipingHelper.DetermineHeightCoverLayer(topLevelAquifer, surfaceLevel); - upliftFactor = upliftLocationAndResult.UpliftFactor; - } - double seepageLength = xExit - xEntry; - damPipingBlighInput.HRiver = riverLevel; - // Reference level is highest value of surfaceLevel or PolderLevel - // Uit TR Zandmeevoerende wellen (1999): "Het verval dH is gelijk aan het verschil tussen buitenwaterstand (het ontwerppeil(OP)) - // bij zeedijken en de maatgevende hoogwaterstand (MHW bij rivierdijken) en de waterstand binnendijks ter plaatse van het uittredepunt, - // rekening houdend met zeespiegelrijzing etc.(zie paragraaf 3.7.2). In dien ter plaatse van het uittreepunt of de opbarstlocatie - // geen vrije waterstand heerst kan gerekend worden met het maaiveldniveau, rekening houdend met eventuele maaiveld daling (zie paragraaf 3.7.2)." - var referenceLevel = Math.Max(location.PolderLevel, surfaceLevel); - kernelDataInput = new DamPipingBlighInput() - { - HRiver = riverLevel, - HExit = referenceLevel, - Rc = defaultFluidisationGradient, - DTotal = dCoverLayer, - SeepageLength = seepageLength, - D70 = d70, - - }; - damPipingBlighOutput.ExitPointX = xExit; - damPipingBlighOutput.UpliftFactor = upliftFactor; - damPipingBlighOutput.UpliftSituation = upliftSituation; + PLLines plLines = PlLinesHelper.CreatePlLines(location, soilProfile1D, waterLevel, out upliftSituation); + EvaluateUpliftSituation(damKernelInput, out kernelDataInput, plLines, damPipingBlighInput, waterLevel, damPipingBlighOutput); return PrepareResult.Successful; } kernelDataInput = null; return PrepareResult.NotRelevant; } + private static void EvaluateUpliftSituation(DamKernelInput damKernelInput, out IKernelDataInput kernelDataInput, PLLines plLines, DamPipingBlighInput damPipingBlighInput, double waterLevel, DamPipingBlighOutput damPipingBlighOutput) + { + SoilProfile1D soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile1D; + SurfaceLine2 surfaceLine = damKernelInput.Location.SurfaceLine; + Location location = damKernelInput.Location; + UpliftSituation upliftSituation = new UpliftSituation(); + UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator + { + PLLines = plLines, + SoilProfile = soilProfile1D, + SurfaceLine = surfaceLine, + DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), + XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin + }; + var upliftLocationAndResult = upliftLocationDeterminator.GetLocationAndResult(damKernelInput.DesignScenario.GetUpliftCriterionPiping(null)); + upliftSituation.IsUplift = (upliftLocationAndResult != null); + double xEntry = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; + double xExit = 0.0; + double surfaceLevel = 0.0; + double d70 = 0.0; + double dCoverLayer = 0.0; + double? upliftFactor = null; + if (upliftLocationAndResult != null) + { + xExit = upliftLocationAndResult.X; + surfaceLevel = surfaceLine.Geometry.GetZatX(upliftLocationAndResult.X); + SoilLayer1D heaveLayer = soilProfile1D.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId); + d70 = Physics.FactorMeterToMicroMeter * heaveLayer.Soil.DiameterD70; + var topLevelAquifer = soilProfile1D.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId).TopLevel; + dCoverLayer = DamPipingHelper.DetermineHeightCoverLayer(topLevelAquifer, surfaceLevel); + upliftFactor = upliftLocationAndResult.UpliftFactor; + } + double seepageLength = xExit - xEntry; + damPipingBlighInput.HRiver = waterLevel; + // Reference level is highest value of surfaceLevel or PolderLevel + // Uit TR Zandmeevoerende wellen (1999): "Het verval dH is gelijk aan het verschil tussen buitenwaterstand (het ontwerppeil(OP)) + // bij zeedijken en de maatgevende hoogwaterstand (MHW bij rivierdijken) en de waterstand binnendijks ter plaatse van het uittredepunt, + // rekening houdend met zeespiegelrijzing etc.(zie paragraaf 3.7.2). In dien ter plaatse van het uittreepunt of de opbarstlocatie + // geen vrije waterstand heerst kan gerekend worden met het maaiveldniveau, rekening houdend met eventuele maaiveld daling (zie paragraaf 3.7.2)." + var referenceLevel = Math.Max(location.PolderLevel, surfaceLevel); + kernelDataInput = new DamPipingBlighInput() + { + HRiver = waterLevel, + HExit = referenceLevel, + Rc = defaultFluidisationGradient, + DTotal = dCoverLayer, + SeepageLength = seepageLength, + D70 = d70, + }; + damPipingBlighOutput.ExitPointX = xExit; + damPipingBlighOutput.UpliftFactor = upliftFactor; + damPipingBlighOutput.UpliftSituation = upliftSituation; + } + /// /// Validates the kernel data input. /// @@ -174,12 +185,16 @@ { throw new NoNullAllowedException(Resources.DamPipingBlighKernelWrapper_NoOutputObjectDefinedForBligh); } + PerformSingleCalculationBligh(out messages, damPipingBlighOutput, damPipingBlighInput); + } + + private static void PerformSingleCalculationBligh(out List messages, DamPipingBlighOutput damPipingBlighOutput, DamPipingBlighInput damPipingBlighInput) + { damPipingBlighOutput.CalculationResult = CalculationResult.NoRun; damPipingBlighOutput.FoSp = defaultMaxReturnValue; messages = new List(); try { - if (damPipingBlighOutput.UpliftSituation.IsUplift) { var calculatorBligh = CreatePipingCalculatorBligh(damPipingBlighInput); @@ -232,14 +247,8 @@ public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, string resultMessage, out List designResults) { DamPipingBlighOutput damPipingBlighOutput = kernelDataOutput as DamPipingBlighOutput; - if (damKernelInput == null) - { - throw new NoNullAllowedException(Resources.DamPipingBlighKernelWrapper_NoInputObjectDefinedForBligh); - } - if (damPipingBlighOutput == null) - { - throw new NoNullAllowedException(Resources.DamPipingBlighKernelWrapper_NoOutputObjectDefinedForBligh); - } + ThrowWhenKernelInputNull(damKernelInput); + ThrowWhenKernelOutputNull(damPipingBlighOutput); designResults = new List(); var designResult = new DesignResult(damKernelInput.DamFailureMechanismeCalculationSpecification, @@ -261,5 +270,112 @@ designResults.Add(designResult); } + private static void ThrowWhenKernelOutputNull(DamPipingBlighOutput damPipingBlighOutput) + { + if (damPipingBlighOutput == null) + { + throw new NoNullAllowedException(Resources.DamPipingBlighKernelWrapper_NoOutputObjectDefinedForBligh); + } + } + + private static void ThrowWhenKernelInputNull(DamKernelInput damKernelInput) + { + if (damKernelInput == null) + { + throw new NoNullAllowedException(Resources.DamPipingBlighKernelWrapper_NoInputObjectDefinedForBligh); + } + } + + public ShoulderDesign CalculateDesignAtPoint(DamKernelInput damKernelInput, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, GeometryPoint point, out List messages) + { + messages = new List(); + DamPipingBlighInput damPipingBlighInput = kernelDataInput as DamPipingBlighInput; + DamPipingBlighOutput damPipingBlighOutput = (DamPipingBlighOutput)kernelDataOutput; + ThrowWhenKernelInputNull(damKernelInput); + ThrowWhenKernelOutputNull(damPipingBlighOutput); + + // ============================ Start of SetupCalculationAtGivePoint() + Location location = damKernelInput.Location; + SoilProfile1D soilProfile = damKernelInput.SubSoilScenario.SoilProfile1D; + double waterLevel = damKernelInput.RiverLevelHigh; + SurfaceLine2 surfaceLine = damKernelInput.Location.SurfaceLine; + + ThrowHelper.ThrowWhenConditionIsTrue( + string.Format(Resources.NoSoilProfile1DDefinedForLocation, location.Name), + () => (soilProfile == null || soilProfile.Layers.Count < 1)); + ThrowHelper.ThrowIfArgumentNull(soilProfile, string.Format(Resources.NoSurfaceLineDefinedForLocation, location.Name)); + + GeometryPoint entryPoint = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver); + + ThrowHelper.ThrowIfArgumentNull(entryPoint, string.Format(Resources.NoDikeToeDefinedForLocation, location.Name)); + ThrowHelper.ThrowIfArgumentNull(soilProfile.BottomAquiferLayer, string.Format(Resources.NoBottomAquiferLayer, soilProfile.Name)); + + PLLines plLines = CreatePlLines(damKernelInput); + + UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator + { + PLLines = plLines, + SoilProfile = soilProfile, + SurfaceLine = surfaceLine, + DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), + XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin + }; + UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetUpliftFactorAtPoint(point); + // ============================ End of SetupCalculationAtGivePoint() + double requiredFoS = damKernelInput.DesignScenario.GetRequiredSafetyFactorPiping(null); + double upliftCriterion = damKernelInput.DesignScenario.GetUpliftCriterionPiping(null); + // if there is no uplift, then there is no piping so return null + if (upliftLocationAndResult != null) + { + double xEntry = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X; + double xExit = upliftLocationAndResult.X; + damPipingBlighInput.SeepageLength = xExit - xEntry; + // Calculate the piping safety factor using the level of the given point + PerformSingleCalculationBligh(out messages, damPipingBlighOutput, damPipingBlighInput); + //var sp = CalculatePipingFactorAtLevel(location, waterLevel, point.Z); + + // If too low, then determine required height and length (from uplift) + if (damPipingBlighOutput.FoSp < requiredFoS) + { + // Finally, determine the required shoulderheight + double currentShoulderHeight = upliftLocationAndResult.Z - + surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + var shoulderDesign = new ShoulderDesign( + upliftLocationAndResult.X - surfaceLine.GetDikeToeInward().X, + currentShoulderHeight + CalculateExtraShoulderHeight(soilProfile, plLines, upliftLocationAndResult, upliftCriterion)); + return shoulderDesign; + } + } + return null; + } + + protected double CalculateExtraShoulderHeight(SoilProfile1D soilProfile, PLLines plLines, UpliftLocationAndResult upliftLocationAndResult, double upliftCriterion) + { + var calculator = new UpliftCalculator(); + calculator.SoilProfile = soilProfile; + calculator.SurfaceLevel = upliftLocationAndResult.Z; + calculator.PhreaticLevel = plLines.Lines[PLLineType.PL1].ZFromX(upliftLocationAndResult.X); + calculator.TopOfLayerToBeEvaluated = soilProfile.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId).TopLevel; + PLLine plLine; + if (upliftLocationAndResult.LayerWhereUpliftOccuresId == soilProfile.BottomAquiferLayer.Name) + { + plLine = plLines.Lines[PLLineType.PL3]; + } + else + { + plLine = plLines.Lines[PLLineType.PL4]; + } + return calculator.CalculateExtraHeight(plLine.ZFromX(upliftLocationAndResult.X), upliftCriterion); + } + + private PLLines CreatePlLines(DamKernelInput damKernelInput) + { + var soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile1D; + var location = damKernelInput.Location; + double waterLevel = damKernelInput.RiverLevelHigh; + UpliftSituation upliftSituation; + PLLines plLines = PlLinesHelper.CreatePlLines(location, soilProfile1D, waterLevel, out upliftSituation); + return plLines; + } } }