Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.BlighCalculator/PipingCalculatorBligh.cs =================================================================== diff -u -r259 -r269 --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.BlighCalculator/PipingCalculatorBligh.cs (.../PipingCalculatorBligh.cs) (revision 259) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.BlighCalculator/PipingCalculatorBligh.cs (.../PipingCalculatorBligh.cs) (revision 269) @@ -5,29 +5,295 @@ namespace Deltares.DamPiping.BlighCalculator { + /// + /// Calculates piping according to Bligh + /// public class PipingCalculatorBligh { - public const double cDefaultMaxReturnValue = 90.0; - public PipingCalculatorBligh() + public const double RcDefault = 0.3; + public const double Epsilon = 1e-8; + + private double foSp; + private double hc; + private double hcp; + private double rc = RcDefault; + private double zp; + private double reducedFall; + // private LanguageType language = LanguageType.Dutch; + + /// + /// Model factor for piping as input + /// + public double ModelFactorPiping { get; set; } + + /// + /// River level as input + /// + public double HRiver { get; set; } + + /// + /// Phreatic level at exit point as input + /// + public double HExit { get; set; } + + /// + /// Reduction factor as input + /// + public double Rc { + get { return rc; } + set { rc = value; } } - public double CalculatePipingFactor(double upliftCriterion) + /// + /// Total thickness of cover layer as input + /// + public double DTotal { get; set; } + + /// + /// Seepage length (xExit - xEntry) as input + /// + public double SeepageLength { get; set; } + + /// + /// The bottom level of the aquitard layer which is on a level above the exit point's + /// z-coordinate. A value of indicates that no such aquitard + /// layer exists. + /// + public double BottomLevelAquitardAboveExitPointZ { get; set; } + + /// + /// Median grainsize D50 as input + /// + public double D50 { get; set; } + + /// + /// Limit state function as result + /// + public double Zp { - //base.CalculatePipingFactor(location, surfaceLine, soilProfile, waterLevel); + get + { + return zp; + } + set { } + } + + /// + /// Safety factor of piping as result + /// + public double FoSp + { + get + { + return foSp; + } + set { } + } + + /// + /// Critical water lever for piping as result + /// + public double Hcp + { + get + { + return hcp; + } + set { } + } + + /// + /// Critical head difference for piping as result. + /// + public double Hc + { + get + { + return hc; + } + set { } + } + + /// + /// Start the calculation of all output parameters. + /// + public void Calculate() + { +// var restoreLanguage = LocalizationManager.CurrentLanguage; +// LocalizationManager.CurrentLanguage = Language; +// var dumper = new XmlDumper(); try { -// if (UpliftLocationAndResult != null) -// { -// return CalculatePipingFactorAtLevel(location, waterLevel, surfaceLine.Geometry.GetZAtX(UpliftLocationAndResult.X)); -// } - return cDefaultMaxReturnValue; +// DumpThis(dumper); + + hc = GetHc(); + reducedFall = GetReducedFall(); + zp = (ModelFactorPiping*hc) - reducedFall; + DetermineFactorOfSafety(); + hcp = (ModelFactorPiping*hc) + HExit + (Rc*DTotal); } - catch (Exception e) + finally { - throw new Exception("An unexpected error occurred", e); +// DumpThis(dumper); +// LocalizationManager.CurrentLanguage = restoreLanguage; } } + private void DetermineFactorOfSafety() + { + foSp = 0; + + if (!IsPipingPossible()) + { + foSp = double.PositiveInfinity; + } + else + { + var reducedCriticalHeadDifference = ModelFactorPiping*hc; + if (Math.Abs(reducedCriticalHeadDifference) > Epsilon) + { + foSp = (reducedCriticalHeadDifference)/Math.Max(0, reducedFall); + } + } + } + + /// + /// Calculate Hc according to the required model + /// + /// the proper value of Hc according to Bligh + private double GetHc() + { + return SeepageLength/CCreep(); + } + + /// + /// Determine creep factor for Bligh + /// + /// creep factor + private double CCreep() + { + // d50 is in meters; the table for Bligh is in micro meters so convert locally + var ld50 = D50*1e6; + if (ld50 < 150.0) + { + // according to specs: d50 < 150 + return 18.0; + } + if (ld50 < 300.0) + { + // according to specs: 150 < d50 < 300 + return 15.0; + } + if (ld50 < 2000.0) + { + // according to specs: 300 < d50 < 2000 + return 12.0; + } + if (ld50 < 16000.0) + { + // according to specs: 2000 < d50 < 16000 + return 9.0; + } + // according to specs: d50 > 16000 + return 4.0; + } + + private double GetReducedFall() + { + return HRiver - HExit - (Rc*DTotal); + } + + /// + /// Validates the input + /// + /// a filled list when errors are found else an empty list + public List Validate() + { +// var restoreLanguage = LocalizationManager.CurrentLanguage; +// LocalizationManager.CurrentLanguage = Language; + + var errors = new List(); +// var dumper = new XmlDumper(); + try + { +// DumpThis(dumper); + errors.AddRange(PerformValidate()); + } + finally + { +// DumpThis(dumper); +// LocalizationManager.CurrentLanguage = restoreLanguage; + } + + return errors; + } + + private List PerformValidate() + { + var errors = new List(); + if (Math.Abs(GetReducedFall()) < double.Epsilon) + { + errors.Add(RiverHexitRcDTotalError); + } + + if (double.IsNaN(SeepageLength)) + { + LogParameterIsNaN(errors, "SeepageLength"); + } + if (double.IsNaN(HRiver)) + { + LogParameterIsNaN(errors, "HRiver"); + } + if (double.IsNaN(Rc)) + { + LogParameterIsNaN(errors, "Rc"); + } + if (Rc < 0) + { + errors.Add(this.Translate("RcLessThan0")); + } + if (double.IsNaN(DTotal)) + { + LogParameterIsNaN(errors, "DTotal"); + } + if (double.IsNaN(ModelFactorPiping)) + { + LogParameterIsNaN(errors, "ModelFactorPiping"); + } + if (double.IsNaN(HExit)) + { + LogParameterIsNaN(errors, "HExit"); + } + if (double.IsNaN(D50)) + LogParameterIsNaN(errors, "D50"); + + return errors; + } + + private void LogParameterIsNaN(IList list, string paramName) + { + var msg = string.Format(this.Translate("NaNParameterError"), paramName); + list.Add(msg); + } + private string RiverHexitRcDTotalError + { + get { return this.Translate("HRiver_HExit_Rc_DTotal_Zero"); } + } + + private string Translate(string error) + { + return error + ": %s"; + } + + private bool IsPipingPossible() + { + var isCoverageLayerThicknessZero = Math.Abs(DTotal) < Epsilon; + var isAquitardLayerInDikePresent = !double.IsNaN(BottomLevelAquitardAboveExitPointZ); + var isAquitardAbovePhreaticLevelAtExitPoint = BottomLevelAquitardAboveExitPointZ <= HExit; + + return !isCoverageLayerThicknessZero || + (isAquitardLayerInDikePresent && isAquitardAbovePhreaticLevelAtExitPoint); + } } } Fisheye: Tag 269 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/Class1.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/Deltares.DamPiping.BlighCalculatorTests.csproj =================================================================== diff -u -r267 -r269 --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/Deltares.DamPiping.BlighCalculatorTests.csproj (.../Deltares.DamPiping.BlighCalculatorTests.csproj) (revision 267) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/Deltares.DamPiping.BlighCalculatorTests.csproj (.../Deltares.DamPiping.BlighCalculatorTests.csproj) (revision 269) @@ -44,7 +44,6 @@ - Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/PipingCalculatorBlighTests.cs =================================================================== diff -u -r267 -r269 --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/PipingCalculatorBlighTests.cs (.../PipingCalculatorBlighTests.cs) (revision 267) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.BlighCalculatorTests/PipingCalculatorBlighTests.cs (.../PipingCalculatorBlighTests.cs) (revision 269) @@ -10,31 +10,59 @@ [TestFixture] public class PipingCalculatorBlighTests { - + [Test] - public void CanCalculateThePipingFactorUsingBlighNoUplift() + public void TestCalculation() { - var calculator = new PipingCalculatorBligh(); - const double upliftCriterion = 1.0; - var actual = calculator.CalculatePipingFactor(upliftCriterion); - - // Phreatic level in profile - // Mass of soil volume above - // dry 6 m x 12 kN/m3 = 72 - // wet 9 m x 16 kN/m3 = 144 - // Total: 72 + 144 = 216 - // Phreatic pressure - // 20 m x 10 kN/m3 = 200 - // UpliftFactor = 216/200 = 1.08 - // UpliftFactor > 1.0, so no piping, so returns cDefaultMaxReturnValue - var expected = PipingCalculatorBligh.cDefaultMaxReturnValue; - - Assert.AreEqual(expected, actual); + const double diff = 0.0001; + var bc = new PipingCalculatorBligh + { + HRiver = 1 + }; + bc.Calculate(); + Assert.AreEqual(-1, bc.Zp); + Assert.AreEqual(0, bc.FoSp); + Assert.AreEqual(0, bc.Hcp); + Assert.AreEqual(0, bc.Hc); + + bc.HRiver = 7; + bc.ModelFactorPiping = 0.5; + bc.HExit = 2; + bc.Rc = 0.8; + bc.DTotal = 3; + bc.SeepageLength = 18; + bc.D50 = 2.5e-3; + bc.Calculate(); + Assert.AreEqual(-1.6, bc.Zp, diff); + Assert.AreEqual(1 / 2.6, bc.FoSp, diff); + Assert.AreEqual(5.4, bc.Hcp, diff); + Assert.AreEqual(2, bc.Hc, diff); } // [Test] // public void CanCalculateThePipingFactorUsingBlighNoUplift() // { +// var calculator = new PipingCalculatorBligh(); +// const double upliftCriterion = 1.0; +// var actual = calculator.CalculatePipingFactor(upliftCriterion); +// +// // Phreatic level in profile +// // Mass of soil volume above +// // dry 6 m x 12 kN/m3 = 72 +// // wet 9 m x 16 kN/m3 = 144 +// // Total: 72 + 144 = 216 +// // Phreatic pressure +// // 20 m x 10 kN/m3 = 200 +// // UpliftFactor = 216/200 = 1.08 +// // UpliftFactor > 1.0, so no piping, so returns cDefaultMaxReturnValue +// var expected = PipingCalculatorBligh.cDefaultMaxReturnValue; +// +// Assert.AreEqual(expected, actual); +// } +// +// [Test] +// public void CanCalculateThePipingFactorUsingBlighNoUplift() +// { // using (var surfaceLine = FactoryForSurfaceLineTests.CreateSurfaceLineTutorial1()) // using (var dike = new Dike()) // {