// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of the application DAM - Clients Library. // // DAM - UI is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using Deltares.Geometry; using Deltares.Geotechnics.SurfaceLines; namespace Deltares.Dam.Data { using System; 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; } } }