//----------------------------------------------------------------------- // // Copyright (c) 2009 Deltares. All rights reserved. // // B.S.T.I.M. The // tom.the@deltares.nl // 07-07-2009 // Calculates the remaining grass strength when overtopping occurs //----------------------------------------------------------------------- using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.SurfaceLines; namespace Deltares.Dam.Data { using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; [global::System.Serializable] public class OvertoppingErosionCalculatorException : Exception { // // 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 OvertoppingErosionCalculatorException() { } public OvertoppingErosionCalculatorException(string message) : base(message) { } public OvertoppingErosionCalculatorException(string message, Exception inner) : base(message, inner) { } protected OvertoppingErosionCalculatorException( SerializationInfo info, StreamingContext context) : base(info, context) { } } public class OvertoppingErosionCalculator { public double TimeStepInHours { get; set; } public double GrassQualityFactor { get; set; } public Location Location { get; set; } public OvertoppingErosionCalculator() { TimeStepInHours = 1.0; GrassQualityFactor = 0.9; } public double Calculate(double overtoppingRate) { double dikeSlopeAtPolder = DetermineDikeSlopeAtPolder(); return CalculateRemainingStrength(TimeStepInHours, dikeSlopeAtPolder, GrassQualityFactor, overtoppingRate); } /// /// Calculates the remaining strength of grass as a factor between 0.0 and 1.0 /// /// /// public double CalculateRemainingStrength(double timeStepInHour, double dikeSlopeAtPolder, double grassQualityFactor, double OvertoppingRate) { const double roughnessFactor = 0.015; if(grassQualityFactor==0) throw new OvertoppingErosionCalculatorException("grassQualityFactor can not be zero"); double criticalFlowSpeed = Math.Pow(((OvertoppingRate / 1000.0) * 125 * Math.Pow(Math.Tan(dikeSlopeAtPolder), 0.75)) / Math.Pow(roughnessFactor, 0.25), 0.4); double criticalFlowTime = Math.Pow(10,( (((grassQualityFactor * 3.8) / criticalFlowSpeed) - 1) / Math.Pow(0.8,10.0))); if (criticalFlowTime == 0) throw new OvertoppingErosionCalculatorException("Division byte zero when calculating GrassDecay"); double grassDecay = (timeStepInHour * 3600)/ criticalFlowTime; return (grassDecay > 1.0 ? 0.0 : 1 - grassDecay); } /// /// Determines the slope at Polder side /// /// Angle in radians private double DetermineDikeSlopeAtPolder() { GeometryPoint dikeTopAtPolderPoint = dikeTopAtPolderPoint = GetDikeTopAtPolder(); GeometryPoint insteekShoulderInsidePoint = Location.LocalXZSurfaceLine2.GetDikeToeInward(); double dx = insteekShoulderInsidePoint.X - dikeTopAtPolderPoint.X; double dz = dikeTopAtPolderPoint.Z - insteekShoulderInsidePoint.Z; if (dx == 0) throw new OvertoppingErosionCalculatorException("Division by zero when calculating tan alpha"); return Math.Atan(dz/dx); } /// /// Retrieve the CharacteristicPoint DikeTopAtPolder. /// /// private GeometryPoint GetDikeTopAtPolder() { GeometryPoint dikeTopAtPolderPoint = null; var dikeTopAtPolder = Location.LocalXZSurfaceLine2.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder); if (dikeTopAtPolder != null) { dikeTopAtPolderPoint = dikeTopAtPolder; } else throw new OvertoppingErosionCalculatorException("Could not find the required charactersisticpoints in surfaceline"); return dikeTopAtPolderPoint; } } }