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