using System; using System.Collections.Generic; using Deltares.Piping.Data; namespace Deltares.Piping.Data { public class PipingDAMAnalysis { private const string sDGSDAMPipingBBN = @"C:\WebAppDirs\www.delftgeosystems.nl\applications\ASP\DGWebDAM\BBNData\DAM Piping.bbnet"; //private const string sDGSDAMPipingBBN = ".\\CalcDlls\\DAM Piping.bbnet"; private PipingDAMInput fPipingDAMInput; public PipingDAMInput PipingDAMInput { get { return fPipingDAMInput; } set { fPipingDAMInput = value; } } /// /// Determine piping factor by weighted average of all soils belonging to location. /// Waterlevel is determined from aFlowLobith /// /// /// /// Piping Factor public double DetermineLocationPipingFactor(string aLocation, double aFlowLobith) { PipingDAMLocationGeometryStruct locationGeometry = fPipingDAMInput.GetLocationGeometry(aLocation); List locationSoils = fPipingDAMInput.GetLocationSoils(aLocation); double waterLevel = fPipingDAMInput.DetermineWaterLevel(aLocation, aFlowLobith); return DetermineLocationPipingFactorFromWaterLevel(aLocation, waterLevel); } /// /// Determine piping factor by weighted average of all soils belonging to location. /// Waterlevel is specified /// /// /// /// Piping Factor public double DetermineLocationPipingFactorFromWaterLevel(string aLocation, double aWaterLevel) { PipingDAMLocationGeometryStruct locationGeometry = fPipingDAMInput.GetLocationGeometry(aLocation); List locationSoils = fPipingDAMInput.GetLocationSoils(aLocation); double pipingFactor = 0.0; bool isCracking = false; const double cCrackFactorLimit = 1.0; const double cPipingFactorIfNoCracking = 100.0; foreach (PipingDAMLocationSoilStruct locationSoil in locationSoils) { double crackFactor = DetermineCrackFactor(locationGeometry.FNeer, locationGeometry.BovenkantZand, aWaterLevel, locationGeometry.PolderLevel, locationGeometry.thicknessSoftSoils, locationGeometry.SeepageLength, locationSoil.Height1, locationSoil.Permeability1, locationSoil.Height2, locationSoil.Permeability2); if (crackFactor >= cCrackFactorLimit) { isCracking = true; } double headDrop = DetermineHeadDrop(locationSoil, locationGeometry); double partialPipingFactor = ((headDrop - (aWaterLevel - locationGeometry.PolderLevel)) / locationGeometry.DecimeringsHoogte); partialPipingFactor = partialPipingFactor * locationSoil.ChanceOccurence; pipingFactor = pipingFactor + partialPipingFactor; } if (isCracking) { return pipingFactor; } else { // If crackfactor for all soils is < cCrackFactorLimit then no cracking (opbarsten) will occur and a safe pipingfactor will be returned return cPipingFactorIfNoCracking; } } /// /// Determine demping; required for CrackFactor determination /// /// /// /// /// /// /// /// /// /// private double DetermineDemping(double aWaterLevel, double aPolderLevel, double aD, double aL, double aD1, double aK1, double aD2, double aK2) { double cv = aD*0.00001; return (aWaterLevel-aPolderLevel) * Math.Exp(-cv * aD * aL / ( aK1*aD1 + aK2 * aD2))/(aWaterLevel - aPolderLevel); } /// /// Determine Crackfactor (opbarstfactor) /// /// /// /// /// /// /// /// /// /// /// /// public double DetermineCrackFactor(double aFNeer, double aTopLevelSand, double aWaterLevel, double aPolderLevel, double aD, double aL, double aD1, double aK1, double aD2, double aK2) { double demping = DetermineDemping(aWaterLevel, aPolderLevel, aD, aL, aK1, aD1, aD2, aK2); return (aFNeer * aD) / ((demping * (aWaterLevel - aPolderLevel) - aTopLevelSand)* 10); } /// /// Determine piping chance by weighted average of all soils belonging to location. /// Waterlevel is specified /// /// /// /// Piping Chance public double DetermineLocationPipingChanceFromWaterLevel(string aLocation, double aWaterLevel, double aWaterLevelMax) { PipingDAMLocationGeometryStruct locationGeometry = fPipingDAMInput.GetLocationGeometry(aLocation); List locationSoils = fPipingDAMInput.GetLocationSoils(aLocation); double pipingChance = 0.0; IntPtr calcHandle = PipingDAMBBNDll.CreateHandle(); const double cToleranceWaterlevelTrend = 0.2; // (m) try { foreach (PipingDAMLocationSoilStruct locationSoil in locationSoils) { double headDrop; double headDropWell; DetermineHeadDropExt(locationSoil, locationGeometry, out headDrop, out headDropWell); PipingDAMBBNDll.SetBBNFilename(calcHandle, sDGSDAMPipingBBN); var pipingDAMBBNDllInput = new PipingDAMBBNInputStruct(); double crackFactor = DetermineCrackFactor(locationGeometry.FNeer, locationGeometry.BovenkantZand, aWaterLevel, locationGeometry.PolderLevel, locationGeometry.thicknessSoftSoils, locationGeometry.SeepageLength, locationSoil.Height1, locationSoil.Permeability1, locationSoil.Height2, locationSoil.Permeability2); double crackFactorFor1MeterHigherLevel = DetermineCrackFactor(locationGeometry.FNeer, locationGeometry.BovenkantZand, aWaterLevel + 1.0, locationGeometry.PolderLevel, locationGeometry.thicknessSoftSoils, locationGeometry.SeepageLength, locationSoil.Height1, locationSoil.Permeability1, locationSoil.Height2, locationSoil.Permeability2); double crackFactorAtMaxLevel = DetermineCrackFactor(locationGeometry.FNeer, locationGeometry.BovenkantZand, aWaterLevelMax, locationGeometry.PolderLevel, locationGeometry.thicknessSoftSoils, locationGeometry.SeepageLength, locationSoil.Height1, locationSoil.Permeability1, locationSoil.Height2, locationSoil.Permeability2); pipingDAMBBNDllInput.CrackFactor = crackFactor; pipingDAMBBNDllInput.IsWellVisible = locationGeometry.IsWellVisible; pipingDAMBBNDllInput.IsSandBoilVisible = locationGeometry.IsSandBoilVisible; pipingDAMBBNDllInput.HistoricSandBoil = (int)locationGeometry.HistoricSandBoil; pipingDAMBBNDllInput.QualityOfSurvey = (int)locationGeometry.PipingDAMRegionInfo.QualityOfSurvey; pipingDAMBBNDllInput.ElapsedTimeSinceLastSurvey = (int) locationGeometry.PipingDAMRegionInfo.ElapsedTimeSinceLastSurvey; pipingDAMBBNDllInput.HistoricMaxLevelComparison = (int) locationGeometry.PipingDAMRegionInfo.HistoricMaxLevelComparison; if (aWaterLevel > aWaterLevelMax + cToleranceWaterlevelTrend) { pipingDAMBBNDllInput.WaterLevelTrend = (int)DAMPipingWaterLevelTrend.AtTop; } else { pipingDAMBBNDllInput.WaterLevelTrend = (int)DAMPipingWaterLevelTrend.Rising; } pipingDAMBBNDllInput.CrackFactorAtMaxLevel = crackFactorAtMaxLevel; pipingDAMBBNDllInput.CrackFactorSensitivity = crackFactorFor1MeterHigherLevel - crackFactor; pipingDAMBBNDllInput.WaterLevelChange = aWaterLevelMax - aWaterLevel; pipingDAMBBNDllInput.CalculatedSandBoilLevelDiff = aWaterLevelMax - headDropWell; pipingDAMBBNDllInput.CalculatedOpenPipeLevelDiff = aWaterLevelMax - headDrop; bool isSandBoilCalculated = (aWaterLevel > headDropWell); bool isOpenPipeCalculated = (aWaterLevel > headDrop); pipingDAMBBNDllInput.IsSandBoilCalculated = isSandBoilCalculated; pipingDAMBBNDllInput.IsOpenPipeCalculated = isOpenPipeCalculated; PipingDAMBBNDll.SetInputParameters(calcHandle, pipingDAMBBNDllInput); int calcResult = PipingDAMBBNDll.Calculate(calcHandle); if (calcResult != PipingDAMBBNDll.cDllErrorNone) { throw new Exception(PipingDAMBBNDll.GetErrorMessage(calcHandle)); } PipingDAMBBNOutputStruct pipingDAMBBNDllOutput = new PipingDAMBBNOutputStruct(); PipingDAMBBNDll.GetOutputParameters(calcHandle, ref pipingDAMBBNDllOutput); double partialPipingChance = pipingDAMBBNDllOutput.ChanceOpenPipeTrue; partialPipingChance = partialPipingChance * locationSoil.ChanceOccurence; pipingChance = pipingChance + partialPipingChance; } } finally { PipingDAMBBNDll.DestroyHandle(calcHandle); } return pipingChance; } /// /// Determine critical headdrop and headdrop when WellContent of 0.001 is reached for given soil and geometry /// /// /// /// /// public void DetermineHeadDropExt(PipingDAMLocationSoilStruct aSoil, PipingDAMLocationGeometryStruct aGeometry, out double aHeadDrop, out double aHeadDropWell) { const double CWellContent = 0.001; PipingModel3Calculation pipingModel3Calculation = new PipingModel3Calculation(); pipingModel3Calculation.PipingCommonData = fPipingDAMInput.CommonData; pipingModel3Calculation.CrackLength = aGeometry.thicknessSoftSoils; pipingModel3Calculation.Height1 = aSoil.Height1; pipingModel3Calculation.Height2 = aSoil.Height2; pipingModel3Calculation.IsHeadDropCalculation = true; pipingModel3Calculation.ParticleDiameter = aSoil.ParticleDiameter; pipingModel3Calculation.Permeability1 = aSoil.Permeability1; pipingModel3Calculation.Permeability2 = aSoil.Permeability2; pipingModel3Calculation.Permeability3 = aSoil.Permeability3; pipingModel3Calculation.SeepageLength = aGeometry.SeepageLength; pipingModel3Calculation.WellContent = CWellContent; pipingModel3Calculation.CalculateHeadDropPC3(); aHeadDrop = pipingModel3Calculation.HeadDrop; aHeadDropWell = pipingModel3Calculation.HeadDropWell; } /// /// Determine headdrop for given soil and geometry /// /// /// /// Head drop public double DetermineHeadDrop(PipingDAMLocationSoilStruct aSoil, PipingDAMLocationGeometryStruct aGeometry) { double headDrop; double headDropWell; DetermineHeadDropExt(aSoil, aGeometry, out headDrop, out headDropWell); return headDrop; } } }