// 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;
}
}
}