//-----------------------------------------------------------------------
//
// Copyright (c) 2009 Deltares. All rights reserved.
//
// B. Faassen
// barry.faassen@deltares.nl
// 18-6-2009
// n.a.
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Deltares.Geometry;
using Deltares.Geotechnics;
using Deltares.Geotechnics.Soils;
using Deltares.Geotechnics.SurfaceLines;
using Deltares.Standard;
namespace Deltares.Dam.Data
{
public class PipingCalculatorBligh : PipingCalculator
{
public PipingCalculatorBligh(ModelParametersForPLLines modelParametersForPLLines, double requiredSafetyFactor,
IList gaugePLLines, IList gauges, double upliftCriterion) :
base(modelParametersForPLLines, requiredSafetyFactor, gaugePLLines, gauges, null,
upliftCriterion)
{
}
private const double cBligh = 18.0;
[global::System.Serializable]
public class PipingCalculatorBlighException : 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 PipingCalculatorBlighException() { }
public PipingCalculatorBlighException(string message) : base(message) { }
public PipingCalculatorBlighException(string message, Exception inner) : base(message, inner) { }
protected PipingCalculatorBlighException(
SerializationInfo info,
StreamingContext context)
: base(info, context) { }
}
override public double? CalculatePipingFactor(Location location, SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, double waterLevel)
{
base.CalculatePipingFactor(location, surfaceLine, soilProfile, waterLevel);
try
{
if (UpliftLocationAndResult != null)
{
return CalculatePipingFactorAtLevel(location, waterLevel, surfaceLine.Geometry.GetZAtX(UpliftLocationAndResult.X));
}
return cDefaultMaxReturnValue;
}
catch (Exception e)
{
throw new DamFailureMechanismeCalculatorException("An unexpected error occurred", e);
}
}
///
/// Determine creep factor for Bligh
///
///
static private double CreepFactor(double? d70)
{
if (d70 != null)
{
double d50 = D50DividedByD70 * d70.Value;
if (d50 < 150.0)
{
// according to specs: d50 < 150
return 18.0;
}
else
{
if (d50 < 300.0)
{
// according to specs: 150 < d50 < 300
return 15.0;
}
else
{
// according to specs: 300 < d50 < 2000
return 12.0;
}
}
}
else
{
return cBligh;
}
}
///
/// Determine critical head
///
///
///
///
static public double CalculateHCritical(double length, double? d70)
{
double creepFactor = CreepFactor(d70);
return length / creepFactor;
}
///
/// Calculates the piping factor at given surfacelevel.
///
/// The location.
/// The water level.
/// The surface level.
///
private double CalculatePipingFactorAtLevel(Location location, double waterLevel, double surfaceLevel)
{
var dCoverLayer = DetermineHeightCoverLayer(surfaceLevel);
var heaveLayer = SoilProfile.GetLayerWithId(UpliftLocationAndResult.LayerWhereUpliftOccuresId);
var length = UpliftLocationAndResult.X - entryPoint.X;
// Reference level is highest value of surfaceLevel or PolderLevel
// Uit TR Zandmeevoerende wellen (1999): "Het verval dH is gelijk aan het verschil tussen buitenwaterstand (het ontwerppeil(OP))
// bij zeedijken en de maatgevende hoogwaterstand (MHW bij rivierdijken) en de waterstand binnendijks ter plaatse van het uittredepunt,
// rekening houdend met zeespiegelrijzing etc.(zie paragraaf 3.7.2). In dien ter plaatse van het uittreepunt of de opbarstlocatie
// geen vrije waterstand heerst kan gerekend worden met het maaiveldniveau, rekening houdend met eventuele maaiveld daling (zie paragraaf 3.7.2)."
var referenceLevel = Math.Max(location.PolderLevel, surfaceLevel);
ThrowIfInvalidD70(heaveLayer.Soil.DiameterD70);
HCritical = CalculateHCritical(length, Physics.FactorMeterToMicroMeter * heaveLayer.Soil.DiameterD70);
// After consulting Erik Vastenburg, Jan Blinde, Andre Koelewijn, Alexander van Duinen en Huub de Bruijn
// it was decided that the fluidisation correction shopuld be applied on the hActual and not the hCritical.
double hActual = waterLevel - referenceLevel - (CDefaultFluidisationGradient * dCoverLayer);
double pipingFactor = DeterminePipingFactorWithUpperLimit(hActual, HCritical);
return pipingFactor;
}
///
/// Determines the required shoulder (height and length as seen from the original dike toe)
///
///
///
///
///
///
/// The required dimensions when needed else null
public override PipingDesign CalculateDesignAtPoint(Location location, SurfaceLine2 surfaceLine, SoilProfile1D soilProfile, double waterLevel, GeometryPoint point)
{
// call base class for initializations, this will also calculate the uplift
var pipingDesign = base.CalculateDesignAtPoint(location, surfaceLine, soilProfile, waterLevel, point);
// if there is nu uplift, then there is no piping so return null
if (UpliftLocationAndResult != null)
{
// Calculate the piping safety factor using the level of the given point
var sp = CalculatePipingFactorAtLevel(location, waterLevel, point.Z);
// If too low, then determine required height and length (from uplift)
if (sp < requiredSafetyFactor)
{
// Finally, determine the required shoulderheight
double currentShoulderHeight = UpliftLocationAndResult.Z -
surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z;
pipingDesign.ShoulderHeightFromToe = currentShoulderHeight + CalculateExtraShoulderHeight();
pipingDesign.PipingLengthFromToe = UpliftLocationAndResult.X - surfaceLine.GetDikeToeInward().X;
return pipingDesign;
}
}
return null;
}
}
}