// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.Collections.Generic; using System.Linq; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Core.Common.TestUtil; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.Probabilistics; using Ringtoets.MacroStabilityInwards.Data.SoilProfile; using Ringtoets.MacroStabilityInwards.Data.TestUtil.SoilProfile; using Ringtoets.MacroStabilityInwards.Primitives; namespace Ringtoets.MacroStabilityInwards.Data.Test.SoilProfile { [TestFixture] public class MacroStabilityInwardsSoilProfileUnderSurfaceLineFactoryTest { [Test] public void Create_SoilProfileNull_ThrowArgumentNullException() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); // Call TestDelegate test = () => MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(null, surfaceLine); // Assert var exception = Assert.Throws(test); Assert.AreEqual("soilProfile", exception.ParamName); } [Test] public void Create_SurfaceLineNull_ThrowArgumentNullException() { // Setup var soilLayer = new MacroStabilityInwardsSoilLayer1D(3.2); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", 2.0, new[] { soilLayer }); // Call TestDelegate test = () => MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, null); // Assert var exception = Assert.Throws(test); Assert.AreEqual("surfaceLine", exception.ParamName); } [Test] public void Create_SoilProfileNot1DOr2D_ThrowNotSupportedException() { // Setup var mocks = new MockRepository(); var soilProfile = mocks.Stub>(); mocks.ReplayAll(); var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); // Call TestDelegate test = () => MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert var exception = Assert.Throws(test); Assert.AreEqual($"{soilProfile.GetType().Name} is not supported. " + $"Supported types are: {nameof(MacroStabilityInwardsSoilProfile1D)} and " + $"{nameof(MacroStabilityInwardsSoilProfile2D)}.", exception.Message); mocks.VerifyAll(); } [Test] public void SoilProfile1DCreate_SurfaceLineOnTopOrAboveSoilLayer_ReturnsSoilLayerPointsAsRectangle() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 4), new Point3D(0, 0, 3.2), new Point3D(2, 0, 4) }); var soilLayer = new MacroStabilityInwardsSoilLayer1D(3.2); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", 2.0, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(1, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(2, 3.2), new Point2D(2, 2), new Point2D(0, 2), new Point2D(0, 3.2) }, areas.Layers.ElementAt(0).OuterRing); } [Test] public void SoilProfile1DCreate_SurfaceLineBelowSoilLayer_ReturnsEmptyAreasCollection() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 2.0), new Point3D(2, 0, 2.0) }); var soilLayer = new MacroStabilityInwardsSoilLayer1D(3.2); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", 2.0, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert CollectionAssert.IsEmpty(areas.Layers); } [Test] public void SoilProfile1DCreate_SurfaceLineThroughMiddleLayerButNotSplittingIt_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 3.0), new Point3D(1, 0, 2.0), new Point3D(2, 0, 3.0) }); const double bottom = 1.5; const double top = 2.5; var soilLayer = new MacroStabilityInwardsSoilLayer1D(top); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", bottom, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(1, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(0.5, top), new Point2D(1, 2.0), new Point2D(1.5, top), new Point2D(2, top), new Point2D(2, bottom), new Point2D(0, bottom), new Point2D(0, top) }, areas.Layers.ElementAt(0).OuterRing); } [Test] public void SoilProfile1DCreate_SurfaceLineThroughMiddleLayerButNotSplittingItIntersectionOnTopLevel_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 3.0), new Point3D(0.5, 0, 2.5), new Point3D(1, 0, 2.0), new Point3D(1.5, 0, 2.5), new Point3D(2, 0, 3.0) }); const double bottom = 1.5; const double top = 2.5; var soilLayer = new MacroStabilityInwardsSoilLayer1D(top); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", bottom, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(1, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(0.5, top), new Point2D(1, 2.0), new Point2D(1.5, top), new Point2D(2, top), new Point2D(2, bottom), new Point2D(0, bottom), new Point2D(0, top) }, areas.Layers.ElementAt(0).OuterRing); } [Test] public void SoilProfile1DCreate_SurfaceLineStartsBelowLayerTopButAboveBottom_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 2.0), new Point3D(1, 0, 2.0), new Point3D(2, 0, 3.0) }); const double bottom = 1.5; const double top = 2.5; var soilLayer = new MacroStabilityInwardsSoilLayer1D(top); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", bottom, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(1, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(0, 2.0), new Point2D(1, 2.0), new Point2D(1.5, top), new Point2D(2, top), new Point2D(2, bottom), new Point2D(0, bottom) }, areas.Layers.ElementAt(0).OuterRing); } [Test] public void SoilProfile1DCreate_SurfaceLineEndsBelowLayerTopButAboveBottom_ReturnsSoilLayerPointsAsRectangleFollowingSurfaceLine() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 3.0), new Point3D(1, 0, 2.0), new Point3D(2, 0, 2.0) }); const double bottom = 1.5; const double top = 2.5; var soilLayer = new MacroStabilityInwardsSoilLayer1D(top); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", bottom, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(1, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(0.5, top), new Point2D(1, 2.0), new Point2D(2, 2.0), new Point2D(2, bottom), new Point2D(0, bottom), new Point2D(0, top) }, areas.Layers.ElementAt(0).OuterRing); } [Test] public void SoilProfile1DCreate_SurfaceLineZigZagsThroughSoilLayer_ReturnsSoilLayerPointsSplitInMultipleAreas() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 4.0), new Point3D(4, 0, 0.0), new Point3D(8, 0, 4.0) }); const int bottom = 1; const int top = 3; var soilLayer = new MacroStabilityInwardsSoilLayer1D(top); var soilProfile = new MacroStabilityInwardsSoilProfile1D("name", bottom, new[] { soilLayer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine areas = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(soilProfile, surfaceLine); // Assert Assert.AreEqual(2, areas.Layers.Count()); CollectionAssert.AreEqual(new[] { new Point2D(1, top), new Point2D(3, bottom), new Point2D(0, bottom), new Point2D(0, top) }, areas.Layers.ElementAt(0).OuterRing); CollectionAssert.AreEqual(new[] { new Point2D(5, bottom), new Point2D(7, top), new Point2D(8, top), new Point2D(8, bottom) }, areas.Layers.ElementAt(1).OuterRing); } [Test] public void SoilProfile1DCreate_WithData_ReturnsData() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 4.0), new Point3D(4, 0, 0.0), new Point3D(8, 0, 4.0) }); var random = new Random(21); bool usePop = random.NextBoolean(); bool isAquifer = random.NextBoolean(); var shearStrengthModel = random.NextEnumValue(); const double abovePhreaticLevelMean = 10; const double abovePhreaticLevelCoefficientOfVariation = 0.2; const double abovePhreaticLevelShift = 0.1; const double belowPhreaticLevelMean = 9; const double belowPhreaticLevelCoefficientOfVariation = 0.4; const double belowPhreaticLevelShift = 0.2; double cohesionMean = random.NextDouble(); double cohesionCoefficientOfVariation = random.NextDouble(); double frictionAngleMean = random.NextDouble(); double frictionAngleCoefficientOfVariation = random.NextDouble(); double shearStrengthRatioMean = random.NextDouble(); double shearStrengthRatioCoefficientOfVariation = random.NextDouble(); double strengthIncreaseExponentMean = random.NextDouble(); double strengthIncreaseExponentCoefficientOfVariation = random.NextDouble(); double popMean = random.NextDouble(); double popCoefficientOfVariation = random.NextDouble(); const string material = "Clay"; var layer = new MacroStabilityInwardsSoilLayer1D(1) { Data = { UsePop = usePop, IsAquifer = isAquifer, ShearStrengthModel = shearStrengthModel, MaterialName = material, AbovePhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) abovePhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) abovePhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) abovePhreaticLevelShift }, BelowPhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) belowPhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) belowPhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) belowPhreaticLevelShift }, Cohesion = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) cohesionMean, CoefficientOfVariation = (RoundedDouble) cohesionCoefficientOfVariation }, FrictionAngle = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) frictionAngleMean, CoefficientOfVariation = (RoundedDouble) frictionAngleCoefficientOfVariation }, ShearStrengthRatio = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) shearStrengthRatioMean, CoefficientOfVariation = (RoundedDouble) shearStrengthRatioCoefficientOfVariation }, StrengthIncreaseExponent = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) strengthIncreaseExponentMean, CoefficientOfVariation = (RoundedDouble) strengthIncreaseExponentCoefficientOfVariation }, Pop = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) popMean, CoefficientOfVariation = (RoundedDouble) popCoefficientOfVariation } } }; var profile = new MacroStabilityInwardsSoilProfile1D("name", 0, new[] { layer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine profileUnderSurfaceLine = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create( profile, surfaceLine); // Assert Assert.AreSame(layer.Data, profileUnderSurfaceLine.Layers.First().Data); } [Test] public void SoilProfile1DCreate_ValidSoilProfile1D_ReturnsEmptyPreconsolidationStresses() { // Setup var surfaceLine = new MacroStabilityInwardsSurfaceLine(string.Empty); surfaceLine.SetGeometry(new[] { new Point3D(0, 0, 4.0), new Point3D(4, 0, 0.0), new Point3D(8, 0, 4.0) }); var layer = new MacroStabilityInwardsSoilLayer1D(1); var profile = new MacroStabilityInwardsSoilProfile1D("name", 0, new[] { layer }); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine profileUnderSurfaceLine = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create( profile, surfaceLine); // Assert CollectionAssert.IsEmpty(profileUnderSurfaceLine.PreconsolidationStresses); } [Test] public void SoilProfile2DCreate_ProfileWithOuterRingAndHoles_ReturnsEqualGeometries() { // Setup Ring outerRingA = CreateRing(21); Ring outerRingB = CreateRing(12); var holesA = new[] { CreateRing(4), CreateRing(7) }; var holesB = new[] { CreateRing(4), CreateRing(7), CreateRing(2) }; IEnumerable layers = new[] { new MacroStabilityInwardsSoilLayer2D(outerRingA, holesA), new MacroStabilityInwardsSoilLayer2D(outerRingB, holesB) }; var profile = new MacroStabilityInwardsSoilProfile2D("name", layers, Enumerable.Empty()); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine profileUnderSurfaceLine = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create(profile, new MacroStabilityInwardsSurfaceLine(string.Empty)); // Assert Assert.AreEqual(2, profileUnderSurfaceLine.Layers.Count()); CollectionAssert.AreEqual(new[] { outerRingA.Points, outerRingB.Points }, profileUnderSurfaceLine.Layers.Select(layer => layer.OuterRing)); CollectionAssert.AreEqual(new[] { holesA.Select(h => h.Points), holesB.Select(h => h.Points) }, profileUnderSurfaceLine.Layers.Select(layer => layer.Holes)); } [Test] public void SoilProfile2DCreate_WithData_ReturnsData() { // Setup const string material = "Clay"; var random = new Random(21); bool usePop = random.NextBoolean(); bool isAquifer = random.NextBoolean(); var shearStrengthModel = random.NextEnumValue(); const double abovePhreaticLevelMean = 10; const double abovePhreaticLevelCoefficientOfVariation = 0.5; const double abovePhreaticLevelShift = 1; const double belowPhreaticLevelMean = 9; const double belowPhreaticLevelCoefficientOfVariation = 0.4; const double belowPhreaticLevelShift = 0.2; double cohesionMean = random.NextDouble(); double cohesionCoefficientOfVariation = random.NextDouble(); double frictionAngleMean = random.NextDouble(); double frictionAngleCoefficientOfVariation = random.NextDouble(); double shearStrengthRatioMean = random.NextDouble(); double shearStrengthRatioCoefficientOfVariation = random.NextDouble(); double strengthIncreaseExponentMean = random.NextDouble(); double strengthIncreaseExponentCoefficientOfVariation = random.NextDouble(); double popMean = random.NextDouble(); double popCoefficientOfVariation = random.NextDouble(); MacroStabilityInwardsSoilLayer2D layer = GetSoilLayer(); layer.Data.UsePop = usePop; layer.Data.IsAquifer = isAquifer; layer.Data.ShearStrengthModel = shearStrengthModel; layer.Data.MaterialName = material; layer.Data.AbovePhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) abovePhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) abovePhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) abovePhreaticLevelShift }; layer.Data.BelowPhreaticLevel = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) belowPhreaticLevelMean, CoefficientOfVariation = (RoundedDouble) belowPhreaticLevelCoefficientOfVariation, Shift = (RoundedDouble) belowPhreaticLevelShift }; layer.Data.Cohesion = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) cohesionMean, CoefficientOfVariation = (RoundedDouble) cohesionCoefficientOfVariation }; layer.Data.FrictionAngle = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) frictionAngleMean, CoefficientOfVariation = (RoundedDouble) frictionAngleCoefficientOfVariation }; layer.Data.ShearStrengthRatio = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) shearStrengthRatioMean, CoefficientOfVariation = (RoundedDouble) shearStrengthRatioCoefficientOfVariation }; layer.Data.StrengthIncreaseExponent = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) strengthIncreaseExponentMean, CoefficientOfVariation = (RoundedDouble) strengthIncreaseExponentCoefficientOfVariation }; layer.Data.Pop = new VariationCoefficientLogNormalDistribution { Mean = (RoundedDouble) popMean, CoefficientOfVariation = (RoundedDouble) popCoefficientOfVariation }; var profile = new MacroStabilityInwardsSoilProfile2D("name", new[] { layer }, Enumerable.Empty()); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine profileUnderSurfaceLine = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create( profile, new MacroStabilityInwardsSurfaceLine(string.Empty)); // Assert Assert.AreSame(layer.Data, profileUnderSurfaceLine.Layers.First().Data); } [Test] [TestCaseSource(nameof(GetPreconsolidationStresses))] public void SoilProfile2DCreate_WithPreconsolidationStresses_ReturnsExpectedPreconsolidationStresses( IEnumerable preconsolidationStresses) { // Setup MacroStabilityInwardsPreconsolidationStress[] expectedStresses = preconsolidationStresses.ToArray(); var profile = new MacroStabilityInwardsSoilProfile2D("name", new[] { GetSoilLayer() }, expectedStresses); // Call MacroStabilityInwardsSoilProfileUnderSurfaceLine profileUnderSurfaceLine = MacroStabilityInwardsSoilProfileUnderSurfaceLineFactory.Create( profile, new MacroStabilityInwardsSurfaceLine(string.Empty)); // Assert Assert.AreSame(profileUnderSurfaceLine.PreconsolidationStresses, profileUnderSurfaceLine.PreconsolidationStresses); } private static MacroStabilityInwardsSoilLayer2D GetSoilLayer() { return new MacroStabilityInwardsSoilLayer2D(CreateRing(21), Enumerable.Empty()); } private static Ring CreateRing(int seed) { var random = new Random(seed); int x1 = random.Next(); int y1 = random.Next(); int x2 = x1; int y2 = y1 + random.Next(); int x3 = x2 + random.Next(); int y3 = y2; double x4 = x1 + (x3 - x1) * random.NextDouble(); int y4 = y1; return new Ring(new[] { new Point2D(x1, y1), new Point2D(x2, y2), new Point2D(x3, y3), new Point2D(x4, y4) }); } private static IEnumerable GetPreconsolidationStresses() { yield return new TestCaseData(Enumerable.Empty()) .SetName("No preconsolidation stresses"); var preconsolidationStresses = new List { MacroStabilityInwardsPreconsolidationStressTestFactory.CreateMacroStabilityInwardsPreconsolidationStress(), MacroStabilityInwardsPreconsolidationStressTestFactory.CreateMacroStabilityInwardsPreconsolidationStress() }; yield return new TestCaseData(preconsolidationStresses) .SetName("Multiple preconsolidation stresses"); } } }