Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorShoulderPerPoint.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorShoulderPerPoint.cs (.../DesignCalculatorShoulderPerPoint.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorShoulderPerPoint.cs (.../DesignCalculatorShoulderPerPoint.cs) (revision 4052) @@ -34,206 +34,205 @@ using Deltares.DamEngine.Data.Standard.Calculation; using Deltares.DamEngine.Data.Standard.Logging; -namespace Deltares.DamEngine.Calculators.DikesDesign +namespace Deltares.DamEngine.Calculators.DikesDesign; + +/// +/// The Dam Engine design calculator +/// +public class DesignCalculatorShoulderPerPoint { + private const double minimumShoulderElevation = 0.5; + private const double minimumShoulderLength = 2; + private const double toleranceShoulderChanges = 0.001; + /// - /// The Dam Engine design calculator + /// Performs the design calculation shoulder iterative per point. + /// This is a design strategy used for Piping /// - public class DesignCalculatorShoulderPerPoint + /// The kernel wrapper. + /// The kernel data input. + /// The kernel data output. + /// The dam kernel input. + /// The design scenario. + /// The calculation messages. + /// The design calculations. + /// + public static void PerformDesignCalculationShoulderPerPoint + (IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, + IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, + DesignScenario designScenario, + List calculationMessages, List designCalculations) { - private const double minimumShoulderElevation = 0.5; - private const double minimumShoulderLength = 2; - private const double toleranceShoulderChanges = 0.001; - - /// - /// Performs the design calculation shoulder iterative per point. - /// This is a design strategy used for Piping - /// - /// The kernel wrapper. - /// The kernel data input. - /// The kernel data output. - /// The dam kernel input. - /// The design scenario. - /// The calculation messages. - /// The design calculations. - /// - public static void PerformDesignCalculationShoulderPerPoint - (IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, - IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, - DesignScenario designScenario, - List calculationMessages, List designCalculations) + var designResults = new List(); + Location location = damKernelInput.Location; + SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; + SurfaceLine2 surfaceLine = designScenario.GetMostRecentSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D); + damKernelInput.Location.SurfaceLine = surfaceLine; + try { - var designResults = new List(); - Location location = damKernelInput.Location; - SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; - SurfaceLine2 surfaceLine = designScenario.GetMostRecentSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D); - damKernelInput.Location.SurfaceLine = surfaceLine; - try - { - List locationCalculationMessages; - double orgShoulderLength = surfaceLine.DetermineShoulderLength(); - double orgShoulderHeight = surfaceLine.DetermineShoulderHeight(); + List locationCalculationMessages; + double orgShoulderLength = surfaceLine.DetermineShoulderLength(); + double orgShoulderHeight = surfaceLine.DetermineShoulderHeight(); - GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward(); + GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward(); - IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points - where point.X >= startSurfacePoint.X - orderby point.X - select point; - relevantSurfacePointsList = GetDiscretizedSurfaceLine(relevantSurfacePointsList); - double desiredShoulderLength = orgShoulderLength; - double oldDesiredShoulderLength = orgShoulderLength; - double desiredShoulderHeight = orgShoulderHeight; - double oldDesiredShoulderHeight = orgShoulderHeight; - foreach (GeometryPoint point in relevantSurfacePointsList) + IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points + where point.X >= startSurfacePoint.X + orderby point.X + select point; + relevantSurfacePointsList = GetDiscretizedSurfaceLine(relevantSurfacePointsList); + double desiredShoulderLength = orgShoulderLength; + double oldDesiredShoulderLength = orgShoulderLength; + double desiredShoulderHeight = orgShoulderHeight; + double oldDesiredShoulderHeight = orgShoulderHeight; + foreach (GeometryPoint point in relevantSurfacePointsList) + { + // Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any. + ShoulderDesign shoulderDesign = kernelWrapper.CalculateDesignAtPoint(damKernelInput, kernelDataInput, kernelDataOutput, point, out locationCalculationMessages); + if (shoulderDesign != null) { - // Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any. - ShoulderDesign shoulderDesign = kernelWrapper.CalculateDesignAtPoint(damKernelInput, kernelDataInput, kernelDataOutput, point, out locationCalculationMessages); - if (shoulderDesign != null) - { - // Piping is an issue so adapt the surfaceline for it - desiredShoulderLength = shoulderDesign.ShoulderLengthFromToe; - desiredShoulderLength = Math.Max(desiredShoulderLength, oldDesiredShoulderLength); - oldDesiredShoulderLength = desiredShoulderLength; - // shoulder height is height above surfacelevel!! - desiredShoulderHeight = shoulderDesign.ShoulderHeightFromToe; - desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight); - oldDesiredShoulderHeight = desiredShoulderHeight; - } + // Piping is an issue so adapt the surfaceline for it + desiredShoulderLength = shoulderDesign.ShoulderLengthFromToe; + desiredShoulderLength = Math.Max(desiredShoulderLength, oldDesiredShoulderLength); + oldDesiredShoulderLength = desiredShoulderLength; + // shoulder height is height above surfacelevel!! + desiredShoulderHeight = shoulderDesign.ShoulderHeightFromToe; + desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight); + oldDesiredShoulderHeight = desiredShoulderHeight; } + } - if (desiredShoulderLength > 0) - { - desiredShoulderLength = Math.Max(desiredShoulderLength, minimumShoulderLength); - } + if (desiredShoulderLength > 0) + { + desiredShoulderLength = Math.Max(desiredShoulderLength, minimumShoulderLength); + } - if (desiredShoulderHeight > 0) - { - desiredShoulderHeight = Math.Max(desiredShoulderHeight, minimumShoulderElevation); - } + if (desiredShoulderHeight > 0) + { + desiredShoulderHeight = Math.Max(desiredShoulderHeight, minimumShoulderElevation); + } - bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < toleranceShoulderChanges) && - (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < toleranceShoulderChanges)); - SurfaceLine2 newSurfaceLine; - if (isNewShoulderSameAsOriginal) - { - newSurfaceLine = surfaceLine; - } - else - { - // Adapt the surfaceline for the finally required shoulder dimensions. - double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, 1.0); // no limit to height of shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location, designScenario.PolderLevel); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(desiredShoulderLength, desiredShoulderHeight, true); - } - - damKernelInput.Location.SurfaceLine = newSurfaceLine; - kernelWrapper.Prepare(damKernelInput, 0, out kernelDataInput, out kernelDataOutput); - kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out locationCalculationMessages); - // Process output - calculationMessages.AddRange(locationCalculationMessages); - var sb = new StringBuilder(); - foreach (LogMessage message in locationCalculationMessages) - { - sb.Append(message.Message + Environment.NewLine); - } - - var resultMessage = sb.ToString(); - kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); - - string evaluationMessage; - DesignAdvise designAdvise; - bool designSuccessful = kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); - if (!designSuccessful) - { - throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + evaluationMessage); - } + bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < toleranceShoulderChanges) && + (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < toleranceShoulderChanges)); + SurfaceLine2 newSurfaceLine; + if (isNewShoulderSameAsOriginal) + { + newSurfaceLine = surfaceLine; } - catch (Exception exception) + else { - string resultMessage = exception.Message; - kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); - ChangeSafetyFactor(designResults, -1); - ChangeCalculationResult(designResults, CalculationResult.RunFailed); - throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + resultMessage); + // Adapt the surfaceline for the finally required shoulder dimensions. + double maxShoulderLevel = CalculateMaximumShoulderLevel(surfaceLine, 1.0); // no limit to height of shoulder + var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location, designScenario.PolderLevel); + surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; + newSurfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(desiredShoulderLength, desiredShoulderHeight, true); } - finally + + damKernelInput.Location.SurfaceLine = newSurfaceLine; + kernelWrapper.Prepare(damKernelInput, 0, out kernelDataInput, out kernelDataOutput); + kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out locationCalculationMessages); + // Process output + calculationMessages.AddRange(locationCalculationMessages); + var sb = new StringBuilder(); + foreach (LogMessage message in locationCalculationMessages) { - foreach (DesignResult designResult in designResults) - { - designCalculations.Add(designResult); - } + sb.Append(message.Message + Environment.NewLine); } - } - private static void ChangeSafetyFactor(List designResults, double safetyFactor) - { - foreach (DesignResult designResult in designResults) + var resultMessage = sb.ToString(); + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); + + string evaluationMessage; + DesignAdvise designAdvise; + bool designSuccessful = kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); + if (!designSuccessful) { - designResult.SafetyFactor = safetyFactor; + throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + evaluationMessage); } } - - private static void ChangeCalculationResult(List designResults, CalculationResult calculationResult) + catch (Exception exception) { + string resultMessage = exception.Message; + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); + ChangeSafetyFactor(designResults, -1); + ChangeCalculationResult(designResults, CalculationResult.RunFailed); + throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + resultMessage); + } + finally + { foreach (DesignResult designResult in designResults) { - designResult.CalculationResult = calculationResult; + designCalculations.Add(designResult); } } + } - /// - /// Calculates the maximum level for the shoulder. - /// - /// The surface line. - /// The fraction of dike height to determine maximimum shoulder height. - /// - private static double CalculateMaximumShoulderLevel(SurfaceLine2 surfaceLine, double maxFractionOfDikeHeightForShoulderHeight) + private static void ChangeSafetyFactor(List designResults, double safetyFactor) + { + foreach (DesignResult designResult in designResults) { - double top = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; - double bottom = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; - if (top - bottom <= 0) - { - throw new DesignCalculatorException(Resources.SurfaceLineShoulderAdapterMaxShoulderHeightError); - } + designResult.SafetyFactor = safetyFactor; + } + } - double maxHeight = Math.Abs((top - bottom) * maxFractionOfDikeHeightForShoulderHeight); - return bottom + maxHeight; + private static void ChangeCalculationResult(List designResults, CalculationResult calculationResult) + { + foreach (DesignResult designResult in designResults) + { + designResult.CalculationResult = calculationResult; } + } - /// - /// Ensures that the points on the surface line are never more than cDiff (0.5) apart. - /// - /// - /// - private static IEnumerable GetDiscretizedSurfaceLine(IEnumerable originalLine) + /// + /// Calculates the maximum level for the shoulder. + /// + /// The surface line. + /// The fraction of dike height to determine maximimum shoulder height. + /// + private static double CalculateMaximumShoulderLevel(SurfaceLine2 surfaceLine, double maxFractionOfDikeHeightForShoulderHeight) + { + double top = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z; + double bottom = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z; + if (top - bottom <= 0) { - const double cDiff = 0.5; - var newLine = new List(); - double currentX = originalLine.First().X; - foreach (GeometryPoint point in originalLine) + throw new DesignCalculatorException(Resources.SurfaceLineShoulderAdapterMaxShoulderHeightError); + } + + double maxHeight = Math.Abs((top - bottom) * maxFractionOfDikeHeightForShoulderHeight); + return bottom + maxHeight; + } + + /// + /// Ensures that the points on the surface line are never more than cDiff (0.5) apart. + /// + /// + /// + private static IEnumerable GetDiscretizedSurfaceLine(IEnumerable originalLine) + { + const double cDiff = 0.5; + var newLine = new List(); + double currentX = originalLine.First().X; + foreach (GeometryPoint point in originalLine) + { + while (point.X > currentX + cDiff) { - while (point.X > currentX + cDiff) + var newPoint = new GeometryPoint(point) { - var newPoint = new GeometryPoint(point) - { - X = currentX + cDiff - }; - if (newPoint.X > newLine.Last().X) - { - newPoint.Z = newLine.Last().Z + ((newPoint.X - newLine.Last().X) / (point.X - newLine.Last().X)) * - (point.Z - newLine.Last().Z); - newLine.Add(newPoint); - } - - currentX = newPoint.X; + X = currentX + cDiff + }; + if (newPoint.X > newLine.Last().X) + { + newPoint.Z = newLine.Last().Z + ((newPoint.X - newLine.Last().X) / (point.X - newLine.Last().X)) * + (point.Z - newLine.Last().Z); + newLine.Add(newPoint); } - newLine.Add(point); + currentX = newPoint.X; } - return newLine; + newLine.Add(point); } + + return newLine; } } \ No newline at end of file