Index: DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs
===================================================================
diff -u -r5556 -r5981
--- DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs (.../FactoryForSurfaceLines.cs) (revision 5556)
+++ DamEngine/trunk/src/Deltares.DamEngine.TestHelpers/Factories/FactoryForSurfaceLines.cs (.../FactoryForSurfaceLines.cs) (revision 5981)
@@ -27,12 +27,11 @@
public static class FactoryForSurfaceLines
{
///
- /// Creates a surface line, that is almost the same as Tutorial 1
+ /// Creates a surface line, that is almost the same as Tutorial 1
///
/// surface line
- public static SurfaceLine2 CreateSurfaceLineTutorial1(bool includingTraffic = false)
+ public static SurfaceLine2 CreateSurfaceLineTutorial1(bool includingTraffic = false, double ditchBottomLevel = -2)
{
- //Surface line tutorial 1
var surfaceLine = new SurfaceLine2
{
Name = "Tutorial1",
@@ -56,8 +55,8 @@
surfaceLine.EnsurePointOfType(40.5, 5, CharacteristicPointType.DikeTopAtPolder);
surfaceLine.EnsurePointOfType(50.5, 0, CharacteristicPointType.DikeToeAtPolder);
surfaceLine.EnsurePointOfType(58.5, 0, CharacteristicPointType.DitchDikeSide);
- surfaceLine.EnsurePointOfType(59.5, -2, CharacteristicPointType.BottomDitchDikeSide);
- surfaceLine.EnsurePointOfType(61.5, -2, CharacteristicPointType.BottomDitchPolderSide);
+ surfaceLine.EnsurePointOfType(59.5, ditchBottomLevel, CharacteristicPointType.BottomDitchDikeSide);
+ surfaceLine.EnsurePointOfType(61.5, ditchBottomLevel, CharacteristicPointType.BottomDitchPolderSide);
surfaceLine.EnsurePointOfType(61.51, 0, CharacteristicPointType.DitchPolderSide);
surfaceLine.EnsurePointOfType(75.0, 0, CharacteristicPointType.SurfaceLevelInside);
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs
===================================================================
diff -u -r5960 -r5981
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 5960)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/PlLinesCreator.cs (.../PlLinesCreator.cs) (revision 5981)
@@ -22,6 +22,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Deltares.DamEngine.Calculators.KernelWrappers.Common;
using Deltares.DamEngine.Calculators.Uplift;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Gauges;
@@ -40,7 +41,7 @@
private const double cUpliftFactorEquilibrium = 1.0;
private const double cOffsetPhreaticLineBelowSurface = 0.01;
protected readonly Dictionary cachedSoilProfiles1D = new Dictionary();
-
+
private double? waterLevelRiverLow;
private PlLine currentPl1Line; // is needed when calculating uplift reduction for PL3 and Pl4
@@ -149,7 +150,7 @@
break;
}
- // If PL Line2 does not exist, make it equal to PL line 4
+ // If PL line 2 does not exist, make it equal to PL line 4
if (!plLines.Lines[PlLineType.Pl2].Exists())
{
plLines.Lines[PlLineType.Pl2] = plLines.Lines[PlLineType.Pl4].Clone();
@@ -380,7 +381,7 @@
return plLine;
}
-
+
///
/// Create PL3
///
@@ -402,12 +403,12 @@
private PlLine CreatePlLine3Or4ByExpertKnowledge(double headValue, double dampingFactor, PlLineType plLineType, double slopeGradient)
{
var plLine = new PlLine();
-
+
if (dampingFactor < 0.0)
{
throw new PlLinesCreatorException("Damping factor < 0.0");
}
-
+
// Soil profile 1D below toe of dike at polder is used to check if there is really a relevant aquifer.
SoilProfile1D actualSoilProfile = GetRelevantSoilProfileForAquiferLayersSearch();
SoilLayer1D relevantAquiferLayer = GetRelevantAquiferLayer(plLineType, actualSoilProfile);
@@ -417,16 +418,27 @@
double headAtPolderDikeToe = headValue - Math.Max(0, dampingFactor * (headValue - referenceLevel));
plLine.Points.Add(new PlLinePoint(SurfaceLine.Geometry.Points.First().X, headValue));
plLine.Points.Add(new PlLinePoint(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X, headValue));
- plLine.Points.Add(new PlLinePoint(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, headAtPolderDikeToe));
- // Now continue PlLine to the end with a slope of SlopeGradient
- AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, plLine);
-
- if (IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled)
+ SoilProfile2D soilProfile2D = SoilProfileType == SoilProfileType.ProfileType2D ? SoilProfile2D : DetermineSoilProfile2DFrom1D();
+ SoilProfile2DHelper.LayerType aquiferType = plLineType == PlLineType.Pl3 ? SoilProfile2DHelper.LayerType.BottomAquiferCluster : SoilProfile2DHelper.LayerType.InBetweenAquiferCluster;
+ double xStart = SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X;
+ if (SoilProfile2DHelper.IsSurfaceLineIntersectedByAquifer(aquiferType, soilProfile2D, xStart, out GeometryPoint intersectionAquifer))
{
- AdjustLineAccordingToTrwUplift(plLine, plLineType, slopeGradient);
+ ReducePlLineToPl1(soilProfile2D, intersectionAquifer, plLine);
}
+ else
+ {
+ plLine.Points.Add(new PlLinePoint(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).X, headAtPolderDikeToe));
+ // Now continue PlLine to the end with a slope of SlopeGradient
+ AddTailOfPl3OrPl4WithSlopeGradient(slopeGradient, plLine);
+
+ if (IsAdjustPL3AndPL4SoNoUpliftWillOccurEnabled)
+ {
+ AdjustLineAccordingToTrwUplift(plLine, plLineType, slopeGradient);
+ }
+ }
+
EnsureDescendingLine(plLine);
RemoveRedundantPoints(plLine);
@@ -436,6 +448,28 @@
}
///
+ /// Refer to Word document "20250116 Schematisatie freatische lijn en waterspanningen waarbij teensloot een aquifer insnijdt"
+ /// in doc/Work folder for details on the reduction of the PL-line.
+ ///
+ /// The soil profile.
+ /// The intersection point of the surface line (often ditch) with the aquifer.
+ /// The PL-line.
+ private void ReducePlLineToPl1(SoilProfile2D soilProfile2D, GeometryPoint intersectionAquifer, PlLine plLine)
+ {
+ if (IsDitchIntersectedByPl1(soilProfile2D, intersectionAquifer, out GeometryPoint intersectDitchPl1))
+ {
+ plLine.Points.Add(new PlLinePoint(intersectDitchPl1.X, intersectDitchPl1.Z));
+ plLine.Points.Add(new PlLinePoint(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X, intersectDitchPl1.Z));
+ }
+ else
+ {
+ double pl1Level = currentPl1Line.ZFromX(intersectionAquifer.X);
+ plLine.Points.Add(new PlLinePoint(intersectionAquifer.X, pl1Level));
+ plLine.Points.Add(new PlLinePoint(SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.SurfaceLevelInside).X, pl1Level));
+ }
+ }
+
+ ///
/// Continue PlLine to the end with a slope of slope gradient
/// If PlLine is lower than polder level, continue with polder level
///
@@ -894,7 +928,7 @@
private PlLines CreateAllPlLinesWithExpertKnowledge(Location location)
{
ValidateSoilProfileForPlLinesCreation();
-
+
var plLines = new PlLines();
foreach (PlLineType plLineType in Enum.GetValues(typeof(PlLineType)))
{
@@ -1647,7 +1681,7 @@
{
throw new PlLinesCreatorException("Characteristic point \"dike toe at polder\" is not defined.");
}
-
+
return GetSoilProfileBelowPoint(relevantPoint.X);
}
@@ -1691,4 +1725,60 @@
validator.ValidateSoilProfileForPlLinesCreator();
}
+
+ private SoilProfile2D DetermineSoilProfile2DFrom1D()
+ {
+ var soilSurfaceProfile = new SoilSurfaceProfile
+ {
+ SoilProfile = SoilProfile,
+ SurfaceLine2 = SurfaceLine,
+ DikeEmbankmentMaterial = DikeEmbankmentMaterial,
+ Name = SoilProfile.Name
+ };
+
+ return soilSurfaceProfile.ConvertToSoilProfile2D();
+ }
+
+ ///
+ /// The intersection of PL 1 with the ditch is found starting at .
+ /// If PL 1 (polder level) is higher than , search in the outward direction.
+ /// If PL 1 (polder level) is lower than , search in the inward direction.
+ /// Return the first intersection point found as .
+ ///
+ /// The soil profile 2D.
+ /// The intersection point of the ditch with the aquifer.
+ /// Returns the intersection point of the ditch with PL 1. If no intersection point is
+ /// found, returns null.
+ /// true if the ditch intersects the polder level; otherwise, false.
+ private bool IsDitchIntersectedByPl1(SoilProfile2D soilProfile2D, GeometryPoint intersectionDitchAquifer, out GeometryPoint intersectionDitchPl1)
+ {
+ const double toleranceAlmostEquals = 1e-6;
+ intersectionDitchPl1 = new GeometryPoint();
+ bool isPl1AboveAquifer = currentPl1Line.Points.Last().Z.IsGreaterThanOrEqualTo(intersectionDitchAquifer.Z);
+ GeometryPoint dikeToeAtPolder = SurfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder);
+ int indexStart = soilProfile2D.Geometry.SurfaceLine.Points.FindIndex(p => p.X.AlmostEquals(intersectionDitchAquifer.X, toleranceAlmostEquals));
+ int indexDikeToeAtPolder = soilProfile2D.Geometry.SurfaceLine.Points.FindIndex(p => p.X.AlmostEquals(dikeToeAtPolder.X, toleranceAlmostEquals));
+ int indexEnd = isPl1AboveAquifer ? indexDikeToeAtPolder : soilProfile2D.Geometry.SurfaceLine.Points.Count - 1;
+
+ int index = indexStart;
+ while (index != indexEnd)
+ {
+ GeometryPoint currentPoint = soilProfile2D.Geometry.SurfaceLine.Points[index];
+ GeometryPoint nextPoint = soilProfile2D.Geometry.SurfaceLine.Points[index + 1];
+ var surfaceLineSegment = new Line();
+ surfaceLineSegment.SetBeginAndEndPoints(new Point2D(currentPoint.X, currentPoint.Z), new Point2D(nextPoint.X, nextPoint.Z));
+ var phreaticPolderPartialLine = new Line();
+ PlLinePoint endPl1 = currentPl1Line.Points.Find(p => p.X.IsGreaterThanOrEqualTo(currentPoint.X, toleranceAlmostEquals));
+ PlLinePoint beginPl1 = currentPl1Line.Points.Find(p => p.X.IsLessThan(currentPoint.X, toleranceAlmostEquals));
+ phreaticPolderPartialLine.SetBeginAndEndPoints(new Point2D(beginPl1.X, beginPl1.Z), new Point2D(endPl1.X, endPl1.Z));
+ if (LineHelper.GetStrictIntersectionPoint(surfaceLineSegment, phreaticPolderPartialLine, ref intersectionDitchPl1))
+ {
+ return true;
+ }
+ index = isPl1AboveAquifer ? index - 1 : index + 1;
+ }
+
+ intersectionDitchPl1 = null;
+ return false;
+ }
}
\ No newline at end of file
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs
===================================================================
diff -u -r5969 -r5981
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5969)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5981)
@@ -54,6 +54,47 @@
private const double toleranceAlmostEqual = 1e-09;
///
+ /// Find the intersection point between the aquifer (bottom aquifer or in-between aquifer) and the surface line if relevant.
+ /// Start the search at in the inward direction.
+ /// Return the first intersection point found as .
+ ///
+ /// The type of aquifer: bottom aquifer or in-between aquifer.
+ /// The soil profile 2D.
+ /// The X coordinate of the starting point for the search.
+ /// The intersection point of the surface line (often the ditch) with the aquifer.
+ /// true if the aquifer intersects the surface line; otherwise, false.
+ public static bool IsSurfaceLineIntersectedByAquifer(LayerType aquiferType, SoilProfile2D soilProfile, double xStart, out GeometryPoint intersectionPoint)
+ {
+ intersectionPoint = new GeometryPoint();
+ double[] xCoordinates = DetermineAllXCoordinatesOfSoilProfile(soilProfile);
+ foreach (double xCoordinate in xCoordinates.Where(xCoordinate => xCoordinate.IsGreaterThanOrEqualTo(xStart)))
+ {
+ SoilProfile1D crossSection = soilProfile.GetSoilProfile1D(xCoordinate);
+ if (aquiferType == LayerType.BottomAquiferCluster)
+ {
+ if (crossSection.Layers.All(layer => layer.IsAquifer))
+ {
+ intersectionPoint.X = xCoordinate;
+ intersectionPoint.Z = crossSection.TopLevel;
+ return true;
+ }
+ }
+
+ if (aquiferType == LayerType.InBetweenAquiferCluster)
+ {
+ if (crossSection.Layers[0].IsAquifer && crossSection.Layers.Any(layer => !layer.IsAquifer))
+ {
+ intersectionPoint.X = xCoordinate;
+ intersectionPoint.Z = crossSection.TopLevel;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ ///
/// Check if at least one isolated in-between aquifer is present.
///
///
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/Common/PlLinesHelperTests.cs
===================================================================
diff -u -r5416 -r5981
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/Common/PlLinesHelperTests.cs (.../PlLinesHelperTests.cs) (revision 5416)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/KernelWrappers/Common/PlLinesHelperTests.cs (.../PlLinesHelperTests.cs) (revision 5981)
@@ -42,7 +42,8 @@
var location = new Location
{
CurrentScenario = new DesignScenario(),
- SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(),
+ // Ditch bottom level (-1.9 m) must be above the bottom aquifer (-2 m) to avoid reduction of PL 3
+ SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(false, -1.9),
DikeEmbankmentMaterial = soilList.Soils[0].Name,
SoilList = soilList
};
@@ -81,7 +82,8 @@
var location = new Location
{
CurrentScenario = new DesignScenario(),
- SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(),
+ // Ditch bottom level (-1.9 m) must be above the bottom aquifer (-2 m) to avoid reduction of PL 3
+ SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(false, -1.9),
DikeEmbankmentMaterial = soilList.Soils[0].Name,
SoilList = soilList
};
@@ -115,10 +117,10 @@
// expected values retrieved from debugging Dam Classic (rev.663)
// test CanCalculateThePipingFactorUsingSellmeijer4Forces
- // PL1 is same as TestCreatePlLinesHydraulicShortcutWithHeadPl3 (same riverlevel = 0.5)
- // PL3 is same as TestCreatePlLinesNoHydraulicShortcut because HeadInPlLine3 is given with value 1 and there is a
- // in between aquifer so Head (1.0) is used instead of riverlevel.
- // PL2 and PL4 now generated at riverlevel.
+ // PL1 is same as TestCreatePlLinesHydraulicShortcutWithHeadPl3 (same river level = 0.5)
+ // PL3 is same as TestCreatePlLinesNoHydraulicShortcut because HeadInPlLine3 is given with value 1 and there is an
+ // in between aquifer so Head (1.0) is used instead of river level.
+ // PL2 and PL4 now generated at river level.
SoilProfile1D soilProfile1D = FactoryForSoilProfiles.CreatePipingSellmeijerProfileWithOneSandLayer(out SoilList soilList);
AddLayerToSoilProfile(soilProfile1D, -4, false);
AddLayerToSoilProfile(soilProfile1D, -5, true);
@@ -130,7 +132,8 @@
var location = new Location
{
CurrentScenario = scenario,
- SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(),
+ // Ditch bottom level (-1.9 m) must be above the bottom aquifer (-2 m) to avoid reduction of PL 3
+ SurfaceLine = FactoryForSurfaceLines.CreateSurfaceLineTutorial1(false, -1.9),
DikeEmbankmentMaterial = soilList.Soils[0].Name,
SoilList = soilList
};
@@ -167,17 +170,17 @@
{
var layer = new SoilLayer1D
{
- Name = GetNewUniqueLayerId(soilProfile)
+ Name = GetNewUniqueLayerId(soilProfile),
+ TopLevel = topLevel,
+ Soil = new Soil("Sand", 22.0, 20.0)
+ {
+ PermeabKx = 0.0001,
+ DiameterD70 = Physics.FactorMicroMeterToMeter * 200.0,
+ WhitesConstant = 0.25,
+ BeddingAngle = 37.0
+ },
+ IsAquifer = isAquifer
};
- layer.TopLevel = topLevel;
- layer.Soil = new Soil("Sand", 22.0, 20.0)
- {
- PermeabKx = 0.0001,
- DiameterD70 = Physics.FactorMicroMeterToMeter * 200.0,
- WhitesConstant = 0.25,
- BeddingAngle = 37.0
- };
- layer.IsAquifer = isAquifer;
soilProfile.Layers.Add(layer);
}
Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs
===================================================================
diff -u -r5936 -r5981
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 5936)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/PlLinesCreatorTest.cs (.../PlLinesCreatorTest.cs) (revision 5981)
@@ -1633,10 +1633,13 @@
public void CreatePl4For1DGeometryWithExpertKnowledgeRrd()
{
const double cDampingFactor = 0.4;
- SurfaceLine2 surfaceLineTutorial1 = FactoryForSurfaceLines.CreateSurfaceLineTutorial1();
+ // 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,
@@ -1649,10 +1652,14 @@
// Change WaterLevelRiverHigh to be sure the value of HeadInPlLine3 is really used
HeadInPlLine4 = 4.0
};
-
- PlLine plLine = plLineCreator.CreatePlLineByExpertKnowledge(PlLineType.Pl4, 0.02);
-
- CheckPl4LowFor1DGeometryWithExpertKnowledgeRrd(plLine);
+ var location = new Location
+ {
+ SlopeDampingPiezometricHeightPolderSide = 0.02
+ };
+
+ PlLines plLines = plLineCreator.CreateAllPlLines(location);
+
+ CheckPl4LowFor1DGeometryWithExpertKnowledgeRrd(plLines.Lines[PlLineType.Pl4]);
}
[Test]
@@ -2026,7 +2033,121 @@
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