// Copyright (C) Stichting Deltares 2021. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero 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 Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard; using NUnit.Framework; namespace Deltares.DamEngine.Data.Tests.Geotechnics { [TestFixture] public class SoilSurfaceProfileTests { [Test] public void ConvertToSoilProfile2D_WithSurfaceLineFullyAboveSoilLayers_ReturnsExpectedSoilProfile2D() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName); var profile = new SoilProfile1D { BottomLevel = -10 }; profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, 0), new GeometryPoint(5, 10), new GeometryPoint(10, 10) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(3)); SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName)); AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D); AssertGeometry(new [] { new GeometryCurve(new Point2D(0, 0), new Point2D(5, 10)), new GeometryCurve(new Point2D(5, 10), new Point2D(10, 10)), new GeometryCurve(new Point2D(10, 10), new Point2D(10, -2)), new GeometryCurve(new Point2D(10, -2), new Point2D(5, -2)), new GeometryCurve(new Point2D(5, -2), new Point2D(0, -2)), new GeometryCurve(new Point2D(0, -2), new Point2D(0, 0)) }, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName)); AssertSoilLayerProperties(middleLayer, middleSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -2), new Point2D(5, -2)), new GeometryCurve(new Point2D(5, -2), new Point2D(10, -2)), new GeometryCurve(new Point2D(10, -2), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5)), new GeometryCurve(new Point2D(0, -5), new Point2D(0, -2)) }, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5)) }, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithLayerFullyAboveSurfaceLine_ReturnsExpectedSoilProfile2D() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D irrelevantLayer = CreateSoilLayer(0, "Does not matter"); SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName); var profile = new SoilProfile1D { BottomLevel = -10 }; profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.Layers.Add(irrelevantLayer); SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, -5), new GeometryPoint(5, -3), new GeometryPoint(10, -5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(2)); SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName)); AssertSoilLayerProperties(middleLayer, middleSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -5), new Point2D(5, -3)), new GeometryCurve(new Point2D(5, -3), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5)) }, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5)) }, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLineFullyEnvelopedByTopSoilLayer_ReturnsExpectedSoilProfile2D() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(-2, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, -4), new GeometryPoint(5, -2.5), new GeometryPoint(10, -2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(2)); SoilLayer2D middleLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName)); AssertSoilLayerProperties(middleLayer, middleLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -4), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(0, -5)), new GeometryCurve(new Point2D(0, -5), new Point2D(0, -4)) }, middleLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5)) }, bottomLayer2D.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLinePartiallyEnvelopedByTopSoilLayer_ReturnsExpectedSoilProfile2D() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, -2.5), new GeometryPoint(5, 2.5), new GeometryPoint(10, -2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(3)); SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName)); AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, 2.5)), new GeometryCurve(new Point2D(5, 2.5), new Point2D(7.5, 0)), new GeometryCurve(new Point2D(7.5, 0), new Point2D(5, 0)), new GeometryCurve(new Point2D(5, 0), new Point2D(2.5, 0)) }, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName)); AssertSoilLayerProperties(middleLayer, middleSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, 0)), new GeometryCurve(new Point2D(5, 0), new Point2D(7.5, 0)), new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(7.5, -5)), new GeometryCurve(new Point2D(7.5, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(2.5, -5)), new GeometryCurve(new Point2D(2.5, -5), new Point2D(0, -5)), new GeometryCurve(new Point2D(0, -5), new Point2D(0, -2.5)) }, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -5), new Point2D(2.5, -5)), new GeometryCurve(new Point2D(2.5, -5), new Point2D(5, -5)), new GeometryCurve(new Point2D(5, -5), new Point2D(7.5, -5)), new GeometryCurve(new Point2D(7.5, -5), new Point2D(10, -5)), new GeometryCurve(new Point2D(10, -5), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)), new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)), new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -5)) }, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayers_ReturnsExpectedSoilProfile() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-1.25, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, 2.5), new GeometryPoint(5, -2.5), new GeometryPoint(10, 2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(5)); var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray(); Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in topSoilLayerSurfaces) { AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface); } AssertGeometry(new [] { new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)), new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5)) }, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)), new GeometryCurve(new Point2D(10, 2.5), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0)) }, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray(); Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in middleLayerSurfaces) { AssertSoilLayerProperties(middleLayer, surface); } AssertGeometry(new[] { new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(3.75, -1.25)), new GeometryCurve(new Point2D(3.75, -1.25), new Point2D(2.5, -1.25)), new GeometryCurve(new Point2D(2.5, -1.25), new Point2D(0, -1.25)), new GeometryCurve(new Point2D(0, -1.25), new Point2D(0, 0)) }, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(10, -1.25)), new GeometryCurve(new Point2D(10, -1.25), new Point2D(7.5, -1.25)), new GeometryCurve(new Point2D(7.5, -1.25), new Point2D(6.25, -1.25)), new GeometryCurve(new Point2D(6.25, -1.25), new Point2D(7.5, 0)) }, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomLayerSurface); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -1.25), new Point2D(2.5, -1.25)), new GeometryCurve(new Point2D(2.5, -1.25), new Point2D(3.75, -1.25)), new GeometryCurve(new Point2D(3.75, -1.25), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(6.25, -1.25)), new GeometryCurve(new Point2D(6.25, -1.25), new Point2D(7.5, -1.25)), new GeometryCurve(new Point2D(7.5, -1.25), new Point2D(10, -1.25)), new GeometryCurve(new Point2D(10, -1.25), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)), new GeometryCurve(new Point2D(7.5, -10), new Point2D(6.25, -10)), new GeometryCurve(new Point2D(6.25, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(3.75, -10)), new GeometryCurve(new Point2D(3.75, -10), new Point2D(2.5, -10)), new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -1.25)) }, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayerAndInflectionAtBottomIntersection_ReturnsExpectedSoilProfile() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, 2.5), new GeometryPoint(5, -2.5), new GeometryPoint(10, 2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(5)); var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray(); Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in topSoilLayerSurfaces) { AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface); } AssertGeometry(new[] { new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)), new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5)) }, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)), new GeometryCurve(new Point2D(10, 2.5), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0)) }, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray(); Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in middleLayerSurfaces) { AssertSoilLayerProperties(middleLayer, surface); } AssertGeometry(new[] { new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(2.5, -2.5)), new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(0, -2.5)), new GeometryCurve(new Point2D(0, -2.5), new Point2D(0, 0)) }, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(7.5, -2.5)), new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, 0)) }, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomLayerSurface); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, -2.5)), new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, -2.5)), new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)), new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)), new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5)) }, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLineIntersectingSoilLayerAndHorizontalLineAtBottomIntersection_ReturnsExpectedSoilProfile() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, 2.5), new GeometryPoint(5, -2.5), new GeometryPoint(10, -2.5), new GeometryPoint(15, 2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; Assert.That(soilLayer2Ds, Has.Count.EqualTo(5)); var topSoilLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, topLayerName)).ToArray(); Assert.That(topSoilLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in topSoilLayerSurfaces) { AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, surface); } AssertGeometry(new[] { new GeometryCurve(new Point2D(0, 2.5), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(0, 0)), new GeometryCurve(new Point2D(0, 0), new Point2D(0, 2.5)) }, topSoilLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, 2.5)), new GeometryCurve(new Point2D(15, 2.5), new Point2D(15, 0)), new GeometryCurve(new Point2D(15, 0), new Point2D(12.5, 0)) }, topSoilLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); var middleLayerSurfaces = soilLayer2Ds.Where(l => string.Equals(l.Name, middleLayerName)).ToArray(); Assert.That(middleLayerSurfaces.Length, Is.EqualTo(2)); foreach (SoilLayer2D surface in middleLayerSurfaces) { AssertSoilLayerProperties(middleLayer, surface); } AssertGeometry(new[] { new GeometryCurve(new Point2D(0, 0), new Point2D(2.5, 0)), new GeometryCurve(new Point2D(2.5, 0), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(2.5, -2.5)), new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(0, -2.5)), new GeometryCurve(new Point2D(0, -2.5), new Point2D(0, 0)) }, middleLayerSurfaces[0].GeometrySurface.OuterLoop.CurveList); AssertGeometry(new[] { new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, 0)), new GeometryCurve(new Point2D(15, 0), new Point2D(15, -2.5)), new GeometryCurve(new Point2D(15, -2.5), new Point2D(12.5, -2.5)), new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, 0)) }, middleLayerSurfaces[1].GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomLayerSurface = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomLayerSurface); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -2.5), new Point2D(2.5, -2.5)), new GeometryCurve(new Point2D(2.5, -2.5), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, -2.5)), new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(15, -2.5)), new GeometryCurve(new Point2D(15, -2.5), new Point2D(15, -10)), new GeometryCurve(new Point2D(15, -10), new Point2D(12.5, -10)), new GeometryCurve(new Point2D(12.5, -10), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(2.5, -10)), new GeometryCurve(new Point2D(2.5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5)) }, bottomLayerSurface.GeometrySurface.OuterLoop.CurveList); } [Test] public void ConvertToSoilProfile2D_WithSurfaceLineStartingHorizontallyAtBottomLayer_ReturnsExpectedSoilProfile() { // Setup const string bottomLayerName = "BottomLayer"; const string middleLayerName = "MiddleLayer"; const string topLayerName = "TopLayer"; SoilLayer1D bottomLayer = CreateSoilLayer(-2.5, bottomLayerName); SoilLayer1D middleLayer = CreateSoilLayer(0, middleLayerName); var profile = new SoilProfile1D(); profile.Layers.Add(bottomLayer); profile.Layers.Add(middleLayer); profile.BottomLevel = -10; SurfaceLine2 surfaceLine = CreateSurfaceLine(new[] { new GeometryPoint(0, -2.5), new GeometryPoint(5, -2.5), new GeometryPoint(10, 2.5), new GeometryPoint(15, -2.5), new GeometryPoint(20, -2.5) }); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = profile, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil { Name = topLayerName } }; // Call SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); // Assert var soilLayer2Ds = soilProfile2D.Surfaces; SoilLayer2D topSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, topLayerName)); AssertDikeEmbankmentSoilLayerProperties(soilSurfaceProfile, topSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 2.5)), new GeometryCurve(new Point2D(10, 2.5), new Point2D(12.5, 0)), new GeometryCurve(new Point2D(12.5, 0), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(7.5, 0)) }, topSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D middleSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, middleLayerName)); AssertSoilLayerProperties(middleLayer, middleSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, 0)), new GeometryCurve(new Point2D(7.5, 0), new Point2D(10, 0)), new GeometryCurve(new Point2D(10, 0), new Point2D(12.5, 0)), new GeometryCurve(new Point2D(12.5, 0), new Point2D(15, -2.5)), new GeometryCurve(new Point2D(15, -2.5), new Point2D(12.5, -2.5)), new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(7.5, -2.5)), new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(5, -2.5)) }, middleSoilLayer2D.GeometrySurface.OuterLoop.CurveList); SoilLayer2D bottomSoilLayer2D = soilLayer2Ds.Single(l => string.Equals(l.Name, bottomLayerName)); AssertSoilLayerProperties(bottomLayer, bottomSoilLayer2D); AssertGeometry(new[] { new GeometryCurve(new Point2D(0, -2.5), new Point2D(5, -2.5)), new GeometryCurve(new Point2D(5, -2.5), new Point2D(7.5, -2.5)), new GeometryCurve(new Point2D(7.5, -2.5), new Point2D(10, -2.5)), new GeometryCurve(new Point2D(10, -2.5), new Point2D(12.5, -2.5)), new GeometryCurve(new Point2D(12.5, -2.5), new Point2D(15, -2.5)), new GeometryCurve(new Point2D(15, -2.5), new Point2D(20, -2.5)), new GeometryCurve(new Point2D(20, -2.5), new Point2D(20, -10)), new GeometryCurve(new Point2D(20, -10), new Point2D(15, -10)), new GeometryCurve(new Point2D(15, -10), new Point2D(12.5, -10)), new GeometryCurve(new Point2D(12.5, -10), new Point2D(10, -10)), new GeometryCurve(new Point2D(10, -10), new Point2D(7.5, -10)), new GeometryCurve(new Point2D(7.5, -10), new Point2D(5, -10)), new GeometryCurve(new Point2D(5, -10), new Point2D(0, -10)), new GeometryCurve(new Point2D(0, -10), new Point2D(0, -2.5)) }, bottomSoilLayer2D.GeometrySurface.OuterLoop.CurveList); } private static void AssertGeometry(IEnumerable expectedCurves, IEnumerable actualCurves) { int nrOfExpectedCurves = expectedCurves.Count(); Assert.That(actualCurves.Count(), Is.EqualTo(nrOfExpectedCurves)); var actualCurveString = actualCurves.Select(c => string.Format("Coordinate ({0}, {1}) --> ({2}, {3})", c.HeadPoint.X, c.HeadPoint.Z, c.EndPoint.X, c.EndPoint.Z)); foreach (GeometryCurve expectedCurve in expectedCurves) { Assert.That(actualCurves.Any(c => c.LocationEquals(expectedCurve)), Is.True, $"Expected curve ({expectedCurve.HeadPoint.X}, {expectedCurve.HeadPoint.Z}) --> ({expectedCurve.EndPoint.X}, {expectedCurve.EndPoint.Z}) not found. " + $"Actual curves {string.Join(", ", actualCurveString)}"); } } private static void AssertSoilLayerProperties(SoilLayer1D expectedLayer, SoilLayer2D actualSoilLayer) { Assert.That(actualSoilLayer.IsAquifer, Is.EqualTo(expectedLayer.IsAquifer)); Assert.That(actualSoilLayer.WaterpressureInterpolationModel, Is.EqualTo(expectedLayer.WaterpressureInterpolationModel)); Assert.That(actualSoilLayer.Soil, Is.SameAs(expectedLayer.Soil)); } private static void AssertDikeEmbankmentSoilLayerProperties(SoilSurfaceProfile expectedProfile, SoilLayer2D actualSoilLayer) { Assert.That(actualSoilLayer.IsAquifer, Is.False); Assert.That(actualSoilLayer.WaterpressureInterpolationModel, Is.EqualTo(WaterpressureInterpolationModel.Hydrostatic)); Assert.That(actualSoilLayer.Soil, Is.SameAs(expectedProfile.DikeEmbankmentMaterial)); } private static SoilLayer1D CreateSoilLayer(double topLevel, string soilName) { var random = new Random(soilName.GetHashCode()); Array values = Enum.GetValues(typeof(WaterpressureInterpolationModel)); var model = (WaterpressureInterpolationModel)values.GetValue(random.Next(values.Length)); return new SoilLayer1D { TopLevel = topLevel, Soil = new Soil(soilName), IsAquifer = Convert.ToBoolean(random.Next(0, 2)), WaterpressureInterpolationModel = model }; } private static SurfaceLine2 CreateSurfaceLine(IEnumerable coordinates) { var surfaceLine = new SurfaceLine2(); surfaceLine.Geometry.Points.AddRange(coordinates); surfaceLine.Geometry.SyncCalcPoints(); return surfaceLine; } } }