//----------------------------------------------------------------------- // // Copyright (c) 2009 Deltares. All rights reserved. // // B.S.T.I.M. The // tom.the@deltares.nl // 10-07-2009 // Determine in which location uplift occurs //----------------------------------------------------------------------- using Deltares.Geometry; using Deltares.Geotechnics; using Deltares.Geotechnics.Soils; using Deltares.Geotechnics.SurfaceLines; using Deltares.Uplift; namespace Deltares.Dam.Data { using System; using System.Collections.Generic; using System.Linq; using System.Text; using Deltares.Soilbase; /// /// Exception for UpliftLocationDeterminator class /// public class UpliftLocationDeterminatorException : ApplicationException { // // 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 UpliftLocationDeterminatorException() { } public UpliftLocationDeterminatorException(string message) : base(message) { } } /// /// Data class containing information about uplift location and uplift factor /// public class UpliftLocationAndResult : GeometryPoint { public UpliftLocationAndResult() { UpliftFactor = 0; LayerWhereUpliftOccuresId = ""; } public UpliftLocationAndResult(double upliftFactor, string layerWhereUpliftOccuresId) { UpliftFactor = upliftFactor; LayerWhereUpliftOccuresId = layerWhereUpliftOccuresId; } public UpliftLocationAndResult(GeometryPoint point, double upliftFactor, string layerWhereUpliftOccuresId) { x = point.X; y = point.Y; z = point.Z; UpliftFactor = upliftFactor; LayerWhereUpliftOccuresId = layerWhereUpliftOccuresId; } public double? UpliftFactor { get; set; } public string LayerWhereUpliftOccuresId { get; set; } } /// /// Determie uplift location and uplift factor /// public class UpliftLocationDeterminator { public bool IsUseOvenDryUnitWeight { get; set; } public PLLines PLLines { get; set; } public SurfaceLine2 SurfaceLine { get; set; } public SoilProfile1D SoilProfile { get; set; } public SoilProfile2D SoilProfile2D { get; set; } public string SoilGeometry2DName { get; set; } public Soil DikeEmbankmentMaterial { get; set; } public SoilbaseDB SoilBaseDB { get; set; } public SoilList SoilList { get; set; } public double XSoilGeometry2DOrigin { get; set; } /// /// Constructor /// public UpliftLocationDeterminator() { IsUseOvenDryUnitWeight = false; } /// /// Get location nearest dike with and upliftfactor lower than required /// /// location and upliftfactor public UpliftLocationAndResult GetLocationAndResult(double upliftCriterion) { ThrowIfNoPLLinesDefined(); ThrowIfNoSurfaceLinDefined(); ThrowIfNoSoilProfileDefined(); return GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(upliftCriterion); } /// /// Get location nearest dike with and upliftfactor lower than required /// /// location and upliftfactor public UpliftLocationAndResult GetLocationInPolderNearestDikeWithUpliftFactorLowerThanRequired(double upliftCriterion) { ThrowIfNoPLLinesDefined(); ThrowIfNoSurfaceLinDefined(); ThrowIfNoSoilProfileDefined(); GeometryPoint startSurfacePoint = SurfaceLine.GetDikeToeInward(); IEnumerable relevantSurfacePointsList = from GeometryPoint point in SurfaceLine.Geometry.Points where point.X >= startSurfacePoint.X orderby point.X ascending select point; bool foundUpliftFactor = false; UpliftLocationAndResult upliftLocationAndResult = null; foreach (GeometryPoint surfacePoint in relevantSurfacePointsList) { upliftLocationAndResult = GetUpliftFactorAtPoint(surfacePoint); if ((upliftLocationAndResult != null) && (upliftLocationAndResult.UpliftFactor < upliftCriterion)) { foundUpliftFactor = true; upliftLocationAndResult.X = surfacePoint.X; upliftLocationAndResult.Z = surfacePoint.Z; break; } } return (foundUpliftFactor == true) ? upliftLocationAndResult : null; } /// /// Create upliftcalculator at given point /// /// GeometryPoint for which to calculate upliftfactor /// Top of layer where uplift occurs /// location and upliftfactor private UpliftCalculator CreateUpliftCalculator(GeometryPoint point, double topOfLayer, SoilProfile1D soilProfile) { PLLine phreaticLine = PLLines.Lines[PLLineType.PL1]; return new UpliftCalculator { PhreaticLevel = phreaticLine.ZFromX(point.X), SoilProfile = soilProfile, TopOfLayerToBeEvaluated = topOfLayer, SurfaceLevel = point.Z, UnitWeightSoilEmbankment = (this.DikeEmbankmentMaterial == null) ? (double?) null : this.DikeEmbankmentMaterial.AbovePhreaticLevel, IsUseOvenDryUnitWeight = this.IsUseOvenDryUnitWeight }; } /// /// Calculate upliftfactor for given point /// /// /// location and upliftfactor public UpliftLocationAndResult GetUpliftFactorAtPoint(GeometryPoint point) { SoilProfile1D soilProfileInCurrentPoint = GetSoilProfileBelowPoint(point.X); double upliftFactorForInBetweenSandLayer = double.MaxValue; if (soilProfileInCurrentPoint.InBetweenAquiferLayer != null) { // Check if inbetween sandlayer below surface double topInBetweenSandLayer = soilProfileInCurrentPoint.InBetweenAquiferLayer.TopLevel; if (topInBetweenSandLayer < point.Z) { // There is an aquitard above the aquifer, for which we can determine the uplift factor UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, topInBetweenSandLayer, soilProfileInCurrentPoint); if ( (PLLines.Lines[PLLineType.PL4] != null) && (PLLines.Lines[PLLineType.PL4].Points.Count > 0 )) upliftFactorForInBetweenSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL4].ZFromX(point.X)); } else { if (soilProfileInCurrentPoint.GetBottomLevel(soilProfileInCurrentPoint.InBetweenAquiferLayer) < point.Z) { // The surface cuts into the aquifer so the level to be evaluated is at surfacelevel UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, point.Z, soilProfileInCurrentPoint); if ((PLLines.Lines[PLLineType.PL4] != null) && (PLLines.Lines[PLLineType.PL4].Points.Count > 0)) upliftFactorForInBetweenSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL4].ZFromX(point.X)); } } } double upliftFactorForBottomSandLayer = double.MaxValue; if (soilProfileInCurrentPoint.BottomAquiferLayer != null) { // Check if bottom sandlayer below surface double topBottomSandLayer = soilProfileInCurrentPoint.BottomAquiferLayer.TopLevel; if (topBottomSandLayer < point.Z) { UpliftCalculator upliftCalculatorForBottomSandLayer = CreateUpliftCalculator(point, soilProfileInCurrentPoint.BottomAquiferLayer.TopLevel, soilProfileInCurrentPoint); if ((PLLines.Lines[PLLineType.PL3] != null) && (PLLines.Lines[PLLineType.PL3].Points.Count > 0)) upliftFactorForBottomSandLayer = upliftCalculatorForBottomSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL3].ZFromX(point.X)); } else { if (soilProfileInCurrentPoint.GetBottomLevel(soilProfileInCurrentPoint.BottomAquiferLayer) < point.Z) { // The surface cuts into the aquifer so the level to be evaluated is at surfacelevel UpliftCalculator upliftCalculatorForInBetweenSandLayer = CreateUpliftCalculator(point, point.Z, soilProfileInCurrentPoint); if ((PLLines.Lines[PLLineType.PL3] != null) && (PLLines.Lines[PLLineType.PL3].Points.Count > 0)) upliftFactorForBottomSandLayer = upliftCalculatorForInBetweenSandLayer.CalculateUpliftFactor(PLLines.Lines[PLLineType.PL3].ZFromX(point.X)); } } } if((upliftFactorForBottomSandLayer == double.MaxValue) && (upliftFactorForInBetweenSandLayer == double.MaxValue)) return null; if (upliftFactorForBottomSandLayer < upliftFactorForInBetweenSandLayer) { return new UpliftLocationAndResult(point, upliftFactorForBottomSandLayer, soilProfileInCurrentPoint.BottomAquiferLayer.Id); } else { return new UpliftLocationAndResult(point, upliftFactorForInBetweenSandLayer, soilProfileInCurrentPoint.InBetweenAquiferLayer.Id); } } /// /// Determine location with lowest upliftfactor /// /// location and upliftfactor public UpliftLocationAndResult GetLocationAtWithLowestUpliftFactor() { double? lowestUpliftFactor = null; ThrowIfNoPLLinesDefined(); ThrowIfNoSurfaceLinDefined(); ThrowIfNoSoilProfileDefined(); GeometryPoint startSurfacePoint = SurfaceLine.GetDikeToeInward(); IEnumerable relevantSurfacePointsList = from GeometryPoint point in SurfaceLine.Geometry.Points where point.X >= startSurfacePoint.X orderby point.X ascending select point; UpliftLocationAndResult upliftLocationAndResult = null; UpliftLocationAndResult lowestUpliftLocationAndResult = null; foreach (GeometryPoint surfacePoint in relevantSurfacePointsList) { upliftLocationAndResult = GetUpliftFactorAtPoint(surfacePoint); if (upliftLocationAndResult != null) { if (!lowestUpliftFactor.HasValue || upliftLocationAndResult.UpliftFactor < lowestUpliftFactor) { lowestUpliftFactor = upliftLocationAndResult.UpliftFactor; lowestUpliftLocationAndResult = upliftLocationAndResult; } } } return lowestUpliftLocationAndResult; } /// /// /// /// /// private SoilProfile1D GetSoilProfileBelowPoint(double xCoordinate) { if (this.SoilProfile != null) { return this.SoilProfile; } if (SoilProfile2D != null) { return SoilProfile2D.GetSoilProfile1D(xCoordinate); } Geometry2DTo1DConverter geometry2DTo1DConverter = new Geometry2DTo1DConverter(this.SoilGeometry2DName, this.SurfaceLine, this.DikeEmbankmentMaterial, this.SoilBaseDB, this.SoilList, -this.XSoilGeometry2DOrigin); return geometry2DTo1DConverter.Convert(xCoordinate); } /// /// Check on precondition /// private void ThrowIfNoPLLinesDefined() { if (PLLines == null) throw new UpliftLocationDeterminatorException("Required pllines not found"); } /// /// Check on precondition /// private void ThrowIfNoSurfaceLinDefined() { if (SurfaceLine == null) throw new UpliftLocationDeterminatorException("Required surfaceLine line not found"); } /// /// Check on precondition /// private void ThrowIfNoSoilProfileDefined() { if (SoilProfile == null && (SoilGeometry2DName == null || SoilGeometry2DName == "") && SoilProfile2D == null) throw new UpliftLocationDeterminatorException("Required soilProfile not found"); } } }