Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs (.../DesignCalculatorCombinedSlopeAndShoulderAdaption.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorCombinedSlopeAndShoulderAdaption.cs (.../DesignCalculatorCombinedSlopeAndShoulderAdaption.cs) (revision 4052) @@ -34,189 +34,188 @@ using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamEngine.Data.Standard.Validation; -namespace Deltares.DamEngine.Calculators.DikesDesign +namespace Deltares.DamEngine.Calculators.DikesDesign; + +/// +/// Design strategy: combined slope adaption and shoulder adaption +/// +public class DesignCalculatorCombinedSlopeAndShoulderAdaption { + private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67; + /// - /// Design strategy: combined slope adaption and shoulder adaption + /// Performs the design calculation combined slope adaption and shoulder adaption. /// - public class DesignCalculatorCombinedSlopeAndShoulderAdaption + /// 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 PerformDesignCalculationCombinedSlopeAdaptionAndShoulderAdaption( + IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, + DamKernelInput damKernelInput, DesignScenario designScenario, + List calculationMessages, List designCalculations) { - private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67; + List designResults; + Location location = damKernelInput.Location; + SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; + const int maxRedesignIterations = 200; + var resultMessage = ""; + int iterationIndex = -1; - /// - /// Performs the design calculation combined slope adaption and shoulder adaption. - /// - /// 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 PerformDesignCalculationCombinedSlopeAdaptionAndShoulderAdaption( - IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, - DamKernelInput damKernelInput, DesignScenario designScenario, - List calculationMessages, List designCalculations) + designScenario.CalculationResult = CalculationResult.NoRun; + EmbankmentDesignParameters embankmentDesignParameters; + + // Prepare the kernel for design + kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); + SurfaceLine2 surfaceLine = designScenario.GetMostRecentSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D).FullDeepClone(); + try { - List designResults; - Location location = damKernelInput.Location; - SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; - const int maxRedesignIterations = 200; - var resultMessage = ""; - int iterationIndex = -1; + iterationIndex = 1; + bool isRedesignRequired; + damKernelInput.Location.SurfaceLine = surfaceLine; + location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); + List locationCalculationMessages; + DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, iterationIndex, out locationCalculationMessages); + calculationMessages.AddRange(locationCalculationMessages); + DesignAdvise designAdvise; + string evaluationMessage; + isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); - designScenario.CalculationResult = CalculationResult.NoRun; - EmbankmentDesignParameters embankmentDesignParameters; - - // Prepare the kernel for design - kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); - SurfaceLine2 surfaceLine = designScenario.GetMostRecentSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D).FullDeepClone(); - try + if (!isRedesignRequired && surfaceLine != null) { - iterationIndex = 1; - bool isRedesignRequired; - damKernelInput.Location.SurfaceLine = surfaceLine; - location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); - List locationCalculationMessages; - DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, iterationIndex, out locationCalculationMessages); - calculationMessages.AddRange(locationCalculationMessages); - DesignAdvise designAdvise; - string evaluationMessage; - isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); - - if (!isRedesignRequired && surfaceLine != null) + // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); + } + else + { + double maxFractionOfDikeHeightForShoulderHeight = location.UseNewMaxHeightShoulderAsFraction ? location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; + double maxShoulderLevel = DesignCalculatorUtils.CalculateMaximumShoulderLevel(surfaceLine, + maxFractionOfDikeHeightForShoulderHeight); + while (isRedesignRequired && surfaceLine != null) { - // Set redesigned surfaceline to original, so in case no redesign is needed, the original surfaceline will be returned - designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); - } - else - { - double maxFractionOfDikeHeightForShoulderHeight = location.UseNewMaxHeightShoulderAsFraction ? location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; - double maxShoulderLevel = DesignCalculatorUtils.CalculateMaximumShoulderLevel(surfaceLine, - maxFractionOfDikeHeightForShoulderHeight); - while (isRedesignRequired && surfaceLine != null) + iterationIndex++; + DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); + + GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); + if (designAdvise == DesignAdvise.ShoulderInwards) { - iterationIndex++; - DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); + // If exit point of circle is after the limitPointForShoulderDesign then enlarge the shoulder + // Determine new width and height for shoulder + double shoulderHeight; + double shoulderLength; + DesignCalculatorUtils.DetermineNewShoulderLengthAndHeight(location.StabilityShoulderGrowDeltaX, + location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderLength); - GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - if (designAdvise == DesignAdvise.ShoulderInwards) - { - // If exit point of circle is after the limitPointForShoulderDesign then enlarge the shoulder - // Determine new width and height for shoulder - double shoulderHeight; - double shoulderLength; - DesignCalculatorUtils.DetermineNewShoulderLengthAndHeight(location.StabilityShoulderGrowDeltaX, - location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, out shoulderHeight, out shoulderLength); + // Create new shoulder + var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location, designScenario.PolderLevel); + surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; + surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderLength, shoulderHeight, false); - // Create new shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, location, designScenario.PolderLevel); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderLength, shoulderHeight, false); - - ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } - - designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); - } - else if (designAdvise == DesignAdvise.SlopeInwards) + ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); + if (validationError != null) { - // If exit point of circle is in the slope (inward) of the dike or the top of the shoulder then adapt slope - var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, location, designScenario.PolderLevel); - surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLine(location.StabilitySlopeAdaptionDeltaX); + throw new SurfaceLineException(validationError.Text); + } - ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); + } + else if (designAdvise == DesignAdvise.SlopeInwards) + { + // If exit point of circle is in the slope (inward) of the dike or the top of the shoulder then adapt slope + var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, location, designScenario.PolderLevel); + surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLine(location.StabilitySlopeAdaptionDeltaX); - designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); - } - else + ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); + if (validationError != null) { - throw new NotImplementedException(); + throw new SurfaceLineException(validationError.Text); } - // Calculate again - designScenario.Location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); - damKernelInput.Location.SurfaceLine = surfaceLine; - kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); - if (damKernelInput.SubSoilScenario.SoilProfileType == SoilProfileType.ProfileType2D) - { - Soil embankmentSoil = - damKernelInput.Location.SoilList.GetSoilByName(embankmentDesignParameters - .EmbankmentMaterialname); - damKernelInput.SubSoilScenario.SoilProfile2D = - AdaptProfile2DToNewSurfaceLine(damKernelInput.SubSoilScenario.SoilProfile2D, surfaceLine, embankmentSoil); - } + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); + } + else + { + throw new NotImplementedException(); + } - DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, - iterationIndex, out locationCalculationMessages); - calculationMessages.AddRange(locationCalculationMessages); - isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, - out evaluationMessage); + // Calculate again + designScenario.Location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); + damKernelInput.Location.SurfaceLine = surfaceLine; + kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); + if (damKernelInput.SubSoilScenario.SoilProfileType == SoilProfileType.ProfileType2D) + { + Soil embankmentSoil = + damKernelInput.Location.SoilList.GetSoilByName(embankmentDesignParameters + .EmbankmentMaterialname); + damKernelInput.SubSoilScenario.SoilProfile2D = + AdaptProfile2DToNewSurfaceLine(damKernelInput.SubSoilScenario.SoilProfile2D, surfaceLine, embankmentSoil); } - } - calculationMessages.AddRange(locationCalculationMessages); - designScenario.CalculationResult = CalculationResult.Succeeded; - designScenario.SetResultMessage(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, "Succes"); - kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); - designCalculations.AddRange(designResults); - } - catch (Exception exception) - { - string errorMessage = exception.Message; - Exception innerException = exception.InnerException; - while (innerException != null) - { - errorMessage = errorMessage + ";" + innerException.Message; - innerException = innerException.InnerException; + DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, + iterationIndex, out locationCalculationMessages); + calculationMessages.AddRange(locationCalculationMessages); + isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, + out evaluationMessage); } - - designScenario.SetResultMessage(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, errorMessage); - designScenario.CalculationResult = CalculationResult.RunFailed; - // Redesign not succesful, so no redesigned surfaceline will be returned - designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, null); - kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, errorMessage, out designResults); - designCalculations.AddRange(designResults); - throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + errorMessage); } - } - private static SoilProfile2D AdaptProfile2DToNewSurfaceLine(SoilProfile2D soilProfile2D, SurfaceLine2 surfaceLine, Soil dikeEmbankmentSoil) + calculationMessages.AddRange(locationCalculationMessages); + designScenario.CalculationResult = CalculationResult.Succeeded; + designScenario.SetResultMessage(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, "Succes"); + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, resultMessage, out designResults); + designCalculations.AddRange(designResults); + } + catch (Exception exception) { - double topX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; - SoilProfile1D soilProfile1D = soilProfile2D.GetSoilProfile1D(topX); - var soilSurfaceProfile = new SoilSurfaceProfile + string errorMessage = exception.Message; + Exception innerException = exception.InnerException; + while (innerException != null) { - SoilProfile = soilProfile1D, - SurfaceLine2 = surfaceLine, - Name = soilProfile2D.Name, - DikeEmbankmentMaterial = dikeEmbankmentSoil - }; - // Convert the soilSurfaceProfile to a SoilProfile2D to be able to edit it properly. - SoilProfile2D soilProfile2DNew = soilSurfaceProfile.ConvertToSoilProfile2D(); - int numberOfCommonSurface = Math.Min(soilProfile2DNew.Surfaces.Count, soilProfile2D.Surfaces.Count); - for (var i = 0; i < numberOfCommonSurface; i++) - { - soilProfile2DNew.Surfaces[i].WaterpressureInterpolationModel = - soilProfile2D.Surfaces[i].WaterpressureInterpolationModel; + errorMessage = errorMessage + ";" + innerException.Message; + innerException = innerException.InnerException; } - for (int i = numberOfCommonSurface; i < soilProfile2DNew.Surfaces.Count; i++) - { - soilProfile2DNew.Surfaces[i].WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic; - } + designScenario.SetResultMessage(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, errorMessage); + designScenario.CalculationResult = CalculationResult.RunFailed; + // Redesign not succesful, so no redesigned surfaceline will be returned + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, null); + kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, designScenario, errorMessage, out designResults); + designCalculations.AddRange(designResults); + throw new DesignCalculatorException(Resources.DesignUnsuccessful + " " + errorMessage); + } + } - return soilProfile2DNew; + private static SoilProfile2D AdaptProfile2DToNewSurfaceLine(SoilProfile2D soilProfile2D, SurfaceLine2 surfaceLine, Soil dikeEmbankmentSoil) + { + double topX = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).X; + SoilProfile1D soilProfile1D = soilProfile2D.GetSoilProfile1D(topX); + var soilSurfaceProfile = new SoilSurfaceProfile + { + SoilProfile = soilProfile1D, + SurfaceLine2 = surfaceLine, + Name = soilProfile2D.Name, + DikeEmbankmentMaterial = dikeEmbankmentSoil + }; + // Convert the soilSurfaceProfile to a SoilProfile2D to be able to edit it properly. + SoilProfile2D soilProfile2DNew = soilSurfaceProfile.ConvertToSoilProfile2D(); + int numberOfCommonSurface = Math.Min(soilProfile2DNew.Surfaces.Count, soilProfile2D.Surfaces.Count); + for (var i = 0; i < numberOfCommonSurface; i++) + { + soilProfile2DNew.Surfaces[i].WaterpressureInterpolationModel = + soilProfile2D.Surfaces[i].WaterpressureInterpolationModel; } + + for (int i = numberOfCommonSurface; i < soilProfile2DNew.Surfaces.Count; i++) + { + soilProfile2DNew.Surfaces[i].WaterpressureInterpolationModel = WaterpressureInterpolationModel.Automatic; + } + + return soilProfile2DNew; } } \ No newline at end of file