// Copyright (C) Stichting Deltares 2017. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine 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 System; using System.Runtime.Serialization; using Deltares.DamEngine.Data.Geotechnics; namespace Deltares.DamEngine.Calculators.Uplift { [Serializable] public class UpliftCalculatorException : ApplicationException { // // For guidelines regarding the creation of new exception types, see // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconerrorraisinghandlingguidelines.asp // and // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp07192001.asp // public UpliftCalculatorException() {} public UpliftCalculatorException(string message) : base(message) {} public UpliftCalculatorException(string message, ApplicationException inner) : base(message, inner) {} protected UpliftCalculatorException( SerializationInfo info, StreamingContext context) : base(info, context) {} } public class UpliftCalculator { public UpliftCalculator() { VolumicWeightOfWater = 9.81; UnitWeightSoilEmbankment = null; IsUseOvenDryUnitWeight = false; } public bool IsUseOvenDryUnitWeight { get; set; } public double VolumicWeightOfWater { get; set; } public SoilProfile1D SoilProfile { get; set; } public double TopOfLayerToBeEvaluated { get; set; } public double SurfaceLevel { get; set; } public double PhreaticLevel { get; set; } public double UpLiftTopLevel { get; set; } public double? UnitWeightSoilEmbankment { get; set; } /// /// /// /// /// public double CalculateUpliftFactor(double headOfPLLine) { ThrowWhenSoilProfileIsNull(); var massCalculator = CreateSoilVolumeMassCalculator(); massCalculator.IsUseOvenDryUnitWeight = IsUseOvenDryUnitWeight; var mass = massCalculator.CalculateTotalMass(); var height = headOfPLLine - TopOfLayerToBeEvaluated; var phreaticPressure = VolumicWeightOfWater*height; if (phreaticPressure > 0) { return mass/phreaticPressure; } else { return double.MaxValue; } } /// /// Calculate soil extra height to be added to obtain the specified upliftFactor with a given head of PLline /// /// /// /// /// Required extra height public double CalculateExtraHeight(double headOfPLLine, double upliftFactor) { ThrowWhenSoilProfileIsNull(); var massCalculator = CreateSoilVolumeMassCalculator(); var mass = massCalculator.CalculateTotalMass(); var toplevel = Math.Min(SurfaceLevel, TopOfLayerToBeEvaluated); var height = headOfPLLine - toplevel; var phreaticPressure = VolumicWeightOfWater*height; double requiredExtraMass = upliftFactor*phreaticPressure - mass; double unitWeightSoil = SoilProfile.Layers[0].Soil.AbovePhreaticLevel; if (UnitWeightSoilEmbankment != null) { unitWeightSoil = UnitWeightSoilEmbankment.Value; } if (requiredExtraMass > 0) { return requiredExtraMass/unitWeightSoil; } else { return 0.0; } } /// /// /// /// /// public double CalculateHeadOfPLLine(double upliftFactor) { ThrowWhenSoilProfileIsNull(); var massCalculator = CreateSoilVolumeMassCalculator(); massCalculator.IsUseOvenDryUnitWeight = IsUseOvenDryUnitWeight; var massSoils = massCalculator.CalculateTotalMass(); var massWater = massSoils/(upliftFactor*VolumicWeightOfWater); return massWater + TopOfLayerToBeEvaluated; } /// /// /// /// private SoilVolumicMassCalculator CreateSoilVolumeMassCalculator() { SoilProfile1D updatedSoilProfile = AddTopLayerIfSurfaceLevelHigherThenToplevelSoilProfile(SoilProfile); return new SoilVolumicMassCalculator { PhreaticLevel = PhreaticLevel, SoilProfile = updatedSoilProfile, TopOfLayerToBeEvaluated = TopOfLayerToBeEvaluated, SurfaceLevel = SurfaceLevel, VolumicWeightOfWater = VolumicWeightOfWater }; } /// /// Adds an extra top layer if surface level is higher then toplevel soil profile. /// /// The updated soil profile. /// private SoilProfile1D AddTopLayerIfSurfaceLevelHigherThenToplevelSoilProfile(SoilProfile1D updatedSoilProfile) { if ((SurfaceLevel > SoilProfile.TopLevel) && (UnitWeightSoilEmbankment != null)) { updatedSoilProfile = new SoilProfile1D(); updatedSoilProfile.Assign(SoilProfile); updatedSoilProfile.Layers.Insert(0, new SoilLayer1D(new Soil() { AbovePhreaticLevel = UnitWeightSoilEmbankment.Value, BelowPhreaticLevel = UnitWeightSoilEmbankment.Value }, SurfaceLevel)); } return updatedSoilProfile; } /// /// Check precondition /// private void ThrowWhenSoilProfileIsNull() { if (SoilProfile == null) { throw new UpliftCalculatorException("The soilprofile is not defined"); } } } }