Index: DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs
===================================================================
diff -u -r1040 -r1052
--- DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs (.../DesignCalculator.cs) (revision 1040)
+++ DamEngine/trunk/src/Deltares.DamEngine.Calculators/DikesDesign/DesignCalculator.cs (.../DesignCalculator.cs) (revision 1052)
@@ -27,6 +27,7 @@
using Deltares.DamEngine.Calculators.KernelWrappers.Common;
using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces;
using Deltares.DamEngine.Calculators.Properties;
+using Deltares.DamEngine.Data.Design;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.Geometry;
@@ -40,6 +41,12 @@
///
public class DesignCalculator
{
+ private const double CMinimumShoulderElevation = 0.5;
+ private const double CMinimumShoulderExtraElevation = 0.05;
+ private const double CMinimumShoulderWidth = 2;
+ private const double CMinimumShoulderExtraWidth = 1;
+ private const double CToleranceShoulderChanges = 0.001;
+
///
/// Performs the design calculation
///
@@ -77,7 +84,7 @@
damKernelInput.RiverLevelHigh = damKernelInput.DesignScenario.RiverLevel;
damKernelInput.RiverLevelLow = damKernelInput.DesignScenario.RiverLevelLow;
AnalysisType analysisType = DamProjectCalculationSpecification.SelectedAnalysisType;
- SynchronizeScenarioDataWithLocationData(damKernelInput);
+ SynchronizeDesignScenarioDataWithLocationData(damKernelInput.DesignScenario, damKernelInput.Location);
IKernelDataInput kernelDataInput;
IKernelDataOutput kernelDataOutput;
PrepareResult prepareResult = kernelWrapper.Prepare(damKernelInput, 0, out kernelDataInput, out kernelDataOutput);
@@ -129,51 +136,62 @@
/// Synchronizes the scenario data with location data.
/// Note that scenario data is leading when available.
///
- /// The dam kernel input.
- private void SynchronizeScenarioDataWithLocationData(DamKernelInput damKernelInput)
+ /// The design scenario.
+ /// The location.
+ private void SynchronizeDesignScenarioDataWithLocationData(DesignScenario designScenario, Location location)
{
- var scenario = damKernelInput.DesignScenario;
- if (scenario.PlLineOffsetBelowDikeToeAtPolder.HasValue)
+ // Synchronize PlLinescreator parameters
+ if (designScenario.PlLineOffsetBelowDikeToeAtPolder.HasValue)
{
- scenario.Location.PlLineOffsetBelowDikeToeAtPolder = scenario.PlLineOffsetBelowDikeToeAtPolder.Value;
+ location.PlLineOffsetBelowDikeToeAtPolder = designScenario.PlLineOffsetBelowDikeToeAtPolder.Value;
}
- if (scenario.PlLineOffsetBelowDikeTopAtPolder.HasValue)
+ if (designScenario.PlLineOffsetBelowDikeTopAtPolder.HasValue)
{
- scenario.Location.PlLineOffsetBelowDikeTopAtPolder = scenario.PlLineOffsetBelowDikeTopAtPolder.Value;
+ location.PlLineOffsetBelowDikeTopAtPolder = designScenario.PlLineOffsetBelowDikeTopAtPolder.Value;
}
- if (scenario.PlLineOffsetBelowDikeTopAtRiver.HasValue)
+ if (designScenario.PlLineOffsetBelowDikeTopAtRiver.HasValue)
{
- scenario.Location.PlLineOffsetBelowDikeTopAtRiver = scenario.PlLineOffsetBelowDikeTopAtRiver.Value;
+ location.PlLineOffsetBelowDikeTopAtRiver = designScenario.PlLineOffsetBelowDikeTopAtRiver.Value;
}
- if (scenario.PlLineOffsetBelowShoulderBaseInside.HasValue)
+ if (designScenario.PlLineOffsetBelowShoulderBaseInside.HasValue)
{
- scenario.Location.PlLineOffsetBelowShoulderBaseInside = scenario.PlLineOffsetBelowShoulderBaseInside.Value;
+ location.PlLineOffsetBelowShoulderBaseInside = designScenario.PlLineOffsetBelowShoulderBaseInside.Value;
}
- if (scenario.PlLineOffsetBelowDikeCrestMiddle.HasValue)
+ if (designScenario.PlLineOffsetBelowDikeCrestMiddle.HasValue)
{
- scenario.Location.PlLineOffsetBelowDikeCrestMiddle = scenario.PlLineOffsetBelowDikeCrestMiddle;
+ location.PlLineOffsetBelowDikeCrestMiddle = designScenario.PlLineOffsetBelowDikeCrestMiddle;
}
- if (scenario.PlLineOffsetFactorBelowShoulderCrest.HasValue)
+ if (designScenario.PlLineOffsetFactorBelowShoulderCrest.HasValue)
{
- scenario.Location.PlLineOffsetFactorBelowShoulderCrest = scenario.PlLineOffsetFactorBelowShoulderCrest;
+ location.PlLineOffsetFactorBelowShoulderCrest = designScenario.PlLineOffsetFactorBelowShoulderCrest;
}
- if (scenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue)
+ if (designScenario.UsePlLineOffsetBelowDikeCrestMiddle.HasValue)
{
- scenario.Location.UsePlLineOffsetBelowDikeCrestMiddle = scenario.UsePlLineOffsetBelowDikeCrestMiddle;
+ location.UsePlLineOffsetBelowDikeCrestMiddle = designScenario.UsePlLineOffsetBelowDikeCrestMiddle;
}
- if (scenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue)
+ if (designScenario.UsePlLineOffsetFactorBelowShoulderCrest.HasValue)
{
- scenario.Location.UsePlLineOffsetFactorBelowShoulderCrest = scenario.UsePlLineOffsetFactorBelowShoulderCrest;
+ location.UsePlLineOffsetFactorBelowShoulderCrest = designScenario.UsePlLineOffsetFactorBelowShoulderCrest;
}
- if (scenario.HeadPl3.HasValue)
+ if (designScenario.HeadPl3.HasValue)
{
- scenario.Location.HeadPl3 = scenario.HeadPl3.Value;
+ location.HeadPl3 = designScenario.HeadPl3.Value;
}
- if (scenario.HeadPl4.HasValue)
+ if (designScenario.HeadPl4.HasValue)
{
- scenario.Location.HeadPl4 = scenario.HeadPl4.Value;
+ location.HeadPl4 = designScenario.HeadPl4.Value;
}
+
+ // Synchronize piping design parameters
+ if (designScenario.UpliftCriterionPiping.HasValue)
+ {
+ location.UpliftCriterionPiping = designScenario.UpliftCriterionPiping.Value;
+ }
+ if (designScenario.RequiredSafetyFactorPiping.HasValue)
+ {
+ location.ModelFactors.RequiredSafetyFactorPiping = designScenario.RequiredSafetyFactorPiping.Value;
+ }
}
private static void PerformSingleCalculation(IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput,
@@ -245,11 +263,32 @@
return newLine;
}
+ ///
+ /// 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)
+ {
+ var top = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeTopAtPolder).Z;
+ var bottom = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z;
+ if (top - bottom <= 0)
+ {
+ throw new DesignCalculatorException(Resources.SurfaceLineShoulderAdapterMaxShoulderHeightError);
+ }
+ double maxHeight = Math.Abs((top - bottom) * maxFractionOfDikeHeightForShoulderHeight);
+ return bottom + maxHeight;
+ }
private static void PerformDesignCalculation(IKernelWrapper kernelWrapper, IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput,
List calculationMessages, List designCalculations)
{
List locationCalculationMessages = new List();
- var surfaceLine = damKernelInput.Location.SurfaceLine;
+ var location = damKernelInput.Location;
+ var surfaceLine = location.SurfaceLine;
+ double orgShoulderLength = surfaceLine.DetermineShoulderWidth();
+ double orgShoulderHeight = surfaceLine.DetermineShoulderHeight();
+
GeometryPoint startSurfacePoint = surfaceLine.GetDikeToeInward();
IEnumerable relevantSurfacePointsList = from GeometryPoint point in surfaceLine.Geometry.Points
@@ -258,18 +297,13 @@
select point;
relevantSurfacePointsList = GetCheckedSurfaceLine(relevantSurfacePointsList);
double oldDesiredShoulderLength = 0.0;
- double desiredShoulderLength;
- double desiredShoulderHeight;
+ double desiredShoulderLength = 0.0;
+ double desiredShoulderHeight = 0.0;
double oldDesiredShoulderHeight = 0.0;
int pointCount = 0;
foreach (var point in relevantSurfacePointsList)
{
pointCount++;
- // Determine calculation filename to output piping calculation file
- //pipingCalculator.PipingCalculationDirectory = GetPipingCalculationBaseDirectory();
- //string fileNameCalculation =String.Format("Calc({0})_Loc({1})_Pro({2})_Pnt({3}))",
- // pipingCalculator.CalculationModelIdentifier, scenario.Location.Name, soilProfileProbability.SoilProfile.Name, pointCount.ToString("d4")); ;
- //pipingCalculator.FilenameCalculation = Path.Combine(pipingCalculator.PipingCalculationDirectory, fileNameCalculation);
// Calculate the piping design at the given point. This returns the required adaption (berm length and height) if any.
var pipingDesign = kernelWrapper.CalculateDesignAtPoint(damKernelInput, kernelDataInput, kernelDataOutput, point, out locationCalculationMessages);
@@ -283,9 +317,56 @@
desiredShoulderHeight = pipingDesign.ShoulderHeightFromToe;
desiredShoulderHeight = Math.Max(desiredShoulderHeight, oldDesiredShoulderHeight);
oldDesiredShoulderHeight = desiredShoulderHeight;
-
}
+
}
+ if (desiredShoulderLength > 0)
+ {
+ desiredShoulderLength = Math.Max(desiredShoulderLength, CMinimumShoulderWidth);
+ }
+ if (desiredShoulderLength > 0)
+ {
+ desiredShoulderHeight = Math.Max(desiredShoulderHeight, CMinimumShoulderElevation);
+ }
+ bool isNewShoulderSameAsOriginal = ((Math.Abs(desiredShoulderLength - orgShoulderLength) < CToleranceShoulderChanges) &&
+ (Math.Abs(desiredShoulderHeight - orgShoulderHeight) < CToleranceShoulderChanges));
+ SurfaceLine2 newSurfaceLine = null;
+ 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);
+ 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);
+ List designResults;
+ StringBuilder sb = new StringBuilder();
+ foreach (var message in locationCalculationMessages)
+ {
+ sb.Append(message.Message + Environment.NewLine);
+ }
+ string resultMessage = sb.ToString();
+ kernelWrapper.PostProcess(damKernelInput, kernelDataOutput, resultMessage, out designResults);
+ foreach (var designResult in designResults)
+ {
+ designCalculations.Add(designResult);
+ }
+ // safetyFactor = pipingCalculator.CalculatePipingFactor(location, newSurfaceLine, soilProfileProbability.SoilProfile, scenario.RiverLevel);
+ // if (safetyFactor < scenario.RequiredSafetyFactorPiping)
+ // {
+ // throw new DamFailureMechanismeCalculatorException("Deterministic Design: Piping is not safe yet.");
+ // }
+ // return newSurfaceLine;
}
}
}