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; // TODO: temporary outcommented to get UI working //if (designResult.CalculationResult == CalculationResult.Succeeded) { // TODO: for now this only works for NoAdaption of geometry; if adaption is enabled, the real redesigned surfaceline has to be assigned pipingDesignResults.RedesignedSurfaceLine = damKernelInput.Location.SurfaceLine; pipingDesignResults.Sellmeijer4ForcesFactor = damPipingOutput.FoSp; pipingDesignResults.Sellmeijer4ForcesHcritical = damPipingOutput.Hc; pipingDesignResults.LocalExitPointX = damPipingOutput.ExitPointX; pipingDesignResults.UpliftFactor = damPipingOutput.UpliftFactor; pipingDesignResults.UpliftSituation = damPipingOutput.UpliftSituation; } } } }