using System;
using System.Collections.Generic;
using System.Data;
using Deltares.DamEngine.Calculators.KernelWrappers.Common;
using Deltares.DamEngine.Calculators.KernelWrappers.Interfaces;
using Deltares.DamEngine.Calculators.Properties;
using Deltares.DamEngine.Calculators.Uplift;
using Deltares.DamEngine.Data.General;
using Deltares.DamEngine.Data.General.Results;
using Deltares.DamEngine.Data.Geotechnics;
using Deltares.DamEngine.Data.Standard.Calculation;
using Deltares.DamEngine.Data.Standard.Logging;
using Deltares.DamPiping.Sellmeijer4ForcesCalculator;
namespace Deltares.DamEngine.Calculators.KernelWrappers.DamPipingSellmeijer4Forces
{
public class DamPipingSellmeijer4ForcesKernelWrapper : IKernelWrapper
{
private const double defaultFluidisationGradient = 0.3;
private const double defaultMaxReturnValue = 90.0;
///
/// Prepares the specified dam kernel input.
///
/// The dam kernel input.
/// The kernel data input.
/// The krenel data output
///
/// Result of the prepare
///
public PrepareResult Prepare(DamKernelInput damKernelInput, out IKernelDataInput kernelDataInput, out IKernelDataOutput kernelDataOutput)
{
var damOutput = new DamPipingSellmeijer4ForcesOutput()
{
FoSp = defaultMaxReturnValue
};
kernelDataOutput = damOutput;
if (damKernelInput.SubSoilScenario.SegmentFailureMechanismType == FailureMechanismSystemType.Piping)
{
const double cDefaultWaterViscosity = 1.33E-06;
const double factorMeterToMicroMeter = 1000000.0;
var soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile1D;
var surfaceLine = damKernelInput.Location.SurfaceLine;
var location = damKernelInput.Location;
var riverLevel = damKernelInput.DesignScenario.RiverLevel;
UpliftSituation upliftSituation;
var plLines = PlLinesHelper.CreatePlLines(location, soilProfile1D, riverLevel, out upliftSituation);
var upliftLocationDeterminator = new UpliftLocationDeterminator
{
PLLines = plLines,
SoilProfile = soilProfile1D,
SurfaceLine = surfaceLine,
DikeEmbankmentMaterial = location.GetDikeEmbankmentSoil(),
XSoilGeometry2DOrigin = location.XSoilGeometry2DOrigin
};
var upliftLocationAndResult = upliftLocationDeterminator.GetLocationAndResult(damKernelInput.DesignScenario.GetUpliftCriterionPiping(null));
upliftSituation.IsUplift = (upliftLocationAndResult != null);
var xEntry = surfaceLine.CharacteristicPoints.GetGeometryPoint(CharacteristicPointType.DikeToeAtRiver).X;
var xExit = 0.0;
var surfaceLevel = 0.0;
var dCoverLayer = 0.0;
var d70 = 0.0;
var aquiferHeight = 0.0;
var permeabilityKx = 0.0;
double? upliftFactor = null;
if (upliftLocationAndResult != null)
{
xExit = upliftLocationAndResult.X;
surfaceLevel = surfaceLine.Geometry.GetZatX(upliftLocationAndResult.X);
var topLevelAquifer = soilProfile1D.GetLayerWithName(upliftLocationAndResult.LayerWhereUpliftOccuresId).TopLevel;
dCoverLayer = DamPipingHelper.DetermineHeightCoverLayer(topLevelAquifer, surfaceLevel);
var aquiferLayer = SoilProfile1DAquiferLayerCombiner.CombineLayers(soilProfile1D, upliftLocationAndResult.LayerWhereUpliftOccuresId);
d70 = aquiferLayer.D70 * factorMeterToMicroMeter;
aquiferHeight = aquiferLayer.Height;
permeabilityKx = aquiferLayer.PermeabilityKx;
upliftFactor = upliftLocationAndResult.UpliftFactor;
}
var seepageLength = xExit - xEntry;
// Reference level is highest value of surfaceLevel or PolderLevel
// Uit TR Zandmeevoerende wellen (1999): "Het verval dH is gelijk aan het verschil tussen buitenwaterstand (het ontwerppeil(OP))
// bij zeedijken en de maatgevende hoogwaterstand (MHW bij rivierdijken) en de waterstand binnendijks ter plaatse van het uittredepunt,
// rekening houdend met zeespiegelrijzing etc.(zie paragraaf 3.7.2). In dien ter plaatse van het uittreepunt of de opbarstlocatie
// geen vrije waterstand heerst kan gerekend worden met het maaiveldniveau, rekening houdend met eventuele maaiveld daling (zie paragraaf 3.7.2)."
var referenceLevel = Math.Max(location.PolderLevel, surfaceLevel);
Soil inBetweenAquiferlayerSoil = soilProfile1D.BottomAquiferLayer.Soil;
if (soilProfile1D.InBetweenAquiferLayer != null)
{
inBetweenAquiferlayerSoil = soilProfile1D.InBetweenAquiferLayer.Soil;
}
kernelDataInput = new DamPipingSellmeijer4ForcesInput()
{
HRiver = riverLevel,
HExit = referenceLevel,
Rc = defaultFluidisationGradient,
DTotal = dCoverLayer,
SeepageLength = seepageLength,
// specific Sellmeijer 4 Forces
WaterViscosity = cDefaultWaterViscosity,
WhitesConstant = inBetweenAquiferlayerSoil.WhitesConstant,
BeddingAngle = inBetweenAquiferlayerSoil.BeddingAngle,
D70 = d70,
AquiferHeight = aquiferHeight,
PermeabilityKx = permeabilityKx,
};
damOutput.ExitPointX = xExit;
damOutput.UpliftFactor = upliftFactor;
damOutput.UpliftSituation = upliftSituation;
return PrepareResult.Successful;
}
kernelDataInput = null;
return PrepareResult.NotRelevant;
}
///
/// Validates the specified kernel data input.
///
/// The kernel data input.
/// The kernel data output.
/// The return messages.
///
/// Number of errors that prevent a calculation
///
public int Validate(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages)
{
DamPipingSellmeijer4ForcesOutput damPipingOutput = (DamPipingSellmeijer4ForcesOutput)kernelDataOutput;
var calculator = CreatePipingCalculatorSellmeijer4Forces(kernelDataInput);
List kernelMessages = calculator.Validate();
messages = new List();
foreach (string stringMessage in kernelMessages)
{
messages.Add(new LogMessage() { Message = stringMessage, MessageType = LogMessageType.Error });
}
if (messages.Count > 0)
{
damPipingOutput.CalculationResult = CalculationResult.InvalidInputData;
}
return messages.Count;
}
///
/// Executes the kernel.
///
/// The kernel data input.
/// The kernel data input.
/// The return messages.
/// No input object defined
public void Execute(IKernelDataInput kernelDataInput, IKernelDataOutput kernelDataOutput, out List messages)
{
DamPipingSellmeijer4ForcesInput damPipingInput = kernelDataInput as DamPipingSellmeijer4ForcesInput;
if (damPipingInput == null)
{
throw new NoNullAllowedException(Resources.DamPipingSellmeijer4ForcesKernelWrapper_NoInputObjectDefinedForSellmeijer4Forces);
}
DamPipingSellmeijer4ForcesOutput damPipingOutput = (DamPipingSellmeijer4ForcesOutput)kernelDataOutput;
if (damPipingOutput == null)
{
throw new NoNullAllowedException(Resources.DamPipingSellmeijer4ForcesKernelWrapper_NoInputObjectDefinedForSellmeijer4Forces);
}
damPipingOutput.FoSp = defaultMaxReturnValue;
messages = new List();
if (damPipingOutput.UpliftSituation.IsUplift)
{
var calculator = CreatePipingCalculatorSellmeijer4Forces(kernelDataInput);
calculator.Calculate();
damPipingOutput.FoSp = calculator.FoSp;
damPipingOutput.Hc = calculator.Hc;
damPipingOutput.CalculationResult = CalculationResult.Succeeded;
}
}
private static PipingCalculatorSellmeijer4Forces CreatePipingCalculatorSellmeijer4Forces(IKernelDataInput kernelDataInput)
{
DamPipingSellmeijer4ForcesInput damPipingInput = kernelDataInput as DamPipingSellmeijer4ForcesInput;
if (damPipingInput == null)
{
throw new NoNullAllowedException(Resources.DamPipingSellmeijer4ForcesKernelWrapper_NoInputObjectDefinedForSellmeijer4Forces);
}
var calculator = new PipingCalculatorSellmeijer4Forces
{
HRiver = damPipingInput.HRiver,
HExit = damPipingInput.HExit,
Rc = damPipingInput.Rc,
DTotal = damPipingInput.DTotal,
AquiferHeight = damPipingInput.AquiferHeight,
SeepageLength = damPipingInput.SeepageLength,
D70 = damPipingInput.D70,
WhitesConstant = damPipingInput.WhitesConstant,
BeddingAngle = damPipingInput.BeddingAngle,
PermeabilityKx = damPipingInput.PermeabilityKx,
WaterViscosity = damPipingInput.WaterViscosity,
};
return calculator;
}
///
/// Fills the design results with the kernel output.
///
/// The dam kernel input.
/// The kernel data output.
/// The result message.
/// The design result.
/// No input or output object defined
public void PostProcess(DamKernelInput damKernelInput, IKernelDataOutput kernelDataOutput, string resultMessage, out DesignResult designResult)
{
DamPipingSellmeijer4ForcesOutput damPipingOutput = kernelDataOutput as DamPipingSellmeijer4ForcesOutput;
if (damPipingOutput == null)
{
throw new NoNullAllowedException(Resources.DamPipingSellmeijer4ForcesKernelWrapper_NoOutputObjectDefinedForSellmeijer4Forces);
}
if (damKernelInput == null)
{
throw new NoNullAllowedException(Resources.DamPipingSellmeijer4ForcesKernelWrapper_NoInputObjectDefinedForSellmeijer4Forces);
}
string soilProfile2DName = "";
var d = new DamFailureMechanismeCalculationSpecification();
var designScenario = damKernelInput.DesignScenario;
var soilProfile1D = damKernelInput.SubSoilScenario.SoilProfile1D;
designResult = new DesignResult(d, designScenario, soilProfile1D, soilProfile2DName, AnalysisType.NoAdaption);
designResult.CalculationResult = damPipingOutput.CalculationResult;
var pipingDesignResults = new PipingDesignResults(PipingModelType.Sellmeijer4Forces);
designResult.PipingDesignResults = pipingDesignResults;
pipingDesignResults.ResultMessage = resultMessage;
if (designResult.CalculationResult == CalculationResult.Succeeded)
{
pipingDesignResults.Sellmeijer4ForcesFactor = damPipingOutput.FoSp;
pipingDesignResults.Sellmeijer4ForcesHcritical = damPipingOutput.Hc;
pipingDesignResults.LocalExitPointX = damPipingOutput.ExitPointX;
pipingDesignResults.UpliftFactor = damPipingOutput.UpliftFactor;
pipingDesignResults.UpliftSituation = damPipingOutput.UpliftSituation;
}
}
}
}