Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption.cs =================================================================== diff -u -r4000 -r4052 --- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption.cs (.../DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption.cs) (revision 4000) +++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption.cs (.../DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption.cs) (revision 4052) @@ -34,173 +34,172 @@ using Deltares.DamEngine.Data.Standard.Logging; using Deltares.DamEngine.Data.Standard.Validation; -namespace Deltares.DamEngine.Calculators.DikesDesign +namespace Deltares.DamEngine.Calculators.DikesDesign; + +/// +/// Design strategy: first slope adaption, then shoulder adaption +/// +public class DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption { + private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67; + /// - /// Design strategy: first slope adaption, then shoulder adaption + /// Performs the design calculation with strategy: first slope adaption then shoulder adaption. /// - public class DesignCalculatorFirstSlopeAdaptionThenShoulderAdaption + /// 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 PerformDesignCalculationFirstSlopeAdaptionThenShoulderAdaption(IKernelWrapper kernelWrapper, + IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, + DesignScenario designScenario, List calculationMessages, List designCalculations) { - private const double defaultMaxFractionOfDikeHeightForShoulderHeight = 0.67; + Location location = damKernelInput.Location; + SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; + const int maxRedesignIterations = 200; + var resultMessage = ""; + List designResults; + int iterationIndex = -1; - /// - /// Performs the design calculation with strategy: first slope adaption then 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 PerformDesignCalculationFirstSlopeAdaptionThenShoulderAdaption(IKernelWrapper kernelWrapper, - IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput, - DesignScenario designScenario, List calculationMessages, List designCalculations) - { - Location location = damKernelInput.Location; - SoilGeometryProbability subSoilScenario = damKernelInput.SubSoilScenario; - const int maxRedesignIterations = 200; - var resultMessage = ""; - List designResults; - int iterationIndex = -1; + designScenario.CalculationResult = CalculationResult.NoRun; + EmbankmentDesignParameters embankmentDesignParameters; - 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(); - // Prepare the kernel for design - kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); - SurfaceLine2 surfaceLine = designScenario.GetMostRecentSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D).FullDeepClone(); - - try + try + { + iterationIndex = 1; + bool isRedesignRequired; + 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) { - iterationIndex = 1; - bool isRedesignRequired; - 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 = designScenario.Location.UseNewMaxHeightShoulderAsFraction ? designScenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; + double maxShoulderLevel = DesignCalculatorUtils.CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); + + // First slope adaption + double startCoTangent = location.SlopeAdaptionStartCotangent; + double endCoTangent = location.SlopeAdaptionEndCotangent; + double stepCoTangent = location.SlopeAdaptionStepCotangent; + double orgCotangent = surfaceLine.GetCotangentOfInnerSlope(); + double coTangent = startCoTangent; + double currentCoTangent = orgCotangent; + + // Find out for which cotangent we want to start designing + while (coTangent <= orgCotangent) { - // 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); + coTangent += stepCoTangent; } - else + + // Design for slope adaption + while (isRedesignRequired && (coTangent < endCoTangent)) { - double maxFractionOfDikeHeightForShoulderHeight = designScenario.Location.UseNewMaxHeightShoulderAsFraction ? designScenario.Location.NewMaxHeightShoulderAsFraction : defaultMaxFractionOfDikeHeightForShoulderHeight; - double maxShoulderLevel = DesignCalculatorUtils.CalculateMaximumShoulderLevel(surfaceLine, maxFractionOfDikeHeightForShoulderHeight); + iterationIndex++; + DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); - // First slope adaption - double startCoTangent = location.SlopeAdaptionStartCotangent; - double endCoTangent = location.SlopeAdaptionEndCotangent; - double stepCoTangent = location.SlopeAdaptionStepCotangent; - double orgCotangent = surfaceLine.GetCotangentOfInnerSlope(); - double coTangent = startCoTangent; - double currentCoTangent = orgCotangent; + var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, location, designScenario.PolderLevel); + // The parameter for ConstructNewSurfaceLineBySlope is the tangent of the slope, so use reciproce value + surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLineBySlope(1 / coTangent); + currentCoTangent = coTangent; - // Find out for which cotangent we want to start designing - while (coTangent <= orgCotangent) + ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); + if (validationError != null) { - coTangent += stepCoTangent; + throw new SurfaceLineException(validationError.Text); } - // Design for slope adaption - while (isRedesignRequired && (coTangent < endCoTangent)) - { - iterationIndex++; - DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, + subSoilScenario.SoilProfile2D, surfaceLine); - var surfaceLineSlopeAdapter = new SurfaceLineSlopeAdapter(surfaceLine, location, designScenario.PolderLevel); - // The parameter for ConstructNewSurfaceLineBySlope is the tangent of the slope, so use reciproce value - surfaceLine = surfaceLineSlopeAdapter.ConstructNewSurfaceLineBySlope(1 / coTangent); - currentCoTangent = coTangent; + // Recalculate new surfaceline + location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); + damKernelInput.Location.SurfaceLine = surfaceLine; + kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); + DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, iterationIndex, out locationCalculationMessages); + calculationMessages.AddRange(locationCalculationMessages); + isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); - ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); - if (validationError != null) - { - throw new SurfaceLineException(validationError.Text); - } + coTangent += stepCoTangent; + } - designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, - subSoilScenario.SoilProfile2D, surfaceLine); + // Then shoulder adaption + while (isRedesignRequired && surfaceLine != null) + { + iterationIndex++; + DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); - // Recalculate new surfaceline - location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); - damKernelInput.Location.SurfaceLine = surfaceLine; - kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); - DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, iterationIndex, out locationCalculationMessages); - calculationMessages.AddRange(locationCalculationMessages); - isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); + // Determine new width and height for shoulder + double shoulderHeight; + double shoulderLength; + GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); + DesignCalculatorUtils.DetermineNewShoulderLengthAndHeight(designScenario.Location.StabilityShoulderGrowDeltaX, + designScenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, + out shoulderHeight, out shoulderLength); - coTangent += stepCoTangent; - } + // Create new shoulder + var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, designScenario.Location, designScenario.PolderLevel); + surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; + surfaceLineShoulderAdapter.SlopeOfNewShoulder = currentCoTangent; + surfaceLine = surfaceLineShoulderAdapter.ConstructNewSurfaceLine(shoulderLength, shoulderHeight, false); - // Then shoulder adaption - while (isRedesignRequired && surfaceLine != null) + ValidationResult validationError = surfaceLine.Validate().FirstOrDefault(vr => vr.MessageType == ValidationResultType.Error); + if (validationError != null) { - iterationIndex++; - DesignCalculatorUtils.ThrowWhenMaxIterationsExceeded(iterationIndex, maxRedesignIterations); + throw new SurfaceLineException(validationError.Text); + } - // Determine new width and height for shoulder - double shoulderHeight; - double shoulderLength; - GeometryPoint limitPointForShoulderDesign = surfaceLine.GetLimitPointForShoulderDesign(); - DesignCalculatorUtils.DetermineNewShoulderLengthAndHeight(designScenario.Location.StabilityShoulderGrowDeltaX, - designScenario.Location.StabilityShoulderGrowSlope, surfaceLine, limitPointForShoulderDesign, - out shoulderHeight, out shoulderLength); + designScenario.SetRedesignedSurfaceLine(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, surfaceLine); - // Create new shoulder - var surfaceLineShoulderAdapter = new SurfaceLineShoulderAdapter(surfaceLine, designScenario.Location, designScenario.PolderLevel); - surfaceLineShoulderAdapter.MaxShoulderLevel = maxShoulderLevel; - surfaceLineShoulderAdapter.SlopeOfNewShoulder = currentCoTangent; - 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); - - // Recalculate new surfaceline - designScenario.Location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); - damKernelInput.Location.SurfaceLine = surfaceLine; - kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); - DesignCalculatorUtils.KernelCalculate(out kernelDataInput, kernelWrapper, out kernelDataOutput, damKernelInput, iterationIndex, out locationCalculationMessages); - calculationMessages.AddRange(locationCalculationMessages); - isRedesignRequired = !kernelWrapper.EvaluateDesign(damKernelInput, kernelDataInput, kernelDataOutput, out designAdvise, out evaluationMessage); - } + // Recalculate new surfaceline + designScenario.Location.AlignBoundaryPointsOfPl1LineWithAdaptedSurfaceLine(surfaceLine); + damKernelInput.Location.SurfaceLine = surfaceLine; + kernelWrapper.PrepareDesign(kernelDataInput, kernelDataOutput, damKernelInput, iterationIndex, out embankmentDesignParameters); + 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, "Succes"); - designScenario.CalculationResult = CalculationResult.Succeeded; - 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; - } - 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); + designScenario.SetResultMessage(subSoilScenario.SoilProfile1D, subSoilScenario.SoilProfile2D, "Succes"); + designScenario.CalculationResult = CalculationResult.Succeeded; + 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; } + + 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); } } } \ No newline at end of file