// Copyright (C) Stichting Deltares 2024. 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 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.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.GetGeometryPoint(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.GetGeometryPoint(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.GetGeometryPoint(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.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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.GetGeometryPoint(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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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.GetGeometryPoint(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.GetGeometryPoint(CharacteristicPointType.DikeTopAtRiver).Z; plLineCreator.WaterLevelPolder = plLineCreator.SurfaceLine.CharacteristicPoints.GetGeometryPoint(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.GetGeometryPoint(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 polderlevel /// [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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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); surfaceLine.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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.GetGeometryPoint(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.Geometry.SyncCalcPoints(); 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.GetGeometryPoint(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()), 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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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 GeometryPoint(1.0, 2.0)); surfaceLine.AddCharacteristicPoint(new GeometryPoint(10.0, 2.0)); surfaceLine.AddCharacteristicPoint(new GeometryPoint(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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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, -1.5, -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] 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, -1.5, -5), SurfaceLine = surfaceLineTutorial1, DikeEmbankmentMaterial = new Soil() }; var location = new Location(); PlLines plLines = plLineCreator.CreateAllPlLines(location); 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); } } [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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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.That(plLineCreator.SoilProfile.InfiltrationLayer, Is.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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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.That(plLineCreator.SoilProfile.InfiltrationLayer, Is.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 GeometryPoint(1.0, 2.0)); surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new GeometryPoint(21.0, 2.5)); surfaceLine.Geometry.SyncCalcPoints(); 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.That(plLineCreator.SoilProfile.InfiltrationLayer, Is.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, -1.5, -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, -1.5, -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, -1.5, -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); 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]), 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]); 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]); 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]); 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 /// -----------/ 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 [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 [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) { SurfaceLine2 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" }; SoilProfile2D soilProfile2D = soilSurfaceProfile.ConvertToSoilProfile2D(); 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); // 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)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[0].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[1].Z, Is.EqualTo(plLineCreator.WaterLevelRiverHigh)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[5].X, Is.EqualTo(expectedIntersectionDitchPl1)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[5].Z, Is.EqualTo(waterLevelPolder)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[6].Z, Is.EqualTo(waterLevelPolder)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[7].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl1].Points[7].Z, Is.EqualTo(waterLevelPolder)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[0].X, Is.EqualTo(0)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[0].Z, Is.EqualTo(plLineCreator.HeadInPlLine3)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[1].X, Is.EqualTo(10)); 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)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[2].Z, Is.EqualTo(waterLevelPolder)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[3].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl3].Points[3].Z, Is.EqualTo(waterLevelPolder)); if (isInBetweenLayerAquifer) { Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].X, Is.EqualTo(0)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[0].Z, Is.EqualTo(plLineCreator.HeadInPlLine4)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].X, Is.EqualTo(10)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[1].Z, Is.EqualTo(plLineCreator.HeadInPlLine4)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].X, Is.EqualTo(expectedXPl4)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[2].Z, Is.EqualTo(waterLevelPolder)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].X, Is.EqualTo(75)); Assert.That(plLines.Lines[PlLineType.Pl4].Points[3].Z, Is.EqualTo(waterLevelPolder)); } }); } 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 }); } [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.GetGeometryPoint(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)); }); } }