// Copyright (C) Stichting Deltares 2025. 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.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Threading; using Deltares.DamEngine.Calculators.PlLinesCreator; using Deltares.DamEngine.Data.General; using Deltares.DamEngine.Data.General.Gauges; using Deltares.DamEngine.Data.General.PlLines; using Deltares.DamEngine.Data.Geometry; using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Interface; using Deltares.DamEngine.TestHelpers.Factories; using NUnit.Framework; namespace Deltares.DamEngine.Calculators.Tests.PlLinesCreator; [TestFixture] public class PlLinesCreatorTest { private const double tolerance4Decimals = 0.000051; [SetUp] public void TestFixtureSetup() {} [SetUp] public void TestSetup() {} /// /// Test if PL1 created correctly if PolderLevel above toe at polder /// [Test] public void CreatePl1WithPolderLevelHigherDikeToeAtPolder() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z + 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(9.25).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); plLineCreator.ModelParametersForPlLines.PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD; plLineCreator.PlLineOffsetBelowDikeTopAtRiver = 0.5; // Default value plLineCreator.PlLineOffsetBelowDikeTopAtPolder = 1.5; // Default value plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(9.25).Within(tolerance4Decimals)); // this point and following points are raised to match polderlevel Assert.That(plLine.Points[4].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); } /// /// Test if PL1 created correctly if PolderLevel above shoulder top inside /// [Test] public void CreatePL1WithPolderLevelBetweenShoulderBaseInsideAndShoulderTopInside() { SurfaceLine2 surfaceLineDikeWithSlopingShoulder = FactoryForSurfaceLines.CreateSurfacelineDikeWithSlopingShoulder(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, // Default value PlLineOffsetBelowDikeTopAtPolder = 1.0, SurfaceLine = surfaceLineDikeWithSlopingShoulder, WaterLevelPolder = 2.75 // CharacteristicPointType.ShoulderTopInside.Z = 2.5; CharacteristicPointType.ShoulderBaseInside.Z = 3.0); }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(7)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(9.0).Within(tolerance4Decimals)); // This point has offset below surface level of PlLineOffsetBelowShoulderBaseInside Assert.That(plLine.Points[4].Z, Is.EqualTo(2.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // This point and following points are raised to match polder level Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].X, Is.EqualTo(15).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); } /// /// Test if PL1 created correctly if PolderLevel above shoulder base inside /// [Test] public void CreatePL1WithPolderLevelHigherShoulderBaseInside() { SurfaceLine2 surfaceLineDikeWithSlopingShoulder = FactoryForSurfaceLines.CreateSurfacelineDikeWithSlopingShoulder(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.5, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, // Default value PlLineOffsetBelowDikeTopAtPolder = 1.0, SurfaceLine = surfaceLineDikeWithSlopingShoulder, WaterLevelPolder = 3.25 // CharacteristicPointType.ShoulderBaseInside.Z = 3.0); Lower than PlLineOffsetBelowDikeTopAtPolder }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.75).Within(tolerance4Decimals)); // This point and following points are raised to match polderlevel Assert.That(plLine.Points[4].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(15).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); plLineCreator.WaterLevelPolder = 3.75; // CharacteristicPointType.ShoulderBaseInside.Z = 3.0); Higher than PlLineOffsetBelowDikeTopAtPolder plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); // This point and following points are raised to match polderlevel Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.25).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(15).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); plLineCreator.WaterLevelPolder = 4.25; // CharacteristicPointType.ShoulderBaseInside.Z = 3.0); Higher than PlLineOffsetBelowDikeTopAtRiver plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); // This point and following points are raised to match polderlevel Assert.That(plLine.Points[2].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(7.75).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(15).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); } /// /// Test if exception is thrown if PolderLevel above top of dike /// [Test] public void ThrowsWhenPolderLevelHigherDikeTopAtPolder() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeTopAtPolder).Z + 0.1; Assert.That(() => plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02), Throws.InstanceOf()); } /// /// Test if PL1 is created correctly with expert knowledge /// [Test] public void CreatePL1For1DGeometryWithExpertKnowledgeLinearInDike() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is created correctly with expert knowledge /// [Test] public void CreatePL1For1DGeometryWithExpertKnowledgeLinearInDikeWithShoulder() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); // Add shoulder; this should not affect the creation of the phreatic line surfaceLineSimpleDike.EnsurePointOfType(8.0, 4.0, CharacteristicPointType.ShoulderBaseInside); surfaceLineSimpleDike.EnsurePointOfType(9.0, 4.0, CharacteristicPointType.ShoulderTopInside); surfaceLineSimpleDike.SortPoints(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is created correctly with expert knowledge when low water crosses dike /// [Test] public void CreatePL1LowMidFor1DGeometryWithExpertKnowledgeLinearInDike() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 3.0, // <===================== low waterlevel crossing dike IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(5)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is refused correctly with expert knowledge when low water below surface level /// [Test] public void CreatePL1LowLowFor1DGeometryWithExpertKnowledgeLinearInDike() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 1.0, // <===== low water level below surface level IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; Assert.That(() => plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02), Throws.TypeOf(typeof(SurfaceLineException)).With.Message.Contains("should be higher than dike toe at river side")); } /// /// Test if PL1 is created correctly with expert knowledge when low water crosses multi segment dike /// [Test] public void CreatePL1LowMidFor1DGeometryWithExpertKnowledgeLinearInDikeWithMultiSegmentTalud() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePoint(1.5, 2.5); surfaceLine.EnsurePoint(2.5, 3.0); surfaceLine.EnsurePoint(3.0, 4.0); surfaceLine.EnsurePointOfType(4.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(12.0, 1.0, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateComplexProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 3.0, // <===================== low waterlevel crossing dike IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike } }; plLineCreator.SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(); plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(5)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is refused correctly with expert knowledge when low water below multi segment surface level /// [Test] public void CreatePL1LowLowFor1DGeometryWithExpertKnowledgeLinearInDikeWithMultiSegmentTalud() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePoint(1.5, 2.5); surfaceLine.EnsurePoint(2.5, 3.0); surfaceLine.EnsurePoint(3.0, 4.0); surfaceLine.EnsurePointOfType(4.0, 5.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 5.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(12.0, 1.0, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 1.0, // <===================== low water level below surface level IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeLinearInDike } }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; Assert.That(() => plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02), Throws.TypeOf(typeof(SurfaceLineException)).With.Message.Contains("should be higher than dike toe at river side")); } /// /// Test if PL1 is created correctly with expert knowledge with complex profile /// [Test] public void CreatePL1For1DGeometryWithExpertKnowledgeRRD() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh - plLineCreator.PlLineOffsetBelowDikeTopAtRiver).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh - plLineCreator.PlLineOffsetBelowDikeTopAtPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is created correctly with expert knowledge with complex profile when waterlevel of river equlas top of dike /// This could cause a problem in PlLinesCreator.ValidatePhreaticBelowDike /// [Test] public void CreatePl1For1DGeometryWithExpertKnowledgeRrdIfRiverLevelEqualsTopOfDike() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelRiverHigh = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeTopAtRiver).Z; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeTopAtRiver).X).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh - plLineCreator.PlLineOffsetBelowDikeTopAtRiver).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh - plLineCreator.PlLineOffsetBelowDikeTopAtPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } } /// /// Test if PL1 creation expert knowledge with does not create pl-line below polder level /// [Test] public void CreatePL1_WithPointBelowDikeTopAtPolderLowerPolderLevel_ReturnsPointAtPolderLevel() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), WaterLevelRiverHigh = 2.5, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SurfaceLine = surfaceLineSimpleDike, PlLineOffsetBelowDikeTopAtRiver = 0.5, PlLineOffsetBelowDikeTopAtPolder = 3.0 }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(plLineCreator.WaterLevelPolder).Within(tolerance4Decimals)); }); } } /// /// Test if PL1 creation expert knowledge can be configured with /// PlLineOffsetBelowShoulderBaseInside and PlLineOffsetBelowDikeToeAtPolder /// [Test] public void CreatePL1_WithPointBelowShoulderAndPointBelowToeDefined_ReturnsCorrectPl1() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(4.0, 4.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 4.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(8.0, 2.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(9.0, 2.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePointOfType(12.0, 1.0, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), WaterLevelRiverHigh = 3.0, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, PlLineOffsetBelowDikeTopAtPolder = 1.0, PlLineOffsetBelowShoulderBaseInside = 0.2, PlLineOffsetBelowDikeToeAtPolder = 0.3 }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(7)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(1.8).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.7).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].Z, Is.EqualTo(0.7).Within(tolerance4Decimals)); }); } [Test] public void CreatePL1_WithPointBelowShoulderAndPointBelowToeDefinedWithSlopingSurfaceAtPolderSide_ReturnsCorrectPl1() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(4.0, 4.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 4.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(8.0, 2.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(9.0, 2.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePoint(11.0, 0.5); surfaceLine.EnsurePoint(12.0, 0.4); surfaceLine.EnsurePointOfType(13.0, 0.3, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), WaterLevelRiverHigh = 3.0, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, PlLineOffsetBelowDikeTopAtPolder = 1.0, PlLineOffsetBelowShoulderBaseInside = 0.2, PlLineOffsetBelowDikeToeAtPolder = 0.3 }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(9)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(1.8).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.7).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].X, Is.EqualTo(11).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].Z, Is.EqualTo(0.2).Within(tolerance4Decimals)); Assert.That(plLine.Points[7].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[7].Z, Is.EqualTo(0.1).Within(tolerance4Decimals)); Assert.That(plLine.Points[8].X, Is.EqualTo(13).Within(tolerance4Decimals)); Assert.That(plLine.Points[8].Z, Is.EqualTo(0.0).Within(tolerance4Decimals)); }); } [Test] public void CreatePL1_WithPointBelowShoulderAndPointBelowToeDefinedWithSlopingSurfaceAtPolderSidePartBelowPolderLevel_ReturnsCorrectPl1() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(4.0, 4.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 4.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(8.0, 2.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(9.0, 2.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePoint(11.0, 0.5); surfaceLine.EnsurePoint(12.0, 0.1); surfaceLine.EnsurePoint(14.0, 0.5); surfaceLine.EnsurePointOfType(15.0, 0.0, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), WaterLevelRiverHigh = 3.0, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, PlLineOffsetBelowDikeTopAtPolder = 1.0, PlLineOffsetBelowShoulderBaseInside = 0.2, PlLineOffsetBelowDikeToeAtPolder = 0.3 }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(9)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(1.8).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.7).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].X, Is.EqualTo(11).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].Z, Is.EqualTo(0.2).Within(tolerance4Decimals)); Assert.That(plLine.Points[7].X, Is.EqualTo(11.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[7].Z, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[8].X, Is.EqualTo(15).Within(tolerance4Decimals)); Assert.That(plLine.Points[8].Z, Is.EqualTo(0.0).Within(tolerance4Decimals)); }); } [Test] public void CreatePL1_WithPointBelowShoulderAndPointBelowToeDefinedWithSlopingSurfaceAtPolderSideAllBelowPolderLevel_ReturnsCorrectPl1() { var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.EnsurePointOfType(0.0, 2.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLine.EnsurePointOfType(1.0, 2.0, CharacteristicPointType.DikeToeAtRiver); surfaceLine.EnsurePointOfType(4.0, 4.0, CharacteristicPointType.DikeTopAtRiver); surfaceLine.EnsurePointOfType(7.0, 4.0, CharacteristicPointType.DikeTopAtPolder); surfaceLine.EnsurePointOfType(8.0, 2.0, CharacteristicPointType.ShoulderBaseInside); surfaceLine.EnsurePointOfType(9.0, 2.0, CharacteristicPointType.ShoulderTopInside); surfaceLine.EnsurePointOfType(10.0, 1.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.EnsurePoint(11.0, 0.5); surfaceLine.EnsurePoint(12.0, 0.2); surfaceLine.EnsurePointOfType(13.0, 0.0, CharacteristicPointType.SurfaceLevelInside); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), WaterLevelRiverHigh = 3.0, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, PlLineOffsetBelowDikeTopAtRiver = 0.5, PlLineOffsetBelowDikeTopAtPolder = 1.0, PlLineOffsetBelowShoulderBaseInside = 0.2, PlLineOffsetBelowDikeToeAtPolder = 0.3 }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(7)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(8.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(1.8).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(1.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].X, Is.EqualTo(13).Within(tolerance4Decimals)); Assert.That(plLine.Points[6].Z, Is.EqualTo(1.0).Within(tolerance4Decimals)); }); } /// /// Test if PL1 is created correctly with expert knowledge with complex profile and low waterlevel /// [Test] public void CreatePL1LowFor1DGeometryWithExpertKnowledgeRRD() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 3.0, IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4 }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } } /// /// Test if PL1 is created correctly with expert knowledge with complex profile and low waterlevel just above toe of dike riverside /// [Test] public void CreatePL1LowJustAboveToeFor1DGeometryWithExpertKnowledgeRRD() { SurfaceLine2 surfaceLineSimpleDike = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(); // Add voorland to dike surfaceLineSimpleDike.EnsurePointOfType(-2.0, 0.0, CharacteristicPointType.SurfaceLevelOutside); surfaceLineSimpleDike.EnsurePoint(0.0, 2.0); surfaceLineSimpleDike.SortPoints(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 2.1, IsUseLowWaterLevel = true, ModelParametersForPlLines = { DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4 }, SurfaceLine = surfaceLineSimpleDike }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(-2.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(2.1).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(1.1).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(2.1).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } /// /// Test if exception is thrown when creating Pl-lines with no soil profile /// [Test] [SetUICulture("nl-NL")] public void GivenSoilProfile1DIsNull_WhenCreatingPlLines_ThenThrowsException() { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = FactoryForSurfaceLines.CreateSurfacelineSimpleDike(), SoilProfileType = SoilProfileType.ProfileType1D, SoilProfile = null }; Assert.That(() => plLineCreator.CreateAllPlLines(new Location(), out _), Throws.InstanceOf().With.Message.EqualTo ("Voor dit scenario wordt geen berekening uitgevoerd omdat het ondergrondprofiel niet voldoet aan " + "de eisen die aan de aanleg van het waternet worden gesteld: Er is niet voldoende informatie over het " + "ondergrondprofiel (Profiel 1D, Profiel 2D of Ophoogmateriaal dijk) beschikbaar om de PL-lijnen te maken.")); } /// /// Test if PL2 is created correctly if no inbetween aquifer present /// [Test] public void CreatePL2For1DGeometryWithExpertKnowledgeRRDIfNoAquiferLayerInBetween() { const double cHeadPL2 = 3.0; const double cPenetrationLength = 6.0; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, HeadInPlLine2 = cHeadPL2 }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.That(plLine.Exists(), Is.True); } [Test] public void CreatePL2WithExpertKnowledgeRRDThrowsExceptionIfPenetrationLengthNegative() { const double cHeadPl2 = 3.0; const double cPenetrationLength = -1.0; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateSimpleProfile(), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, HeadInPlLine2 = cHeadPl2 }; Assert.That(() => plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02), Throws.InstanceOf()); } /// /// Test if PL2 is created correctly if no inbetween aquifer present and penetration length = 0 /// [Test] public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthZero() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 0.0; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.AddCharacteristicPoint(new Point2D(10.0, 2.0)); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, HeadInPlLine2 = cHeadPl2 }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.Multiple(() => { // No extra layer should have been added to profile Assert.That(plLineCreator.SoilProfile.Layers, Has.Count.EqualTo(4)); Assert.That(plLine.Exists(), Is.False); }); } /// /// Test if PL2 is created correctly if no inbetween aquifer present and penetration length above that aquifer /// [Test] public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthAboveThisSandLayer() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 6.0; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, HeadInPlLine2 = cHeadPl2 }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.That(plLine.Exists(), Is.False); } /// /// Test if PL2 is NOT created if in-between aquifer present and penetration length ending in that aquifer /// [Test] public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer() { const double cPenetrationLength = 4.0; const double cHeadPl2 = 3.0; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength, DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4 }, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), SurfaceLine = surfaceLineTutorial1 }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.That(plLine.Exists(), Is.False); } /// /// Test if PL2 and PL4 are created correctly if in-between aquifer present and penetration length ending in that aquifer /// [Test] [SetUICulture("nl-NL")] public void CreatePL2andPL4For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer() { const double cPenetrationLength = 4.0; const double cHeadInPlLine2 = 3.0; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { HeadInPlLine2 = cHeadInPlLine2, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD, PenetrationLength = cPenetrationLength, DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4 }, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), SurfaceLine = surfaceLineTutorial1, DikeEmbankmentMaterial = new Soil() }; var location = new Location(); PlLines plLines = plLineCreator.CreateAllPlLines(location, out string warningMessage); PlLine plLine2 = plLines.Lines[PlLineType.Pl2]; PlLine plLine4 = plLines.Lines[PlLineType.Pl4]; Assert.Multiple(() => { Assert.That(plLine2.Exists(), Is.True); Assert.That(plLine4.Exists(), Is.True); Assert.That(plLine2.Points, Has.Count.EqualTo(plLine4.Points.Count)); Assert.That(plLine4.Points[0].Z, Is.EqualTo(4.0)); }); for (var pointIndex = 0; pointIndex < plLine4.Points.Count; pointIndex++) { Assert.That(plLine2.Points[pointIndex].LocationEquals(plLine4.Points[pointIndex]), Is.True); } Assert.That(warningMessage, Is.EqualTo("De door de gebruiker gedefinieerde indringingszone overlapt " + "gedeeltelijk of strekt zich uit boven het tussenliggende watervoerende pakket. Daarom wordt PL 2 gelijkgesteld aan PL 4.")); } [Test] public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthBelowBottomOfThisAquiferLayer() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 3.0; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength } }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.Multiple(() => { Assert.That(plLine.Exists(), Is.True); Assert.That(plLine.Points[0].LocationEquals(new PlLinePoint(1.0, cHeadPl2)), Is.True); Assert.That(plLine.Points[1].LocationEquals(new PlLinePoint(21.0, cHeadPl2)), Is.True); }); } [Test] public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthBelowBottomOfThisAquiferLayerWithMultipleInfiltrationLayers() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 2.0; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength } }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.Multiple(() => { Assert.That(plLine.Exists(), Is.True); Assert.That(plLine.Points[0].LocationEquals(new PlLinePoint(1.0, cHeadPl2)), Is.True); Assert.That(plLine.Points[1].LocationEquals(new PlLinePoint(21.0, cHeadPl2)), Is.True); Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer, Is.Not.Null); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer, Is.Not.Null); }); Assert.Multiple(() => { Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer.TopLevel, Is.EqualTo(-5.0)); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer.TopLevel, Is.EqualTo(1.0)); }); } [Test] public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfAInfiltrationLayer() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 2.7; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength } }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.Multiple(() => { Assert.That(plLine.Exists(), Is.True); Assert.That(plLine.Points[0].LocationEquals(new PlLinePoint(1.0, cHeadPl2)), Is.True); Assert.That(plLine.Points[1].LocationEquals(new PlLinePoint(21.0, cHeadPl2)), Is.True); Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer, Is.Not.Null); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer, Is.Not.Null); }); Assert.Multiple(() => { Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer.TopLevel, Is.EqualTo(-5.0)); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer.TopLevel, Is.EqualTo(1.0)); }); } [Test] public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfSandLayer() { const double cHeadPl2 = 3.0; const double cPenetrationLength = 3.5; var surfaceLine = new SurfaceLine2 { Geometry = new GeometryPointString(), CharacteristicPoints = { GeometryMustContainPoint = true } }; surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength } }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); Assert.Multiple(() => { Assert.That(plLine.Exists(), Is.True); Assert.That(plLine.Points[0].LocationEquals(new PlLinePoint(1.0, cHeadPl2)), Is.True); Assert.That(plLine.Points[1].LocationEquals(new PlLinePoint(21.0, cHeadPl2)), Is.True); Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer, Is.Not.Null); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer, Is.Not.Null); }); Assert.Multiple(() => { Assert.That(plLineCreator.SoilProfile.BottomAquiferLayer.TopLevel, Is.EqualTo(-5.0)); Assert.That(plLineCreator.SoilProfile.InBetweenAquiferLayer.TopLevel, Is.EqualTo(1.0)); }); } [Test] public void CreatePl4For1DGeometryWithExpertKnowledgeRrdIfNoInBetweenAquiferLayer() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl4 = cDampingFactor } }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl4, 0.02); Assert.That(plLine.Exists(), Is.False); } /// /// This test evaluates the same situation as CreatePL3For1DGeometryWithExpertKnowledgeRRD() /// The difference is that here the geometry is entered as a 2D-geometry /// [Test] public void CreatePL3For2DGeometryWithExpertKnowledgeRRD() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); SoilProfile1D soilProfile1D = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5); var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = soilProfile1D, SurfaceLine2 = surfaceLineTutorial1, DikeEmbankmentMaterial = new Soil("HW-OBO", 12.0, 10.0) }; SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile2D = soilProfile2D, SoilProfileType = SoilProfileType.ProfileType2D, SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl3 = cDampingFactor } }; // In this case no HeadInPlLine3 is specified, then the head of PL3 will be equal to WaterLevelRiverHigh PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // In this case HeadInPlLine3 is specified (with same value as WaterLevelRiverHigh above, so result should be the same) // Change WaterLevelRiverHigh to be sure the value of HeadInPlLine3 is really used plLineCreator.WaterLevelRiverHigh = 3.0; plLineCreator.HeadInPlLine3 = 4.0; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // Specify Head PL2, so it is used for damping, but give it the same value as WaterLevelPolder. // This will give the same result as when Head PL2 is not specified, because in that case, WaterLevelPolder ius used for damping. plLineCreator.HeadInPlLine2 = -0.5; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // Specify Head PL2, so it is used for damping, but now use different value as WaterLevelPolder to force different result. plLineCreator.HeadInPlLine2 = -5.0; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrdWithHeadPl2Specified(plLine); } /// /// This test evaluates the same situation as CreatePL3For2DGeometryWithExpertKnowledgeRRD() /// The difference is that here the geometry is entered as a 1d-geometry /// [Test] public void CreatePl3For1DGeometryWithExpertKnowledgeRrd() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl3 = cDampingFactor } }; // In this case no HeadInPlLine3 is specified, then the head of PL3 will be equal to WaterLevelRiverHigh PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // In this case HeadInPlLine3 is specified (with same value as WaterLevelRiverHigh above, so result should be the same) // Change WaterLevelRiverHigh to be sure the value of HeadInPlLine3 is really used plLineCreator.WaterLevelRiverHigh = 3.0; plLineCreator.HeadInPlLine3 = 4.0; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // Specify Head PL2, so it is used for damping, but give it the same value as WaterLevelPolder. // This will give the same result as when Head PL2 is not specified, because in that case, WaterLevelPolder is used for damping. plLineCreator.HeadInPlLine2 = -0.5; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrd(plLine); // Specify Head PL2, so it is used for damping, but now use different value as WaterLevelPolder to force different result. plLineCreator.HeadInPlLine2 = -5.0; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3For1DGeometryWithExpertKnowledgeRrdWithHeadPl2Specified(plLine); } [Test] public void CreatePl3LowFor1DGeometryWithExpertKnowledgeRrd() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelRiverLow = 1.0, IsUseLowWaterLevel = true, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl3 = cDampingFactor } }; // In this case no HeadInPlLine3 is specified, then the head of Pl3 will be equal to WaterLevelRiverLow PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3LowFor1DGeometryWithExpertKnowledgeRrd(plLine); // In this case HeadInPlLine3 is specified (with same value as WaterLevelRiverLow above, so result should be the same) // Change WaterLevelRiverLow to be sure the value of HeadInPlLine3 is really used plLineCreator.WaterLevelRiverHigh = 4.0; plLineCreator.HeadInPlLine3 = 1.0; plLineCreator.WaterLevelRiverLow = 2.0; plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); CheckPl3LowFor1DGeometryWithExpertKnowledgeRrd(plLine); } [Test] public void CreatePl3For1DGeometryInBlackHoleWithExpertKnowledgeRrd() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl3 = cDampingFactor } }; // Lower profile for 5 m so upper layer is no longer completely above surface foreach (SoilLayer1D layer in plLineCreator.SoilProfile.Layers) { layer.TopLevel -= 5.0; } plLineCreator.SoilProfile.BottomLevel -= 5.0; // Make upper layer astronomically heavy plLineCreator.SoilProfile.Layers[0].Soil.AbovePhreaticLevel = 1e25; // About twice the entire earth's mass plLineCreator.SoilProfile.Layers[0].Soil.BelowPhreaticLevel = 1e25; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); //double dikeBaseLength = plLineCreator.SurfaceLine.GetDikeToeInward().X - plLineCreator.SurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeToeAtRiver].X; //double lengthFromRiverToe = plLineCreator.SurfaceLine.Points.Last().X - plLineCreator.SurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeToeAtRiver].X; //double deltaHead = (plLineCreator.WaterLevelRiver - plLineCreator.WaterLevelPolder) * 0.01 * cDampingFactor; //double slope = deltaHead / dikeBaseLength; //double headAtDikeToe = plLineCreator.WaterLevelRiver - deltaHead; //double headAtEnd = plLineCreator.WaterLevelRiver - slope * lengthFromRiverToe; // PlLine in this situation is supposed to take the shape of the line with no corrections for uplift Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // entry point Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(50.5).Within(tolerance4Decimals)); // dike toe polder Assert.That(plLine.Points[2].Z, Is.EqualTo(2.65).Within(tolerance4Decimals)); // head dike toe polder Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // dike toe polder Assert.That(plLine.Points[3].Z, Is.EqualTo(2.16).Within(tolerance4Decimals)); // head dike toe polder Assert.That(plLine.ZFromX(plLineCreator.SurfaceLine.GetDikeToeInward().X), Is.EqualTo(2.65).Within(tolerance4Decimals)); // headAtDikeToe }); } [Test] public void CreatePl3For1DGeometryInOuterSpaceWithExpertKnowledgeRrd() { const double cDampingFactor = 0.3; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, ModelParametersForPlLines = { DampingFactorPl3 = cDampingFactor } }; // Lower profile for 5m so upper layer is no longer completely above surface plLineCreator.SoilProfile.BottomLevel -= 5.0; for (int i = plLineCreator.SoilProfile.Layers.Count - 1; i >= 0; --i) { plLineCreator.SoilProfile.Layers[i].TopLevel -= 5.0; // Make all layers weightless plLineCreator.SoilProfile.Layers[i].Soil.AbovePhreaticLevel = 0.0; plLineCreator.SoilProfile.Layers[i].Soil.BelowPhreaticLevel = 0.0; } PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl3, 0.02); //double dikeBaseLength = plLineCreator.SurfaceLine.GetDikeToeInward().X - plLineCreator.SurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeToeAtRiver].X; //double lengthFromRiverToe = plLineCreator.SurfaceLine.Points.Last().X - plLineCreator.SurfaceLine.CharacteristicPoints[CharacteristicPointType.DikeToeAtRiver].X; //double deltaHead = (plLineCreator.WaterLevelRiver - plLineCreator.WaterLevelPolder) * 0.01 * cDampingFactor; //double slope = deltaHead / dikeBaseLength; //double headAtDikeToe = plLineCreator.WaterLevelRiver - deltaHead; //double headAtEnd = plLineCreator.WaterLevelRiver - slope * lengthFromRiverToe; // PlLine in this situation is supposed to burn down to the polder water level from the entry point Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // entry point Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(50.5).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[2].Z, Is.EqualTo(-0.5).Within(tolerance4Decimals)); // water level at polder Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[3].Z, Is.EqualTo(-0.5).Within(tolerance4Decimals)); // water level at polder }); } [Test] public void CreatePl4For1DGeometryWithExpertKnowledgeRrd() { const double cDampingFactor = 0.4; // Ditch bottom level (-0.4 m) must be above the in-between aquifer (-0.5 m) to avoid reduction of PL4 SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(false, -0.4); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), SoilProfileType = SoilProfileType.ProfileType1D, DikeEmbankmentMaterial = new Soil(), SurfaceLine = surfaceLineTutorial1, WaterLevelRiverHigh = 3.0, WaterLevelPolder = -0.5, IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = false, ModelParametersForPlLines = { DampingFactorPl4 = cDampingFactor }, // In this case HeadInPlLine3 is specified (with same value as WaterLevelRiverHigh above, so result should be the same) // Change WaterLevelRiverHigh to be sure the value of HeadInPlLine3 is really used HeadInPlLine4 = 4.0 }; var location = new Location { SlopeDampingPiezometricHeightPolderSide = 0.02 }; PlLines plLines = plLineCreator.CreateAllPlLines(location, out _); CheckPl4LowFor1DGeometryWithExpertKnowledgeRrd(plLines.Lines[PlLineType.Pl4]); } [Test] public void CreatePlLinesFromGaugesWithNonExistentGauge() { SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location { Name = "Location1" }; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLineTutorial1 }; var locations = new List { location }; var gauges = new List { new Gauge { Name = "G1", Location = locations[0], LocalX = 3.2 }, new Gauge { Name = "G2", Location = locations[0], LocalX = 12.4 } // Gauge "G3" is missing }; var gaugePlLines = new List(); var gaugePlLine1 = new GaugePlLine(PlLineType.Pl1); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 1.2, Z = 4.5 }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 3.4, Z = 4.5 }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 4.7, GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G3", GaugeIDZ = "G2" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 17.6, Z = -2.0 }); gaugePlLines.Add(gaugePlLine1); plLineCreator.GaugePlLines = gaugePlLines; plLineCreator.Gauges = gauges; plLineCreator.ModelParametersForPlLines.PlLineCreationMethod = PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD; Assert.That(() => plLineCreator.CreateAllPlLines(locations[0], out _), Throws.InstanceOf()); } [Test] public void CreatePlLinesFromGauges() { SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location { Name = "Location1" }; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLineTutorial1, ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD } }; var locations = new List { location }; var gauges = new List { new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 4 }, new Gauge { Name = "G2", Location = locations[0], LocalX = 45, Value = 1 } }; var gaugePlLines = new List(); var gaugePlLine1 = new GaugePlLine(PlLineType.Pl1); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 0, GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G1", GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G2", GaugeIDZ = "G2" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 75, GaugeIDZ = "G2" }); gaugePlLines.Add(gaugePlLine1); var gaugePlLine2 = new GaugePlLine(PlLineType.Pl2); gaugePlLines.Add(gaugePlLine2); var gaugePlLine3 = new GaugePlLine(PlLineType.Pl3); gaugePlLines.Add(gaugePlLine3); var gaugePlLine4 = new GaugePlLine(PlLineType.Pl4); gaugePlLines.Add(gaugePlLine4); plLineCreator.GaugePlLines = gaugePlLines; plLineCreator.Gauges = gauges; PlLines plLines = plLineCreator.CreateAllPlLines(locations[0], out _); Assert.That(plLines.Lines[PlLineType.Pl1].Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].X, Is.EqualTo(0)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].Z, Is.EqualTo(4)); // The following point.x is the intersection point of PL1 with the dike Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].X, Is.EqualTo(29.6)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].Z, Is.EqualTo(4)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[2].X, Is.EqualTo(45)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[2].Z, Is.EqualTo(1)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[3].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[3].Z, Is.EqualTo(1)); Assert.That(plLines.Lines[PlLineType.Pl2].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl3].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl4].Points, Is.Empty); }); } [Test] public void CreatePlLinesFromGaugesMoses() { SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location { Name = "Location1" }; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD }, SurfaceLine = surfaceLineTutorial1 }; var locations = new List { location }; var gauges = new List { new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 4 }, new Gauge { Name = "G2", Location = locations[0], LocalX = 20, Value = 2 }, new Gauge { Name = "G3", Location = locations[0], LocalX = 45, Value = 1 } }; var gaugePlLines = new List(); var gaugePlLine1 = new GaugePlLine(PlLineType.Pl1); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 0, GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G1", GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G2", GaugeIDZ = "G2" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G3", GaugeIDZ = "G3" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 75, GaugeIDZ = "G3" }); gaugePlLines.Add(gaugePlLine1); var gaugePlLine2 = new GaugePlLine(PlLineType.Pl2); gaugePlLines.Add(gaugePlLine2); var gaugePlLine3 = new GaugePlLine(PlLineType.Pl3); gaugePlLines.Add(gaugePlLine3); var gaugePlLine4 = new GaugePlLine(PlLineType.Pl4); gaugePlLines.Add(gaugePlLine4); plLineCreator.GaugePlLines = gaugePlLines; plLineCreator.Gauges = gauges; PlLines plLines = plLineCreator.CreateAllPlLines(locations[0], out _); Assert.That(plLines.Lines[PlLineType.Pl1].Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].X, Is.EqualTo(0)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].Z, Is.EqualTo(4)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].X, Is.EqualTo(29.6)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].Z, Is.EqualTo(4)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[2].X, Is.EqualTo(45)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[2].Z, Is.EqualTo(1)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[3].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[3].Z, Is.EqualTo(1)); Assert.That(plLines.Lines[PlLineType.Pl2].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl3].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl4].Points, Is.Empty); }); } [Test] public void CreatePlLinesFromGaugesNoah() { SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); var location = new Location { Name = "Location1" }; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.GaugesWithFallbackToExpertKnowledgeRRD }, SurfaceLine = surfaceLineTutorial1 }; var locations = new List { location }; var gauges = new List { new Gauge { Name = "G1", Location = locations[0], LocalX = 15, Value = 6 }, new Gauge { Name = "G2", Location = locations[0], LocalX = 20, Value = 2 }, new Gauge { Name = "G3", Location = locations[0], LocalX = 45, Value = 1 } }; var gaugePlLines = new List(); var gaugePlLine1 = new GaugePlLine(PlLineType.Pl1); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 0, GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G1", GaugeIDZ = "G1" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G2", GaugeIDZ = "G2" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { GaugeIDX = "G3", GaugeIDZ = "G3" }); gaugePlLine1.Points.Add(new GaugePlLinePoint { X = 75, GaugeIDZ = "G3" }); gaugePlLines.Add(gaugePlLine1); var gaugePlLine2 = new GaugePlLine(PlLineType.Pl2); gaugePlLines.Add(gaugePlLine2); var gaugePlLine3 = new GaugePlLine(PlLineType.Pl3); gaugePlLines.Add(gaugePlLine3); var gaugePlLine4 = new GaugePlLine(PlLineType.Pl4); gaugePlLines.Add(gaugePlLine4); plLineCreator.GaugePlLines = gaugePlLines; plLineCreator.Gauges = gauges; PlLines plLines = plLineCreator.CreateAllPlLines(locations[0], out _); Assert.That(plLines.Lines[PlLineType.Pl1].Points, Has.Count.EqualTo(2)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].X, Is.EqualTo(0)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].Z, Is.EqualTo(6)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].Z, Is.EqualTo(6)); Assert.That(plLines.Lines[PlLineType.Pl2].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl3].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl4].Points, Is.Empty); }); } /// /// _______ Level 10 m /// / Clay \ /// /---------\ Level 6 m /// / Aquifer \ /// /-------------\ X=58.5 Level 2 m /// -----------/ Layer 3 \------\ /-------- Level 0 m /// -----------------------------------\ /--------- Level -2 m /// Layer 4 \ / /// -------------------------------------\ /----------- Level -4 m /// Layer 5 \---------/ Level -5 m /// X=59.5 /// ------------------------------------------------------------- Level -6 m /// Bottom aquifer /// ------------------------------------------------------------- Level -10 m /// [Test] [TestCase(1, SoilProfileType.ProfileType1D, true, true, true)] // All layers at polder are aquifers, so no intersection found [TestCase(2, SoilProfileType.ProfileType1D, false, true, false)] // In-between aquifer intersects ditch at Z = -2 [TestCase(3, SoilProfileType.ProfileType2D, false, false, true)] // Bottom aquifer intersects ditch at Z = -4 [TestCase(4, SoilProfileType.ProfileType1D, false, false, false)] // Aquifer is below ditch, so no intersection found public void GivenSoilProfile_WhenDeterminingIfSurfaceLineIsIntersectedByAquifersAtPolder_ThenExpectedResultReturned(int caseNr, SoilProfileType soilProfileType, bool isLayer3Aquifer, bool isLayer4Aquifer, bool isLayer5Aquifer) { SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineWithDikeAndDitch(10, -5); SoilProfile1D soilProfile1D = FactoryForSoilProfiles.CreateClaySandClaySandClaySandProfile(10, 6, 2, 0 - 2, -4, -6); soilProfile1D.Layers[2].IsAquifer = isLayer3Aquifer; soilProfile1D.Layers[3].IsAquifer = isLayer4Aquifer; soilProfile1D.Layers[4].IsAquifer = isLayer5Aquifer; soilProfile1D.BottomLevel = -10; var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = soilProfile1D, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil(), Name = "Test" }; SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SoilProfile = soilProfileType == SoilProfileType.ProfileType1D ? soilProfile1D : null, SoilProfile2D = soilProfileType == SoilProfileType.ProfileType2D ? soilProfile2D : null, SoilProfileType = soilProfileType, SurfaceLine = surfaceLine }; // Call bool isIntersectionWithBottomAquifer = plLineCreator.IsSurfaceLineIntersectedByAquiferAtPolder(PlLineType.Pl3, out Point2D intersectionPointBottomAquifer); bool isIntersectionWithInBetweenAquifer = plLineCreator.IsSurfaceLineIntersectedByAquiferAtPolder(PlLineType.Pl4, out Point2D intersectionPointInBetweenAquifer); // Assert Assert.Multiple(() => { Assert.That(isIntersectionWithBottomAquifer, Is.EqualTo(caseNr == 3)); Assert.That(isIntersectionWithInBetweenAquifer, Is.EqualTo(caseNr == 2)); }); switch (caseNr) { case 1 or 4: Assert.Multiple(() => { Assert.That(intersectionPointBottomAquifer, Is.Null); Assert.That(intersectionPointInBetweenAquifer, Is.Null); }); break; case 2: Assert.Multiple(() => { Assert.That(intersectionPointBottomAquifer, Is.Null); Assert.That(intersectionPointInBetweenAquifer.X, Is.EqualTo(58.9).Within(tolerance4Decimals)); Assert.That(intersectionPointInBetweenAquifer.Z, Is.EqualTo(-2).Within(tolerance4Decimals)); }); break; case 3: Assert.Multiple(() => { Assert.That(intersectionPointInBetweenAquifer, Is.Null); Assert.That(intersectionPointBottomAquifer.X, Is.EqualTo(59.3).Within(tolerance4Decimals)); Assert.That(intersectionPointBottomAquifer.Z, Is.EqualTo(-4).Within(tolerance4Decimals)); }); break; } } [Test] [TestCase(-6.0, 59.25)] // PL 1 intersects the ditch [TestCase(-9.0, 59.00)] // PL 1 below ditch public void GivenSoilProfile2DWithAquifersCuttingTheDitch_WhenReducingPl3ToPl1_ThenExpectedPlLine3Returned(double pl1Level, double expectedXPl3) { SoilProfile2D soilProfile2D = CreateSoilProfile2DWithLayersCuttingTheDitch(false, out SurfaceLine2 surfaceLine); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SoilProfile2D = soilProfile2D, SoilProfileType = SoilProfileType.ProfileType2D, SurfaceLine = surfaceLine, CurrentPl1Line = new PlLine() }; plLineCreator.CurrentPl1Line.Points.Add(new PlLinePoint(0, pl1Level)); plLineCreator.CurrentPl1Line.Points.Add(new PlLinePoint(75, pl1Level)); var pl3 = new PlLine(); var intersectionDitchWithAquifer = new Point2D(59, -4); // Call plLineCreator.ReducePlLineToPl1(intersectionDitchWithAquifer, pl3); // Assert Assert.That(pl3.Points, Has.Count.EqualTo(2)); Assert.Multiple(() => { Assert.That(pl3.Points[0].X, Is.EqualTo(expectedXPl3).Within(tolerance4Decimals)); Assert.That(pl3.Points[0].Z, Is.EqualTo(pl1Level).Within(tolerance4Decimals)); Assert.That(pl3.Points[1].X, Is.EqualTo(75).Within(tolerance4Decimals)); Assert.That(pl3.Points[1].Z, Is.EqualTo(pl1Level).Within(tolerance4Decimals)); }); } [Test] [TestCase(-2.0, 58.75)] // PL 1 intersects the ditch and is above intersection point ditch/aquifer [TestCase(-6.0, 59.25)] // PL 1 intersects the ditch and is below intersection point ditch/aquifer [TestCase(-9.0, double.NaN)] // PL 1 below ditch [TestCase(2.0, double.NaN)] // PL 1 above ditch public void GivenSoilProfile2DWithDitch_WhenDeterminingIfDitchIsIntersectedByPl1_ThenExpectedResultReturned(double pl1Level, double expectedXIntersection) { SoilProfile2D soilProfile2D = CreateSoilProfile2DWithLayersCuttingTheDitch(false, out SurfaceLine2 surfaceLine); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, SoilProfile2D = soilProfile2D, SoilProfileType = SoilProfileType.ProfileType2D, SurfaceLine = surfaceLine, CurrentPl1Line = new PlLine() }; plLineCreator.CurrentPl1Line.Points.Add(new PlLinePoint(0, pl1Level)); plLineCreator.CurrentPl1Line.Points.Add(new PlLinePoint(75, pl1Level)); var intersectionDitchWithAquifer = new Point2D(59, -4); // Call bool isDitchIntersectedByPl1 = plLineCreator.IsDitchIntersectedByPl1(intersectionDitchWithAquifer, out Point2D intersectionDitchPl1); // Assert if (double.IsNaN(expectedXIntersection)) { Assert.Multiple(() => { Assert.That(isDitchIntersectedByPl1, Is.False); Assert.That(intersectionDitchPl1, Is.Null); }); } else { Assert.Multiple(() => { Assert.That(isDitchIntersectedByPl1, Is.True); Assert.That(intersectionDitchPl1, Is.Not.Null); Assert.That(intersectionDitchPl1.X, Is.EqualTo(expectedXIntersection).Within(tolerance4Decimals)); Assert.That(intersectionDitchPl1.Z, Is.EqualTo(pl1Level).Within(tolerance4Decimals)); }); } } /// /// _______ Level 10 m /// / Clay \ /// /---------\ Level 6 m /// / Aquifer \ /// /-------------\ X=58.5 Level 2 m /// -----------/ Clay \------\ /-------- Level 0 m /// -----------------------------------\ /--------- Level -2 m /// In between layer \ / /// -------------------------------------\ /----------- Level -4 m /// Clay \ / /// ---------------------------------------\ /------------- Level -6 m /// \_____/ Level -8 m /// Bottom aquifer X=59.5 /// ------------------------------------------------------------- Level -10 m /// [Test] [TestCase(false, -4.0, 59.000)] // PL 1 above bottom aquifer [TestCase(false, -7.0, 59.375)] // PL 1 below bottom aquifer but above ditch bottom [TestCase(false, -9.0, 59.250)] // PL 1 below ditch [TestCase(true, -1.0, 58.625, 58.625)] // PL 1 above in-between aquifer [TestCase(true, -7.0, 59.375, 59.375)] // PL 1 below in-between aquifer but above ditch bottom [TestCase(true, -9.0, 59.250, 58.750)] // PL 1 below ditch public void GivenSoilProfile2DWithAquifersCuttingTheDitch_WhenCreatingPlLines_ThenExpectedPlLinesReturned(bool isInBetweenLayerAquifer, double waterLevelPolder, double expectedXPl3, double expectedXPl4 = 0) { SoilProfile2D soilProfile2D = CreateSoilProfile2DWithLayersCuttingTheDitch(isInBetweenLayerAquifer, out SurfaceLine2 surfaceLine); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD, PenetrationLength = 0, DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4 }, HeadInPlLine3 = 3.5, HeadInPlLine4 = 3.2, WaterLevelRiverHigh = 4.0, WaterLevelPolder = waterLevelPolder, SoilProfile2D = soilProfile2D, SoilProfileType = SoilProfileType.ProfileType2D, SurfaceLine = surfaceLine, DikeEmbankmentMaterial = new Soil() }; var location = new Location(); // Call PlLines plLines = plLineCreator.CreateAllPlLines(location, out _); // Assert Assert.That(plLines.Lines, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl1].Points, Has.Count.EqualTo(8)); Assert.That(plLines.Lines[PlLineType.Pl3].Points, Has.Count.EqualTo(4)); if (isInBetweenLayerAquifer) { Assert.That(plLines.Lines[PlLineType.Pl4].Points, Has.Count.EqualTo(4)); } else { Assert.That(plLines.Lines[PlLineType.Pl4].Points, Is.Empty); Assert.That(plLines.Lines[PlLineType.Pl2].Points, Is.Empty); } }); double expectedIntersectionDitchPl1 = waterLevelPolder > -8 ? expectedXPl3 : 58.5; Assert.Multiple(() => { // only few points are checked for PL 1 Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[5].X, Is.EqualTo(expectedIntersectionDitchPl1).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[5].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[6].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[7].X, Is.EqualTo(75).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[7].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[0].Z, Is.EqualTo(plLineCreator.HeadInPlLine3).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[1].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[1].Z, Is.EqualTo(plLineCreator.HeadInPlLine3)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[2].X, Is.EqualTo(expectedXPl3).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[2].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[3].X, Is.EqualTo(75).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[3].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); if (isInBetweenLayerAquifer) { Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].Z, Is.EqualTo(plLineCreator.HeadInPlLine4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].X, Is.EqualTo(10).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].Z, Is.EqualTo(plLineCreator.HeadInPlLine4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].X, Is.EqualTo(expectedXPl4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].X, Is.EqualTo(75).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].Z, Is.EqualTo(waterLevelPolder).Within(tolerance4Decimals)); } }); } /// /// The input is generated using the data attached to issue MWDAM-2631 for profile "RK105-320". /// In this profile the in-between aquifer intersects the surface line at X=24.170 and PL1 is situated below the surface line. /// Expected is that PL4 is reduced to the PL1 level at X=24.170 and then is horizontal. /// [Test] public void Given1DProfileFromInputXmlWithInBetweenAquiferCuttingTheSurfaceLineAtPolder_WhenCreatingThePlLines_ThenExpectedPl4Returned() { const string mapTestFiles = @"PlLinesCreator\TestFiles\PlLinesCreatorTests\"; // Setup const string inputFilename = "Input1DProfileWithInBetweenAquiferCuttingTheSurfaceLine.xml"; string fullInputFilename = Path.Combine(mapTestFiles, inputFilename); Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string inputString = File.ReadAllText(fullInputFilename); var engineInterface = new EngineInterface(inputString); Location location = engineInterface.DamProjectData.Dike.Locations[0]; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { IsUseLowWaterLevel = false, WaterLevelRiverHigh = engineInterface.DamProjectData.Dike.Locations[0].Scenarios[0].RiverLevel, SurfaceLine = location.SurfaceLine, WaterLevelPolder = location.CurrentScenario.PolderLevel, HeadInPlLine2 = location.CurrentScenario.HeadPl2, HeadInPlLine3 = location.CurrentScenario.HeadPl3, HeadInPlLine4 = location.CurrentScenario.HeadPl4, ModelParametersForPlLines = location.ModelParametersForPlLines, SoilProfile = engineInterface.DamProjectData.Dike.SoilProfiles.First(s => s.Name == "RK105-320"), SoilProfileType = SoilProfileType.ProfileType1D, IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled = true, PlLineOffsetBelowDikeTopAtRiver = location.CurrentScenario.PlLineOffsetBelowDikeTopAtRiver, PlLineOffsetBelowDikeTopAtPolder = location.CurrentScenario.PlLineOffsetBelowDikeTopAtPolder, PlLineOffsetBelowShoulderBaseInside = location.CurrentScenario.PlLineOffsetBelowShoulderBaseInside, PlLineOffsetBelowDikeToeAtPolder = location.CurrentScenario.PlLineOffsetBelowDikeToeAtPolder, PlLineOffsetBelowDikeCrestMiddle = location.CurrentScenario.PlLineOffsetBelowDikeCrestMiddle, UsePlLineOffsetFactorBelowShoulderCrest = location.CurrentScenario.UsePlLineOffsetFactorBelowShoulderCrest, DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(), SoilList = location.SoilList }; // Call PlLines plLines = plLineCreator.CreateAllPlLines(location, out _); // Assert Assert.That(plLines.Lines[PlLineType.Pl4].Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].Z, Is.EqualTo(plLineCreator.HeadInPlLine4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].X, Is.EqualTo(10.0007).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].Z, Is.EqualTo(plLineCreator.HeadInPlLine4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].X, Is.EqualTo(24.1699).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].Z, Is.EqualTo(-2.2000).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].X, Is.EqualTo(49.3657).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].Z, Is.EqualTo(-2.2000).Within(tolerance4Decimals)); // Check that level Z=-2.2000 is indeed the PL 1 level at X=24.1699 m double pl1Level = plLines.Lines[PlLineType.Pl1].ZFromX(plLines.Lines[PlLineType.Pl4].Points[2].X); Assert.That(pl1Level, Is.EqualTo(-2.2000).Within(tolerance4Decimals)); }); } [Test] public void CreatePL1For2DGeometryWithExpertKnowledgeRRD() { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfileType = SoilProfileType.ProfileType2D, SoilProfile = null, WaterLevelRiverHigh = 4.0, ModelParametersForPlLines = { PenetrationLength = 1.0, DampingFactorPl3 = 0.3, DampingFactorPl4 = 0.4, PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD }, HeadInPlLine2 = 0.0, SurfaceLine = FactoryForSurfaceLines.CreateSurfacelineSimpleDike() }; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetPoint2D(CharacteristicPointType.DikeToeAtPolder).Z - 1.0; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl1, 0.02); Assert.That(plLine.Points, Has.Count.EqualTo(6)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].X, Is.EqualTo(3.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].X, Is.EqualTo(4.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[2].Z, Is.EqualTo(3.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].X, Is.EqualTo(7.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[3].Z, Is.EqualTo(2.5).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[4].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].X, Is.EqualTo(12.0).Within(tolerance4Decimals)); Assert.That(plLine.Points[5].Z, Is.EqualTo(0.9).Within(tolerance4Decimals)); }); } [Test] [TestCase(1, true)] // top level penetration zone in bottom aquitard (OK) [TestCase(1.99, true)] // top level penetration zone in bottom aquitard (OK) [TestCase(2, true)] // top level penetration zone coincides partly with in-between aquifer (OK) [TestCase(2.01, false)] // top level penetration zone partly above in-between aquifer (not OK) [TestCase(4.5, false)] // top level penetration zone in middle aquitard (not OK) [TestCase(16.5, false)] // top level penetration zone partly above surface line (not OK) [TestCase(21.5, false)] // top level penetration zone completely above surface line (not OK) public void IsPenetrationZoneCompletelyWithinInfiltrationZoneTest(double penetrationLength, bool expectedResult) { var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SoilProfileType = SoilProfileType.ProfileType2D, SoilProfile = null, SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DWithNonHorizontalBottomAquitard(out SurfaceLine2 line), ModelParametersForPlLines = { PenetrationLength = penetrationLength }, SurfaceLine = line }; bool result = plLineCreator.IsPenetrationZoneCompletelyWithinInfiltrationZone(penetrationLength); Assert.That(result, Is.EqualTo(expectedResult)); } [Test] [SetUICulture("nl-NL")] [TestCase(1, false)] // top level penetration zone (-5m) in bottom aquitard [TestCase(2.5, true)] // top level penetration zone (-3.5m) half in bottom aquitard, half in in-between aquifer [TestCase(4.5, true)] // top level penetration zone (-2.5m) in middle aquitard [TestCase(16.5, true)] // top level penetration zone (10.5m) partly above surface line public void Given2DGeometry_WhenTopLevelOfPenetrationIsInAquifer_ThenPl2IsEqualToPl4(double penetrationLength, bool isPl2EqualToPl4) { const double headPl4 = 3.2; const double headPl2 = 2.5; var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { ModelParametersForPlLines = { PlLineCreationMethod = PlLineCreationMethod.ExpertKnowledgeRRD, PenetrationLength = penetrationLength, DampingFactorPl4 = 0 }, HeadInPlLine4 = headPl4, WaterLevelRiverHigh = 11.0, WaterLevelPolder = 9.0, HeadInPlLine2 = headPl2, SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DWithNonHorizontalBottomAquitard(out SurfaceLine2 line), SoilProfileType = SoilProfileType.ProfileType2D, SurfaceLine = line, DikeEmbankmentMaterial = new Soil() }; var location = new Location(); // Call PlLines plLines = plLineCreator.CreateAllPlLines(location, out string warningMessage); // Assert Assert.That(plLines.Lines[PlLineType.Pl4], Is.Not.Null); Assert.That(plLines.Lines[PlLineType.Pl4].Points, Has.Count.EqualTo(2)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].Z, Is.EqualTo(headPl4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].X, Is.EqualTo(75).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].Z, Is.EqualTo(headPl4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl2], Is.Not.Null); }); Assert.That(plLines.Lines[PlLineType.Pl2].Points, Has.Count.EqualTo(2)); Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl2].Points[0].X, Is.EqualTo(0).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl2].Points[1].X, Is.EqualTo(75).Within(tolerance4Decimals)); }); if (isPl2EqualToPl4) { Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl2].Points[0].Z, Is.EqualTo(headPl4).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl2].Points[1].Z, Is.EqualTo(headPl4).Within(tolerance4Decimals)); Assert.That(warningMessage, Is.EqualTo("De door de gebruiker gedefinieerde indringingszone overlapt " + "gedeeltelijk of strekt zich uit boven het tussenliggende watervoerende pakket. " + "Daarom wordt PL 2 gelijkgesteld aan PL 4.")); }); } else { Assert.Multiple(() => { Assert.That(plLines.Lines[PlLineType.Pl2].Points[0].Z, Is.EqualTo(headPl2).Within(tolerance4Decimals)); Assert.That(plLines.Lines[PlLineType.Pl2].Points[1].Z, Is.EqualTo(headPl2).Within(tolerance4Decimals)); Assert.That(warningMessage, Is.Null); }); } } /// /// _______ Level 10 m /// / Clay \ /// /---------\ Level 6 m /// / Aquifer \ /// /-------------\ X=58.5 Level 2 m /// -----------/ Clay \------\ /-------- Level 0 m /// -----------------------------------\ /--------- Level -2 m /// In between layer \ / /// -------------------------------------\ /----------- Level -4 m /// Clay \ / /// ---------------------------------------\ /------------- Level -6 m /// \_____/ Level -8 m /// Bottom aquifer X=59.5 /// ------------------------------------------------------------- Level -10 m /// private static SoilProfile2D CreateSoilProfile2DWithLayersCuttingTheDitch(bool isInBetweenLayerAquifer, out SurfaceLine2 surfaceLine) { surfaceLine = FactoryForSurfaceLines.CreateSurfaceLineWithDikeAndDitch(10, -8); SoilProfile1D soilProfile1D = FactoryForSoilProfiles.CreateClaySandClaySandClaySandProfile(10, 6, 2, 0 - 2, -4, -6); soilProfile1D.Layers[3].IsAquifer = isInBetweenLayerAquifer; soilProfile1D.BottomLevel = -10; var soilSurfaceProfile = new SoilSurfaceProfile { SoilProfile = soilProfile1D, SurfaceLine2 = surfaceLine, DikeEmbankmentMaterial = new Soil(), Name = "Test" }; return soilSurfaceProfile.ConvertToSoilProfile2D(); } private void CheckPl3For1DGeometryWithExpertKnowledgeRrd(PlLine plLine) { // PlLine is supposed to have adjusted points at both banks of the ditch Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // entry point Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(59.5).Within(tolerance4Decimals)); // ditch due to adjustment for uplift Assert.That(plLine.Points[2].Z, Is.EqualTo(1.6376).Within(tolerance4Decimals)); // head ditch Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[3].Z, Is.EqualTo(1.3276).Within(tolerance4Decimals)); // headAtDikeEnd }); } private void CheckPl3For1DGeometryWithExpertKnowledgeRrdWithHeadPl2Specified(PlLine plLine) { // PlLine is supposed to have adjusted points at both banks of the ditch Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // entry point Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(50.5).Within(tolerance4Decimals)); // ditch due to adjustment for uplift Assert.That(plLine.Points[2].Z, Is.EqualTo(1.3).Within(tolerance4Decimals)); // head ditch Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[3].Z, Is.EqualTo(0.81).Within(tolerance4Decimals)); // headAtDikeEnd }); } private void CheckPl3LowFor1DGeometryWithExpertKnowledgeRrd(PlLine plLine) { Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(1.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // toe of dike Assert.That(plLine.Points[1].Z, Is.EqualTo(1.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(50.5).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[2].Z, Is.EqualTo(0.55).Within(tolerance4Decimals)); // headAtDikeEnd Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[3].Z, Is.EqualTo(0.06).Within(tolerance4Decimals)); // headAtDikeEnd }); } private void CheckPl4LowFor1DGeometryWithExpertKnowledgeRrd(PlLine plLine) { // PlLine is supposed to have adjusted points at dike toe and end Assert.That(plLine.Points, Has.Count.EqualTo(4)); Assert.Multiple(() => { Assert.That(plLine.Points[0].X, Is.EqualTo(0.0).Within(tolerance4Decimals)); // start Assert.That(plLine.Points[0].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[1].X, Is.EqualTo(10.0).Within(tolerance4Decimals)); // entry point Assert.That(plLine.Points[1].Z, Is.EqualTo(4.0).Within(tolerance4Decimals)); // water level at river Assert.That(plLine.Points[2].X, Is.EqualTo(50.5).Within(tolerance4Decimals)); // dike toe Assert.That(plLine.Points[2].Z, Is.EqualTo(2.2).Within(tolerance4Decimals)); // head dike toe Assert.That(plLine.Points[3].X, Is.EqualTo(75.0).Within(tolerance4Decimals)); // end Assert.That(plLine.Points[3].Z, Is.EqualTo(1.71).Within(tolerance4Decimals)); // head end }); } }