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