// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of the Dam Piping Kernels. // // The Dam Macrostability Kernel 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 Deltares.DamPiping.SellmeijerVNKCalculator.Geo; using System; using System.Collections.Generic; using Deltares.DamPiping.SellmeijerVNKCalculator.Properties; namespace Deltares.DamPiping.SellmeijerVNKCalculator { /// /// Calculates piping according to Sellmeijer VNK /// public class PipingCalculatorSellmeijerVNK { public const double RcDefault = 0.3; /// /// River level as input /// public double HRiver { get; set; } /// /// Phreatic level at exit point as input /// public double HExit { get; set; } /// /// Polder level as input /// public double PolderLevel { get; set; } /// /// Surface level as input /// public double SurfaceLevel { get; set; } /// /// Reduction factor as input /// public double Rc { get; set; } = RcDefault; /// /// Total thickness of cover layer as input /// public double DTotal { get; set; } /// /// Thickness of the layer in between aquifer as input /// public double DInBetweenAquiferlayer { get; set; } /// /// Thickness of the bottom aquifer layer as input /// public double DBottomAquiferlayer { get; set; } /// /// The permeability kx of the layer in between aquifer as input /// public double PermeabilityInBetweenAquiferlayer { get; set; } /// /// The permeability kx of the bottom aquifer layer as input /// public double PermeabilityBottomAquiferlayer { get; set; } /// /// Seepage length (xExit - xEntry) as input /// public double SeepageLength { get; set; } /// /// Median grainsize D70 as input /// public double D70 { get; set; } /// /// The whites constant as input /// public double WhitesConstant { get; set; } /// /// The bedding angle as input /// public double BeddingAngle { get; set; } /// /// The water viscosity as input /// public double WaterViscosity { get; set; } /// /// Safety factor of piping as result /// public double FoSp { get; private set; } /// /// Critical head difference for piping as result. /// public double Hc { get; private set; } /// /// Start the calculation of all output parameters. /// public void Calculate() { Hc = CalculateHCritical(); var reducedFall = GetReducedFall(); FoSp = DetermineFactorOfSafety(Hc, reducedFall); } internal double CalculateHCritical() { PipingModel2Calculation pipingModel2Calculation = CreateAndFillPipingModel2Calculation(); // 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)." pipingModel2Calculation.CalculateHeadDropPC2(); return pipingModel2Calculation.HeadDrop; } internal static double DetermineFactorOfSafety(double hCritical, double headDrop) { const double cDefaultMaxReturnValue = 90.0; const double cDefaultMinReturnValue = 0.0; const double cEpsilon = 1e-8; double factor = cDefaultMinReturnValue; if (Math.Abs(hCritical) > cEpsilon) { factor = cDefaultMaxReturnValue; // If actual headdrop is almost zero or smaller than zero then piping will be no problem // The pipingfactor will be set to cDefaultMaxReturnValue if (headDrop > 0 + cEpsilon) { factor = hCritical / headDrop; } } return factor; } internal double GetReducedFall() { // The Leidraad says that 0.3 * d can be substracted from hActual // In the piping Sellmeijer model (PipingModel2 for VNK) 0.3 * d is added to the hCritical // So we do not substract 0.3 * d from hActual (written by Tom The and Erik Vastenburg) return HRiver - HExit; } /// /// Create PipingModel2Calculation object and fill with input parameters /// /// private PipingModel2Calculation CreateAndFillPipingModel2Calculation() { var pipingModel2Calculation = new PipingModel2Calculation(); pipingModel2Calculation.IsHeadDropCalculation = true; // Constant pipingModel2Calculation.SeepageLength = SeepageLength; pipingModel2Calculation.CrackLength = DTotal; pipingModel2Calculation.HeadDrop = 0.0;// Not used, to be calculated pipingModel2Calculation.PipingCommonData.BeddingAngle = BeddingAngle; // From soilmaterials of upper sandlayer pipingModel2Calculation.PipingCommonData.FluidisationGradient = Rc; //Constant pipingModel2Calculation.PipingCommonData.WaterUnitWeight = Physics.UnitWeightOfwater; //Constant pipingModel2Calculation.PipingCommonData.WaterViscosity = WaterViscosity; //Constant pipingModel2Calculation.PipingCommonData.WhitesConstant = WhitesConstant; // From soilmaterials of upper sandlayer pipingModel2Calculation.PipingCommonData.SafetyFactor = 1.20; //Constant toetsen/ontwerpen = 1.2 en calamiteit = 1.0 pipingModel2Calculation.PipingCommonData.IsAdjustHeadDrop = true; // Constant // Soil parameters pipingModel2Calculation.PipingCommonData.ParticleUnitWeight = 26.50; // Constant pipingModel2Calculation.Permeability1 = PermeabilityInBetweenAquiferlayer; // Kx From upper sandlayer pipingModel2Calculation.Permeability2 = PermeabilityBottomAquiferlayer; // Kx From bottom sandlayer pipingModel2Calculation.Permeability3 = PermeabilityInBetweenAquiferlayer; // Kx From upper sandlayer pipingModel2Calculation.ParticleDiameter = D70; // D70 D60 From soilmaterials of upper sandlayer // Geometry parameters pipingModel2Calculation.Height1 = DInBetweenAquiferlayer; // Thickness upper sandlayer pipingModel2Calculation.Height2 = DBottomAquiferlayer; // Thickness bottom sandlayer return pipingModel2Calculation; // // particleunitweight = gamma_p can be calculated as follows // (gamma_sat - gamma_water) = (gamma_p - gamma_water) / (1 - n); for now 26.50 is good enough // // limit heights: see TPC2Preprocessing.AdjustParameters() // CD1MinSeepageLengthFactor = 0.02; = D1 / Length // CD2MinSeepageLengthFactor = 0.03; = D2 / Length // CD1MaxSeepageLengthFactor = 1.4; // CD2MaxSeepageLengthFactor = 1.4; // // Kx or Ky: Sel: Use Kx } /// /// Validates the input /// /// a filled list when errors are found else an empty list public List Validate() { var errors = new List(); errors.AddRange(PerformValidate()); return errors; } private List PerformValidate() { var errors = new List(); if (Math.Abs(GetReducedFall()) < double.Epsilon) { errors.Add(Resources.PipingCalculatorSellmeijerVNK_PerformValidate_HRiver_HExit_Zero); } if (double.IsNaN(SeepageLength)) { LogParameterIsNaN(errors, "SeepageLength"); } if (double.IsNaN(HRiver)) { LogParameterIsNaN(errors, "HRiver"); } if (double.IsNaN(PolderLevel)) { LogParameterIsNaN(errors, "PolderLevel"); } if (double.IsNaN(SurfaceLevel)) { LogParameterIsNaN(errors, "SurfaceLevel"); } if (double.IsNaN(Rc)) { LogParameterIsNaN(errors, "Rc"); } if (Rc < 0) { errors.Add(Resources.PipingCalculatorSellmeijerVNK_PerformValidate_RcLessThan0); } if (double.IsNaN(DTotal)) { LogParameterIsNaN(errors, "DTotal"); } if (double.IsNaN(DInBetweenAquiferlayer)) { LogParameterIsNaN(errors, "DInBetweenAquiferlayer"); } if (double.IsNaN(DBottomAquiferlayer)) { LogParameterIsNaN(errors, "DBottomAquiferlayer"); } if (double.IsNaN(PermeabilityInBetweenAquiferlayer)) { LogParameterIsNaN(errors, "PermeabilityInBetweenAquiferlayer"); } if (double.IsNaN(PermeabilityBottomAquiferlayer)) { LogParameterIsNaN(errors, "PermeabilityBottomAquiferlayer"); } if (double.IsNaN(HExit)) { LogParameterIsNaN(errors, "HExit"); } if (double.IsNaN(D70)) { LogParameterIsNaN(errors, "D70"); } if (double.IsNaN(WhitesConstant)) { LogParameterIsNaN(errors, "WhitesConstant"); } if (double.IsNaN(BeddingAngle)) { LogParameterIsNaN(errors, "BeddingAngle"); } if (double.IsNaN(WaterViscosity)) { LogParameterIsNaN(errors, "WaterViscosity"); } return errors; } private void LogParameterIsNaN(IList list, string paramName) { var msg = string.Format(Resources.PipingCalculatorSellmeijerVNK_LogParameterIsNaN_NaNParameterError, paramName); list.Add(msg); } } }