//----------------------------------------------------------------------- // // 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 4 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.Linq; using System.Runtime.Serialization; using Deltares.Soilbase; public class PipingCalculatorSellmeijer4Forces : PipingCalculator { public PipingCalculatorSellmeijer4Forces(ModelParametersForPLLines modelParametersForPLLines, double requiredSafetyFactor, IList gaugePLLines, IList gauges, double requiredUpliftFactor) : base(modelParametersForPLLines, requiredSafetyFactor, gaugePLLines, gauges, null, requiredUpliftFactor) { } private const double cBligh = 18.0; [global::System.Serializable] public class PipingCalculatorSellmeijer4ForcesException : 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 PipingCalculatorSellmeijer4ForcesException() { } public PipingCalculatorSellmeijer4ForcesException(string message) : base(message) { } public PipingCalculatorSellmeijer4ForcesException(string message, Exception inner) : base(message, inner) { } protected PipingCalculatorSellmeijer4ForcesException( 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 PipingCalculatorSellmeijer4ForcesException("An unexpected error occurred", e); } } static public double TermLnC(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double waterViscosity) { double result = 0.68 - 0.1 * Math.Log(TermC(whitesConstant, beddingAngle, d70, length, permeability, waterViscosity), Math.E); return result; } static public double TermC(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double waterViscosity) { double kIntrinsic = KIntrinisc(permeability, waterViscosity); double term = Math.Pow((1 / (kIntrinsic * length)), (1.0 / 3.0)); double result = whitesConstant * (d70 * 1.0e-6) * term; return result; } static public double TermAlpha(double length, double dSandlayer) { double result = Math.Pow((dSandlayer / length), 0.28 / ((Math.Pow(dSandlayer / length, 2.8)) - 1)); return result; } static private double HcDividedByLNew(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double dSandlayer, double waterViscosity) { return TermAlpha(length, dSandlayer) * TermC(whitesConstant, beddingAngle, d70, length, permeability, waterViscosity) * CGammaPDividedByGammaW * Math.Tan(cDegreeToRadian * beddingAngle) * TermLnC(whitesConstant, beddingAngle, d70, length, permeability, waterViscosity); } static public double CalculateHCritical(double whitesConstant, double beddingAngle, double d70, double length, double permeability, double dSandlayer, double waterViscosity) { double result = HcDividedByLNew(whitesConstant, beddingAngle, d70, length, permeability, dSandlayer, waterViscosity) * length; return result; } private double CalculatePipingFactorAtLevel(Location location, double waterLevel, double surfaceLevel) { PipingCalculatorInput pipingCalculatorInput = DefinePipingInputFromModel(); var dCoverLayer = DetermineHeightCoverLayer(surfaceLevel); var soilProfile1DAquiferLayerCombiner = new SoilProfile1DAquiferLayerCombiner(SoilProfile); AquiferLayerWithParameters aquiferLayerWithParameters = soilProfile1DAquiferLayerCombiner.CombineLayers(UpliftLocationAndResult.LayerWhereUpliftOccuresId); this.HCritical = CalculateHCritical( pipingCalculatorInput.WhitesConstant, pipingCalculatorInput.BeddingAngle, Physics.FactorMeterToMicroMeter * aquiferLayerWithParameters.D70, pipingCalculatorInput.Length, aquiferLayerWithParameters.PermeabilityKx, aquiferLayerWithParameters.Height, pipingCalculatorInput.WaterViscosity); // 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)." double 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 using the level of 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; } } }