Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs =================================================================== diff -u -r6895 -r6923 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 6895) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 6923) @@ -186,7 +186,7 @@ plLine = CreatePlLine1ByExpertKnowledge(); break; case PlLineType.Pl2: - plLine = CreatePlLine2ByExpertKnowledge(ModelParametersForPlLines.PenetrationLength, HeadInPlLine2); + plLine = CreatePlLine2ByExpertKnowledge(); break; case PlLineType.Pl3: plLine = CreatePlLine3ByExpertKnowledge(DetermineHeadPl3(), ModelParametersForPlLines.DampingFactorPl3, slopeGradient); @@ -312,12 +312,12 @@ return false; } - internal bool IsPenetrationZoneCompletelyWithinInfiltrationZone(double penetrationLength) + internal bool IsPenetrationZoneCompletelyWithinInfiltrationZone() { return SoilProfileType switch { - SoilProfileType.ProfileType1D => IsPenetrationZoneCompletelyWithinInfiltrationZoneFor1DGeometry(penetrationLength), - SoilProfileType.ProfileType2D => IsPenetrationZoneCompletelyWithinInfiltrationZoneFor2DGeometry(penetrationLength), + SoilProfileType.ProfileType1D => IsPenetrationZoneCompletelyWithinInfiltrationZoneFor1DGeometry(), + SoilProfileType.ProfileType2D => IsPenetrationZoneCompletelyWithinInfiltrationZoneFor2DGeometry(), _ => false }; } @@ -411,11 +411,11 @@ /// Create PL2 (is pl line for penetration) /// /// - private PlLine CreatePlLine2ByExpertKnowledge(double penetrationLength, double? headInPlLine2) + private PlLine CreatePlLine2ByExpertKnowledge() { var plLine = new PlLine(); - if (penetrationLength < 0.0) + if (ModelParametersForPlLines.PenetrationLength < 0.0) { throw new PlLinesCreatorException("Negative penetration length."); } @@ -425,17 +425,17 @@ return plLine; } - if (IsPenetrationZoneCompletelyWithinInfiltrationZone(penetrationLength)) + if (IsPenetrationZoneCompletelyWithinInfiltrationZone()) { plLine = new PlLine(); - plLine.Points.Add(new PlLinePoint(SurfaceLine.Geometry.Points.First().X, headInPlLine2.Value)); - plLine.Points.Add(new PlLinePoint(SurfaceLine.Geometry.Points.Last().X, headInPlLine2.Value)); + plLine.Points.Add(new PlLinePoint(SurfaceLine.Geometry.Points.First().X, HeadInPlLine2.Value)); + plLine.Points.Add(new PlLinePoint(SurfaceLine.Geometry.Points.Last().X, HeadInPlLine2.Value)); } return plLine; } - private bool IsPenetrationZoneCompletelyWithinInfiltrationZoneFor1DGeometry(double penetrationLength) + private bool IsPenetrationZoneCompletelyWithinInfiltrationZoneFor1DGeometry() { SoilProfile1D relevantSoilProfile = GetRelevantSoilProfileForAquiferLayersSearch(); // Determine the top level of the infiltration layers: @@ -456,15 +456,15 @@ if (infiltrationLayers.Count > 0) { - double penetrationZoneTopLevel = relevantSoilProfile.BottomAquiferLayer.TopLevel + penetrationLength; + double penetrationZoneTopLevel = relevantSoilProfile.BottomAquiferLayer.TopLevel + ModelParametersForPlLines.PenetrationLength; return penetrationZoneTopLevel <= infiltrationLayers.First().TopLevel; } return false; } - private bool IsPenetrationZoneCompletelyWithinInfiltrationZoneFor2DGeometry(double penetrationLength) + private bool IsPenetrationZoneCompletelyWithinInfiltrationZoneFor2DGeometry() { // Determine the top level of the infiltration zone (= lowest zone with only aquitards) SoilProfile2DHelper.DetermineInBetweenAquifersLayerBoundaryPoints(SoilProfile2D, out List inBetweenAquiferUpperCoordinates, @@ -481,7 +481,7 @@ // Determine the top level of the (user-defined) penetration zone SoilProfile2DHelper.DetermineAquiferLayerBoundaryPoints(SoilProfile2DHelper.LayerType.BottomAquiferCluster, SoilProfile2D, out Point2D[] bottomAquiferCoordinates, out _); - List topLevelPenetrationZone = bottomAquiferCoordinates.Select(p => new Point2D(p.X, p.Z + penetrationLength)).ToList(); + List topLevelPenetrationZone = bottomAquiferCoordinates.Select(p => new Point2D(p.X, p.Z + ModelParametersForPlLines.PenetrationLength)).ToList(); // Compare both lines: check if the top level of the penetration zone has a point above the top level of the // infiltration layers. If so, return false. Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs =================================================================== diff -u -r6917 -r6923 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 6917) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 6923) @@ -987,10 +987,12 @@ } /// - /// Test if PL2 is created correctly if no inbetween aquifer present + /// Test if PL2 is created correctly if no in-between aquifer present /// [Test] - public void CreatePL2For1DGeometryWithExpertKnowledgeRRDIfNoAquiferLayerInBetween() + [TestCase(false)] + [TestCase(true)] + public void CreatePL2For1DGeometryWithExpertKnowledgeRRDIfNoAquiferLayerInBetween(bool is2DBasedOn1D) { const double cHeadPL2 = 3.0; const double cPenetrationLength = 6.0; @@ -1006,15 +1008,18 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, - SoilProfile = FactoryForSoilProfiles.CreateClaySandProfile(out _), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, - HeadInPlLine2 = cHeadPL2 + HeadInPlLine2 = cHeadPL2, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1039,10 +1044,12 @@ } /// - /// Test if PL2 is created correctly if no inbetween aquifer present and penetration length = 0 + /// Test if PL2 is created correctly if no in-between aquifer present and penetration length = 0 /// [Test] - public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthZero() + [TestCase(false)] + [TestCase(true)] + public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthZero(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 0.0; @@ -1057,15 +1064,18 @@ surfaceLine.AddCharacteristicPoint(new Point2D(1.0, 2.0)); surfaceLine.AddCharacteristicPoint(new Point2D(10.0, 2.0)); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, - SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, - HeadInPlLine2 = cHeadPl2 + HeadInPlLine2 = cHeadPl2, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1079,10 +1089,12 @@ } /// - /// Test if PL2 is created correctly if no inbetween aquifer present and penetration length above that aquifer + /// Test if PL2 is created correctly if no in-between aquifer present and penetration length above that aquifer /// [Test] - public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthAboveThisSandLayer() + [TestCase(false)] + [TestCase(true)] + public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthAboveThisSandLayer(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 6.0; @@ -1098,15 +1110,18 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { SurfaceLine = surfaceLine, - SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), ModelParametersForPlLines = { PenetrationLength = cPenetrationLength }, - HeadInPlLine2 = cHeadPl2 + HeadInPlLine2 = cHeadPl2, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1118,11 +1133,14 @@ /// Test if PL2 is NOT created if in-between aquifer present and penetration length ending in that aquifer /// [Test] - public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer() + [TestCase(false)] + [TestCase(true)] + public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer(bool is2DBasedOn1D) { const double cPenetrationLength = 4.0; const double cHeadPl2 = 3.0; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { HeadInPlLine2 = cHeadPl2, @@ -1134,8 +1152,10 @@ }, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, - SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), - SurfaceLine = surfaceLineTutorial1 + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLineTutorial1), + SurfaceLine = surfaceLineTutorial1, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1147,12 +1167,15 @@ /// Test if PL2 and PL4 are created correctly if in-between aquifer present and penetration length ending in that aquifer /// [Test] + [TestCase(false)] + [TestCase(true)] [SetUICulture("nl-NL")] - public void CreatePL2andPL4For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer() + public void CreatePL2andPL4For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthInThisAquiferLayer(bool is2DBasedOn1D) { const double cPenetrationLength = 4.0; const double cHeadInPlLine2 = 3.0; SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { HeadInPlLine2 = cHeadInPlLine2, @@ -1165,10 +1188,12 @@ }, WaterLevelRiverHigh = 4.0, WaterLevelPolder = -0.5, - SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(10, -0.5), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLineTutorial1), SurfaceLine = surfaceLineTutorial1, DikeEmbankmentMaterial = new Soil() }; + plLineCreator.SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D; var location = new Location(); PlLines plLines = plLineCreator.CreateAllPlLines(location, out string warningMessage); @@ -1186,12 +1211,15 @@ { 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() + [TestCase(false)] + [TestCase(true)] + public void CreatePL2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthBelowBottomOfThisAquiferLayer(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 3.0; @@ -1207,15 +1235,18 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { - SoilProfile = FactoryForSoilProfiles.CreateClaySandClaySandProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength - } + }, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1229,7 +1260,9 @@ } [Test] - public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthBelowBottomOfThisAquiferLayerWithMultipleInfiltrationLayers() + [TestCase(false)] + [TestCase(true)] + public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithSandLayerInBetweenAndPenetrationLengthBelowBottomOfThisAquiferLayerWithMultipleInfiltrationLayers(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 2.0; @@ -1245,15 +1278,18 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { - SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength - } + }, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1274,7 +1310,9 @@ } [Test] - public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfAInfiltrationLayer() + [TestCase(false)] + [TestCase(true)] + public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfAInfiltrationLayer(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 2.7; @@ -1290,15 +1328,18 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { - SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength - } + }, + SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D }; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -1319,7 +1360,9 @@ } [Test] - public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfSandLayer() + [TestCase(false)] + [TestCase(true)] + public void CreatePl2For1DGeometryWithExpertKnowledgeRRDWithAquiferLayerInBetweenAndPenetrationLengthExactlyAtBottomOfSandLayer(bool is2DBasedOn1D) { const double cHeadPl2 = 3.0; const double cPenetrationLength = 3.5; @@ -1335,16 +1378,19 @@ surfaceLine.EnsurePointOfType(10.0, 2.0, CharacteristicPointType.DikeToeAtPolder); surfaceLine.AddCharacteristicPoint(new Point2D(21.0, 2.5)); + SoilProfile1D soilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(); var plLineCreator = new Calculators.PlLinesCreator.PlLinesCreator { - SoilProfile = FactoryForSoilProfiles.CreateMultiInfiltrationLayerProfile(), + SoilProfile = soilProfile, + SoilProfile2D = FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile, surfaceLine), SurfaceLine = surfaceLine, HeadInPlLine2 = cHeadPl2, ModelParametersForPlLines = { PenetrationLength = cPenetrationLength } }; + plLineCreator.SoilProfileType = is2DBasedOn1D ? SoilProfileType.ProfileType2D : SoilProfileType.ProfileType1D; PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl2, 0.02); @@ -2388,7 +2434,7 @@ 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) @@ -2410,16 +2456,15 @@ }, SurfaceLine = line }; - - bool result = plLineCreator.IsPenetrationZoneCompletelyWithinInfiltrationZone(penetrationLength); - + + bool result = plLineCreator.IsPenetrationZoneCompletelyWithinInfiltrationZone(); + Assert.That(result, Is.EqualTo(expectedResult)); - } - + [Test] [SetUICulture("nl-NL")] - [TestCase(1, false)] // top level penetration zone (-5m) in bottom aquitard + [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 @@ -2448,7 +2493,7 @@ // 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)); @@ -2513,7 +2558,7 @@ soilProfile1D.BottomLevel = -10; return FactoryForSoilProfiles.CreateSoilProfile2DBasedOnSoilProfile1D(soilProfile1D, surfaceLine); } - + private void CheckPl3For1DGeometryWithExpertKnowledgeRrd(PlLine plLine) { // PlLine is supposed to have adjusted points at both banks of the ditch