Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs (.../PlLinesToWaternetConverter.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/KernelWrappers/MacroStabilityCommon/PlLinesToWaternetConverter.cs (.../PlLinesToWaternetConverter.cs) (revision 4052) @@ -30,287 +30,286 @@ using Deltares.DamEngine.Data.Geotechnics; using Deltares.DamEngine.Data.Standard; -namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon +namespace Deltares.DamEngine.Calculators.KernelWrappers.MacroStabilityCommon; + +public static class PlLinesToWaternetConverter { - public static class PlLinesToWaternetConverter + /// + /// Converts the pl lines to a waternet. + /// + /// The pl lines. + /// The 1D soil profile. + /// Length of the penetration. + /// Left side of the 2D profile. + /// Right side of the 2D profile. + /// + public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile1D soilProfile1D, double penetrationLength, double xLeft, double xRight) { - /// - /// Converts the pl lines to a waternet. - /// - /// The pl lines. - /// The 1D soil profile. - /// Length of the penetration. - /// Left side of the 2D profile. - /// Right side of the 2D profile. - /// - public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile1D soilProfile1D, double penetrationLength, double xLeft, double xRight) + ThrowWhenPlLinesIsNull(plLines); + ThrowWhenSoilProfileIsNull(soilProfile1D); + var waternet = new Waternet { - ThrowWhenPlLinesIsNull(plLines); - ThrowWhenSoilProfileIsNull(soilProfile1D); - var waternet = new Waternet - { - IsGenerated = false - }; + IsGenerated = false + }; - PlLine plLine = plLines.Lines[PlLineType.Pl1]; - if (plLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) - { - waternet.PhreaticLine = CreateLine(plLine); - waternet.PhreaticLine.SyncCalcPoints(); - } + PlLine plLine = plLines.Lines[PlLineType.Pl1]; + if (plLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + { + waternet.PhreaticLine = CreateLine(plLine); + waternet.PhreaticLine.SyncCalcPoints(); + } - plLine = plLines.Lines[PlLineType.Pl2]; - var headLine = CreateLine(plLine); - if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + plLine = plLines.Lines[PlLineType.Pl2]; + var headLine = CreateLine(plLine); + if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + { + waternet.HeadLineList.Add(headLine); + if (soilProfile1D.BottomAquiferLayer != null) { - waternet.HeadLineList.Add(headLine); - if (soilProfile1D.BottomAquiferLayer != null) - { - double level = soilProfile1D.BottomAquiferLayer.TopLevel + penetrationLength; - WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); - waternetLine.HeadLine = headLine; - waternetLine.HeadLine.SyncCalcPoints(); - waternet.WaternetLineList.Add(waternetLine); - } + double level = soilProfile1D.BottomAquiferLayer.TopLevel + penetrationLength; + WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); + waternetLine.HeadLine = headLine; + waternetLine.HeadLine.SyncCalcPoints(); + waternet.WaternetLineList.Add(waternetLine); } + } - plLine = plLines.Lines[PlLineType.Pl3]; - headLine = CreateLine(plLine); - if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + plLine = plLines.Lines[PlLineType.Pl3]; + headLine = CreateLine(plLine); + if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + { + waternet.HeadLineList.Add(headLine); + if (soilProfile1D.BottomAquiferLayer != null) { - waternet.HeadLineList.Add(headLine); - if (soilProfile1D.BottomAquiferLayer != null) - { - double level = soilProfile1D.BottomAquiferLayer.TopLevel; - WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); - waternetLine.HeadLine = headLine; - waternetLine.HeadLine.SyncCalcPoints(); - waternet.WaternetLineList.Add(waternetLine); - } + double level = soilProfile1D.BottomAquiferLayer.TopLevel; + WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); + waternetLine.HeadLine = headLine; + waternetLine.HeadLine.SyncCalcPoints(); + waternet.WaternetLineList.Add(waternetLine); } + } - plLine = plLines.Lines[PlLineType.Pl4]; - headLine = CreateLine(plLine); - if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + plLine = plLines.Lines[PlLineType.Pl4]; + headLine = CreateLine(plLine); + if (headLine != null && !IsBelowSoilProfile(soilProfile1D, plLine)) + { + waternet.HeadLineList.Add(headLine); + if (soilProfile1D.InBetweenAquiferLayer != null) { - waternet.HeadLineList.Add(headLine); - if (soilProfile1D.InBetweenAquiferLayer != null) - { - double level = soilProfile1D.InBetweenAquiferLayer.TopLevel; - WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); - waternetLine.HeadLine = headLine; - waternetLine.HeadLine.SyncCalcPoints(); - waternet.WaternetLineList.Add(waternetLine); - } + double level = soilProfile1D.InBetweenAquiferLayer.TopLevel; + WaternetLine waternetLine = CreateWaternetLine(level, xLeft, xRight); + waternetLine.HeadLine = headLine; + waternetLine.HeadLine.SyncCalcPoints(); + waternet.WaternetLineList.Add(waternetLine); } - - return waternet; } - /// - /// Converts the to a based on a 2D profile. - /// - /// The to convert. - /// The to convert the with. - /// The penetration length. - /// A . - /// Thrown when or - /// is null. - public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile2D soilProfile, double penetrationLength) - { - ThrowWhenPlLinesIsNull(plLines); - ThrowWhenSoilProfileIsNull(soilProfile); + return waternet; + } - // Get all the xCoordinates to make cross sections - IEnumerable points = soilProfile.Surfaces.SelectMany(surf => surf.GeometrySurface.OuterLoop.CalcPoints); - double[] xCoordinates = points.Select(point => point.X).OrderBy(x => x).Distinct().ToArray(); + /// + /// Converts the to a based on a 2D profile. + /// + /// The to convert. + /// The to convert the with. + /// The penetration length. + /// A . + /// Thrown when or + /// is null. + public static Waternet ConvertPlLineToWaternet(PlLines plLines, SoilProfile2D soilProfile, double penetrationLength) + { + ThrowWhenPlLinesIsNull(plLines); + ThrowWhenSoilProfileIsNull(soilProfile); - Point2D[] bottomAquiferCoordinates = GetAquiferCoordinates(sp => sp.BottomAquiferLayer, xCoordinates, soilProfile).ToArray(); - Point2D[] inBetweenAquiferCoordinates = GetAquiferCoordinates(sp => sp.InBetweenAquiferLayer, xCoordinates, soilProfile).ToArray(); + // Get all the xCoordinates to make cross sections + IEnumerable points = soilProfile.Surfaces.SelectMany(surf => surf.GeometrySurface.OuterLoop.CalcPoints); + double[] xCoordinates = points.Select(point => point.X).OrderBy(x => x).Distinct().ToArray(); - var waternet = new Waternet(); - PlLine plLine = plLines.Lines[PlLineType.Pl1]; - if (plLine != null) - { - waternet.PhreaticLine = CreateLine(plLine); - } + Point2D[] bottomAquiferCoordinates = GetAquiferCoordinates(sp => sp.BottomAquiferLayer, xCoordinates, soilProfile).ToArray(); + Point2D[] inBetweenAquiferCoordinates = GetAquiferCoordinates(sp => sp.InBetweenAquiferLayer, xCoordinates, soilProfile).ToArray(); - plLine = plLines.Lines[PlLineType.Pl2]; - if (plLine != null) - { - var headLine = CreateLine(plLine); - waternet.HeadLineList.Add(headLine); + var waternet = new Waternet(); + PlLine plLine = plLines.Lines[PlLineType.Pl1]; + if (plLine != null) + { + waternet.PhreaticLine = CreateLine(plLine); + } - if (bottomAquiferCoordinates.Any()) - { - WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates, penetrationLength); - waternetLine.HeadLine = headLine; - waternet.WaternetLineList.Add(waternetLine); - } - } + plLine = plLines.Lines[PlLineType.Pl2]; + if (plLine != null) + { + var headLine = CreateLine(plLine); + waternet.HeadLineList.Add(headLine); - plLine = plLines.Lines[PlLineType.Pl3]; - if (plLine != null) + if (bottomAquiferCoordinates.Any()) { - var headLine = CreateLine(plLine); - waternet.HeadLineList.Add(headLine); - - if (bottomAquiferCoordinates.Any()) - { - WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates); - waternetLine.HeadLine = headLine; - waternet.WaternetLineList.Add(waternetLine); - } + WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates, penetrationLength); + waternetLine.HeadLine = headLine; + waternet.WaternetLineList.Add(waternetLine); } + } - plLine = plLines.Lines[PlLineType.Pl4]; - if (plLine != null) + plLine = plLines.Lines[PlLineType.Pl3]; + if (plLine != null) + { + var headLine = CreateLine(plLine); + waternet.HeadLineList.Add(headLine); + + if (bottomAquiferCoordinates.Any()) { - var headLine = CreateLine(plLine); - waternet.HeadLineList.Add(headLine); - if (inBetweenAquiferCoordinates.Any()) - { - WaternetLine waternetLine = CreateWaternetLine(inBetweenAquiferCoordinates); - waternetLine.HeadLine = headLine; - waternet.WaternetLineList.Add(waternetLine); - } + WaternetLine waternetLine = CreateWaternetLine(bottomAquiferCoordinates); + waternetLine.HeadLine = headLine; + waternet.WaternetLineList.Add(waternetLine); } - - return waternet; } - internal static WaternetLine CreateWaternetLine(double level, double xLeft, double xRight) + plLine = plLines.Lines[PlLineType.Pl4]; + if (plLine != null) { - var waternetLine = new WaternetLine(); - waternetLine.Points.Add(new GeometryPoint(xLeft, level)); - waternetLine.Points.Add(new GeometryPoint(xRight, level)); - waternetLine.SyncCalcPoints(); - return waternetLine; - } - - private static TLineType CreateLine(PlLine plLine) - where TLineType : GeometryPointString, new() - { - if (plLine == null || !plLine.Points.Any()) + var headLine = CreateLine(plLine); + waternet.HeadLineList.Add(headLine); + if (inBetweenAquiferCoordinates.Any()) { - return null; + WaternetLine waternetLine = CreateWaternetLine(inBetweenAquiferCoordinates); + waternetLine.HeadLine = headLine; + waternet.WaternetLineList.Add(waternetLine); } - - var line = new TLineType(); - line.Points.AddRange(plLine.Points); - return line; } - private static WaternetLine CreateWaternetLine(IEnumerable coordinates) + return waternet; + } + + internal static WaternetLine CreateWaternetLine(double level, double xLeft, double xRight) + { + var waternetLine = new WaternetLine(); + waternetLine.Points.Add(new GeometryPoint(xLeft, level)); + waternetLine.Points.Add(new GeometryPoint(xRight, level)); + waternetLine.SyncCalcPoints(); + return waternetLine; + } + + private static TLineType CreateLine(PlLine plLine) + where TLineType : GeometryPointString, new() + { + if (plLine == null || !plLine.Points.Any()) { - return CreateWaternetLine(coordinates, 0); + return null; } - private static WaternetLine CreateWaternetLine(IEnumerable coordinates, double zOffSet) - { - var line = new WaternetLine(); - foreach (Point2D coordinate in coordinates) - { - var point = new GeometryPoint(coordinate.X, coordinate.Z + zOffSet); - line.Points.Add(point); - } + var line = new TLineType(); + line.Points.AddRange(plLine.Points); + return line; + } - line.SyncCalcPoints(); - return line; - } + private static WaternetLine CreateWaternetLine(IEnumerable coordinates) + { + return CreateWaternetLine(coordinates, 0); + } - private static IEnumerable GetAquiferCoordinates(Func getSoilLayerFunc, IEnumerable xCoordinates, - SoilProfile2D soilProfile) + private static WaternetLine CreateWaternetLine(IEnumerable coordinates, double zOffSet) + { + var line = new WaternetLine(); + foreach (Point2D coordinate in coordinates) { - SoilLayer1D previousAquiferLayer = null; - var coordinates = new List(); - foreach (double xCoordinate in xCoordinates) - { - SoilProfile1D crossSection = soilProfile.GetSoilProfile1D(xCoordinate); + var point = new GeometryPoint(coordinate.X, coordinate.Z + zOffSet); + line.Points.Add(point); + } - // Determine if the bottom aquifer layer is in range of the previous aquifer layer - // If not, return empty coordinates, because the aquifer layer is interrupted - SoilLayer1D currentAquifer = getSoilLayerFunc(crossSection); - if (previousAquiferLayer != null && - currentAquifer != null - && !AreHorizontallyConnected(previousAquiferLayer, currentAquifer)) - { - return Enumerable.Empty(); - } + line.SyncCalcPoints(); + return line; + } - if (currentAquifer != null) - { - previousAquiferLayer = currentAquifer; - coordinates.Add(new Point2D(xCoordinate, currentAquifer.TopLevel)); - } - } + private static IEnumerable GetAquiferCoordinates(Func getSoilLayerFunc, IEnumerable xCoordinates, + SoilProfile2D soilProfile) + { + SoilLayer1D previousAquiferLayer = null; + var coordinates = new List(); + foreach (double xCoordinate in xCoordinates) + { + SoilProfile1D crossSection = soilProfile.GetSoilProfile1D(xCoordinate); - // Perform a short validation that the coordinates are fully defined from the beginning to the end - // of the profile. If not, the aquifer is not continuous. - if (!coordinates.Any() || coordinates.First().X != xCoordinates.First() || coordinates.Last().X != xCoordinates.Last()) + // Determine if the bottom aquifer layer is in range of the previous aquifer layer + // If not, return empty coordinates, because the aquifer layer is interrupted + SoilLayer1D currentAquifer = getSoilLayerFunc(crossSection); + if (previousAquiferLayer != null && + currentAquifer != null + && !AreHorizontallyConnected(previousAquiferLayer, currentAquifer)) { return Enumerable.Empty(); } - return coordinates; + if (currentAquifer != null) + { + previousAquiferLayer = currentAquifer; + coordinates.Add(new Point2D(xCoordinate, currentAquifer.TopLevel)); + } } - private static bool AreHorizontallyConnected(SoilLayer1D leftSoilLayer, SoilLayer1D rightSoilLayer) + // Perform a short validation that the coordinates are fully defined from the beginning to the end + // of the profile. If not, the aquifer is not continuous. + if (!coordinates.Any() || coordinates.First().X != xCoordinates.First() || coordinates.Last().X != xCoordinates.Last()) { - // The layers are identical - if (ReferenceEquals(leftSoilLayer, rightSoilLayer)) - { - return true; - } + return Enumerable.Empty(); + } - // Left soil layer envelopes whole right soil layer - if (leftSoilLayer.BottomLevel <= rightSoilLayer.BottomLevel - && leftSoilLayer.TopLevel >= rightSoilLayer.TopLevel) - { - return true; - } + return coordinates; + } - // Right soil layer envelopes whole left soil layer - if (rightSoilLayer.BottomLevel <= leftSoilLayer.BottomLevel - && rightSoilLayer.TopLevel >= leftSoilLayer.TopLevel) - { - return true; - } + private static bool AreHorizontallyConnected(SoilLayer1D leftSoilLayer, SoilLayer1D rightSoilLayer) + { + // The layers are identical + if (ReferenceEquals(leftSoilLayer, rightSoilLayer)) + { + return true; + } - return (rightSoilLayer.TopLevel <= leftSoilLayer.TopLevel && rightSoilLayer.TopLevel >= leftSoilLayer.BottomLevel) // Top level lies inbetween the left soil layer - || (rightSoilLayer.BottomLevel >= leftSoilLayer.BottomLevel && rightSoilLayer.BottomLevel <= leftSoilLayer.TopLevel); // Bottom level lies inbetween the left soil layer + // Left soil layer envelopes whole right soil layer + if (leftSoilLayer.BottomLevel <= rightSoilLayer.BottomLevel + && leftSoilLayer.TopLevel >= rightSoilLayer.TopLevel) + { + return true; } - private static bool IsBelowSoilProfile(SoilProfile1D soilProfile, PlLine line) + // Right soil layer envelopes whole left soil layer + if (rightSoilLayer.BottomLevel <= leftSoilLayer.BottomLevel + && rightSoilLayer.TopLevel >= leftSoilLayer.TopLevel) { - double bottomSoilProfileLevel = soilProfile.BottomLevel; - return line.Points.Any(point => point.Z <= bottomSoilProfileLevel); + return true; } - /// - /// Throws when the soil profile is not assigned. - /// - /// The soil profile. - /// - private static void ThrowWhenSoilProfileIsNull(SoilProfile soilProfile) + return (rightSoilLayer.TopLevel <= leftSoilLayer.TopLevel && rightSoilLayer.TopLevel >= leftSoilLayer.BottomLevel) // Top level lies inbetween the left soil layer + || (rightSoilLayer.BottomLevel >= leftSoilLayer.BottomLevel && rightSoilLayer.BottomLevel <= leftSoilLayer.TopLevel); // Bottom level lies inbetween the left soil layer + } + + private static bool IsBelowSoilProfile(SoilProfile1D soilProfile, PlLine line) + { + double bottomSoilProfileLevel = soilProfile.BottomLevel; + return line.Points.Any(point => point.Z <= bottomSoilProfileLevel); + } + + /// + /// Throws when the soil profile is not assigned. + /// + /// The soil profile. + /// + private static void ThrowWhenSoilProfileIsNull(SoilProfile soilProfile) + { + if (soilProfile == null) { - if (soilProfile == null) - { - throw new NoNullAllowedException(Resources.PlLinesToWaternetConverter_NoSoilProfileDefined); - } + throw new NoNullAllowedException(Resources.PlLinesToWaternetConverter_NoSoilProfileDefined); } + } - /// - /// Throws when the pl lines object is not assigned. - /// - /// The pl lines. - /// - private static void ThrowWhenPlLinesIsNull(PlLines plLines) + /// + /// Throws when the pl lines object is not assigned. + /// + /// The pl lines. + /// + private static void ThrowWhenPlLinesIsNull(PlLines plLines) + { + if (plLines == null) { - if (plLines == null) - { - throw new NoNullAllowedException(Resources.PlLinesToWaternetConverter_NoPlLinesDefined); - } + throw new NoNullAllowedException(Resources.PlLinesToWaternetConverter_NoPlLinesDefined); } } } \ No newline at end of file