// Copyright (C) Stichting Deltares 2018. All rights reserved.
//
// This file is part of the Dam Engine.
//
// The Dam Engine is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using Deltares.DamEngine.Calculators.KernelWrappers.Common;
using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces;
using Deltares.DamEngine.Calculators.Properties;
using Deltares.DamEngine.Data.Geometry;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Logging;
namespace Deltares.DamEngine.Calculators.DikesDesign
{
public class DesignCalculatorUtils
{
///
/// Determines the new height and length of the shoulder
///
/// The shoulder grow delta X.
/// The shoulder grow slope.
/// The surface line.
/// The limit point for shoulder design.
/// New height of the shoulder.
/// New length of the shoulder.
public static void DetermineNewShoulderLengthAndHeight(double shoulderGrowDeltaX, double shoulderGrowSlope,
SurfaceLine2 surfaceLine, GeometryPoint limitPointForShoulderDesign, out double shoulderHeight, out double shoulderLength)
{
// Determine new shoulderpoint
var newShoulderPoint = new GeometryPoint()
{
X = limitPointForShoulderDesign.X + shoulderGrowDeltaX,
Z = limitPointForShoulderDesign.Z + shoulderGrowDeltaX * shoulderGrowSlope
};
// Determine new shoulder length and height
shoulderLength = surfaceLine.DetermineShoulderLengthForGivenShoulderTopInside(newShoulderPoint);
shoulderHeight = newShoulderPoint.Z - surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtPolder).Z;
}
///
/// Throws the when maximum iterations exceeded.
///
/// Index of the iteration.
/// The maximum redesign iterations.
///
public static void ThrowWhenMaxIterationsExceeded(int iterationIndex, int maxRedesignIterations)
{
if (iterationIndex >= maxRedesignIterations)
{
throw new DesignCalculatorException(string.Format(Resources.DesignMaxIterationsExceeded, maxRedesignIterations));
}
}
///
/// Calculates the maximum shoulder level.
///
/// The surface line.
/// Maximum height of the fraction of dike height for shoulder.
///
///
public 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 SurfaceLineAdapterException(Resources.SurfaceLineShoulderAdapterMaxShoulderHeightError);
}
double maxHeight = Math.Abs((top - bottom) * maxFractionOfDikeHeightForShoulderHeight);
return bottom + maxHeight;
}
///
/// Call the kernel calculation.
///
/// The kernel data input.
/// The kernel wrapper.
/// The kernel data output.
/// The dam kernel input.
/// Index of the iteration.
/// The location calculation messages.
///
public static void KernelCalculate(out IKernelDataInput kernelDataInput, IKernelWrapper kernelWrapper, out IKernelDataOutput kernelDataOutput, DamKernelInput damKernelInput,
int iterationIndex, out List locationCalculationMessages)
{
locationCalculationMessages = new List();
PrepareResult prepareResult = kernelWrapper.Prepare(damKernelInput, iterationIndex, out kernelDataInput, out kernelDataOutput);
if (prepareResult != PrepareResult.Successful)
{
throw new DesignCalculatorException(Resources.KernelCalculationFailed);
}
kernelWrapper.Execute(kernelDataInput, kernelDataOutput, out locationCalculationMessages);
}
}
}