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