//----------------------------------------------------------------------- // // Copyright (c) 2010 Deltares. All rights reserved. // // B.S.T.I.M. The // tom.the@deltares.nl // 13-7-2010 // Calculates the piping factor according to Sellmeijer 2 forces. //----------------------------------------------------------------------- using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Standard; namespace Deltares.Dam.Data { using System; using System.Collections.Generic; using System.Runtime.Serialization; public class PipingCalculatorSellmeijer2Forces : PipingCalculator { public PipingCalculatorSellmeijer2Forces(ModelParametersForPLLines modelParametersForPLLines, double requiredSafetyFactor, IList gaugePLLines, IList gauges, double upliftCriterion) : base(modelParametersForPLLines, requiredSafetyFactor, gaugePLLines, gauges, null, upliftCriterion) { } [global::System.Serializable] public class PipingCalculatorSellmeijer2ForcesException : ApplicationException { // // For guidelines regarding the creation of new exception types, see // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp // and // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp // public PipingCalculatorSellmeijer2ForcesException() { } public PipingCalculatorSellmeijer2ForcesException(string message) : base(message) { } public PipingCalculatorSellmeijer2ForcesException(string message, Exception inner) : base(message, inner) { } protected PipingCalculatorSellmeijer2ForcesException( SerializationInfo info, StreamingContext context) : base(info, context) { } } override public double? CalculatePipingFactor(Location location, SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, double waterLevel) { base.CalculatePipingFactor(location, surfaceLine, soilProfile, waterLevel); try { if (UpliftLocationAndResult != null) { return CalculatePipingFactorAtLevel(location, waterLevel, surfaceLine.Geometry.GetZAtX(UpliftLocationAndResult.X)); } return cDefaultMaxReturnValue; } catch (Exception e) { throw new PipingCalculatorSellmeijer2ForcesException("An unexpected error occurred", e); } } static private double Factor(double whitesConstant, double beddingAngle) { double result = Math.PI / 3.0 * whitesConstant * CGammaPDividedByGammaW * Math.Tan(cDegreeToRadian * beddingAngle); return result; } static private double FRes(double whitesConstant, double beddingAngle) { const double cConst1 = 0.724789473684211; const double cConst2 = 0.50; double result = Factor(whitesConstant, beddingAngle) * Math.Pow((cConst2 / cConst1), 0.35); return result; } static private double FScale(double d70, double length, double permeability) { const double cConst3 = 207.921052631579; double cNuDividedByGravity = 0.00000133 / Physics.GravityConstant; double result = Math.Pow((d70 / cConst3), 0.39) * cConst3 * 0.000001 / Math.Pow(permeability * cNuDividedByGravity * length, 0.333); return result; } static private double FGeom(double dSandlayer, double length) { double result = 0.87 * Math.Pow(dSandlayer / length, 0.28 / (Math.Pow(dSandlayer / length, 2.8) - 1) + 0.04); return result; } static private double HcDividedByLNew(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double dSandlayer) { double result = FRes(whitesConstant, beddingAngle) * FScale(d70, length, permeability) * FGeom(dSandlayer, length); return result; } static public double CalculateHCritical(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double dSandlayer) { double result = HcDividedByLNew(whitesConstant, beddingAngle, d70, length, permeability, dSandlayer) * length; return result; } private double CalculatePipingFactorAtLevel(Location location, double waterLevel, double surfaceLevel) { var pipingCalculatorInput = DefinePipingInputFromModel(); var dCoverLayer = DetermineHeightCoverLayer(surfaceLevel); var soilProfile1DAquiferLayerCombiner = new SoilProfile1DAquiferLayerCombiner(SoilProfile); AquiferLayerWithParameters aquiferLayerWithParameters = soilProfile1DAquiferLayerCombiner.CombineLayers(UpliftLocationAndResult.LayerWhereUpliftOccuresId); HCritical = CalculateHCritical( pipingCalculatorInput.WhitesConstant, pipingCalculatorInput.BeddingAngle, Physics.FactorMeterToMicroMeter * aquiferLayerWithParameters.D70, pipingCalculatorInput.Length, aquiferLayerWithParameters.PermeabilityKx, aquiferLayerWithParameters.Height); // 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); // After consulting Erik Vastenburg, Jan Blinde, Andre Koelewijn, Alexander van Duinen en Huub de Bruijn // it was decided that the fluidisation correction shopuld be applied on the hActual and not the hCritical. double hActual = waterLevel - referenceLevel - (CDefaultFluidisationGradient * dCoverLayer); double pipingFactor = DeterminePipingFactorWithUpperLimit(hActual, HCritical); return pipingFactor; } /// /// Determines the required shoulder (height and length as seen from the original dike toe) /// /// /// /// /// /// /// The required dimensions when needed else null public override PipingDesign CalculateDesignAtPoint(Location location, SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, double waterLevel, GeometryPoint point) { // call base class for initializations, this will also calculate the uplift var pipingDesign = base.CalculateDesignAtPoint(location, surfaceLine, soilProfile, waterLevel, point); // if there is nu uplift, then there is no piping so return null if (UpliftLocationAndResult != null) { // Calculate the piping safety factor at the given point var sp = CalculatePipingFactorAtLevel(location, waterLevel, point.Z); // If too low, then determine required height and length (from uplift) if (sp < requiredSafetyFactor) { // Finally, determine the required shoulderheight double currentShoulderHeight = UpliftLocationAndResult.Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; pipingDesign.ShoulderHeightFromToe = currentShoulderHeight + CalculateExtraShoulderHeight(); pipingDesign.PipingLengthFromToe = UpliftLocationAndResult.X - surfaceLine.GetDikeToeInward().X; return pipingDesign; } } return null; } } }