//-----------------------------------------------------------------------
//
// Copyright (c) 2011 Deltares. All rights reserved.
//
// B.S.T.I.M. The
// tom.the@deltares.nl
// 18-05-2010
// Hydraulic shortcut evaluator
//-----------------------------------------------------------------------
namespace Deltares.Dam.Data
{
using System;
using System.Collections.Generic;
public class HydraulicShortcutRWEvaluator : RWEvaluator
{
private const double cMinUpliftFactor = 1.2;
private const double cMinAquitardThickness = 2.0; // meter
private const double cMinHeadGradient = 1.0; // meter
private const double cMinAquitardThicknessIfDrySensitive = 5.0; // meter
private const double cMinClayThickness = 2.0; // meter
private DikeDrySensitivity dikeDrySensitivity = DikeDrySensitivity.None;
private LoadSituation loadSituation = LoadSituation.Wet;
public HydraulicShortcutRWEvaluator()
{
}
public override Enum Evaluate(Location location, SoilGeometry soilGeometry, params Enum[] previousChoices)
{
base.Evaluate(location, soilGeometry, previousChoices);
HydraulicShortcutType hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
// Determine dikeDrySensitivity and loadsituation
Dictionary choices = new Dictionary();
foreach (Enum enumValue in previousChoices)
{
if (enumValue != null)
{
choices[enumValue.GetType()] = enumValue;
}
}
dikeDrySensitivity = (DikeDrySensitivity)choices[typeof(DikeDrySensitivity)];
loadSituation = (LoadSituation)choices[typeof(LoadSituation)];
System.Diagnostics.Debug.Print(String.Format("==== Hydraulic shortcut evaluation of '{0}'", location.Name));
// determine hydraulic shortcut
// evaluate boezempeil (step 1)
if (EvaluateBoezemLevelBelowHeadAquifer())
{
hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
}
else
{
// Evaluate thickness of aquitard (step 2)
if (!EvaluateAquitardHasEnoughThickness())
{
hydraulicShortcutType = HydraulicShortcutType.HydraulicShortcut;
}
else
{
// Evaluate drysensitive dike (step 3)
if (!EvaluateDikeIsDrySensitive())
{
hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
}
else
{
// Evaluate thickness clay in aquitard and sheetpile (step 4)
if (EvaluateClayInAquitardTooThin())
{
if (loadSituation == LoadSituation.Dry)
{
hydraulicShortcutType = HydraulicShortcutType.HydraulicShortcut;
}
else
{
hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
}
}
else
{
hydraulicShortcutType = HydraulicShortcutType.NoHydraulicShortcut;
}
}
}
}
System.Diagnostics.Debug.Print(String.Format("==== End of Hydraulic shortcut evalution of '{0}'", location.Name));
return hydraulicShortcutType;
}
///
/// Condition: Dikte waterremmende laag minstens 2 meter
///
///
private bool EvaluateAquitardHasEnoughThickness()
{
var aquitardEvaluator = new AquitardEvaluator(soilGeometry.SoilProfile);
double aquitardTichkness = aquitardEvaluator.DetermineAquitardThicknessWithMinimalWeight(location.DredgingDepth, this.location.GetDikeEmbankmentSoil()); // Note: do not evaluate sheetpile here
bool aquitardHasEnoughThickness = (aquitardTichkness >= cMinAquitardThickness);
System.Diagnostics.Debug.Print(String.Format("Aquitard thickness ({0}) sufficient is {1}; it should be more than {2} meter",
aquitardTichkness, aquitardHasEnoughThickness , cMinAquitardThickness));
return aquitardHasEnoughThickness;
}
///
/// Condition: Droogtegevoeilige kade
///
///
private bool EvaluateDikeIsDrySensitive()
{
// Evaluate dry sensivity of dike
// with uplift calculation the pl-lines will be created different when dikematerial is of type peat
bool isDrySensitive = (dikeDrySensitivity == DikeDrySensitivity.Dry);
System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} (check on material)", isDrySensitive));
if (isDrySensitive)
{
double gradient = (GetBoezemLevel() - location.PolderLevelLow);
isDrySensitive = gradient > cMinHeadGradient;
System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} because Gradient in dike ({1}) more than {2} meter", isDrySensitive, gradient, cMinHeadGradient));
}
if (isDrySensitive)
{
double? upliftFactor = 0.0;
upliftFactor = GetLowestUpliftFactor();
if (upliftFactor != null)
{
isDrySensitive = (upliftFactor.Value < cMinUpliftFactor);
System.Diagnostics.Debug.Print(String.Format("Is dry sensitive dike is {0} because upliftfactor ({1}) more than {2}", isDrySensitive, upliftFactor.Value, cMinUpliftFactor));
}
else
{
isDrySensitive = false;
}
}
return isDrySensitive;
}
///
/// Condition: Dikte kleilaag in waterremmende laag kleiner 2 meter of dikte waterremmende kleiner 5 meter
///
///
private bool EvaluateClayInAquitardTooThin()
{
var aquitardEvaluator = new AquitardEvaluator(soilGeometry.SoilProfile);
double aquitardThicknessWithoutMinimalWeight = aquitardEvaluator.DetermineAquitardThicknessWithoutMinimalWeight(GetBoezemBottomOrSheetPileBottom(), this.location.GetDikeEmbankmentSoil());
double claythickness = aquitardEvaluator.DetermineAquitardClayThickness(GetBoezemBottomOrSheetPileBottom());
bool clayInAquitardTooThin = (aquitardThicknessWithoutMinimalWeight < cMinAquitardThicknessIfDrySensitive);
clayInAquitardTooThin = clayInAquitardTooThin || (claythickness < cMinClayThickness);
System.Diagnostics.Debug.Print(String.Format("For dry sensitive dike aquitard thickness ({0} < {1}) or clay thickness ({2} < {3}) evaluate to {4}",
aquitardThicknessWithoutMinimalWeight, cMinAquitardThicknessIfDrySensitive, claythickness, cMinClayThickness, clayInAquitardTooThin));
return clayInAquitardTooThin;
}
///
/// Condition: Boezempeil kleiner of gelijk aan stijghoogte eerste WVP
///
///
private bool EvaluateBoezemLevelBelowHeadAquifer()
{
double boezemLevel = GetBoezemLevel();
bool boezemLevelBelowHeadAquifer = boezemLevel <= location.HeadPl3;
System.Diagnostics.Debug.Print(String.Format("Storage basin level ({0}) below head Aquifer WVP ({1}) is {2}", boezemLevel, location.HeadPl3, boezemLevelBelowHeadAquifer));
return boezemLevelBelowHeadAquifer;
}
private double GetBoezemBottomOrSheetPileBottom()
{
double boezemBottom = location.DredgingDepth;
if (location.SheetPileLength > 0)
{
double rwBankProtectionBottomLevel = location.RwBankProtectionBottomLevel;
boezemBottom = Math.Min(boezemBottom, rwBankProtectionBottomLevel);
//// sheetpile is available
//if (location.LocalXZSheetPilePoint.X < location.LocalXZSurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeTopAtRiver].X)
//{
// double sheetpilePointLevel = location.LocalXZSheetPilePoint.Z - location.SheetPileLength;
// boezemBottom = Math.Min(boezemBottom, sheetpilePointLevel);
//}
//else
//{
// System.Diagnostics.Debug.Print(String.Format("Ignored sheetpile because X sheetpile ({0}) is larger than X dike crest at river ({1})",
// location.LocalXZSheetPilePoint.X, location.LocalXZSurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeTopAtRiver].X));
//}
}
return boezemBottom;
}
///
/// Determine boezemlevel according to loadsituation
///
///
private double GetBoezemLevel()
{
double boezemLevel = 0.0;
switch (loadSituation)
{
case LoadSituation.Wet:
boezemLevel = location.BoezemLevelTp;
break;
case LoadSituation.Dry:
boezemLevel = location.BoezemLevelHbp;
break;
}
return boezemLevel;
}
///
/// Create PL-lines
///
///
private PLLines CreatePLLines()
{
PLLinesCreator plLinesCreator = new PLLinesCreator();
plLinesCreator.WaterLevelRiverHigh = GetBoezemLevel();
plLinesCreator.HeadInPLLine2 = location.HeadPL2;
plLinesCreator.HeadInPLLine3 = location.HeadPl3;
plLinesCreator.HeadInPLLine4 = location.HeadPl4;
plLinesCreator.SurfaceLine = location.LocalXZSurfaceLine2;
plLinesCreator.WaterLevelPolder = location.PolderLevel;
plLinesCreator.ModelParametersForPLLines = location.CreateModelParametersForPLLines();
plLinesCreator.SoilProfile = soilGeometry.SoilProfile;
plLinesCreator.SoilGeometry2DName = null;
plLinesCreator.SoilGeometryType = SoilGeometryType.SoilGeometry1D;
plLinesCreator.GaugePLLines = null;
plLinesCreator.Gauges = null;
plLinesCreator.GaugeMissVal = 0.0;
plLinesCreator.IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true; // for stability this must set to true
plLinesCreator.PlLineOffsetBelowDikeTopAtRiver = location.PlLineOffsetBelowDikeTopAtRiver;
plLinesCreator.PlLineOffsetBelowDikeTopAtPolder = location.PlLineOffsetBelowDikeTopAtPolder;
plLinesCreator.SoilBaseDB = null; // soilbase;
plLinesCreator.DikeEmbankmentMaterial = null; // soilbase.GetSoil(location.DikeEmbankmentMaterial);
plLinesCreator.IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry);
plLinesCreator.IsHydraulicShortcut = false; // in this evaluation obviously no hydraulic shortcut
plLinesCreator.XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin;
PLLines plLines = plLinesCreator.CreateAllPLLines(location);
return plLines;
}
///
/// Determine where lowest uplift factor occurs and the value of that factor
///
///
private double? GetLowestUpliftFactor()
{
UpliftLocationDeterminator upliftLocationDeterminator = new UpliftLocationDeterminator()
{
SurfaceLine = location.SurfaceLine2,
SoilProfile = soilGeometry.SoilProfile,
SoilGeometry2DName = null,
SoilBaseDB = null, //soilbase,
DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
PLLines = CreatePLLines(),
IsUseOvenDryUnitWeight = (dikeDrySensitivity == DikeDrySensitivity.Dry),
XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
};
UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor();
if (upliftLocationAndResult != null)
return upliftLocationAndResult.UpliftFactor;
else
return null;
}
}
}