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;
}
}
}