Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Helper.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Helper.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Helper.cs (revision 328) @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Deltares.DamUplift.Geo +{ + public static class Helper + { + public static bool AlmostEquals(double double1, double double2, double precision) + { + if (double.IsNaN(double1) && double.IsNaN(double2)) + return true; + if (double.IsNaN(double1) || double.IsNaN(double2)) + return false; + return Math.Abs(double1 - double2) <= precision; + } + public static bool AlmostEquals(this double double1, double double2) + { + return AlmostEquals(double1, double2, 1E-07); + } + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingLayer.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingLayer.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingLayer.cs (revision 328) @@ -0,0 +1,71 @@ +namespace Deltares.DamUplift +{ + /// + /// Class to hold layers (1D) for the Piping kernel + /// + public class PipingLayer + { + /// + /// Assigns the specified layer. + /// + /// The layer. + public void Assign(PipingLayer layer) + { + AbovePhreaticLevel = layer.AbovePhreaticLevel; + BelowPhreaticLevel = layer.BelowPhreaticLevel; + DryUnitWeight = layer.DryUnitWeight; + TopLevel = layer.TopLevel; + IsAquifer = layer.IsAquifer; + Name = layer.Name; + } + + /// + /// Gets or sets the unit weight above phreatic level. + /// + /// + /// The unit weight above phreatic level. + /// + public double AbovePhreaticLevel { get; set; } + + /// + /// Gets or sets the unit weight below phreatic level. + /// + /// + /// The unit weight below phreatic level. + /// + public double BelowPhreaticLevel { get; set; } + + /// + /// Gets or sets the dry unit weight. + /// + /// + /// The dry unit weight. + /// + public double DryUnitWeight { get; set; } + + /// + /// Gets or sets the top level. + /// + /// + /// The top level. + /// + public double TopLevel { get; set; } + + /// + /// Gets or sets a value indicating whether this instance is aquifer. + /// + /// + /// true if this instance is aquifer; otherwise, false. + /// + public bool IsAquifer { get; set; } + + /// + /// Gets or sets the name. + /// + /// + /// The name. + /// + public string Name { get; set; } + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorEffectiveStressTest.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorEffectiveStressTest.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorEffectiveStressTest.cs (revision 328) @@ -0,0 +1,178 @@ +using Deltares.DamUplift; +using NUnit.Framework; + +namespace Deltares.DamUpliftTests +{ + [TestFixture] + internal class SoilVolumeMassCalculatorEffectiveStressTest + { + [Test] + public void CalculateWithExceedingMinimumThicknessCoverLayerAndLowSurfaceLevelFullySubmerged() + { + const double expectedResult = 109.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 9.5; + soilVolumeMassCalculator.PhreaticLevel = 0; + soilVolumeMassCalculator.SurfaceLevel = -1.5; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithExceedingMinimumThicknessCoverLayerAndLowSurfaceLevelPartlySubmerged() + { + const double expectedResult = 121.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 9.5; + soilVolumeMassCalculator.PhreaticLevel = -2; + soilVolumeMassCalculator.SurfaceLevel = -1.5; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithExceedingMinimumThicknessCoverLayerFullySubmerged() + { + const double expectedResult = 134.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 12; + soilVolumeMassCalculator.PhreaticLevel = 5; + soilVolumeMassCalculator.SurfaceLevel = 0; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithExceedingMinimumThicknessCoverLayerPartlySubmerged() + { + const double expectedResult = 166.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 12; + soilVolumeMassCalculator.PhreaticLevel = -2; + soilVolumeMassCalculator.SurfaceLevel = 0; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithoutExceedingMinimumThicknessCoverLayerAndLowSurfaceLevelFullySubmerged() + { + const double expectedResult = 99.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 5; + soilVolumeMassCalculator.PhreaticLevel = 0; + soilVolumeMassCalculator.SurfaceLevel = -1.5; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithoutExceedingMinimumThicknessCoverLayerAndLowSurfaceLevelPartlySubmerged() + { + const double expectedResult = 103.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 5; + soilVolumeMassCalculator.PhreaticLevel = -2; + soilVolumeMassCalculator.SurfaceLevel = -1.5; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithoutExceedingMinimumThicknessCoverLayerFullySubmerged() + { + const double expectedResult = 114.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.SurfaceLevel = 0; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + public void CalculateWithoutExceedingMinimumThicknessCoverLayerPartlySubmerged() + { + const double expectedResult = 130.000; + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.PhreaticLevel = -2; + soilVolumeMassCalculator.SurfaceLevel = 0; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -10; + soilVolumeMassCalculator.VolumicWeightOfWater = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + var result = soilVolumeMassCalculator.CalculateEffectiveStress(); + Assert.AreEqual(expectedResult, result, 0.001); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionIfSoilProfileHasNoLayers() + { + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.SurfaceLevel = 2; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -1; + soilVolumeMassCalculator.SoilProfile = new PipingProfile(); + soilVolumeMassCalculator.CalculateEffectiveStress(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionIfSoilProfileNotAssignedInSoilVolumeMassCalculator() + { + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.SurfaceLevel = 2; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -1; + soilVolumeMassCalculator.CalculateEffectiveStress(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionIfSurfaceLevelNotInsideProfile() + { + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.PhreaticLevel = 0; + soilVolumeMassCalculator.SurfaceLevel = 2; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = -1; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + soilVolumeMassCalculator.CalculateEffectiveStress(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionIfTopLayerToBeEvaluatedNotInsideProfile() + { + var soilVolumeMassCalculator = new SoilVolumicMassCalculator(); + soilVolumeMassCalculator.MinimumThicknessCoverLayer = 10; + soilVolumeMassCalculator.PhreaticLevel = 0; + soilVolumeMassCalculator.SurfaceLevel = 0; + soilVolumeMassCalculator.TopOfLayerToBeEvaluated = 10; + soilVolumeMassCalculator.SoilProfile = FactoryForSoilProfileTests.CreateTestProfile(); + soilVolumeMassCalculator.CalculateEffectiveStress(); + } + + } +} \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/UpliftLocationAndResult.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/UpliftLocationDeterminatorTests.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/PipingConstants.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingProfile.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingProfile.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingProfile.cs (revision 328) @@ -0,0 +1,218 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Deltares.DamUplift.Properties; + +namespace Deltares.DamUplift +{ + /// + /// PipingProfile Exception class + /// + public class PipingProfileException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public PipingProfileException(string message) : base(message) { } + } + + /// + /// Class to hold profiles (1D) for the Piping kernel + /// + public class PipingProfile + { + private List layers = new List(); + + /// + /// Gets or sets the name. + /// + /// + /// The name. + /// + public string Name { get; set; } + + /// + /// Gets or sets the layers. + /// + /// + /// The layers. + /// + public List Layers + { + get + { + return layers; + } + set + { + layers = value; + } + } + + /// + /// Assigns the specified profile. + /// + /// The profile. + public void Assign(PipingProfile profile) + { + BottomLevel = profile.BottomLevel; + foreach (var pipingLayer in profile.Layers) + { + var layer = new PipingLayer(); + Layers.Add(layer); + layer.Assign(pipingLayer); + } + } + + /// + /// Gets the top level of the profile. + /// + public virtual double TopLevel + { + get + { + return layers.Any() ? layers.First().TopLevel : BottomLevel; + } + } + + /// + /// Gets or sets the bottom level of the profile. + /// + public double BottomLevel { get; set; } + + /// + /// Gets the top aquifer layer. + /// + /// + /// The top aquifer layer. + /// + public PipingLayer TopAquiferLayer + { + get + { + IList sortedLayers = Layers.OrderByDescending(l => l.TopLevel).ToList(); + return sortedLayers.FirstOrDefault(layer => layer.IsAquifer); + } + } + + /// + /// Gets the bottom aquifer layer. + /// + /// + /// The bottom aquifer layer. + /// + public PipingLayer BottomAquiferLayer + { + get + { + IList sortedLayers = Layers.OrderBy(l => l.TopLevel).ToList(); + PipingLayer aquiferLayer = null; + var aquiferIndex = -1; + + // Search deepest aquifer layer + for (var layerIndex = 0; layerIndex < sortedLayers.Count; layerIndex++) + { + var layer = sortedLayers[layerIndex]; + if (layer.IsAquifer) + { + aquiferIndex = layerIndex; + aquiferLayer = layer; + break; + } + } + + // aquifer may consists of more then 1 connected (aquifer) layers + // Search all layers above the first found aquifer to find top aquifer layer + if (aquiferIndex >= 0) + { + for (var layerIndex = aquiferIndex + 1; layerIndex < sortedLayers.Count; layerIndex++) + { + var layer = sortedLayers[layerIndex]; + if (layer.IsAquifer) + { + aquiferLayer = layer; + } + else + { + break; + } + } + } + return aquiferLayer; + } + } + + /// + /// Gets (calculates) the height for a given layer in the profile + /// + /// The layer to process + /// The height + public double GetLayerHeight(PipingLayer soilLayer) + { + return GetLayerHeight(layers.IndexOf(soilLayer)); + } + + internal void Validate() + { + if (layers.Count == 0) + { + var message = Resources.PipingProfile_Validate_ProfileHasNoLayers; + throw new PipingProfileException(message); + } + if (!AreLayersOrderedTopToBottom()) + { + var message = Resources.PipingProfile_Validate_LayersNotOrderedFromTopToBottom; + throw new PipingProfileException(message); + } + if (!IsBottomLevelDeepEnough()) + { + var format = Resources.PipingProfile_Validate_BottomLevelNotDeepEnough; + var topLevel = layers[layers.Count - 1].TopLevel; + var message = string.Format(format, BottomLevel, PipingConstants.MinimumLayerThickness, topLevel); + throw new PipingProfileException(message); + } + } + + /// + /// Gets the height of the layer. + /// + /// Index of the layer. + /// The height + private double GetLayerHeight(int layerIndex) + { + var soilLayer = Layers[layerIndex]; + var soilLayerBelow = (layerIndex < layers.Count - 1) ? layers[layerIndex + 1] : null; + var levelBelow = (soilLayerBelow != null) ? soilLayerBelow.TopLevel : BottomLevel; + return soilLayer.TopLevel - levelBelow; + } + + /// + /// Determines whether the bottom level is deep. + /// + /// + /// true when it is deep enough else false. + /// + private bool IsBottomLevelDeepEnough() + { + return layers[layers.Count - 1].TopLevel - BottomLevel >= PipingConstants.MinimumLayerThickness; + } + + /// + /// Determines whether the layers are ordered top to bottom. + /// + /// + /// true if they are else false. + /// + private bool AreLayersOrderedTopToBottom() + { + for (int i = 1; i < layers.Count; i++) + { + if (layers[i-1].TopLevel - layers[i].TopLevel < PipingConstants.MinimumLayerThickness) + return false; + } + return true; + } + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.resx =================================================================== diff -u -r327 -r328 --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.resx (.../Resources.resx) (revision 327) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.resx (.../Resources.resx) (revision 328) @@ -1,110 +1,129 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CharacteristicPointXNotAscending + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The profile has no layers, it must have at least 1 layer. - - DitchIncorrect + + The layers are not ordered from top to bottom. - - PointXNotAscending + + The bottomlevel ({0}) of the profile is not deep enough. It must be at least {1} m below the toplevel of the deepest layer ({2}). \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/PipingCharacteristicPointType.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.nl-NL.resx =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.nl-NL.resx (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.nl-NL.resx (revision 328) @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + De onderkant({0}) van het ondergrondprofiel is niet laag genoeg. Het moet tenminste {1} m onder de bovenkant van de diepste laag ({2}) liggen. + + + De lagen zijn niet geordend van boven naar beneden. + + + Het ondergrondprofiel heeft geen lagen, er moet tenminste 1 laag zijn. + + \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingConstants.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingConstants.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/PipingConstants.cs (revision 328) @@ -0,0 +1,20 @@ +namespace Deltares.DamUplift +{ + /// + /// Class holding all constant default values specific to the WTI Piping kernel + /// + public class PipingConstants + { +// public const double GammaSubParticles = 16.5; +// public const double BeddingAngleSellmeijerOriginal = 41.0; +// public const double BeddingAngleSellmeijerRevised = 37.0; +// public const double WhitesDragCoefficient = 0.25; +// public const double D70Mean = 2.08e-4; +// public const double RExitDefault = 1.00; +// public const double RToeDefault = 1.00; +// public const double RcDefault = 0.3; +// public const double Accuracy = 0.0005; + public const double MinimumLayerThickness = 0.001; +// public const double Epsilon = 1e-8; + } +} \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/UpliftCalculator.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/UpliftCalculator.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/UpliftCalculator.cs (revision 328) @@ -0,0 +1,172 @@ +using System; +using System.Runtime.Serialization; + +namespace Deltares.DamUplift +{ + [Serializable] + public class UpliftCalculatorException : 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 UpliftCalculatorException() {} + public UpliftCalculatorException(string message) : base(message) {} + public UpliftCalculatorException(string message, ApplicationException inner) : base(message, inner) {} + + protected UpliftCalculatorException( + SerializationInfo info, + StreamingContext context) + : base(info, context) {} + } + + public class UpliftCalculator + { + public UpliftCalculator() + { + VolumicWeightOfWater = Physics.UnitWeightOfwater; + UnitWeightSoilEmbankment = null; + IsUseOvenDryUnitWeight = false; + } + + public bool IsUseOvenDryUnitWeight { get; set; } + public double VolumicWeightOfWater { get; set; } + public PipingProfile SoilProfile { get; set; } + public double TopOfLayerToBeEvaluated { get; set; } + public double SurfaceLevel { get; set; } + public double PhreaticLevel { get; set; } +// public double UpLiftTopLevel { get; set; } + public double? UnitWeightSoilEmbankment { get; set; } + + /// + /// + /// + /// + /// + public double CalculateUpliftFactor(double headOfPLLine) + { + ThrowWhenSoilProfileIsNull(); + + var massCalculator = CreateSoilVolumeMassCalculator(); + + massCalculator.IsUseOvenDryUnitWeight = IsUseOvenDryUnitWeight; + var mass = massCalculator.CalculateTotalMass(); + var height = headOfPLLine - TopOfLayerToBeEvaluated; + var phreaticPressure = VolumicWeightOfWater*height; + + if (phreaticPressure > 0) + { + return mass/phreaticPressure; + } + else + { + return double.MaxValue; + } + } + + /// + /// Calculate soil extra height to be added to obtain the specified upliftFactor with a given head of PLline + /// + /// + /// + /// + /// Required extra height + public double CalculateExtraHeight(double headOfPLLine, double upliftFactor) + { + ThrowWhenSoilProfileIsNull(); + + var massCalculator = CreateSoilVolumeMassCalculator(); + + var mass = massCalculator.CalculateTotalMass(); + var toplevel = Math.Min(SurfaceLevel, TopOfLayerToBeEvaluated); + var height = headOfPLLine - toplevel; + var phreaticPressure = VolumicWeightOfWater*height; + + double requiredExtraMass = upliftFactor*phreaticPressure - mass; + + double unitWeightSoil = SoilProfile.Layers[0].AbovePhreaticLevel; + if (UnitWeightSoilEmbankment != null) + { + unitWeightSoil = UnitWeightSoilEmbankment.Value; + } + + if (requiredExtraMass > 0) + { + return requiredExtraMass/unitWeightSoil; + } + else + { + return 0.0; + } + } + + /// + /// + /// + /// + /// + public double CalculateHeadOfPLLine(double upliftFactor) + { + ThrowWhenSoilProfileIsNull(); + + var massCalculator = CreateSoilVolumeMassCalculator(); + massCalculator.IsUseOvenDryUnitWeight = IsUseOvenDryUnitWeight; + + var massSoils = massCalculator.CalculateTotalMass(); + var massWater = massSoils/(upliftFactor*VolumicWeightOfWater); + return massWater + TopOfLayerToBeEvaluated; + } + + /// + /// + /// + /// + private SoilVolumicMassCalculator CreateSoilVolumeMassCalculator() + { + PipingProfile updatedSoilProfile = AddTopLayerIfSurfaceLevelHigherThenToplevelSoilProfile(SoilProfile); + return new SoilVolumicMassCalculator + { + PhreaticLevel = PhreaticLevel, + SoilProfile = updatedSoilProfile, + TopOfLayerToBeEvaluated = TopOfLayerToBeEvaluated, + SurfaceLevel = SurfaceLevel, + VolumicWeightOfWater = VolumicWeightOfWater + }; + } + + /// + /// Adds an extra top layer if surface level is higher then toplevel soil profile. + /// + /// The updated soil profile. + /// + private PipingProfile AddTopLayerIfSurfaceLevelHigherThenToplevelSoilProfile(PipingProfile updatedSoilProfile) + { + if ((SurfaceLevel > SoilProfile.TopLevel) && (UnitWeightSoilEmbankment != null)) + { + updatedSoilProfile = new PipingProfile(); + updatedSoilProfile.Assign(SoilProfile); + updatedSoilProfile.Layers.Insert(0, new PipingLayer() + { + AbovePhreaticLevel = UnitWeightSoilEmbankment.Value, + BelowPhreaticLevel = UnitWeightSoilEmbankment.Value, + TopLevel = SurfaceLevel + }); + } + return updatedSoilProfile; + } + + /// + /// Check precondition + /// + private void ThrowWhenSoilProfileIsNull() + { + if (SoilProfile == null) + { + throw new UpliftCalculatorException("The soilprofile is not defined"); + } + } + } +} \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Helper.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/UpliftLocationDeterminator.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorTest.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorTest.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/SoilVolumeMassCalculatorTest.cs (revision 328) @@ -0,0 +1,162 @@ +using Deltares.DamUplift; +using NUnit.Framework; + +namespace Deltares.DamUpliftTests +{ + [TestFixture] + public class SoilVolumeMassCalculatorTest + { + [Test] + public void CalculateForComplexProfileWithPhreaticLineInProfile1() + { + const double cTolerance = 0.001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateComplexProfile(); + calculator.SurfaceLevel = 0.21; + calculator.PhreaticLevel = -0.98; + calculator.TopOfLayerToBeEvaluated = -5.0; + // See spreadsheet "DAM Volumic weight test" + Assert.AreEqual(76.358, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + public void CalculateForComplexProfileWithPhreaticLineInProfile2() + { + const double cTolerance = 0.001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateComplexProfile(); + calculator.SurfaceLevel = 10.0; + calculator.PhreaticLevel = -1.8; + calculator.TopOfLayerToBeEvaluated = -5.0; + // See spreadsheet "DAM Volumic weight test" + Assert.AreEqual(230.22, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + public void CalculateForSimpleProfileWithPhreaticLineAboveProfile() + { + const double cTolerance = 0.0001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = 10.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + // All wet soil + // wet 15 m x 16 kN/m3 = 240 + // water above surface 5 m x 10.0 kN/m3 = 50 + // Total: 240 + 50 = 290 + Assert.AreEqual(290.0, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + public void CalculateForSimpleProfileWithPhreaticLineBelowProfile() + { + const double cTolerance = 0.0001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -20.0; + calculator.TopOfLayerToBeEvaluated = -10; + // All dry soil + // dry 15 m x 12 kN/m3 = 180 + Assert.AreEqual(180.0, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + public void CalculateForSimpleProfileWithPhreaticLineInProfile() + { + const double cTolerance = 0.0001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + // Phreatic level in profile + // dry 6 m x 12 kN/m3 = 72 + // wet 9 m x 16 kN/m3 = 144 + // Total: 72 + 144 = 216 + Assert.AreEqual(216.0, calculator.CalculateTotalMass(), cTolerance); + } + + /// + /// Same as above test, but now the oven dry unit weight has to be used + /// + [Test] + public void CalculateForSimpleProfileWithPhreaticLineInProfileAndDryOption() + { + const double cTolerance = 0.0001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + foreach (var layer in calculator.SoilProfile.Layers) + { + layer.DryUnitWeight = layer.AbovePhreaticLevel; + layer.AbovePhreaticLevel = layer.AbovePhreaticLevel + 1.0; + } + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.IsUseOvenDryUnitWeight = true; + // Phreatic level in profile + // dry 6 m x 12 kN/m3 = 72 + // wet 9 m x 16 kN/m3 = 144 + // Total: 72 + 144 = 216 + Assert.AreEqual(216.0, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + public void CalculateForTwoLayerProfileWithPhreaticLineOnBoundary() + { + const double cTolerance = 0.0001; + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateTwoLayerProfile(); + calculator.SurfaceLevel = 10.0; + calculator.PhreaticLevel = 2.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + // All wet soil + // dry 8 m x 10 kN/m3 = 80 + // wet 12 m x 22 kN/m3 = 264 + // Total: 80 + 264 = 344 + Assert.AreEqual(344.0, calculator.CalculateTotalMass(), cTolerance); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionWhenSoilProfileParameterIsMissing() + { + var calculator = new SoilVolumicMassCalculator(); + calculator.CalculateTotalMass(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionWhenSurfaceLevelIsAboveProfile() + { + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 15.0; + calculator.CalculateTotalMass(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionWhenSurfaceLevelIsBelowProfile() + { + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = -100.0; + calculator.CalculateTotalMass(); + } + + [Test] + [ExpectedException(typeof(SoilVolumicMassCalculatorException))] + public void ThrowsExceptionWhenTopLevelToBeValuatedIsBelowProfile() + { + var calculator = new SoilVolumicMassCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.TopOfLayerToBeEvaluated = -100.0; + calculator.CalculateTotalMass(); + } + } +} \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/FactoryForSoilProfileTests.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/FactoryForSoilProfileTests.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/FactoryForSoilProfileTests.cs (revision 328) @@ -0,0 +1,170 @@ +using Deltares.DamUplift; + +namespace Deltares.DamUpliftTests +{ + public class FactoryForSoilProfileTests + { + + public static PipingProfile CreateSimpleProfile() + { + PipingProfile soilProfile1D = new PipingProfile(); + PipingLayer soilLayer1D = new PipingLayer + { + TopLevel = 10.0, + Name = "Clay", + BelowPhreaticLevel = 16.0, + AbovePhreaticLevel = 12.0, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D); + soilProfile1D.BottomLevel = -20.0; + return soilProfile1D; + } + + public static PipingProfile CreateTwoLayerProfile() + { + PipingProfile soilProfile1D = new PipingProfile(); + + PipingLayer soilLayer1D1 = new PipingLayer + { + TopLevel = 10.0, + Name = "HW-OBO", + BelowPhreaticLevel = 12.0, + AbovePhreaticLevel = 10.0, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D1); + + PipingLayer soilLayer1D2 = new PipingLayer + { + TopLevel = 2.0, + Name = "Alg-zand (0-30)", + BelowPhreaticLevel = 22.0, + AbovePhreaticLevel = 22.0, + DryUnitWeight = 0.01, + IsAquifer = true + }; + soilProfile1D.Layers.Add(soilLayer1D2); + + soilProfile1D.BottomLevel = -10.0; + return soilProfile1D; + } + + public static PipingProfile CreateComplexProfile() + { + PipingProfile soilProfile1D = new PipingProfile(); + + PipingLayer soilLayer1D1 = new PipingLayer + { + TopLevel = 10.0, + Name = "HW-OBO", + BelowPhreaticLevel = 16.8, + AbovePhreaticLevel = 15.8, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D1); + + PipingLayer soilLayer1D2 = new PipingLayer + { + TopLevel = -0.6, + Name = "HW-DUN", + BelowPhreaticLevel = 16.8, + AbovePhreaticLevel = 15.8, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D2); + + PipingLayer soilLayer1D3 = new PipingLayer + { + TopLevel = -1.8, + Name = "HW-DUOzand", + BelowPhreaticLevel = 18.7, + AbovePhreaticLevel = 17.7, + DryUnitWeight = 0.01, + IsAquifer = true + }; + soilProfile1D.Layers.Add(soilLayer1D3); + + PipingLayer soilLayer1D4 = new PipingLayer + { + TopLevel = -2.8, + Name = "HW-HVN", + BelowPhreaticLevel = 11.4, + AbovePhreaticLevel = 10.4, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D4); + + PipingLayer soilLayer1D5 = new PipingLayer + { + TopLevel = -4.0, + Name = "HW-HVN", + BelowPhreaticLevel = 11.4, + AbovePhreaticLevel = 10.4, + DryUnitWeight = 0.01, + IsAquifer = false + }; + soilProfile1D.Layers.Add(soilLayer1D5); + + PipingLayer soilLayer1D6 = new PipingLayer + { + TopLevel = -5.0, + Name = "Alg-zand (0-30)", + BelowPhreaticLevel = 19.0, + AbovePhreaticLevel = 18.0, + DryUnitWeight = 0.01, + IsAquifer = true + }; + soilProfile1D.Layers.Add(soilLayer1D6); + + soilProfile1D.BottomLevel = -10.0; + return soilProfile1D; + } + + public static PipingProfile CreateTestProfile() + { + + PipingProfile soilProfile = new PipingProfile(); + soilProfile.Name = "TestProf"; + + PipingLayer layer1 = new PipingLayer + { + Name = "klei", + TopLevel = 0, + AbovePhreaticLevel = 18, + BelowPhreaticLevel = 20 + }; + soilProfile.Layers.Add(layer1); + + PipingLayer layer2 = new PipingLayer + { + Name = "klei2", + TopLevel = -3, + AbovePhreaticLevel = 20, + BelowPhreaticLevel = 22 + }; + soilProfile.Layers.Add(layer2); + + PipingLayer layer3 = new PipingLayer + { + Name = "klei2", + TopLevel = -10, + AbovePhreaticLevel = 20, + BelowPhreaticLevel = 22 + }; + soilProfile.Layers.Add(layer3); + soilProfile.BottomLevel = -30.0; + + return soilProfile; + } + + + + + } +} \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/UpliftCalculatorTest.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/UpliftCalculatorTest.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/UpliftCalculatorTest.cs (revision 328) @@ -0,0 +1,145 @@ +using Deltares.DamUplift; +using NUnit.Framework; + +namespace Deltares.DamUpliftTests +{ + [TestFixture] + public class UpliftCalculatorTest + { + [Test] + public void CalculateExtraHeightForSimpleProfileWithPhreaticLineInProfile() + { + const double cTolerance = 0.0001; + var calculator = new UpliftCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + + // 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 + // UpliftFactor = 1.2 + // Phreatic pressure + // 20 m x 10 kN/m3 = 200 + // Mass of Watervolume = 200 + // mass of soil = uplift factor * Mass of watervolume = 1.2 * 200 = 240 + // Extra mass soil = 240 - 216 = 24 + // Extra Height = Extra mass soil / (unit weight soil for raising) = 24 / 12 = 2.0 + calculator.UnitWeightSoilEmbankment = null; + Assert.AreEqual(2.0, calculator.CalculateExtraHeight(10.0, 1.2), cTolerance); + + // Extra Height = Extra mass soil / (unit weight soil for raising) = 24 / 8 = 3.0 + calculator.UnitWeightSoilEmbankment = 8.0; + Assert.AreEqual(3.0, calculator.CalculateExtraHeight(10.0, 1.2), cTolerance); + } + + [Test] + public void CalculateHeadOfPlLineForSimpleProfileWithPhreaticLineInProfile() + { + const double cTolerance = 0.0001; + var calculator = new UpliftCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + + // 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 + // UpliftFactor = 1.0 + // Mass of Watervolume = mass of soil / uplift factor = 216 / 1.0 = 216 + // Head = mass of watervolume / volumic weight water - top of layer = 216 / 10 - (-10) = 21.6 - (-10.0) = 11.6 m + Assert.AreEqual(11.6, calculator.CalculateHeadOfPLLine(1.0), cTolerance); + + double upliftFactor = calculator.CalculateUpliftFactor(11.6); + Assert.AreEqual(1.0, upliftFactor, cTolerance); + + calculator.IsUseOvenDryUnitWeight = true; + double head = calculator.CalculateHeadOfPLLine(1.0); + double upliftFactorOvenDry = calculator.CalculateUpliftFactor(head); + Assert.AreEqual(1.0, upliftFactorOvenDry, cTolerance); + } + + [Test] + public void CalculateUpliftFactorForSimpleProfileWithPhreaticLineInProfile() + { + const double cTolerance = 0.0001; + var calculator = new UpliftCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + + // 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 + Assert.AreEqual(1.08, calculator.CalculateUpliftFactor(10.0), cTolerance); + } + + /// + /// Same as above test, but now the oven dry unit weight has to be used + /// + [Test] + public void CalculateUpliftFactorForSimpleProfileWithPhreaticLineInProfileAndDryOption() + { + const double cTolerance = 0.0001; + var calculator = new UpliftCalculator(); + calculator.SoilProfile = FactoryForSoilProfileTests.CreateSimpleProfile(); + foreach (var layer in calculator.SoilProfile.Layers) + { + layer.DryUnitWeight = layer.AbovePhreaticLevel; + layer.AbovePhreaticLevel = layer.AbovePhreaticLevel + 1.0; + } + calculator.SurfaceLevel = 5.0; + calculator.PhreaticLevel = -1.0; + calculator.TopOfLayerToBeEvaluated = -10; + calculator.VolumicWeightOfWater = 10.0; + calculator.IsUseOvenDryUnitWeight = true; + + // 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 + Assert.AreEqual(1.08, calculator.CalculateUpliftFactor(10.0), cTolerance); + } + + [Test] + [ExpectedException(typeof(UpliftCalculatorException))] + public void ThrowsExceptionWhenSoilProfileParameterIsMissingInCalculateHeadOfPlLine() + { + var calculator = new UpliftCalculator(); + calculator.CalculateHeadOfPLLine(0.0); + } + + [Test] + [ExpectedException(typeof(UpliftCalculatorException))] + public void ThrowsExceptionWhenSoilProfileParameterIsMissingInCalculateUpliftFactor() + { + var calculator = new UpliftCalculator(); + calculator.CalculateUpliftFactor(0.0); + } + + [TestFixtureSetUp] + public void FixtureSetup() {} + + [TestFixtureTearDown] + public void FixtureTearDown() {} + } +} \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/PipingSurfaceLine.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.Designer.cs =================================================================== diff -u -r327 -r328 --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 327) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Properties/Resources.Designer.cs (.../Resources.Designer.cs) (revision 328) @@ -61,29 +61,29 @@ } /// - /// Looks up a localized string similar to CharacteristicPointXNotAscending. + /// Looks up a localized string similar to The bottomlevel ({0}) of the profile is not deep enough. It must be at least {1} m below the toplevel of the deepest layer ({2}).. /// - internal static string PipingSurfaceLine_Validate_CharacteristicPointXNotAscending { + internal static string PipingProfile_Validate_BottomLevelNotDeepEnough { get { - return ResourceManager.GetString("PipingSurfaceLine_Validate_CharacteristicPointXNotAscending", resourceCulture); + return ResourceManager.GetString("PipingProfile_Validate_BottomLevelNotDeepEnough", resourceCulture); } } /// - /// Looks up a localized string similar to DitchIncorrect. + /// Looks up a localized string similar to The layers are not ordered from top to bottom.. /// - internal static string PipingSurfaceLine_Validate_DitchIncorrect { + internal static string PipingProfile_Validate_LayersNotOrderedFromTopToBottom { get { - return ResourceManager.GetString("PipingSurfaceLine_Validate_DitchIncorrect", resourceCulture); + return ResourceManager.GetString("PipingProfile_Validate_LayersNotOrderedFromTopToBottom", resourceCulture); } } /// - /// Looks up a localized string similar to PointXNotAscending. + /// Looks up a localized string similar to The profile has no layers, it must have at least 1 layer.. /// - internal static string PipingSurfaceLine_Validate_PointXNotAscending { + internal static string PipingProfile_Validate_ProfileHasNoLayers { get { - return ResourceManager.GetString("PipingSurfaceLine_Validate_PointXNotAscending", resourceCulture); + return ResourceManager.GetString("PipingProfile_Validate_ProfileHasNoLayers", resourceCulture); } } } Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Physics.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Physics.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Physics.cs (revision 328) @@ -0,0 +1,27 @@ +namespace Deltares.DamUplift +{ + /// + /// Physics class with constants that can be redefined + /// + public class Physics + { + /// + /// The gravity constant in m/s2 + /// + public const double GravityConstant = 9.81; + + /// + /// The water density in kg/m3 For temperature = 4 degree Celcius + /// + /// + public const double WaterDensity = 1000; + + /// + /// Gets the unit weight of water in kN/m3. + /// + /// + /// The unit weight of water. + /// + public const double UnitWeightOfwater = GravityConstant*WaterDensity*0.001; + } +} \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/PipingPoint.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Deltares.DamUplift.csproj =================================================================== diff -u -r327 -r328 --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Deltares.DamUplift.csproj (.../Deltares.DamUplift.csproj) (revision 327) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Deltares.DamUplift.csproj (.../Deltares.DamUplift.csproj) (revision 328) @@ -44,22 +44,18 @@ Properties\GlobalAssemblyInfo.cs - - - - - - - - - - + + + + + True True Resources.resx - + + @@ -69,6 +65,7 @@ ResXFileCodeGenerator Resources.Designer.cs + Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/Deltares.DamUpliftTests.csproj =================================================================== diff -u -r327 -r328 --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/Deltares.DamUpliftTests.csproj (.../Deltares.DamUpliftTests.csproj) (revision 327) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamUpliftTests/Deltares.DamUpliftTests.csproj (.../Deltares.DamUpliftTests.csproj) (revision 328) @@ -45,8 +45,11 @@ - + + + + Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/SoilVolumicMassCalculator.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/SoilVolumicMassCalculator.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/SoilVolumicMassCalculator.cs (revision 328) @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Deltares.DamUplift.Geo; + +namespace Deltares.DamUplift +{ + /// + /// Exception class for SoilVolumicMassCalculator + /// + public class SoilVolumicMassCalculatorException : Exception + { + public SoilVolumicMassCalculatorException(string message) : base(message) {} + } + + /// + /// Calculation class to determine weight of the soil between TopOfLayerToBeEvaluated and SurfaceLevel + /// + public class SoilVolumicMassCalculator + { + private const double CTolerance = 0.00000001; + + /// + /// Initializes a new instance of the class. + /// + public SoilVolumicMassCalculator() + { + VolumicWeightOfWater = Physics.UnitWeightOfwater; + IsUseOvenDryUnitWeight = false; + } + + public bool IsUseOvenDryUnitWeight { get; set; } + public double VolumicWeightOfWater { get; set; } + public double PhreaticLevel { get; set; } + public double SurfaceLevel { get; set; } + public double TopOfLayerToBeEvaluated { get; set; } + public PipingProfile SoilProfile { get; set; } + public double MinimumThicknessCoverLayer { get; set; } + + /// + /// Calculates the total weight of the soil between SurfaceLevel and TopOfLayerToBeEvaluated, + /// taking into account whether the soil is submerged or not + /// + /// total mass + public double CalculateTotalMass() + { + ThrowWhenSoilProfileIsNull(); + ThrowWhenSurfaceLevelNotInsideProfile(); + ThrowWhenTopLayerToBeEvaluatedNotInsideProfile(); + + var weight = SoilProfile.Layers + .Where(layer => layer.TopLevel > TopOfLayerToBeEvaluated) + .Sum(layer => GetWeight(layer)); + + // Is there water above the soil layer? If so add the volumic weight + // of water to the soil mass + if (PhreaticLevel > SurfaceLevel) + { + var height = PhreaticLevel - SurfaceLevel; + weight += height*VolumicWeightOfWater; + } + + return weight; + } + + /// + /// Calculates the effective stress of the soil between TopOfLayerToBeEvaluated and SurfaceLevel + /// + /// + public double CalculateEffectiveStress() + { + ThrowWhenSoilProfileIsNull(); + ThrowWhenSoilProfileHasNoLayers(); + ThrowWhenSurfaceLevelNotInsideProfile(); + ThrowWhenTopLayerToBeEvaluatedNotInsideProfile(); + var involvedLayers = SoilProfile.Layers.Where(layer => layer.TopLevel > TopOfLayerToBeEvaluated); + var weight = involvedLayers.Sum(layer => GetEffectiveStress(layer)); + // Check to see if thickness of all involved layers is is smaller than the given minimum thickness. If so, + // then add the weight of the "missing" soil(s) by multipliying the difference by the weight of the toplevel. + // Using the weight of the toplevel might be theoreticaly incorrect but this is a good and simple approach + // which has been accorded by Erik Vastenburg. + var thicknessInvolvedLayers = involvedLayers.Sum(layer => GetLayerHeight(layer)); + if (thicknessInvolvedLayers < MinimumThicknessCoverLayer) + { + PipingLayer layer = involvedLayers.First(); + double bottomLevel = Math.Min(involvedLayers.First().TopLevel, SurfaceLevel); + double height = MinimumThicknessCoverLayer - thicknessInvolvedLayers; + double topLevel = bottomLevel + height; + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + weight += GetSoilUnitWeightDry(layer).Value*factorDry*height + (layer.BelowPhreaticLevel - VolumicWeightOfWater)*factorWet*height; + } + return weight; + } + + /// + /// Validates the input + /// + /// a filled list when errors are found else an empty list + public List Validate() + { + var errors = new List(); + if (SoilProfile == null) + { + errors.Add("The soilprofile is not defined"); + return errors; + } + if ((SurfaceLevel - SoilProfile.TopLevel) > CTolerance || (SurfaceLevel - SoilProfile.BottomLevel) < -CTolerance) + { + errors.Add("Surfacelevel is not inside soil profile"); + } + if ((TopOfLayerToBeEvaluated - SoilProfile.TopLevel) > CTolerance || + (TopOfLayerToBeEvaluated - SoilProfile.BottomLevel) < -CTolerance) + { + errors.Add("The top layer to be evaluated is not inside the soil profile"); + } + return errors; + } + + /// + /// Gets the contribution of the weight of a layer, taking in account the phreatic level + /// + /// The layer. + /// + private double GetWeight(PipingLayer layer) + { + double topLevel, bottomLevel; + double height = GetLayerHeight(layer, out topLevel, out bottomLevel); + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + + return GetSoilUnitWeightDry(layer).Value*factorDry*height + layer.BelowPhreaticLevel*factorWet*height; + } + + /// + /// Gets the contribution to the effective stress of a layer, taking in account the phreatic level + /// + /// The layer. + /// + private double GetEffectiveStress(PipingLayer layer) + { + double topLevel, bottomLevel; + double height = GetLayerHeight(layer, out topLevel, out bottomLevel); + double factorWet; + double factorDry; + DetermineHeightAndDryAndWetFraction(topLevel, bottomLevel, out factorWet, out factorDry); + + // If above phreatic line use the dry weight of the soil + // if below phreatic line use the effective submerged weight (gamma_sat - gamma_water) + return GetSoilUnitWeightDry(layer).Value*factorDry*height + (layer.BelowPhreaticLevel - VolumicWeightOfWater)*factorWet*height; + } + + /// + /// Determines the height and dry and wet fraction of the layer. + /// + /// The layer. + /// The height. + /// The factor wet. + /// The factor dry. + private void DetermineHeightAndDryAndWetFraction(double topLevel, double bottomLevel, out double factorWet, out double factorDry) + { + double height = topLevel - bottomLevel; + factorWet = 0.0; + factorDry = 0.0; + + if (topLevel < PhreaticLevel || topLevel.AlmostEquals(PhreaticLevel)) + { + factorWet = 1.0; + } + else if (bottomLevel > PhreaticLevel || bottomLevel.AlmostEquals(PhreaticLevel)) + { + factorDry = 1.0; + } + else + { + var pLevel = (topLevel - PhreaticLevel); + factorDry = pLevel.AlmostEquals(0.0) ? 0.0 : pLevel/height; + factorWet = 1.0 - factorDry; + } + } + + /// + /// Calculates the height of a layer taking into account the surfacelevel and the TopOfLayerToBeEvaluated + /// + /// + /// + private double GetLayerHeight(PipingLayer layer) + { + var layerHeight = SoilProfile.GetLayerHeight(layer); + double topLevel; + if (layer.TopLevel > SurfaceLevel) + { + topLevel = SurfaceLevel; + layerHeight = Math.Max(layerHeight - (layer.TopLevel - SurfaceLevel), 0); + } + else + { + topLevel = layer.TopLevel; + } + + double bottomLevel = topLevel - layerHeight; + bottomLevel = bottomLevel > TopOfLayerToBeEvaluated ? bottomLevel : TopOfLayerToBeEvaluated; + return topLevel - bottomLevel; + } + + /// + /// Gets the dry unit weight of the layer. + /// + /// The layer. + /// + private double? GetSoilUnitWeightDry(PipingLayer layer) + { + if (IsUseOvenDryUnitWeight) + { + return layer.DryUnitWeight; + } + else + { + return layer.AbovePhreaticLevel; + } + } + + /// + /// Gets the height of the layer. + /// + /// The layer. + /// The top level. + /// The bottom level. + /// + private double GetLayerHeight(PipingLayer layer, out double topLevel, out double bottomLevel) + { + var layerHeight = SoilProfile.GetLayerHeight(layer); + if (layer.TopLevel > SurfaceLevel) + { + topLevel = SurfaceLevel; + layerHeight = Math.Max(layerHeight - (layer.TopLevel - SurfaceLevel), 0); + } + else + { + topLevel = layer.TopLevel; + } + + bottomLevel = topLevel - layerHeight; + bottomLevel = bottomLevel > TopOfLayerToBeEvaluated ? bottomLevel : TopOfLayerToBeEvaluated; + return topLevel - bottomLevel; + } + + /// + /// Check precondition: Throws the when soil profile is null. + /// + /// The soilprofile is not defined + private void ThrowWhenSoilProfileIsNull() + { + if (SoilProfile == null) + { + throw new SoilVolumicMassCalculatorException("The soilprofile is not defined"); + } + } + + /// + /// Throws the when soil profile has no layers. + /// + /// The soilprofile is not defined + private void ThrowWhenSoilProfileHasNoLayers() + { + if (SoilProfile.Layers.Count == 0) + { + throw new SoilVolumicMassCalculatorException("The soilprofile has no layers"); + } + } + + /// + /// Check precondition: Throws the when surface level is not inside profile. + /// + /// Surfaceline is not inside soil profile + private void ThrowWhenSurfaceLevelNotInsideProfile() + { + if ((SurfaceLevel - SoilProfile.TopLevel) > CTolerance || + (SurfaceLevel - SoilProfile.BottomLevel) < -CTolerance) + { + throw new SoilVolumicMassCalculatorException("Surfacelevel is not inside soil profile"); + } + } + + /// + /// Check precondition: Throws the when top layer to be evaluated is not inside profile. + /// + /// The top layer to be evaluated is not inside the soil profile + private void ThrowWhenTopLayerToBeEvaluatedNotInsideProfile() + { + if ((TopOfLayerToBeEvaluated - SoilProfile.TopLevel) > CTolerance || (TopOfLayerToBeEvaluated - SoilProfile.BottomLevel) < -CTolerance) + { + throw new SoilVolumicMassCalculatorException("The top layer to be evaluated is not inside the soil profile"); + } + } + } +} \ No newline at end of file Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Point3D.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Point2D.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Vector3D.cs'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 328 refers to a dead (removed) revision in file `dam failuremechanisms/damPiping/trunk/src/Deltares.DamUplift/Geo/Routines2D.cs'. Fisheye: No comparison available. Pass `N' to diff?