Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/SoilProfileValidatorTests.cs =================================================================== diff -u -r5822 -r5835 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/SoilProfileValidatorTests.cs (.../SoilProfileValidatorTests.cs) (revision 5822) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators.Tests/PlLinesCreator/SoilProfileValidatorTests.cs (.../SoilProfileValidatorTests.cs) (revision 5835) @@ -464,11 +464,11 @@ /// [Test] [SetUICulture("nl-NL")] - [TestCase(true, true)] - [TestCase(true, false)] - [TestCase(false, true)] - [TestCase(false, false)] - public void GivenSoilProfile2DWithInnerLoop_WhenValidating_ThenExpectedResultReturned(bool isOuterLoopAquifer, bool isInnerLoopAquifer) + [TestCase(true, true, true)] + [TestCase(true, false, true)] + [TestCase(false, true, false)] + [TestCase(false, false, true)] + public void GivenSoilProfile2DWithInnerLoop_WhenValidating_ThenExpectedResultReturned(bool isOuterLoopAquifer, bool isInnerLoopAquifer, bool isCombinationValid) { SurfaceLine2 surfaceLine = FactoryForSurfaceLines.CreateHorizontalSurfaceLine(8, leftCoordinate, rightCoordinate); var soilProfile = new SoilProfile2D @@ -501,7 +501,7 @@ SoilProfile2D = soilProfile, DikeEmbankmentMaterial = new Soil() }; - if ((isInnerLoopAquifer && !isOuterLoopAquifer) || (!isInnerLoopAquifer && isOuterLoopAquifer)) + if (!isCombinationValid) { Assert.That(() => soilProfileValidator.ValidateSoilProfileForPlLinesCreator(), Throws.InstanceOf().With.Message.EqualTo Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs =================================================================== diff -u -r5438 -r5835 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5438) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5835) @@ -70,12 +70,13 @@ public static bool IsAtLeastOneIsolatedInBetweenAquiferPresent(SoilProfile2D soilProfile) { - double[] xCoordinates = DetermineAllXCoordinatesOfSoilProfile(soilProfile); + SoilProfile2D soilProfileWithoutInnerLoops = CreateSoilProfileWithoutInnerLoops(soilProfile); + double[] xCoordinates = DetermineAllXCoordinatesOfSoilProfile(soilProfileWithoutInnerLoops); var previousCount = 0; SoilProfile1D previousCrossSection = null; for (var i = 0; i < xCoordinates.Length; i++) { - SoilProfile1D crossSection = soilProfile.GetSoilProfile1D(xCoordinates[i]); + SoilProfile1D crossSection = soilProfileWithoutInnerLoops.GetSoilProfile1D(xCoordinates[i]); int currentCount = crossSection.GetInBetweenAquiferClusters?.Count ?? 0; if (i > 0 && (currentCount != previousCount) && IsAtLeastOneIsolatedInBetweenAquiferPresent(currentCount, previousCount, crossSection, previousCrossSection)) @@ -90,6 +91,23 @@ return false; } + private static SoilProfile2D CreateSoilProfileWithoutInnerLoops(SoilProfile2D soilProfile) + { + SoilProfile2D soilProfileWithoutInnerLoops = soilProfile.Clone(); + + foreach (GeometrySurface geometrySurface in soilProfileWithoutInnerLoops.Geometry.Surfaces.Where(surface => surface.InnerLoops.Count > 0)) + { + geometrySurface.InnerLoops.Clear(); + } + + foreach (SoilLayer2D surface in soilProfileWithoutInnerLoops.Surfaces.Where(surface => surface.GeometrySurface.InnerLoops.Count > 0)) + { + surface.GeometrySurface.InnerLoops.Clear(); + } + + return soilProfileWithoutInnerLoops; + } + private static bool IsAtLeastOneIsolatedInBetweenAquiferPresent(int currentCount, int previousCount, SoilProfile1D currentCrossSection, SoilProfile1D previousCrossSection) { // If more than one new or one less in-between aquifers are found, at least one is an isolated aquifer. @@ -115,6 +133,28 @@ return previousCount - currentCount == 1 && !currentCrossSection.Layers[0].IsAquifer; } + public static bool IsAquitardPresentWithAquiferInnerLoop(SoilProfile2D soilProfile2D) + { + foreach (GeometrySurface surface in soilProfile2D.Geometry.Surfaces.Where(surface => surface.InnerLoops.Count > 0)) + { + SoilLayer2D soilLayerOfOuterLoop = soilProfile2D.Surfaces.First(s => s.GeometrySurface == surface); + if (!soilLayerOfOuterLoop.IsAquifer) + { + foreach (GeometryLoop innerLoop in surface.InnerLoops) + { + GeometrySurface geometrySurfaceOfInnerLoop = soilProfile2D.Geometry.Surfaces.First(s => s.OuterLoop == innerLoop); + SoilLayer2D soilLayerOfInnerLoop = soilProfile2D.Surfaces.First(s => s.GeometrySurface == geometrySurfaceOfInnerLoop); + if (soilLayerOfInnerLoop.IsAquifer) + { + return true; + } + } + } + } + + return false; + } + /// /// Determines all the points of the layer boundary for the specified layer type: /// - For LayerType = BottomAquiferCluster, layerBoundaryTop is the top boundary of the bottom aquifer (= waternet line for PL3) Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SoilProfileValidator.cs =================================================================== diff -u -r5456 -r5835 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SoilProfileValidator.cs (.../SoilProfileValidator.cs) (revision 5456) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/PlLinesCreator/SoilProfileValidator.cs (.../SoilProfileValidator.cs) (revision 5835) @@ -99,7 +99,9 @@ return; } - if (SoilProfile2DHelper.IsAtLeastOneIsolatedInBetweenAquiferPresent(SoilProfile2D)) + bool isValid = !SoilProfile2DHelper.IsAquitardPresentWithAquiferInnerLoop(SoilProfile2D); + isValid = isValid && !SoilProfile2DHelper.IsAtLeastOneIsolatedInBetweenAquiferPresent(SoilProfile2D); + if (!isValid) { throw new PlLinesCreatorException(Resources.SoilProfileValidator_General + string.Format(Resources.SoilProfileValidator_DiscontinuousAquiferPresent, SoilProfile2D.Name));