Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs =================================================================== diff -u -r5382 -r5427 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5382) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/Common/SoilProfile2DHelper.cs (.../SoilProfile2DHelper.cs) (revision 5427) @@ -42,22 +42,10 @@ Top, Bottom } - + private const double deviationX = 1e-06; private const double toleranceAlmostEqual = 1e-09; - /// - /// Determine all the xCoordinates to make cross-sections. - /// - /// The soil profile 2D. - /// All the xCoordinates of the soil profile 2D. - private static double[] DetermineAllXCoordinatesOfSoilProfile(SoilProfile2D soilProfile) - { - IEnumerable points = soilProfile.Surfaces.SelectMany(surf => surf.GeometrySurface.OuterLoop.CalcPoints); - double[] xCoordinates = points.Select(point => point.X).OrderBy(x => x).Distinct().ToArray(); - return xCoordinates; - } - internal static bool AreInBetweenAquiferClustersPresent(SoilProfile2D soilProfile, out int count) { double[] xCoordinates = DetermineAllXCoordinatesOfSoilProfile(soilProfile); @@ -79,7 +67,59 @@ count = currentCount; return count > 0; } + + public static bool IsAtLeastOneIsolatedInBetweenAquiferPresent(SoilProfile2D soilProfile, out int count) + { + double[] xCoordinates = DetermineAllXCoordinatesOfSoilProfile(soilProfile); + var previousCount = 0; + count = 0; + SoilProfile1D previousCrossSection = null; + for (var i = 0; i < xCoordinates.Length; i++) + { + SoilProfile1D crossSection = soilProfile.GetSoilProfile1D(xCoordinates[i]); + int currentCount = crossSection.GetInBetweenAquiferClusters?.Count ?? 0; + count = i == 0 ? currentCount : count; + if (i > 0 && currentCount != previousCount) + { + // If more than one new or one less in-between aquifers are found, at least one is an isolated aquifer. + if (Math.Abs(currentCount - previousCount) > 1) + { + count = -1; + return true; + } + + if (currentCount > 0 && crossSection.GetInBetweenAquiferClusters != null) + { + // If one new in-between aquifer is found, the top layer in the previous cross-section must be an aquifer. + // If not, it is an isolated aquifer. + if (currentCount - previousCount == 1) + { + if (!previousCrossSection.Layers[0].IsAquifer) + { + count = -1; + return true; + } + count++; + } + + // If one less in-between aquifer is found, the top layer in the current section must be an aquifer. + // If not, it is an isolated aquifer. + if (previousCount - currentCount == 1 && !crossSection.Layers[0].IsAquifer) + { + count = -1; + return true; + } + } + } + + previousCount = currentCount; + previousCrossSection = crossSection; + } + + 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) @@ -123,17 +163,17 @@ // If not, return empty coordinates, because the cluster of layers is interrupted. double currentAquiferTop = GetLevel(layerType, BoundaryType.Top, crossSection, indexInBetweenAquifer); double currentAquiferBottom = GetLevel(layerType, BoundaryType.Bottom, crossSection, indexInBetweenAquifer); - - if (!double.IsNaN(previousAquiferTop) && !double.IsNaN(previousAquiferBottom) - && !double.IsNaN(currentAquiferTop) + + if (!double.IsNaN(previousAquiferTop) && !double.IsNaN(previousAquiferBottom) + && !double.IsNaN(currentAquiferTop) && !double.IsNaN(currentAquiferBottom) && !AreHorizontallyConnected(previousAquiferTop, previousAquiferBottom, currentAquiferTop, currentAquiferBottom)) { layerBoundaryTop = null; layerBoundaryBottom = null; return; } - + if (!double.IsNaN(currentAquiferTop) && !double.IsNaN(currentAquiferBottom)) { previousAquiferTop = currentAquiferTop; @@ -152,10 +192,23 @@ layerBoundaryBottom = null; return; } + layerBoundaryTop = layerBoundaryTopPoints.ToArray(); layerBoundaryBottom = layerBoundaryBottomPoints.ToArray(); } + /// + /// Determine all the xCoordinates to make cross-sections. + /// + /// The soil profile 2D. + /// All the xCoordinates of the soil profile 2D. + private static double[] DetermineAllXCoordinatesOfSoilProfile(SoilProfile2D soilProfile) + { + IEnumerable points = soilProfile.Surfaces.SelectMany(surf => surf.GeometrySurface.OuterLoop.CalcPoints); + double[] xCoordinates = points.Select(point => point.X).OrderBy(x => x).Distinct().ToArray(); + return xCoordinates; + } + private static bool IsLayerBoundaryContinuous(IEnumerable boundaryPoints, double leftGeometryBoundary, double rightGeometryBoundary) { IEnumerable point2Ds = boundaryPoints.ToList(); @@ -173,7 +226,7 @@ return double.NaN; } - + private static SoilLayer1D GetLayer(LayerType layerType, BoundaryType boundaryType, SoilProfile1D soilProfile1D, int indexInBetweenAquifer) { switch (layerType) @@ -190,7 +243,7 @@ return null; } - + private static bool HasAquiferAVerticalPartAtGivenX(LayerType layerType, double xCoordinate, SoilProfile2D soilProfile, int indexInBetweenAquifer) { SoilProfile1D crossSectionLeft = soilProfile.GetSoilProfile1D(xCoordinate - deviationX);